DEADSOFTWARE

ambient light for level (doesn't work with dynamic lights; I. WANT. SHADERS!)
[d2df-sdl.git] / src / shared / BinEditor.pas
1 (* Copyright (C) DooM 2D:Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$INCLUDE a_modes.inc}
17 Unit BinEditor;
19 Interface
21 Uses
22 SysUtils;
24 Type
25 EBinSizeError = Class (Exception);
27 TBinMemoryWriter = Class (TObject)
28 Private
29 FSize: Cardinal;
30 FData: Pointer;
31 FPosition: Cardinal;
33 Procedure WriteVar(Var x; varSize: Cardinal);
34 Procedure ExtendMemory(addLen: Cardinal);
36 Public
37 Constructor Create(aSize: Cardinal);
38 Destructor Destroy(); Override;
39 Procedure WriteByte(Var x: Byte);
40 Procedure WriteWord(Var x: Word);
41 Procedure WriteDWORD(Var x: DWORD);
42 Procedure WriteShortInt(Var x: ShortInt);
43 Procedure WriteSmallInt(Var x: SmallInt);
44 Procedure WriteInt(Var x: Integer);
45 Procedure WriteSingle(Var x: Single);
46 Procedure WriteBoolean(Var x: Boolean);
47 Procedure WriteString(const x: AnsiString; aMaxLen: Word=65535);
48 Procedure WriteMemory(Var x: Pointer; memSize: Cardinal);
49 Procedure Fill(aLen: Cardinal; aFillSym: Byte);
50 Procedure SaveToFile(Var aFile: File);
51 Procedure SaveToMemory(Var aMem: TBinMemoryWriter);
52 End;
54 TBinMemoryReader = Class (TObject)
55 Private
56 FSize: Cardinal;
57 FData: Pointer;
58 FPosition: Cardinal;
60 Procedure ReadVar(Var x; varSize: Cardinal);
62 Public
63 Constructor Create();
64 Destructor Destroy(); Override;
65 Procedure ReadByte(Var x: Byte);
66 Procedure ReadWord(Var x: Word);
67 Procedure ReadDWORD(Var x: DWORD);
68 Procedure ReadShortInt(Var x: ShortInt);
69 Procedure ReadSmallInt(Var x: SmallInt);
70 Procedure ReadInt(Var x: Integer);
71 Procedure ReadSingle(Var x: Single);
72 Procedure ReadBoolean(Var x: Boolean);
73 Procedure ReadString(Var x: AnsiString);
74 Procedure ReadMemory(Var x: Pointer; Var memSize: Cardinal);
75 Procedure Skip(aLen: Cardinal);
76 Procedure LoadFromFile(Var aFile: File);
77 Procedure LoadFromMemory(Var aMem: TBinMemoryReader);
78 End;
80 TBinFileWriter = Class (TObject)
81 Private
82 FHandle: File;
83 FOpened: Boolean;
85 Public
86 Constructor Create();
87 Destructor Destroy(); Override;
88 Procedure OpenFile(Const aFileName: String;
89 aFileSig: Cardinal;
90 aFileVer: Byte;
91 aOverWrite: Boolean = True);
92 Procedure Close();
93 Procedure WriteMemory(Var aMemory: TBinMemoryWriter);
94 End;
96 TBinFileReader = Class (TObject)
97 Private
98 FHandle: File;
99 FOpened: Boolean;
101 Public
102 Constructor Create();
103 Destructor Destroy(); Override;
104 Function OpenFile(Const aFileName: String;
105 aFileSig: Cardinal;
106 aFileVer: Byte): Boolean;
107 Procedure Close();
108 Procedure ReadMemory(Var aMemory: TBinMemoryReader);
109 End;
111 procedure FillMemory(Dest: Pointer; Len: Cardinal; Ch: Byte);
112 procedure CopyMemory(Dest: Pointer; Src: Pointer; Len: Cardinal);
113 procedure ZeroMemory(Dest: Pointer; Len: Cardinal);
115 Implementation
117 Uses
118 Math, e_log;
120 Const
121 MAX_BIN_SIZE = 4 * 1024 * 1024; // 4 MB
123 procedure CopyMemory(Dest: Pointer; Src: Pointer; Len: Cardinal);
124 begin
125 Move(Src^, Dest^, Len);
126 end;
128 procedure FillMemory(Dest: Pointer; Len: Cardinal; Ch: Byte);
129 begin
130 FillChar(Dest^, Len, Ch);
131 end;
133 procedure ZeroMemory(Dest: Pointer; Len: Cardinal);
134 begin
135 FillChar(Dest^, Len, 0);
136 end;
138 { T B i n M e m o r y W r i t e r : }
140 Constructor TBinMemoryWriter.Create(aSize: Cardinal);
141 begin
142 if aSize <= 0 then
143 FSize := 1
144 else
145 FSize := aSize;
146 if FSize > MAX_BIN_SIZE then
147 FSize := MAX_BIN_SIZE;
149 GetMem(FData, FSize);
150 FPosition := 0;
151 end;
153 Destructor TBinMemoryWriter.Destroy();
154 begin
155 if FData <> nil then
156 begin
157 FreeMem(FData);
158 FData := nil;
159 end;
161 Inherited;
162 end;
164 Procedure TBinMemoryWriter.WriteVar(Var x; varSize: Cardinal);
165 begin
166 if (FPosition + varSize) > FSize then
167 ExtendMemory(varSize);
169 CopyMemory(Pointer(NativeUInt(FData) + FPosition),
170 @x, varSize);
171 FPosition := FPosition + varSize;
172 end;
174 Procedure TBinMemoryWriter.ExtendMemory(addLen: Cardinal);
175 var
176 tmp: Pointer;
178 begin
179 while ((FPosition + addLen) > FSize) and
180 (FSize <= MAX_BIN_SIZE) do
181 FSize := FSize * 2;
183 if FSize > MAX_BIN_SIZE then
184 begin
185 raise EBinSizeError.Create('TBinMemoryWriter.ExtendMemory: Tried to allocete more than 4 MB');
186 Exit;
187 end;
189 GetMem(tmp, FSize);
191 if FPosition > 0 then
192 CopyMemory(tmp, FData, FPosition);
194 FreeMem(FData);
195 FData := tmp;
197 e_WriteLog('Save Memory Extended: '+IntToStr(FSize), MSG_NOTIFY);
198 end;
200 Procedure TBinMemoryWriter.WriteByte(Var x: Byte);
201 begin
202 WriteVar(x, SizeOf(Byte));
203 end;
205 Procedure TBinMemoryWriter.WriteWord(Var x: Word);
206 begin
207 WriteVar(x, SizeOf(Word));
208 end;
210 Procedure TBinMemoryWriter.WriteDWORD(Var x: DWORD);
211 begin
212 WriteVar(x, SizeOf(DWORD));
213 end;
215 Procedure TBinMemoryWriter.WriteShortInt(Var x: ShortInt);
216 begin
217 WriteVar(x, SizeOf(ShortInt));
218 end;
220 Procedure TBinMemoryWriter.WriteSmallInt(Var x: SmallInt);
221 begin
222 WriteVar(x, SizeOf(SmallInt));
223 end;
225 Procedure TBinMemoryWriter.WriteInt(Var x: Integer);
226 begin
227 WriteVar(x, SizeOf(Integer));
228 end;
230 Procedure TBinMemoryWriter.WriteSingle(Var x: Single);
231 begin
232 WriteVar(x, SizeOf(Single));
233 end;
235 Procedure TBinMemoryWriter.WriteBoolean(Var x: Boolean);
236 var
237 y: Byte;
239 begin
240 if x then
241 y := 1
242 else
243 y := 0;
245 WriteVar(y, SizeOf(Byte));
246 end;
248 Procedure TBinMemoryWriter.WriteString (const x: AnsiString; aMaxLen: Word=65535);
249 var
250 len: Word;
251 begin
252 if (Length(x) > aMaxLen) then len := aMaxLen else len := Word(Length(x));
254 if (FPosition+SizeOf(Byte)+len) > FSize then ExtendMemory(SizeOf(Byte)+len);
256 // Äëèíà ñòðîêè:
257 CopyMemory(Pointer(NativeUInt(FData)+FPosition), @len, SizeOf(len));
258 FPosition := FPosition+SizeOf(len);
259 // Ñòðîêà:
260 if (len > 0) then
261 begin
262 CopyMemory(Pointer(NativeUInt(FData) + FPosition), @x[1], len);
263 FPosition := FPosition+len;
264 end;
265 end;
267 Procedure TBinMemoryWriter.WriteMemory(Var x: Pointer; memSize: Cardinal);
268 begin
269 if (FPosition + SizeOf(Cardinal) + memSize) > FSize then
270 ExtendMemory(SizeOf(Cardinal) + memSize);
272 // Äëèíà áëîêà ïàìÿòè:
273 CopyMemory(Pointer(NativeUInt(FData) + FPosition),
274 @memSize, SizeOf(Cardinal));
275 FPosition := FPosition + SizeOf(Cardinal);
276 // Áëîê ïàìÿòè:
277 if memSize > 0 then
278 begin
279 CopyMemory(Pointer(NativeUInt(FData) + FPosition),
280 x, memSize);
281 FPosition := FPosition + memSize;
282 end;
283 end;
285 Procedure TBinMemoryWriter.Fill(aLen: Cardinal; aFillSym: Byte);
286 begin
287 if (FPosition + aLen) > FSize then
288 ExtendMemory(aLen);
290 if aLen > 0 then
291 begin
292 FillMemory(Pointer(NativeUInt(FData) + FPosition),
293 aLen, aFillSym);
294 FPosition := FPosition + aLen;
295 end;
296 end;
298 Procedure TBinMemoryWriter.SaveToFile(Var aFile: File);
299 var
300 nw: Cardinal;
302 begin
303 // Ðàçìåð áëîêà:
304 BlockWrite(aFile, FPosition, SizeOf(Cardinal), nw);
305 if nw <> SizeOf(Cardinal) then
306 begin
307 raise EInOutError.Create('TBinMemoryWriter.SaveToFile: Writing Length');
308 end
309 else
310 begin
311 // Äàííûå áëîêà:
312 BlockWrite(aFile, FData^, FPosition, nw);
313 if nw <> FPosition then
314 begin
315 raise EInOutError.Create('TBinMemoryWriter.SaveToFile: Writing Data');
316 end
317 end;
318 end;
320 Procedure TBinMemoryWriter.SaveToMemory(Var aMem: TBinMemoryWriter);
321 begin
322 if aMem <> nil then
323 begin
324 aMem.WriteMemory(FData, FPosition);
325 end;
326 end;
328 { T B i n M e m o r y R e a d e r : }
330 Constructor TBinMemoryReader.Create();
331 begin
332 FSize := 0;
333 FData := nil;
334 FPosition := 1;
335 end;
337 Destructor TBinMemoryReader.Destroy();
338 begin
339 if FData <> nil then
340 begin
341 FreeMem(FData);
342 FData := nil;
343 end;
345 Inherited;
346 end;
348 Procedure TBinMemoryReader.ReadVar(Var x; varSize: Cardinal);
349 begin
350 if (FPosition + varSize) <= FSize then
351 begin
352 CopyMemory(@x,
353 Pointer(NativeUInt(FData) + FPosition),
354 varSize);
355 FPosition := FPosition + varSize;
356 end
357 else
358 raise EBinSizeError.Create('TBinMemoryReader.ReadVar: End of Memory');
359 end;
361 Procedure TBinMemoryReader.ReadByte(Var x: Byte);
362 begin
363 ReadVar(x, SizeOf(Byte));
364 end;
366 Procedure TBinMemoryReader.ReadWord(Var x: Word);
367 begin
368 ReadVar(x, SizeOf(Word));
369 end;
371 Procedure TBinMemoryReader.ReadDWORD(Var x: DWORD);
372 begin
373 ReadVar(x, SizeOf(DWORD));
374 end;
376 Procedure TBinMemoryReader.ReadShortInt(Var x: ShortInt);
377 begin
378 ReadVar(x, SizeOf(ShortInt));
379 end;
381 Procedure TBinMemoryReader.ReadSmallInt(Var x: SmallInt);
382 begin
383 ReadVar(x, SizeOf(SmallInt));
384 end;
386 Procedure TBinMemoryReader.ReadInt(Var x: Integer);
387 begin
388 ReadVar(x, SizeOf(Integer));
389 end;
391 Procedure TBinMemoryReader.ReadSingle(Var x: Single);
392 begin
393 ReadVar(x, SizeOf(Single));
394 end;
396 Procedure TBinMemoryReader.ReadBoolean(Var x: Boolean);
397 var
398 y: Byte;
400 begin
401 ReadVar(y, SizeOf(Byte));
403 if y > 0 then
404 x := True
405 else
406 x := False;
407 end;
409 Procedure TBinMemoryReader.ReadString (Var x: AnsiString);
410 var
411 len: Word;
412 begin
413 if (FPosition+SizeOf(len)) <= FSize then
414 begin
415 // Äëèíà ñòðîêè:
416 CopyMemory(@len, Pointer(NativeUInt(FData)+FPosition), SizeOf(len));
417 if (FPosition+SizeOf(len)+len <= FSize) then
418 begin
419 FPosition := FPosition+SizeOf(len);
420 // Ñòðîêà:
421 UniqueString(x);
422 SetLength(x, len);
423 if (len > 0) then
424 begin
425 CopyMemory(@x[1], Pointer(NativeUInt(FData) + FPosition), len);
426 FPosition := FPosition+len;
427 end
428 else
429 begin
430 x := '';
431 end;
432 end
433 else
434 begin
435 raise EBinSizeError.Create('TBinMemoryReader.ReadString: Too Long String');
436 end;
437 end
438 else
439 begin
440 raise EBinSizeError.Create('TBinMemoryReader.ReadString: End of Memory');
441 end;
442 end;
444 Procedure TBinMemoryReader.ReadMemory(Var x: Pointer; Var memSize: Cardinal);
445 begin
446 if (FPosition + SizeOf(Cardinal)) <= FSize then
447 begin
448 // Äëèíà áëîêà ïàìÿòè:
449 CopyMemory(@memSize,
450 Pointer(NativeUInt(FData) + FPosition),
451 SizeOf(Cardinal));
453 if (FPosition + SizeOf(Cardinal) + memSize) <= FSize then
454 begin
455 FPosition := FPosition + SizeOf(Cardinal);
456 // Áëîê ïàìÿòè:
457 if memSize > 0 then
458 begin
459 GetMem(x, memSize);
460 CopyMemory(x,
461 Pointer(NativeUInt(FData) + FPosition),
462 memSize);
463 FPosition := FPosition + memSize;
464 end
465 else
466 x := nil;
467 end
468 else
469 raise EBinSizeError.Create('TBinMemoryReader.ReadMemory: Too Long Memory');
470 end
471 else
472 raise EBinSizeError.Create('TBinMemoryReader.ReadMemory: End of Memory');
473 end;
475 Procedure TBinMemoryReader.Skip(aLen: Cardinal);
476 begin
477 if (FPosition + aLen) <= FSize then
478 begin
479 FPosition := FPosition + aLen;
480 end
481 else
482 raise EBinSizeError.Create('TBinMemoryReader.Skip: End of Memory');
483 end;
485 Procedure TBinMemoryReader.LoadFromFile(Var aFile: File);
486 var
487 nr: Cardinal;
488 aSize: Cardinal;
490 begin
491 if FData <> nil then
492 FreeMem(FData);
494 // Ðàçìåð áëîêà:
495 BlockRead(aFile, aSize, SizeOf(Cardinal), nr);
496 if nr <> SizeOf(Cardinal) then
497 begin
498 raise EInOutError.Create('TBinMemoryReader.LoadFromFile: Reading Length');
499 end
500 else
501 begin
502 FSize := aSize;
503 GetMem(FData, FSize);
504 FPosition := 0;
505 // Äàííûå áëîêà:
506 BlockRead(aFile, FData^, FSize, nr);
507 if nr <> FSize then
508 begin
509 raise EInOutError.Create('TBinMemoryReader.LoadFromFile: Reading Data');
510 end
511 end;
512 end;
514 Procedure TBinMemoryReader.LoadFromMemory(Var aMem: TBinMemoryReader);
515 begin
516 if FData <> nil then
517 FreeMem(FData);
519 if aMem <> nil then
520 begin
521 aMem.ReadMemory(FData, FSize);
522 FPosition := 0;
523 end;
524 end;
526 { T B i n F i l e W r i t e r : }
528 Constructor TBinFileWriter.Create();
529 begin
530 FOpened := False;
531 end;
533 Destructor TBinFileWriter.Destroy();
534 begin
535 Close();
537 Inherited;
538 end;
540 Procedure TBinFileWriter.OpenFile(Const aFileName: String;
541 aFileSig: Cardinal;
542 aFileVer: Byte;
543 aOverWrite: Boolean = True);
544 var
545 nw: Integer;
547 begin
548 Close();
550 if (not FileExists(aFileName)) or (aOverWrite) then
551 begin
552 AssignFile(FHandle, aFileName);
553 ReWrite(FHandle, 1);
555 // Ñèãíàòóðà:
556 BlockWrite(FHandle, aFileSig, SizeOf(Cardinal), nw);
557 if nw <> SizeOf(Cardinal) then
558 begin
559 raise EInOutError.Create('TBinFileWriter.OpenFile: Writing File Signature');
560 end
561 else
562 begin
563 // Âåðñèÿ:
564 BlockWrite(FHandle, aFileVer, SizeOf(Byte), nw);
565 if nw <> SizeOf(Byte) then
566 begin
567 raise EInOutError.Create('TBinFileWriter.OpenFile: Writing File Version');
568 end
569 else
570 begin
571 FOpened := True;
572 end;
573 end;
574 end;
575 end;
577 Procedure TBinFileWriter.Close();
578 begin
579 if FOpened then
580 begin
581 System.Close(FHandle);
582 FOpened := False;
583 end;
584 end;
586 Procedure TBinFileWriter.WriteMemory(Var aMemory: TBinMemoryWriter);
587 begin
588 if (FOpened) and (aMemory <> nil) then
589 begin
590 aMemory.SaveToFile(FHandle);
591 end;
592 end;
594 { T B i n F i l e R e a d e r : }
596 Constructor TBinFileReader.Create();
597 begin
598 FOpened := False;
599 end;
601 Destructor TBinFileReader.Destroy();
602 begin
603 Close();
605 Inherited;
606 end;
608 Function TBinFileReader.OpenFile(Const aFileName: String;
609 aFileSig: Cardinal;
610 aFileVer: Byte): Boolean;
611 var
612 nr: Integer;
613 sig: Cardinal;
614 ver: Byte;
616 begin
617 Result := False;
619 Close();
621 if FileExists(aFileName) then
622 begin
623 AssignFile(FHandle, aFileName);
624 ReSet(FHandle, 1);
626 // Ñèãíàòóðà:
627 BlockRead(FHandle, sig, SizeOf(Cardinal), nr);
628 if (nr <> SizeOf(Cardinal)) then
629 begin
630 raise EInOutError.Create('TBinFileReader.OpenFile: Reading File Signature');
631 end
632 else
633 if (sig <> aFileSig) then
634 begin
635 raise EInOutError.Create('TBinFileReader.OpenFile: Wrong File Signature');
636 end
637 else
638 begin
639 // Âåðñèÿ:
640 BlockRead(FHandle, ver, SizeOf(Byte), nr);
641 if (nr <> SizeOf(Byte)) then
642 begin
643 raise EInOutError.Create('TBinFileReader.OpenFile: Reading File Version');
644 end
645 else
646 if (ver <> aFileVer) then
647 begin
648 raise EInOutError.Create('TBinFileReader.OpenFile: Wrong File Version');
649 end
650 else
651 begin
652 FOpened := True;
653 Result := True;
654 end;
655 end;
656 end;
657 end;
659 Procedure TBinFileReader.Close();
660 begin
661 if FOpened then
662 begin
663 System.Close(FHandle);
664 FOpened := False;
665 end;
666 end;
668 Procedure TBinFileReader.ReadMemory(Var aMemory: TBinMemoryReader);
669 begin
670 if (FOpened) and (aMemory <> nil) then
671 begin
672 aMemory.LoadFromFile(FHandle);
673 end;
674 end;
677 End.