mirror of
https://github.com/dpethes/rerogue.git
synced 2025-06-07 18:58:32 +02:00
terrain viewer: use textures. Works for quads only at the moment
This commit is contained in:
parent
93536c4b64
commit
ef525fc0ff
@ -20,9 +20,9 @@ type
|
|||||||
TTile = packed record
|
TTile = packed record
|
||||||
texture_index: word;
|
texture_index: word;
|
||||||
unknown_attrib: byte;
|
unknown_attrib: byte;
|
||||||
unknown_lo: byte;
|
height_lo: byte;
|
||||||
unknown_hi: byte;
|
height_hi: byte;
|
||||||
unknown: array[0..24] of byte;
|
heights: array[0..24] of byte;
|
||||||
end;
|
end;
|
||||||
PTile = ^TTile;
|
PTile = ^TTile;
|
||||||
|
|
||||||
@ -52,10 +52,6 @@ type
|
|||||||
|
|
||||||
procedure LoadTextures(const tex_fname, texidx_fname: string);
|
procedure LoadTextures(const tex_fname, texidx_fname: string);
|
||||||
procedure LoadHeightmap(fname: string);
|
procedure LoadHeightmap(fname: string);
|
||||||
procedure GenerateCompositeTexture;
|
|
||||||
procedure HeightmapToTexture;
|
|
||||||
procedure GenerateVertices;
|
|
||||||
procedure WriteToObj(const objFname: string);
|
|
||||||
|
|
||||||
public
|
public
|
||||||
heightmap: THeightmap;
|
heightmap: THeightmap;
|
||||||
@ -66,12 +62,12 @@ type
|
|||||||
property TileHeight: word read heightmap.height;
|
property TileHeight: word read heightmap.height;
|
||||||
|
|
||||||
procedure LoadFromFiles(const hmp, tex, texmap: string);
|
procedure LoadFromFiles(const hmp, tex, texmap: string);
|
||||||
procedure ExportToObj(const objfname: string);
|
|
||||||
|
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure pnm_save(const fname: string; const p: pbyte; const w, h: integer);
|
||||||
|
|
||||||
//**************************************************************************************************
|
//**************************************************************************************************
|
||||||
implementation
|
implementation
|
||||||
@ -102,7 +98,7 @@ Begin
|
|||||||
CloseFile (f);
|
CloseFile (f);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure convert_4bit_to_32bit(const indices: PByte; const w, h: Word; const image: PByte; const pal: TPalette_4bit);
|
procedure convert_4bit_to_24bit(const indices: PByte; const w, h: Word; const image: PByte; const pal: TPalette_4bit);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
index: integer;
|
index: integer;
|
||||||
@ -173,7 +169,7 @@ begin
|
|||||||
image := getmem(TEX_WIDTH * TEX_HEIGHT * 3);
|
image := getmem(TEX_WIDTH * TEX_HEIGHT * 3);
|
||||||
Blockread(f, buf^, tex_size);
|
Blockread(f, buf^, tex_size);
|
||||||
Blockread(f, palette, palette_size);
|
Blockread(f, palette, palette_size);
|
||||||
convert_4bit_to_32bit(buf, TEX_WIDTH, TEX_HEIGHT, image, palette);
|
convert_4bit_to_24bit(buf, TEX_WIDTH, TEX_HEIGHT, image, palette);
|
||||||
heightmap.textures[i] := image;
|
heightmap.textures[i] := image;
|
||||||
end;
|
end;
|
||||||
freemem(buf);
|
freemem(buf);
|
||||||
@ -231,189 +227,10 @@ begin
|
|||||||
CloseFile(f);
|
CloseFile(f);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TWorld.GenerateCompositeTexture;
|
|
||||||
var
|
|
||||||
image: pbyte;
|
|
||||||
image_size: integer;
|
|
||||||
x, y, stride: integer;
|
|
||||||
tile_idx, texture_idx, texmap_idx: integer;
|
|
||||||
texture: pbyte;
|
|
||||||
begin
|
|
||||||
image_size := heightmap.width * heightmap.height * TEX_WIDTH * TEX_HEIGHT * 3;
|
|
||||||
image := GetMem(image_size);
|
|
||||||
stride := heightmap.width * TEX_WIDTH * 3;
|
|
||||||
|
|
||||||
for y := 0 to heightmap.height - 1 do
|
|
||||||
for x := 0 to heightmap.width - 1 do begin
|
|
||||||
tile_idx := heightmap.blk[y * heightmap.width + x];
|
|
||||||
|
|
||||||
texmap_idx := heightmap.tiles[tile_idx].texture_index;
|
|
||||||
if texmap_idx > Length(heightmap.texture_index_map) - 1 then
|
|
||||||
texmap_idx := 0;
|
|
||||||
|
|
||||||
texture_idx := heightmap.texture_index_map[texmap_idx];
|
|
||||||
texture := heightmap.textures[texture_idx];
|
|
||||||
CopyTexToXY(image, texture, x * TEX_WIDTH, (heightmap.height - y - 1) * TEX_HEIGHT, stride);
|
|
||||||
end;
|
|
||||||
|
|
||||||
world_texture := image;
|
|
||||||
pnm_save(TEXTURE_FNAME, image, heightmap.width * TEX_WIDTH, heightmap.height * TEX_HEIGHT);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TWorld.HeightmapToTexture;
|
|
||||||
const
|
|
||||||
TILE_WIDTH = 4;
|
|
||||||
SCALE = 128;
|
|
||||||
var
|
|
||||||
x, y: integer;
|
|
||||||
tile_idx: integer;
|
|
||||||
i: integer;
|
|
||||||
image_size: integer;
|
|
||||||
image: pbyte;
|
|
||||||
begin
|
|
||||||
image_size := heightmap.width * heightmap.height * TILE_WIDTH * TILE_WIDTH;
|
|
||||||
image := GetMem(image_size);
|
|
||||||
|
|
||||||
for y := 0 to heightmap.height - 1 do begin
|
|
||||||
for x := 0 to heightmap.width - 1 do begin
|
|
||||||
tile_idx := heightmap.blk[y * heightmap.width + x];
|
|
||||||
|
|
||||||
CopyTileToXY(image, @(heightmap.tiles[tile_idx].unknown),
|
|
||||||
x * TILE_WIDTH, (heightmap.height - y - 1) * TILE_WIDTH, heightmap.width * TILE_WIDTH);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
//scale
|
|
||||||
for i := 0 to image_size - 1 do
|
|
||||||
image[i] := byte(image[i] + SCALE);
|
|
||||||
|
|
||||||
height_texture := image;
|
|
||||||
//pgm_save('map_height.pgm', image, heightmap.width * TILE_WIDTH, heightmap.height * TILE_WIDTH);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{
|
|
||||||
While vertical scaling is stored within file, horizontal seems to be always 0.5
|
|
||||||
The height values need to be centered, 128 seems to be the correct offset.
|
|
||||||
The generated y coords are flipped for (opengl) rendering
|
|
||||||
}
|
|
||||||
procedure TWorld.GenerateVertices;
|
|
||||||
const
|
|
||||||
h_scale = 0.5;
|
|
||||||
var
|
|
||||||
va_size: integer;
|
|
||||||
x, y: integer;
|
|
||||||
vert: TVertex3f;
|
|
||||||
width_half, height_half: integer;
|
|
||||||
i: integer;
|
|
||||||
v_scale: single;
|
|
||||||
begin
|
|
||||||
vertex_count := heightmap.width * 4 * heightmap.height * 4;
|
|
||||||
va_size := vertex_count * SizeOf(TVertex3f);
|
|
||||||
vertex_array := getmem(va_size);
|
|
||||||
|
|
||||||
width_half := heightmap.width * 2;
|
|
||||||
height_half := heightmap.height * 2;
|
|
||||||
v_scale := heightmap.y_scale;
|
|
||||||
|
|
||||||
for y := 0 to heightmap.height * 4 - 1 do
|
|
||||||
for x := 0 to heightmap.width * 4 - 1 do begin
|
|
||||||
vert.x := (-width_half + x) * h_scale;
|
|
||||||
vert.z := (-height_half + y) * h_scale;
|
|
||||||
vert.u := x / (heightmap.width * 4);
|
|
||||||
vert.v := y / (heightmap.height * 4);
|
|
||||||
i := y * heightmap.width * 4 + x;
|
|
||||||
vert.y := (height_texture[i] - 128) * v_scale;
|
|
||||||
vert.y := -vert.y;
|
|
||||||
vertex_array[i] := vert;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure SaveMaterialFile(const obj_fname, mtl_name, texture_fname: string);
|
|
||||||
var
|
|
||||||
f: TextFile;
|
|
||||||
begin
|
|
||||||
AssignFile(f, obj_fname + '.mtl');
|
|
||||||
Rewrite(f);
|
|
||||||
|
|
||||||
writeln(f, '# RS heightmap');
|
|
||||||
writeln(f, 'newmtl ', mtl_name); //begin new material
|
|
||||||
writeln(f, 'map_Kd ', texture_fname); //texture
|
|
||||||
writeln(f, 'Ka 1.000 1.000 1.000'); //ambient color
|
|
||||||
writeln(f, 'Kd 1.000 1.000 1.000'); //diffuse color
|
|
||||||
writeln(f, 'Ks 1.000 1.000 1.000'); //specular color
|
|
||||||
writeln(f, 'Ns 100.0'); //specular weight
|
|
||||||
writeln(f, 'illum 2'); //Color on and Ambient on, Highlight on
|
|
||||||
|
|
||||||
CloseFile(f);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TWorld.WriteToObj(const objFname: string);
|
|
||||||
const
|
|
||||||
MAT_NAME = 'default';
|
|
||||||
var
|
|
||||||
f: textfile;
|
|
||||||
i: integer;
|
|
||||||
v: TVertex3f;
|
|
||||||
x, y, stride: integer;
|
|
||||||
i2, i3: integer;
|
|
||||||
texfname: string;
|
|
||||||
begin
|
|
||||||
AssignFile(f, objFname);
|
|
||||||
Rewrite(f);
|
|
||||||
|
|
||||||
writeln(f, '# RS heightmap');
|
|
||||||
writeln(f, 'mtllib ', objFname + '.mtl');
|
|
||||||
|
|
||||||
//vertices
|
|
||||||
for i := 0 to vertex_count - 1 do begin
|
|
||||||
v := vertex_array[i];
|
|
||||||
writeln(f, 'v ', v.x:10:6, ' ', v.y:10:6, ' ', v.z:10:6);
|
|
||||||
end;
|
|
||||||
|
|
||||||
//uv-s
|
|
||||||
for i := 0 to vertex_count - 1 do begin
|
|
||||||
v := vertex_array[i];
|
|
||||||
writeln(f, 'vt ', v.u:10:6, ' ', v.v:10:6);
|
|
||||||
end;
|
|
||||||
|
|
||||||
//select material
|
|
||||||
writeln(f, 'usemtl ' + MAT_NAME);
|
|
||||||
|
|
||||||
//faces
|
|
||||||
{
|
|
||||||
12 2
|
|
||||||
3 34
|
|
||||||
}
|
|
||||||
stride := heightmap.width * 4;
|
|
||||||
for y := 0 to heightmap.height * 4 - 2 do
|
|
||||||
for x := 0 to heightmap.width * 4 - 2 do begin
|
|
||||||
i := y * stride + x + 1;
|
|
||||||
i2 := i + 1;
|
|
||||||
i3 := i + stride;
|
|
||||||
writeln(f, Format('f %d/%d %d/%d %d/%d', [i, i, i2, i2, i3, i3]));
|
|
||||||
i := i3 + 1;
|
|
||||||
writeln(f, Format('f %d/%d %d/%d %d/%d', [i2, i2, i, i, i3, i3]));
|
|
||||||
end;
|
|
||||||
|
|
||||||
CloseFile(f);
|
|
||||||
|
|
||||||
SaveMaterialFile(objFname, MAT_NAME, TEXTURE_FNAME);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TWorld.LoadFromFiles(const hmp, tex, texmap: string);
|
procedure TWorld.LoadFromFiles(const hmp, tex, texmap: string);
|
||||||
begin
|
begin
|
||||||
LoadHeightmap(hmp);
|
LoadHeightmap(hmp);
|
||||||
//LoadTextures(tex, texmap);
|
LoadTextures(tex, texmap);
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TWorld.ExportToObj(const objfname: string);
|
|
||||||
begin
|
|
||||||
//GenerateCompositeTexture;
|
|
||||||
HeightmapToTexture;
|
|
||||||
GenerateVertices;
|
|
||||||
//WriteToObj(objfname);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TWorld.Create;
|
constructor TWorld.Create;
|
||||||
|
@ -17,10 +17,18 @@ type
|
|||||||
fg_to_draw: integer;
|
fg_to_draw: integer;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TTerrainBlock = packed record
|
||||||
|
texture_index: integer;
|
||||||
|
vertices: array[0..25] of TVertex3f;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TTerrainMesh }
|
{ TTerrainMesh }
|
||||||
TTerrainMesh = class
|
TTerrainMesh = class
|
||||||
private
|
private
|
||||||
terrain: TWorld;
|
terrain: TWorld;
|
||||||
|
blocks: array of array of TTerrainBlock;
|
||||||
|
textures_glidx: array of integer;
|
||||||
|
procedure TransformTiles;
|
||||||
public
|
public
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure Load(const hmp_filename: string);
|
procedure Load(const hmp_filename: string);
|
||||||
@ -30,6 +38,56 @@ type
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
{
|
||||||
|
While vertical scaling is stored within file, horizontal seems to be always 0.5
|
||||||
|
The generated y coords are flipped for (opengl) rendering
|
||||||
|
}
|
||||||
|
procedure TTerrainMesh.TransformTiles;
|
||||||
|
|
||||||
|
//basex/y - offset in vertices
|
||||||
|
procedure TileToBlock(var blk: TTerrainBlock; var tile: TTile; basex, basey: integer);
|
||||||
|
const
|
||||||
|
h_scale = 0.5;
|
||||||
|
var
|
||||||
|
x, y: integer;
|
||||||
|
v: TVertex3f;
|
||||||
|
width_half, height_half: integer; //size in vertices
|
||||||
|
v_scale: single;
|
||||||
|
begin
|
||||||
|
width_half := terrain.TileWidth * 2;
|
||||||
|
height_half := terrain.TileHeight * 2;
|
||||||
|
v_scale := terrain.heightmap.y_scale;
|
||||||
|
for y := 0 to 4 do
|
||||||
|
for x := 0 to 4 do begin
|
||||||
|
v.x := (-width_half + basex + x) * h_scale;
|
||||||
|
v.z := (-height_half + basey + y) * h_scale;
|
||||||
|
v.u := -x * 1/4;
|
||||||
|
v.v := -y * 1/4;
|
||||||
|
v.y := shortint(tile.heights[y+x*5]) * v_scale; //hmm... all transforms are flipped?
|
||||||
|
v.y := -v.y;
|
||||||
|
|
||||||
|
blk.vertices[y * 5 + x] := v;
|
||||||
|
end;
|
||||||
|
blk.texture_index := tile.texture_index;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
x, y, i, tile_idx: integer;
|
||||||
|
blk: TTerrainBlock;
|
||||||
|
tile: TTile;
|
||||||
|
begin
|
||||||
|
SetLength(blocks, terrain.TileWidth, terrain.TileHeight);
|
||||||
|
for y := 0 to terrain.TileHeight - 1 do begin
|
||||||
|
for x := 0 to terrain.TileWidth - 1 do begin
|
||||||
|
tile_idx := terrain.heightmap.blk[y * terrain.TileWidth + x];
|
||||||
|
tile := terrain.heightmap.tiles[tile_idx];
|
||||||
|
|
||||||
|
TileToBlock(blk, tile, y * 4, x * 4);
|
||||||
|
blocks[y, x] := blk;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
destructor TTerrainMesh.Destroy;
|
destructor TTerrainMesh.Destroy;
|
||||||
begin
|
begin
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
@ -38,22 +96,112 @@ end;
|
|||||||
procedure TTerrainMesh.Load(const hmp_filename: string);
|
procedure TTerrainMesh.Load(const hmp_filename: string);
|
||||||
begin
|
begin
|
||||||
terrain := TWorld.Create;
|
terrain := TWorld.Create;
|
||||||
terrain.LoadFromFiles(hmp_filename, '', '');
|
terrain.LoadFromFiles('hmp_0', 'lv_0.text', 'lv_0.tex');
|
||||||
terrain.ExportToObj(''); //generate vertices
|
//terrain.LoadFromFiles('hmp_1', 'lv_1.text', 'lv_1.tex');
|
||||||
|
TransformTiles;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//generate textures / texture atlas?
|
//generate textures. TODO texture atlas?
|
||||||
procedure TTerrainMesh.InitGL;
|
procedure TTerrainMesh.InitGL;
|
||||||
begin
|
|
||||||
|
|
||||||
end;
|
procedure GenTexture(tex_idx: integer);
|
||||||
|
const
|
||||||
|
TexW = 64;
|
||||||
|
TexH = 64;
|
||||||
|
var
|
||||||
|
tex: pbyte;
|
||||||
|
y: Integer;
|
||||||
|
x: Integer;
|
||||||
|
begin
|
||||||
|
glGenTextures(1, @textures_glidx[tex_idx]);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textures_glidx[tex_idx]);
|
||||||
|
|
||||||
|
tex := terrain.heightmap.textures[tex_idx];
|
||||||
|
//pnm_save('tex'+IntToStr(tex_idx) + '.pnm', tex, TexW, TexH); //debug
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, TexW, TexH, 0, GL_RGB, GL_UNSIGNED_BYTE, tex);
|
||||||
|
|
||||||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||||
|
//glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||||
|
//glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||||
|
end;
|
||||||
|
|
||||||
//draw vertices / tiles around actual position
|
|
||||||
procedure TTerrainMesh.DrawGL(opts: TRenderOpts);
|
|
||||||
var
|
var
|
||||||
i: integer;
|
i: integer;
|
||||||
|
begin
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
SetLength(textures_glidx, terrain.heightmap.texture_count);
|
||||||
|
for i := 0 to terrain.heightmap.texture_count - 1 do
|
||||||
|
GenTexture(i);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//draw vertices from each block
|
||||||
|
procedure TTerrainMesh.DrawGL(opts: TRenderOpts);
|
||||||
|
|
||||||
|
procedure RenderBlock(var blk: TTerrainBlock);
|
||||||
|
var
|
||||||
|
i, x, y, stride: integer;
|
||||||
v: TVertex3f;
|
v: TVertex3f;
|
||||||
begin
|
begin
|
||||||
|
stride := 5;
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textures_glidx[blk.texture_index]);
|
||||||
|
{
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
//glColor3f(0, 1, 0);
|
||||||
|
for y := 0 to 3 do
|
||||||
|
for x := 0 to 3 do begin
|
||||||
|
//do two triangles
|
||||||
|
i := y * stride + x;
|
||||||
|
|
||||||
|
v := blk.vertices[i + 1];
|
||||||
|
glVertex3fv(@v);
|
||||||
|
glTexCoord2f(v.u, v.v);
|
||||||
|
v := blk.vertices[i];
|
||||||
|
glVertex3fv(@v);
|
||||||
|
glTexCoord2f(v.u, v.v);
|
||||||
|
v := blk.vertices[i + stride];
|
||||||
|
glVertex3fv(@v);
|
||||||
|
glTexCoord2f(v.u, v.v);
|
||||||
|
|
||||||
|
v := blk.vertices[i + 1];
|
||||||
|
glVertex3fv(@v);
|
||||||
|
glTexCoord2f(v.u, v.v);
|
||||||
|
v := blk.vertices[i + stride];
|
||||||
|
glVertex3fv(@v);
|
||||||
|
glTexCoord2f(v.u, v.v);
|
||||||
|
v := blk.vertices[i + stride + 1];
|
||||||
|
glVertex3fv(@v);
|
||||||
|
glTexCoord2f(v.u, v.v);
|
||||||
|
end;
|
||||||
|
glEnd;
|
||||||
|
|
||||||
|
}
|
||||||
|
//quad from block corners
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
i := y * stride + x;
|
||||||
|
|
||||||
|
v := blk.vertices[4];
|
||||||
|
glVertex3fv(@v);
|
||||||
|
glTexCoord2f(v.u, v.v);
|
||||||
|
v := blk.vertices[0];
|
||||||
|
glVertex3fv(@v);
|
||||||
|
glTexCoord2f(v.u, v.v);
|
||||||
|
v := blk.vertices[20];
|
||||||
|
glVertex3fv(@v);
|
||||||
|
glTexCoord2f(v.u, v.v);
|
||||||
|
v := blk.vertices[24];
|
||||||
|
glVertex3fv(@v);
|
||||||
|
glTexCoord2f(v.u, v.v);
|
||||||
|
glEnd;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
i, x, y, stride: integer;
|
||||||
|
blk: TTerrainBlock;
|
||||||
|
v: TVertex3f;
|
||||||
|
begin
|
||||||
|
if opts.points then begin
|
||||||
glBegin(GL_POINTS);
|
glBegin(GL_POINTS);
|
||||||
glColor3f(0, 1, 0);
|
glColor3f(0, 1, 0);
|
||||||
for i := 0 to terrain.vertex_count - 1 do begin
|
for i := 0 to terrain.vertex_count - 1 do begin
|
||||||
@ -61,6 +209,18 @@ begin
|
|||||||
glVertex3fv(@v);
|
glVertex3fv(@v);
|
||||||
end;
|
end;
|
||||||
glEnd;
|
glEnd;
|
||||||
|
end else begin
|
||||||
|
if opts.wireframe then
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
|
||||||
|
else
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
for y := 0 to terrain.TileHeight - 1 do
|
||||||
|
for x := 0 to terrain.TileWidth - 1 do begin
|
||||||
|
blk := blocks[y, x];
|
||||||
|
RenderBlock(blk);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -338,7 +338,7 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
if Paramcount < 1 then begin
|
if Paramcount < 1 then begin
|
||||||
writeln('specify HOB file');
|
writeln('specify HMP file');
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
in_file := ParamStr(1);
|
in_file := ParamStr(1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user