DEADSOFTWARE

put "{$MODE ...}" directive in each source file; removed trailing spaces, and convert...
[d2df-sdl.git] / src / shared / MAPREADER.pas
1 {$MODE DELPHI}
2 unit MAPREADER;
4 {
5 -----------------------------------
6 MAPREADER.PAS ÂÅÐÑÈß ÎÒ 13.11.07
8 Ïîääåðæêà êàðò âåðñèè 1
9 -----------------------------------
10 }
12 interface
14 uses
15 MAPSTRUCT;
17 type
18 TDataBlock = packed record
19 Block: TBlock;
20 Data: Pointer;
21 end;
23 TDataBlocksArray = packed array of TDataBlock;
25 TMapReader = class(TObject)
26 private
27 FError: Byte;
28 FVersion: Byte;
29 FDataBlocks: TDataBlocksArray;
30 function GetBlocks(BlocksType: Byte): TDataBlocksArray;
31 public
32 constructor Create();
33 destructor Destroy(); override;
34 function LoadMap(Data: Pointer): Boolean;
35 procedure FreeMap();
36 function HandledVersion(): Byte; virtual;
38 property GetError: Byte read FError;
39 property GetVersion: Byte read FVersion;
40 end;
42 TMapReader_1 = class(TMapReader)
43 private
44 public
45 function GetMapHeader(): TMapHeaderRec_1;
46 function GetTextures(): TTexturesRec1Array;
47 function GetPanels(): TPanelsRec1Array;
48 function GetItems(): TItemsRec1Array;
49 function GetAreas(): TAreasRec1Array;
50 function GetMonsters(): TMonsterRec1Array;
51 function GetTriggers(): TTriggersRec1Array;
52 function HandledVersion(): Byte; override;
53 end;
55 const
56 MAP_ERROR_NONE = $00;
57 MAP_ERROR_SIGNATURE = $01;
58 MAP_ERROR_VERSION = $02;
60 NNF_NO_NAME = 0;
61 NNF_NAME_BEFORE = 1;
62 NNF_NAME_EQUALS = 2;
63 NNF_NAME_AFTER = 3;
65 function g_Texture_NumNameFindStart(name: String): Boolean;
66 function g_Texture_NumNameFindNext(var newName: String): Byte;
68 implementation
70 uses
71 SysUtils, BinEditor;
73 var
74 NNF_PureName: String; // Èìÿ òåêñòóðû áåç öèôð â êîíöå
75 NNF_FirstNum: Integer; // ×èñëî ó íà÷àëüíîé òåêñòóðû
76 NNF_CurrentNum: Integer; // Ñëåäóþùåå ÷èñëî ó òåêñòóðû
78 function g_Texture_NumNameFindStart(name: String): Boolean;
79 var
80 i: Integer;
82 begin
83 Result := False;
84 NNF_PureName := '';
85 NNF_FirstNum := -1;
86 NNF_CurrentNum := -1;
88 for i := Length(name) downto 1 do
89 if (name[i] = '_') then // "_" - ñèìâîë íà÷àëà íîìåðíîãî ïîñòôèêñà
90 begin
91 if i = Length(name) then
92 begin // Íåò öèôð â êîíöå ñòðîêè
93 Exit;
94 end
95 else
96 begin
97 NNF_PureName := Copy(name, 1, i);
98 Delete(name, 1, i);
99 Break;
100 end;
101 end;
103 // Íå ïåðåâåñòè â ÷èñëî:
104 if not TryStrToInt(name, NNF_FirstNum) then
105 Exit;
107 NNF_CurrentNum := 0;
109 Result := True;
110 end;
112 function g_Texture_NumNameFindNext(var newName: String): Byte;
113 begin
114 if (NNF_PureName = '') or (NNF_CurrentNum < 0) then
115 begin
116 newName := '';
117 Result := NNF_NO_NAME;
118 Exit;
119 end;
121 newName := NNF_PureName + IntToStr(NNF_CurrentNum);
123 if NNF_CurrentNum < NNF_FirstNum then
124 Result := NNF_NAME_BEFORE
125 else
126 if NNF_CurrentNum > NNF_FirstNum then
127 Result := NNF_NAME_AFTER
128 else
129 Result := NNF_NAME_EQUALS;
131 Inc(NNF_CurrentNum);
132 end;
134 { T M a p R e a d e r _ 1 : }
136 function TMapReader_1.GetAreas(): TAreasRec1Array;
137 var
138 TempDataBlocks: TDataBlocksArray;
139 a: Integer;
140 b, Size: LongWord;
141 begin
142 Result := nil;
144 TempDataBlocks := GetBlocks(BLOCK_AREAS);
146 if TempDataBlocks = nil then Exit;
148 size := SizeOf(TAreaRec_1);
150 for a := 0 to High(TempDataBlocks) do
151 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
152 begin
153 SetLength(Result, Length(Result)+1);
154 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
155 end;
157 TempDataBlocks := nil;
158 end;
160 function TMapReader_1.GetItems(): TItemsRec1Array;
161 var
162 TempDataBlocks: TDataBlocksArray;
163 a: Integer;
164 b, Size: LongWord;
165 begin
166 Result := nil;
168 TempDataBlocks := GetBlocks(BLOCK_ITEMS);
170 if TempDataBlocks = nil then Exit;
172 size := SizeOf(TItemRec_1);
174 for a := 0 to High(TempDataBlocks) do
175 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
176 begin
177 SetLength(Result, Length(Result)+1);
178 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
179 end;
181 TempDataBlocks := nil;
182 end;
184 function TMapReader_1.GetMapHeader(): TMapHeaderRec_1;
185 var
186 TempDataBlocks: TDataBlocksArray;
187 begin
188 ZeroMemory(@Result, SizeOf(TMapHeaderRec_1));
190 TempDataBlocks := GetBlocks(BLOCK_HEADER);
192 if TempDataBlocks = nil then Exit;
194 CopyMemory(@Result, TempDataBlocks[0].Data, SizeOf(TMapHeaderRec_1));
196 TempDataBlocks := nil;
197 end;
199 function TMapReader_1.GetMonsters(): TMonsterRec1Array;
200 var
201 TempDataBlocks: TDataBlocksArray;
202 a: Integer;
203 b, Size: LongWord;
204 begin
205 Result := nil;
207 TempDataBlocks := GetBlocks(BLOCK_MONSTERS);
209 if TempDataBlocks = nil then Exit;
211 size := SizeOf(TMonsterRec_1);
213 for a := 0 to High(TempDataBlocks) do
214 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
215 begin
216 SetLength(Result, Length(Result)+1);
217 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
218 end;
220 TempDataBlocks := nil;
221 end;
223 function TMapReader_1.GetPanels(): TPanelsRec1Array;
224 var
225 TempDataBlocks: TDataBlocksArray;
226 a: Integer;
227 b, Size: LongWord;
228 begin
229 Result := nil;
231 TempDataBlocks := GetBlocks(BLOCK_PANELS);
233 if TempDataBlocks = nil then Exit;
235 size := SizeOf(TPanelRec_1);
237 for a := 0 to High(TempDataBlocks) do
238 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
239 begin
240 SetLength(Result, Length(Result)+1);
241 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
242 end;
244 TempDataBlocks := nil;
245 end;
247 function TMapReader_1.GetTextures(): TTexturesRec1Array;
248 var
249 TempDataBlocks: TDataBlocksArray;
250 a: Integer;
251 b, Size: LongWord;
252 begin
253 Result := nil;
255 TempDataBlocks := GetBlocks(BLOCK_TEXTURES);
257 if TempDataBlocks = nil then Exit;
259 size := SizeOf(TTextureRec_1);
261 for a := 0 to High(TempDataBlocks) do
262 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
263 begin
264 SetLength(Result, Length(Result)+1);
265 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
266 end;
268 TempDataBlocks := nil;
269 end;
271 function TMapReader_1.GetTriggers(): TTriggersRec1Array;
272 var
273 TempDataBlocks: TDataBlocksArray;
274 a: Integer;
275 b, Size: LongWord;
276 begin
277 Result := nil;
279 TempDataBlocks := GetBlocks(BLOCK_TRIGGERS);
281 if TempDataBlocks = nil then Exit;
283 size := SizeOf(TTriggerRec_1);
285 for a := 0 to High(TempDataBlocks) do
286 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
287 begin
288 SetLength(Result, Length(Result)+1);
289 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
290 end;
292 TempDataBlocks := nil;
293 end;
295 function TMapReader_1.HandledVersion: Byte;
296 begin
297 Result := $01;
298 end;
300 { T M a p R e a d e r : }
302 constructor TMapReader.Create();
303 begin
304 FDataBlocks := nil;
305 FError := MAP_ERROR_NONE;
306 FVersion := $00;
307 end;
309 destructor TMapReader.Destroy();
310 begin
311 FreeMap();
313 inherited;
314 end;
316 procedure TMapReader.FreeMap();
317 var
318 a: Integer;
319 begin
320 if FDataBlocks <> nil then
321 for a := 0 to High(FDataBlocks) do
322 if FDataBlocks[a].Data <> nil then FreeMem(FDataBlocks[a].Data);
324 FDataBlocks := nil;
325 FVersion := $00;
326 FError := MAP_ERROR_NONE;
327 end;
329 function TMapReader.GetBlocks(BlocksType: Byte): TDataBlocksArray;
330 var
331 a: Integer;
332 begin
333 Result := nil;
335 if FDataBlocks = nil then Exit;
337 for a := 0 to High(FDataBlocks) do
338 if FDataBlocks[a].Block.BlockType = BlocksType then
339 begin
340 SetLength(Result, Length(Result)+1);
341 Result[High(Result)] := FDataBlocks[a];
342 end;
343 end;
345 function TMapReader.HandledVersion(): Byte;
346 begin
347 Result := $00;
348 end;
350 function TMapReader.LoadMap(Data: Pointer): Boolean;
351 var
352 adr: LongWord;
353 _id: Integer;
354 Sign: array[0..2] of Char;
355 Ver: Byte;
356 begin
357 Result := False;
359 CopyMemory(@Sign[0], Data, 3);
360 if Sign <> MAP_SIGNATURE then
361 begin
362 FError := MAP_ERROR_SIGNATURE;
363 Exit;
364 end;
365 adr := 3;
367 CopyMemory(@Ver, Pointer(LongWord(Data)+adr), 1);
368 FVersion := Ver;
369 if Ver > HandledVersion() then
370 begin
371 FError := MAP_ERROR_VERSION;
372 Exit;
373 end;
374 adr := adr+1;
376 repeat
377 SetLength(FDataBlocks, Length(FDataBlocks)+1);
378 _id := High(FDataBlocks);
380 CopyMemory(@FDataBlocks[_id].Block, Pointer(LongWord(Data)+adr), SizeOf(TBlock));
381 adr := adr+SizeOf(TBlock);
383 FDataBlocks[_id].Data := GetMemory(FDataBlocks[_id].Block.BlockSize);
385 CopyMemory(FDataBlocks[_id].Data, Pointer(LongWord(Data)+adr), FDataBlocks[_id].Block.BlockSize);
387 adr := adr+FDataBlocks[_id].Block.BlockSize;
388 until FDataBlocks[_id].Block.BlockType = BLOCK_NONE;
390 Result := True;
391 end;
393 end.