PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/MyEntries.pas

https://bitbucket.org/HarpyWar/tfk
Pascal | 548 lines | 434 code | 70 blank | 44 comment | 29 complexity | abc9b9b830d3c5e4363aa782d65343a5 MD5 | raw file
  1. unit MyEntries;
  2. (***************************************)
  3. (* Entries&Maps module version 1.0.1 *)
  4. (***************************************)
  5. (* Created by Neoff *)
  6. (* mail : neoff@fryazino.net *)
  7. (* site : http://tfk.mirgames.ru *)
  8. (***************************************)
  9. interface
  10. //÷ňîáű čńďîëüçîâŕňü TList âěĺńňî äčí. ěŕńńčâŕ, đŕńęîěĺíňčđóé ýňî:
  11. //ĐĹÄŔĘŇÎĐ ÁĹÇ ÝŇÎĂÎ ÍĹ ĘÎĚĎČËČŇŃß
  12. //Ŕ ČĂĐŔ Ń ÝŇČĚ ÂĹŃČŇ Â ÄÂŔ ĐŔÇŔ ÁÎËÜŘĹ!!!
  13. //{$DEFINE EDITORMODE}
  14. //ĘŔĆÄŰÉ ĎÎŇÎĚÎĘ TCustomEntry îá˙çŕí:
  15. //*ăđóçčňü čç ôŕéëŕ číôó ěóňîäîě Create(head, var f file);
  16. //*äŕâŕňü číôîđěŕöčţ î ńĺáĺ ôóíęöčĺé
  17. // class function EntryClassName: TEntryClassName;
  18. //*ńîîáůŕňü ęŕęóţ âĺđńčţ îí ďîääĺđćčâŕĺň ôóíęöčĺé
  19. // class function IsValidVersion(version: integer): boolean;
  20. // ÝŇČ CLASS-ÔÓÍĘÖČČ ÍĹ ĚÎĂÓŇ ÁŰŇÜ ÂČĐŇÓŔËÜÍŰ, ÎÍČ ÂŰÇŰÂŔŢŇŃß ÍĹĎÎŃĐĹÄŃŇÂĹÍÍÎ Ó ĘËŔŃŃŔ!!!
  21. //*ńîîáůŕňü ňĺęóůóţ âĺđńčţ ńŕěîăî ÎÁÚĹĘŇŔ ŕ íĺ číôű čç ôŕéëŕ...
  22. // function DefaultVersion: integer;
  23. //*çŕďčńűâŕňü číôó î ńĺáĺ, đŕçěĺđĺ, âĺđńčč â FHEAD ôóíęöčĺé
  24. //function GetHead: TEntryHead;
  25. //Â ďđčíöčďĺ ôôôń¸...
  26. //Ďđčěĺđ - TBricksEntry â ńîńĺäíĺě ěîäóëĺ
  27. {$IFDEF EDITORMODE}
  28. uses Classes;
  29. {$ENDIF}
  30. const
  31. MapVersion=1;
  32. LowMapVersion=1;
  33. HighMapVersion=5;
  34. type
  35. TEntryClassName=string[15];
  36. TEntryName = string[15];
  37. // BFile=^File;
  38. type
  39. TEntryHead=record
  40. name: TEntryName;
  41. EntryClass: TEntryClassName;
  42. version: integer;
  43. size: cardinal;
  44. case integer of
  45. 0: (reserved: array [0..9] of byte);
  46. 1: (maxx: integer;maxy:integer; defaultbrick: word);
  47. 2: (TEXCount: word);
  48. end;//ňčď çŕíčěŕĺň 48 áŕéň âđîäĺ...
  49. type
  50. TCustomEntry = class
  51. constructor Create(Head_: TEntryHead;var F: File);overload;
  52. constructor Create;overload;
  53. protected
  54. fhead: TEntryHead;
  55. function GetHead: TEntryHead;virtual;
  56. public
  57. class function EntryClassName: TEntryClassName;
  58. class function IsValidVersion(version: integer): boolean;
  59. function DefaultVersion: integer;virtual;
  60. property Head: TEntryHead read GetHead;
  61. procedure WriteToFile(var F: File);virtual;
  62. end;
  63. type
  64. TSimpleEntry= class(TCustomEntry)
  65. constructor Create(Head_: TEntryHead; var F: File);overload;
  66. constructor Create;overload;
  67. destructor Destroy;override;
  68. protected
  69. procedure SetBufSize(newlength: integer);
  70. procedure ResizeBuf(newlength: integer);
  71. public
  72. buf: array of byte;//đŕçěĺđ óńňŕíîâëĺí - head.size :))
  73. procedure WriteToFile(var F: File);override;
  74. end;
  75. type
  76. TMapType= array [0..3] of char;
  77. TPaletteFile = string[28];
  78. string64 = string[64];
  79. string32 = string[32];
  80. string16 = string[16];
  81. TMapHeader1=
  82. record
  83. MapType: TMapType;//Must be equivalent Map.MapType variable
  84. ECount : integer;//Entries Count
  85. Version: integer;//
  86. Author: string64;
  87. pass: string16;
  88. reserved0: array [0..173] of byte;
  89. Name: shortstring;
  90. EnvColor: array [0..2] of byte;
  91. gametype: byte;
  92. fade_mode: boolean;
  93. reserved: array [1..27] of byte;
  94. end;
  95. type
  96. TCustomMap= class
  97. constructor Create;
  98. destructor Destroy;override;
  99. protected
  100. MapType, MapType2: string;
  101. fhead: TMapHeader1;
  102. function GetHead: TMapHeader1;virtual;
  103. public
  104. Entries: array of TCustomEntry;
  105. lastfilename: string;
  106. function GetEntry(ind: integer): TCustomEntry;
  107. function EntriesCount: integer;
  108. procedure SetEntriesSize(newlength: integer);
  109. property head: TMapHeader1 read GetHead;
  110. property Name: shortstring read fhead.Name write fhead.Name;
  111. property Author: string64 read fhead.Author write fhead.Author;
  112. procedure BeforeLoad;virtual;
  113. procedure AfterLoad;virtual;
  114. procedure Clear;virtual;
  115. function CreateEntry(head: TEntryHead; var f: File): TCustomEntry;virtual;
  116. procedure Delete(ind: integer);
  117. function LoadFromFile(FileName: string): integer;virtual;
  118. function SaveToFile(FileName: string): integer;virtual;
  119. function FullSize: cardinal;
  120. function GetFileName: string;
  121. end;
  122. function AppendSectionToFile(section: TCustomEntry; inputfile: string; outputfile: string; multi: boolean = false): integer;
  123. function DeleteSectionFromFile(cl: TEntryClassName; inputfile, outputfile: string): integer;
  124. function RewriteMapHeader(head: TMapHeader1; inputfile, outputfile: string): integer;
  125. implementation
  126. function AppendSectionToFile(section: TCustomEntry; inputfile: string; outputfile: string; multi: boolean = false): integer;
  127. var
  128. Map: TCustomMap;
  129. i: integer;
  130. temp: TCustomEntry;
  131. f: boolean;
  132. begin
  133. Result:=0;
  134. i := 0;
  135. Map:=TCustomMap.Create;
  136. temp:=nil;
  137. with Map do
  138. begin
  139. if LoadFromFile(inputfile)<0 then
  140. begin
  141. Result:=-1;
  142. Exit;
  143. end;
  144. f:=false;
  145. if not multi then
  146. for i:=0 to EntriesCount-1 do
  147. if Entries[i].Head.EntryClass=section.Head.EntryClass then
  148. begin
  149. //íŕéäĺíŕ ńĺęöč˙!!!
  150. temp:=Entries[i];
  151. Entries[i]:=section;
  152. f:=true;
  153. break;
  154. end;
  155. if not f then
  156. begin
  157. SetLength(Entries, EntriesCount+1);
  158. Entries[Entriescount-1]:=section;
  159. end;
  160. SaveToFile(outputfile);
  161. if not f then
  162. SetLength(Entries, EntriesCount-1)
  163. else Entries[i]:=temp;
  164. Free;
  165. end;
  166. end;
  167. function DeleteSectionFromFile(cl: TEntryClassName; inputfile, outputfile: string): integer;
  168. var
  169. Map: TCustomMap;
  170. i, j: integer;
  171. begin
  172. Result:=0;
  173. Map:=TCustomMap.Create;
  174. with Map do
  175. begin
  176. if LoadFromFile(inputfile)<0 then
  177. begin
  178. Result:=-1;
  179. Exit;
  180. end;
  181. for i:=0 to EntriesCount-1 do
  182. if Entries[i].Head.EntryClass=cl then
  183. begin
  184. //íŕéäĺíŕ ńĺęöč˙!!!
  185. Entries[i].Free;
  186. for j:=i to EntriesCount-2 do
  187. Entries[j]:=Entries[j+1];
  188. SetLength(Entries, EntriesCount-1)
  189. end;
  190. SaveToFile(outputfile);
  191. Free;
  192. end;
  193. end;
  194. function RewriteMapHeader(head: TMapHeader1; inputfile, outputfile: string): integer;
  195. var
  196. Map: TCustomMap;
  197. begin
  198. Map:=TCustomMap.Create;
  199. Map.LoadFromFile(inputfile);
  200. Map.fhead:=head;
  201. Map.SaveToFile(outputfile);
  202. Map.Free;
  203. Result:=1;
  204. end;
  205. { TCustomEntry }
  206. constructor TCustomEntry.Create(Head_: TEntryHead; var F: File);
  207. begin
  208. fhead:=head_;
  209. end;
  210. constructor TCustomEntry.Create;
  211. begin
  212. fhead.EntryClass:=Self.EntryClassName;
  213. fhead.Size:=0;
  214. fhead.version:=DefaultVersion;
  215. end;
  216. function TCustomEntry.DefaultVersion: integer;
  217. begin
  218. Result:=1;
  219. end;
  220. class function TCustomEntry.EntryClassName: TEntryClassName;
  221. begin
  222. Result:='unknown';
  223. end;
  224. function TCustomEntry.GetHead: TEntryHead;
  225. begin
  226. //
  227. Result:=fhead;
  228. end;
  229. class function TCustomEntry.IsValidVersion(version: integer): boolean;
  230. begin
  231. Result:=true;
  232. end;
  233. procedure TCustomEntry.WriteToFile(var F: File);
  234. begin
  235. GetHead;
  236. BlockWrite(f, fhead, SizeOf(fhead));
  237. end;
  238. { TSimpleEntry }
  239. const
  240. PAGE_SIZE = 4096;
  241. constructor TSimpleEntry.Create(Head_: TEntryHead; var F: File);
  242. var
  243. i: cardinal;
  244. begin
  245. inherited Create(head_, F);
  246. SetLength(buf, head_.size);
  247. i:=0;
  248. while head_.size-i>PAGE_SIZE do
  249. begin
  250. BlockRead(f, buf[i], PAGE_SIZE);
  251. Inc(i, PAGE_SIZE);
  252. end;
  253. BlockRead(f, buf[i], head_.size-i);
  254. end;
  255. constructor TSimpleEntry.Create;
  256. begin
  257. inherited Create;
  258. end;
  259. destructor TSimpleEntry.Destroy;
  260. begin
  261. buf:=nil;
  262. end;
  263. procedure TSimpleEntry.ResizeBuf(newlength: integer);
  264. begin
  265. SetLength(buf, newlength);
  266. fhead.size:=newlength;
  267. end;
  268. procedure TSimpleEntry.SetBufSize(newlength: integer);
  269. begin
  270. buf:=nil;
  271. SetLength(buf, newlength);
  272. fhead.size:=newlength;
  273. end;
  274. procedure TSimpleEntry.WriteToFile(var F: File);
  275. var
  276. i: cardinal;
  277. begin
  278. inherited;
  279. if buf<>nil then
  280. begin
  281. i:=0;
  282. while fhead.size-i>PAGE_SIZE do
  283. begin
  284. BlockWrite(f, buf[i], PAGE_SIZE);
  285. Inc(i, PAGE_SIZE);
  286. end;
  287. BlockWrite(f, buf[i], fhead.size-i);
  288. end;
  289. end;
  290. { TCustomMap }
  291. procedure TCustomMap.AfterLoad;
  292. begin
  293. end;
  294. procedure TCustomMap.BeforeLoad;
  295. begin
  296. end;
  297. procedure TCustomMap.Clear;
  298. var
  299. i: integer;
  300. begin
  301. lastfilename:='';
  302. for i:=0 to EntriesCount-1 do
  303. if entries[i]<>nil then
  304. TCustomEntry(Entries[i]).Free;
  305. Entries:=nil;
  306. end;
  307. constructor TCustomMap.Create;
  308. begin
  309. MapType:='TFKM';
  310. MapType2:='TFKĚ';
  311. fhead.Version:=MapVersion;
  312. fhead.ECount:=0;
  313. lastfilename:='';
  314. {$IFDEF EDITORMODE}
  315. Entries:=TList.Create;
  316. {$ENDIF}
  317. end;
  318. function TCustomMap.CreateEntry(head: TEntryHead; var f: File): TCustomEntry;
  319. begin
  320. Result:=TSimpleEntry.Create(head, F);
  321. end;
  322. procedure TCustomMap.Delete(ind: integer);
  323. var
  324. ecount: integer;
  325. begin
  326. ecount:=EntriesCount;
  327. if (ind>=0) and (ind<ecount) then
  328. begin
  329. GetEntry(ind).Free;
  330. {$IFDEF EDITORMODE}
  331. Entries.Delete(ind);
  332. {$ELSE}
  333. while ind<ECount-1 do
  334. begin
  335. Entries[ind]:=Entries[ind+1];
  336. Inc(ind);
  337. end;
  338. SetLength(Entries, ecount-1);
  339. {$ENDIF}
  340. end;
  341. end;
  342. function TCustomMap.EntriesCount: integer;
  343. begin
  344. {$IFDEF EDITORMODE}
  345. Result:=Entries.Count;
  346. {$ELSE}
  347. Result:=High(Entries)+1;
  348. {$ENDIF}
  349. end;
  350. function TCustomMap.GetEntry(ind: integer): TCustomEntry;
  351. begin
  352. Result:=nil;
  353. if (ind>=0) and (ind<EntriesCount) then
  354. Result:=TCustomEntry(Entries[ind]);
  355. end;
  356. function TCustomMap.GetHead: TMapHeader1;
  357. begin
  358. fhead.ECount:=EntriesCount;
  359. Result:=fhead;
  360. end;
  361. function TCustomMap.LoadFromFile(FileName: string): integer;
  362. var
  363. f: File;
  364. i: integer;
  365. pos: integer;
  366. head0: TMapHeader1;
  367. EHead:TEntryHead;
  368. function Decode(s: string16): string16;
  369. var
  370. i: integer;
  371. begin
  372. for i:=1 to length(s) do
  373. s[i]:=chr(ord(s[i]) xor 138);
  374. Result:=s;
  375. end;
  376. begin
  377. Result:=0;
  378. try
  379. FileMode:=64;
  380. AssignFile(f, FileName);
  381. Reset(f, 1);
  382. BlockRead(f, head0, SizeOf(head0));
  383. if (head0.MapType<>MapType) and
  384. (head0.MapType<>MapType2) or
  385. (head0.version<LowMapVersion) or (head0.version>HighMapVersion) then
  386. begin
  387. CloseFile(f);
  388. Result:=-2;
  389. Exit;
  390. end;
  391. Clear;
  392. fhead:=head0;
  393. BeforeLoad;
  394. {$IFDEF EDITORMODE}
  395. for i:=0 to fhead.ECount-1 do
  396. begin
  397. BlockRead(F, EHead, SizeOf(EHead));
  398. Entries.Add(CreateEntry(EHead, F));
  399. end;
  400. {$ELSE}
  401. SetLength(Entries, fhead.ECount);
  402. for i:=0 to fhead.ECount-1 do
  403. begin
  404. BlockRead(F, EHead, SizeOf(EHead));
  405. pos:=FilePos(F)+integer(EHead.size);
  406. Entries[i]:=CreateEntry(EHead, F);
  407. if FilePos(F)<>pos then
  408. Seek(F, pos);
  409. if Entries[i].head.size=0 then
  410. Continue;
  411. if Entries[i]=nil then
  412. begin
  413. CloseFile(f);
  414. Clear;
  415. result:=-1;
  416. Exit;
  417. end;
  418. end;
  419. {$ENDIF}
  420. CloseFile(F);
  421. lastfilename:=filename;
  422. AfterLoad;
  423. except
  424. Clear;
  425. result := -1;
  426. end;
  427. end;
  428. function TCustomMap.SaveToFile(FileName: string): integer;
  429. var
  430. F: File;
  431. i: integer;
  432. head0: TMapHeader1;
  433. begin
  434. Result:=0;
  435. head0:=head;
  436. try
  437. FileMode:=64;
  438. AssignFile(f, FileName);
  439. Rewrite(f, 1);
  440. BlockWrite(f, head0, SizeOf(head0));
  441. for i:=0 to head0.ECount-1 do
  442. TCustomEntry(Entries[i]).WriteToFile(f);
  443. CloseFile(f);
  444. except
  445. Result:=-1;
  446. end;
  447. end;
  448. procedure TCustomMap.SetEntriesSize(newlength: integer);
  449. begin
  450. SetLength(Entries, newlength);
  451. end;
  452. function TCustomMap.FullSize: cardinal;
  453. var
  454. i: integer;
  455. begin
  456. Result:=SizeOf(TMapHeader1)+EntriesCount*SizeOf(TEntryHead);
  457. for i:=0 to EntriesCount-1 do
  458. Result:=Result+Entries[i].GetHead.size;
  459. end;
  460. destructor TCustomMap.Destroy;
  461. begin
  462. Clear;
  463. inherited;
  464. end;
  465. function TCustomMap.GetFileName: string;
  466. var
  467. k, l: integer;
  468. begin
  469. Result:=lastfilename;
  470. k:=length(result);
  471. l:=length(result);
  472. while (k>0) and (result[k]<>'\') do Dec(k);
  473. while (l>0) and (result[l]<>'.') do Dec(l);
  474. if (k>0) and (l>0) then
  475. Result:=Copy(Result, k+1, l-k-1);
  476. end;
  477. end.