FMainForm.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. unit FMainForm;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. System.SysUtils,
  6. System.Classes,
  7. System.Actions,
  8. System.Math,
  9. Vcl.Graphics,
  10. Vcl.Controls,
  11. Vcl.Forms,
  12. Vcl.Dialogs,
  13. ValEdit,
  14. Vcl.Grids,
  15. Vcl.Menus,
  16. Vcl.StdCtrls,
  17. Vcl.ComCtrls,
  18. Vcl.ToolWin,
  19. Vcl.ExtCtrls,
  20. Vcl.ActnList,
  21. Vcl.ImgList,
  22. GLS.HeightTileFileHDS;
  23. type
  24. TSrc = record
  25. fs : TFileStream;
  26. x, y, w, h : Integer;
  27. format : Integer;
  28. FlipRotate : Integer;
  29. end;
  30. PSrc = ^TSrc;
  31. TMainForm = class(TForm)
  32. MainMenu: TMainMenu;
  33. StringGrid: TStringGrid;
  34. File1: TMenuItem;
  35. ActionList: TActionList;
  36. ImageList: TImageList;
  37. ACOpen: TAction;
  38. ACSave: TAction;
  39. ACExit: TAction;
  40. Open1: TMenuItem;
  41. Save1: TMenuItem;
  42. N1: TMenuItem;
  43. Exit1: TMenuItem;
  44. Panel1: TPanel;
  45. Label1: TLabel;
  46. Label2: TLabel;
  47. EDHTFName: TEdit;
  48. EDDEMPath: TEdit;
  49. BUDEMPath: TButton;
  50. BUPickHTF: TButton;
  51. ToolBar: TToolBar;
  52. ToolButton1: TToolButton;
  53. ToolButton2: TToolButton;
  54. ToolButton3: TToolButton;
  55. DEMs1: TMenuItem;
  56. ACNewDEM: TAction;
  57. ACRemoveDEM: TAction;
  58. ToolButton4: TToolButton;
  59. ToolButton5: TToolButton;
  60. AddDEMsource1: TMenuItem;
  61. RemoveDEMsource1: TMenuItem;
  62. SDHTF: TSaveDialog;
  63. PopupMenu: TPopupMenu;
  64. AddDEMsource2: TMenuItem;
  65. RemoveDEMsource2: TMenuItem;
  66. MIAbout: TMenuItem;
  67. CBType: TComboBox;
  68. CBFile: TComboBox;
  69. Label3: TLabel;
  70. EDSizeX: TEdit;
  71. EDSizeY: TEdit;
  72. Label4: TLabel;
  73. Label5: TLabel;
  74. EDDefaultZ: TEdit;
  75. ODTerrainPack: TOpenDialog;
  76. SDTerrainPack: TSaveDialog;
  77. ToolButton6: TToolButton;
  78. ACProcess: TAction;
  79. ToolButton7: TToolButton;
  80. N2: TMenuItem;
  81. Process1: TMenuItem;
  82. PanelFoot: TPanel;
  83. ProgressBar: TProgressBar;
  84. EDTileSize: TEdit;
  85. Label6: TLabel;
  86. ToolButton8: TToolButton;
  87. ACViewer: TAction;
  88. N3: TMenuItem;
  89. HTFViewer1: TMenuItem;
  90. ToolButton9: TToolButton;
  91. ODPath: TOpenDialog;
  92. Label7: TLabel;
  93. EDTileOverlap: TEdit;
  94. Label8: TLabel;
  95. EDZFilter: TEdit;
  96. Label9: TLabel;
  97. EDZScale: TEdit;
  98. CBWholeOnly: TCheckBox;
  99. CBFlipRotate: TComboBox;
  100. procedure ACExitExecute(Sender: TObject);
  101. procedure FormCreate(Sender: TObject);
  102. procedure BUDEMPathClick(Sender: TObject);
  103. procedure BUPickHTFClick(Sender: TObject);
  104. procedure MIAboutClick(Sender: TObject);
  105. procedure ActionListUpdate(Action: TBasicAction; var Handled: Boolean);
  106. procedure ACNewDEMExecute(Sender: TObject);
  107. procedure ACRemoveDEMExecute(Sender: TObject);
  108. procedure StringGridSelectCell(Sender: TObject; ACol, ARow: Integer;
  109. var CanSelect: Boolean);
  110. procedure CBTypeChange(Sender: TObject);
  111. procedure ACSaveExecute(Sender: TObject);
  112. procedure ACOpenExecute(Sender: TObject);
  113. procedure EDDEMPathChange(Sender: TObject);
  114. procedure FormDestroy(Sender: TObject);
  115. procedure EDDefaultZChange(Sender: TObject);
  116. procedure ACProcessExecute(Sender: TObject);
  117. procedure ACViewerExecute(Sender: TObject);
  118. procedure EDZFilterChange(Sender: TObject);
  119. procedure EDZScaleChange(Sender: TObject);
  120. private
  121. sources : array of TSrc;
  122. defaultZ : SmallInt;
  123. filterZ : SmallInt;
  124. zScale : Single;
  125. procedure Parse;
  126. procedure Cleanup;
  127. procedure SrcExtractFlip(src : PSrc; relX, relY, len : Integer; dest : PSmallInt);
  128. procedure SrcExtract(src : PSrc; relX, relY, len : Integer; dest : PSmallInt; DiagFlip:boolean=false);
  129. procedure WorldExtract(x, y, len : Integer; dest : PSmallInt);
  130. public
  131. end;
  132. var
  133. MainForm: TMainForm;
  134. implementation
  135. uses
  136. FViewerForm;
  137. {$R *.dfm}
  138. procedure TMainForm.FormCreate(Sender: TObject);
  139. var
  140. i : Integer;
  141. begin
  142. with ActionList do
  143. for i:=0 to ActionCount-1 do with TAction(Actions[i]) do
  144. Hint:=Caption;
  145. with StringGrid do begin
  146. Cells[0, 0]:='File Name'; ColWidths[0]:=140;
  147. Cells[1, 0]:='World Offset'; ColWidths[1]:=80;
  148. Cells[2, 0]:='Size (rotated)'; ColWidths[2]:=80;
  149. Cells[3, 0]:='Data type'; ColWidths[3]:=120;
  150. Cells[4, 0]:='Flip and Rotate'; ColWidths[4]:=110;
  151. Row:=0;
  152. end;
  153. zScale:=1;
  154. end;
  155. procedure TMainForm.FormDestroy(Sender: TObject);
  156. begin
  157. Cleanup;
  158. end;
  159. procedure TMainForm.ACExitExecute(Sender: TObject);
  160. begin
  161. Close;
  162. end;
  163. procedure TMainForm.BUDEMPathClick(Sender: TObject);
  164. begin
  165. ODPath.InitialDir:=EDDEMPath.Text;
  166. ODPath.FileName:=EDDEMPath.Text+'pick a dummy.file';
  167. if ODPath.Execute then
  168. EDDEMPath.Text:=ExtractFilePath(ODPath.FileName);
  169. end;
  170. procedure TMainForm.BUPickHTFClick(Sender: TObject);
  171. begin
  172. SDHTF.FileName:=EDHTFName.Text;
  173. if SDHTF.Execute then
  174. EDHTFName.Text:=SDHTF.FileName;
  175. end;
  176. procedure TMainForm.MIAboutClick(Sender: TObject);
  177. begin
  178. ShowMessage(Caption+#13#10#13#10
  179. +'HTF Generation Utility'#13#10
  180. +'Part of GLScene library.'#13#10#13#10
  181. +'http://glscene.org');
  182. end;
  183. procedure TMainForm.ActionListUpdate(Action: TBasicAction;
  184. var Handled: Boolean);
  185. begin
  186. ACRemoveDEM.Enabled:=(StringGrid.RowCount>2);
  187. end;
  188. procedure TMainForm.ACNewDEMExecute(Sender: TObject);
  189. begin
  190. StringGrid.RowCount:=StringGrid.RowCount+1;
  191. end;
  192. procedure TMainForm.ACRemoveDEMExecute(Sender: TObject);
  193. var
  194. i : Integer;
  195. begin
  196. with StringGrid do begin
  197. i:=Row;
  198. if i<RowCount-1 then begin
  199. while i<RowCount-1 do begin
  200. Rows[i]:=Rows[i+1];
  201. Inc(i);
  202. end;
  203. end else Row:=i-1;
  204. RowCount:=RowCount-1;
  205. end;
  206. end;
  207. procedure TMainForm.StringGridSelectCell(Sender: TObject; ACol,
  208. ARow: Integer; var CanSelect: Boolean);
  209. procedure SetCB(const cb : TComboBox);
  210. var
  211. r : TRect;
  212. i : Integer;
  213. begin
  214. r:=StringGrid.CellRect(ACol, ARow);
  215. cb.Left:=r.Left+StringGrid.Left;
  216. cb.Top:=r.Top+StringGrid.Top;
  217. cb.Width:=r.Right+1-r.Left;
  218. i:=cb.Items.IndexOf(StringGrid.Cells[ACol, ARow]);
  219. if i>=0 then
  220. cb.ItemIndex:=i
  221. else cb.Text:=StringGrid.Cells[ACol, ARow];
  222. if Visible then
  223. cb.SetFocus;
  224. end;
  225. begin
  226. if ARow>0 then begin
  227. if ACol=0 then begin
  228. CBFile.Visible:=True;
  229. SetCB(CBFile);
  230. end else CBFile.Visible:=False;
  231. if ACol=3 then begin
  232. CBType.Visible:=True;
  233. SetCB(CBType);
  234. end else CBType.Visible:=False;
  235. if ACol=4 then begin
  236. CBFlipRotate.Visible:=True;
  237. SetCB(CBFlipRotate);
  238. end else CBFlipRotate.Visible:=False;
  239. CanSelect:=True;
  240. end;
  241. end;
  242. procedure TMainForm.CBTypeChange(Sender: TObject);
  243. begin
  244. with StringGrid do
  245. Cells[Col, Row]:=(Sender as TComboBox).Text;
  246. end;
  247. procedure TMainForm.ACSaveExecute(Sender: TObject);
  248. var
  249. i : Integer;
  250. sl, sg : TStringList;
  251. begin
  252. if SDTerrainPack.Execute then begin
  253. sl:=TStringList.Create;
  254. with sl do begin
  255. Values['HTFName']:=EDHTFName.Text;
  256. Values['WorldSizeX']:=EDSizeX.Text;
  257. Values['WorldSizeY']:=EDSizeY.Text;
  258. Values['TileSize']:=EDTileSize.Text;
  259. Values['TileOverlap']:=EDTileOverlap.Text;
  260. Values['DefaultZ']:=EDDefaultZ.Text;
  261. Values['FilterZ']:=EDZFilter.Text;
  262. Values['ZScale']:=EDZScale.Text;
  263. Values['DEMPath']:=EDDEMPath.Text;
  264. Values['WholeTiles']:=IntToStr(Integer(CBWholeOnly.Checked));
  265. sg:=TStringList.Create;
  266. for i:=1 to StringGrid.RowCount-1 do
  267. sg.Add(StringGrid.Rows[i].CommaText);
  268. Values['DEMs']:=sg.CommaText;
  269. sg.Free;
  270. end;
  271. sl.SaveToFile(SDTerrainPack.FileName);
  272. sl.Free;
  273. end;
  274. end;
  275. procedure TMainForm.ACOpenExecute(Sender: TObject);
  276. var
  277. i : Integer;
  278. sl, sg : TStringList;
  279. begin
  280. if ODTerrainPack.Execute then begin
  281. sl:=TStringList.Create;
  282. sl.LoadFromFile(ODTerrainPack.FileName);
  283. with sl do begin
  284. EDHTFName.Text:=Values['HTFName'];
  285. EDSizeX.Text:=Values['WorldSizeX'];
  286. EDSizeY.Text:=Values['WorldSizeY'];
  287. EDTileSize.Text:=Values['TileSize'];
  288. EDTileOverlap.Text:=Values['TileOverlap'];
  289. EDDefaultZ.Text:=Values['DefaultZ'];
  290. EDZFilter.Text:=Values['FilterZ'];
  291. EDZScale.Text:=Values['ZScale'];
  292. EDDEMPath.Text:=Values['DEMPath'];
  293. CBWholeOnly.Checked:=(Values['WholeTiles']='1');
  294. sg:=TStringList.Create;
  295. sg.CommaText:=Values['DEMs'];
  296. StringGrid.RowCount:=sg.Count+1;
  297. for i:=0 to sg.Count-1 do
  298. StringGrid.Rows[i+1].CommaText:=sg[i];
  299. sg.Free;
  300. end;
  301. sl.Free;
  302. SDTerrainPack.FileName:=ODTerrainPack.FileName;
  303. end;
  304. end;
  305. procedure TMainForm.EDDEMPathChange(Sender: TObject);
  306. var
  307. f : TSearchRec;
  308. r : Integer;
  309. begin
  310. CBFile.Items.Clear;
  311. r:=FindFirst(EDDEMPath.Text+'\*.*', faAnyFile, f);
  312. while r=0 do begin
  313. if (f.Attr and faDirectory)=0 then
  314. CBFile.Items.Add(f.Name);
  315. r:=FindNext(f);
  316. end;
  317. FindClose(f);
  318. end;
  319. procedure TMainForm.EDDefaultZChange(Sender: TObject);
  320. begin
  321. defaultZ:=StrToIntDef(EDDefaultZ.Text, 0);
  322. if EDZFilter.Text='' then
  323. filterZ:=defaultZ;
  324. end;
  325. procedure TMainForm.EDZFilterChange(Sender: TObject);
  326. begin
  327. filterZ:=StrToIntDef(EDZFilter.Text, defaultZ);
  328. end;
  329. procedure TMainForm.EDZScaleChange(Sender: TObject);
  330. begin
  331. zScale:=StrToFloatDef(EDZScale.Text, 1.0);
  332. end;
  333. procedure TMainForm.Parse;
  334. var
  335. i, p : Integer;
  336. row : TStrings;
  337. begin
  338. Cleanup;
  339. SetLength(sources, StringGrid.RowCount-1);
  340. for i:=0 to High(sources) do begin
  341. row:=StringGrid.Rows[i+1];
  342. sources[i].fs:=TFileStream.Create(EDDEMPath.Text+'\'+row[0], fmOpenRead+fmShareDenyNone);
  343. p:=Pos(',', row[1]);
  344. sources[i].x:=StrToInt(Copy(row[1], 1, p-1));
  345. sources[i].y:=StrToInt(Copy(row[1], p+1, MaxInt));
  346. p:=Pos('x', row[2]);
  347. sources[i].w:=StrToInt(Copy(row[2], 1, p-1));
  348. sources[i].h:=StrToInt(Copy(row[2], p+1, MaxInt));
  349. sources[i].format:=CBType.Items.IndexOf(row[3]); //File format
  350. sources[i].FlipRotate:=CBFlipRotate.Items.IndexOf(row[4]); //Flip and Rotate
  351. end;
  352. end;
  353. procedure TMainForm.Cleanup;
  354. var
  355. i : Integer;
  356. begin
  357. for i:=0 to High(sources) do
  358. sources[i].fs.Free;
  359. SetLength(sources, 0);
  360. end;
  361. procedure TMainForm.SrcExtractFlip(src : PSrc; relX, relY, len : Integer; dest : PSmallInt);
  362. var i:integer;
  363. val:SmallInt;
  364. begin
  365. if src.FlipRotate<=0 then SrcExtract(src,relX, relY, len, dest) //None
  366. else begin
  367. for i:=0 to len-1 do begin
  368. case src.FlipRotate of
  369. //0 : SrcExtract(src,relX, relY+i,1,@val); //No change ( )
  370. 1 : SrcExtract(src,src.w-(relX+i),relY,1,@val); //H-Flip (Flip)
  371. 2 : SrcExtract(src,relY,src.w-(relX+i),1,@val,true); //DiagFlip + H-Flip (90deg)
  372. 3 : SrcExtract(src,src.w-(relX+i),src.h-relY,1,@val); //H-Flip + V-Flip (180deg)
  373. 4 : SrcExtract(src,src.h-relY,(relX+i),1,@val,true); //DiagFlip + V-Flip (270deg)
  374. 5 : SrcExtract(src,src.h-relY,src.w-(relX+i),1,@val,true); //DiagFlip + V-Flip + H-Flip (Flip-90deg)
  375. 6 : SrcExtract(src,relX+i,src.h-relY,1,@val); //V-FLIP (Flip-180deg)
  376. 7 : SrcExtract(src,relY, relX+i,1,@val,true); //DiagFlip (Flip-270deg)
  377. end;
  378. PSmallIntArray(dest)[i]:=val;
  379. end;
  380. end;
  381. end;
  382. procedure TMainForm.SrcExtract(src : PSrc; relX, relY, len : Integer; dest : PSmallInt; DiagFlip:boolean=false);
  383. var
  384. i, c : Integer;
  385. wd : Word;
  386. buf : array of Single;
  387. bmp : TBitmap;
  388. rw : integer; //rotated width
  389. begin
  390. if DiagFlip then rw:=src.h else rw:=src.w;
  391. with src^ do begin
  392. case format of
  393. 0 : begin // 16bits Intel
  394. fs.Position:=(relX+relY*rw)*2;
  395. fs.Read(dest^, len*2);
  396. end;
  397. 1 : begin // 16bits unsigned Intel
  398. fs.Position:=(relX+relY*rw)*2;
  399. fs.Read(dest^, len*2);
  400. for i:=0 to len-1 do begin
  401. wd:=PWord(Integer(dest)+i*2)^;
  402. PSmallInt(Integer(dest)+i*2)^:=Integer(wd)-32768;
  403. end;
  404. end;
  405. 2 : begin // 16bits non-Intel
  406. fs.Position:=(relX+relY*rw)*2;
  407. fs.Read(dest^, len*2);
  408. for i:=0 to len-1 do begin
  409. wd:=PWord(Integer(dest)+i*2)^;
  410. PWord(Integer(dest)+i*2)^:=((wd and 255) shl 8)+(wd shr 8);
  411. end;
  412. end;
  413. 3 : begin // VTP's BT single
  414. fs.Position:=(relX+relY*rw)*4+256;
  415. SetLength(buf, len);
  416. fs.Read(buf[0], len*4);
  417. for i:=0 to len-1 do
  418. PSmallInt(Integer(dest)+i*2)^:=Round(buf[i]);
  419. end;
  420. 4 : begin // windows BMP
  421. bmp:=TBitmap.Create;
  422. try
  423. fs.Position:=0;
  424. bmp.LoadFromStream(fs);
  425. if DiagFlip then rw:=bmp.Width else rw:=bmp.Height;
  426. for i:=0 to len-1 do begin
  427. c:=bmp.Canvas.Pixels[relX+i, rw-relY-1];
  428. PSmallInt(Integer(dest)+i*2)^:=(GetGValue(c)-128) shl 7;
  429. end;
  430. finally
  431. bmp.Free;
  432. end;
  433. end;
  434. 5 : begin // 32bits FP Intel
  435. fs.Position:=(relX+relY*rw)*4;
  436. SetLength(buf, len);
  437. fs.Read(buf[0], len*4);
  438. for i:=0 to len-1 do
  439. PSmallInt(Integer(dest)+i*2)^:=Round((buf[i]-0.5)*32000);
  440. end;
  441. 6 : begin // DTED
  442. fs.Position:=3434+(relX+relY*rw)*2 +(relY*12);
  443. fs.Read(dest^, len*2);
  444. for i:=0 to len-1 do begin
  445. wd:=PWord(Integer(dest)+i*2)^;
  446. PWord(Integer(dest)+i*2)^:=((wd and 255) shl 8)+(wd shr 8);
  447. end;
  448. end;
  449. end;
  450. end;
  451. end;
  452. procedure TMainForm.WorldExtract(x, y, len : Integer; dest : PSmallInt);
  453. var
  454. i, n, rx, ry : Integer;
  455. src : PSrc;
  456. begin
  457. while len>0 do begin
  458. src:=nil;
  459. for i:=0 to High(sources) do begin
  460. if (sources[i].x<=x) and (sources[i].y<=y)
  461. and (x<sources[i].x+sources[i].w)
  462. and (y<sources[i].y+sources[i].h) then begin
  463. src:=@sources[i];
  464. Break;
  465. end;
  466. end;
  467. if Assigned(src) then begin
  468. rx:=x-src.x;
  469. ry:=y-src.y;
  470. n:=len;
  471. if rx+n>src.w then
  472. n:=src.w-rx;
  473. SrcExtractFlip(src, rx, ry, n, dest);
  474. if filterZ<>defaultZ then begin
  475. for i:=0 to n-1 do
  476. if PSmallIntArray(dest)[i]=filterZ then
  477. PSmallIntArray(dest)[i]:=defaultZ;
  478. end;
  479. if zScale<>1 then begin
  480. for i:=0 to n-1 do
  481. PSmallIntArray(dest)[i]:=Round(PSmallIntArray(dest)[i]*zScale);
  482. end;
  483. Dec(len, n);
  484. Inc(dest, n);
  485. Inc(x, n);
  486. end else begin
  487. dest^:=defaultZ;
  488. Inc(dest);
  489. Dec(len);
  490. Inc(x);
  491. end;
  492. end;
  493. end;
  494. procedure TMainForm.ACProcessExecute(Sender: TObject);
  495. var
  496. x, y, wx, wy, ts, tx, ty, i, j, overlap : Integer;
  497. n, maxN : Cardinal;
  498. htf : TGLHeightTileFile;
  499. buf : array of SmallInt;
  500. f : file of Byte;
  501. begin
  502. Screen.Cursor:=crHourGlass;
  503. wx:=StrToInt(EDSizeX.Text);
  504. wy:=StrToInt(EDSizeY.Text);
  505. ts:=StrToInt(EDTileSize.Text);
  506. overlap:=StrToInt(EDTileOverlap.Text);
  507. Parse;
  508. SetLength(buf, ts*ts);
  509. htf:=TGLHeightTileFile.CreateNew(EDHTFName.Text, wx, wy, ts);
  510. htf.DefaultZ:=defaultZ;
  511. ProgressBar.Max:=1000;
  512. maxN:=Ceil(wx/ts)*Ceil(wy/ts);
  513. n:=0;
  514. ProgressBar.Position:=0;
  515. y:=0; while y<wy do begin
  516. ty:=wy+overlap-y;
  517. if ty>ts then
  518. ty:=ts;
  519. x:=0; while x<wx do begin
  520. tx:=wx+overlap-x;
  521. if (not CBWholeOnly.Checked) or ((tx>=ts) and ((wy-y)>=ts)) then begin
  522. if tx>ts then
  523. tx:=ts;
  524. for i:=0 to ty-1 do begin
  525. WorldExtract(x, y+i, tx, @buf[i*ts]);
  526. if overlap>0 then begin
  527. for j:=tx to ts-1 do
  528. buf[i*ts+j]:=buf[i*ts+tx-1];
  529. end else begin
  530. for j:=tx to ts-1 do
  531. buf[i*ts+j]:=defaultZ;
  532. end;
  533. end;
  534. if overlap>0 then begin
  535. for i:=ty to ts-1 do for j:=0 to ts-1 do
  536. buf[i*ts+j]:=buf[(i-1)*ts+j];
  537. end else begin
  538. for i:=ty to ts-1 do for j:=0 to ts-1 do
  539. buf[i*ts+j]:=defaultZ;
  540. end;
  541. htf.CompressTile(x, y, ts, ts, @buf[0]);
  542. end;
  543. Inc(x, ts-overlap);
  544. Inc(n);
  545. ProgressBar.Position:=(n*1000) div maxN;
  546. if (n and 15)=0 then begin
  547. Application.ProcessMessages;
  548. end;
  549. end;
  550. Inc(y, ts-overlap);
  551. end;
  552. htf.Free;
  553. Cleanup;
  554. Screen.Cursor:=crDefault;
  555. AssignFile(f, EDHTFName.Text);
  556. Reset(f);
  557. i:=FileSize(f);
  558. CloseFile(f);
  559. ShowMessage( 'HTF file created.'#13#10#13#10
  560. +IntToStr(i)+' bytes in file'#13#10
  561. +'('+IntToStr(wx*wy*2)+' raw bytes)');
  562. end;
  563. procedure TMainForm.ACViewerExecute(Sender: TObject);
  564. var
  565. viewer : TViewerForm;
  566. begin
  567. viewer:=TViewerForm.Create(nil);
  568. try
  569. Viewer.htf:=TGLHeightTileFile.Create(EDHTFName.Text); //R
  570. Viewer.Caption:='HTFViewer - '+ExtractFileName(EDHTFName.Text); //R
  571. viewer.ShowModal;
  572. finally
  573. viewer.Free;
  574. end;
  575. end;
  576. end.