DEADSOFTWARE

f9f5780be6d6c930212edccae1218c482f39caac
[d2df-sdl.git] / src / shared / MAPREADER.pas
1 unit MAPREADER;
3 {
4 -----------------------------------
5 MAPREADER.PAS ÂÅÐÑÈß ÎÒ 13.11.07
7 Ïîääåðæêà êàðò âåðñèè 1
8 -----------------------------------
9 }
11 interface
13 uses
14 MAPSTRUCT;
16 type
17 TDataBlock = packed record
18 Block: TBlock;
19 Data: Pointer;
20 end;
22 TDataBlocksArray = packed array of TDataBlock;
24 TMapReader = class(TObject)
25 private
26 FError: Byte;
27 FVersion: Byte;
28 FDataBlocks: TDataBlocksArray;
29 function GetBlocks(BlocksType: Byte): TDataBlocksArray;
30 public
31 constructor Create();
32 destructor Destroy(); override;
33 function LoadMap(Data: Pointer): Boolean;
34 procedure FreeMap();
35 function HandledVersion(): Byte; virtual;
37 property GetError: Byte read FError;
38 property GetVersion: Byte read FVersion;
39 end;
41 TMapReader_1 = class(TMapReader)
42 private
43 public
44 function GetMapHeader(): TMapHeaderRec_1;
45 function GetTextures(): TTexturesRec1Array;
46 function GetPanels(): TPanelsRec1Array;
47 function GetItems(): TItemsRec1Array;
48 function GetAreas(): TAreasRec1Array;
49 function GetMonsters(): TMonsterRec1Array;
50 function GetTriggers(): TTriggersRec1Array;
51 function HandledVersion(): Byte; override;
52 end;
54 const
55 MAP_ERROR_NONE = $00;
56 MAP_ERROR_SIGNATURE = $01;
57 MAP_ERROR_VERSION = $02;
59 NNF_NO_NAME = 0;
60 NNF_NAME_BEFORE = 1;
61 NNF_NAME_EQUALS = 2;
62 NNF_NAME_AFTER = 3;
64 function g_Texture_NumNameFindStart(name: String): Boolean;
65 function g_Texture_NumNameFindNext(var newName: String): Byte;
67 implementation
69 uses
70 SysUtils, BinEditor;
72 var
73 NNF_PureName: String; // Èìÿ òåêñòóðû áåç öèôð â êîíöå
74 NNF_FirstNum: Integer; // ×èñëî ó íà÷àëüíîé òåêñòóðû
75 NNF_CurrentNum: Integer; // Ñëåäóþùåå ÷èñëî ó òåêñòóðû
77 function g_Texture_NumNameFindStart(name: String): Boolean;
78 var
79 i: Integer;
81 begin
82 Result := False;
83 NNF_PureName := '';
84 NNF_FirstNum := -1;
85 NNF_CurrentNum := -1;
87 for i := Length(name) downto 1 do
88 if (name[i] = '_') then // "_" - ñèìâîë íà÷àëà íîìåðíîãî ïîñòôèêñà
89 begin
90 if i = Length(name) then
91 begin // Íåò öèôð â êîíöå ñòðîêè
92 Exit;
93 end
94 else
95 begin
96 NNF_PureName := Copy(name, 1, i);
97 Delete(name, 1, i);
98 Break;
99 end;
100 end;
102 // Íå ïåðåâåñòè â ÷èñëî:
103 if not TryStrToInt(name, NNF_FirstNum) then
104 Exit;
106 NNF_CurrentNum := 0;
108 Result := True;
109 end;
111 function g_Texture_NumNameFindNext(var newName: String): Byte;
112 begin
113 if (NNF_PureName = '') or (NNF_CurrentNum < 0) then
114 begin
115 newName := '';
116 Result := NNF_NO_NAME;
117 Exit;
118 end;
120 newName := NNF_PureName + IntToStr(NNF_CurrentNum);
122 if NNF_CurrentNum < NNF_FirstNum then
123 Result := NNF_NAME_BEFORE
124 else
125 if NNF_CurrentNum > NNF_FirstNum then
126 Result := NNF_NAME_AFTER
127 else
128 Result := NNF_NAME_EQUALS;
130 Inc(NNF_CurrentNum);
131 end;
133 { T M a p R e a d e r _ 1 : }
135 function TMapReader_1.GetAreas(): TAreasRec1Array;
136 var
137 TempDataBlocks: TDataBlocksArray;
138 a: Integer;
139 b, Size: LongWord;
140 begin
141 Result := nil;
143 TempDataBlocks := GetBlocks(BLOCK_AREAS);
145 if TempDataBlocks = nil then Exit;
147 size := SizeOf(TAreaRec_1);
149 for a := 0 to High(TempDataBlocks) do
150 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
151 begin
152 SetLength(Result, Length(Result)+1);
153 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
154 end;
156 TempDataBlocks := nil;
157 end;
159 function TMapReader_1.GetItems(): TItemsRec1Array;
160 var
161 TempDataBlocks: TDataBlocksArray;
162 a: Integer;
163 b, Size: LongWord;
164 begin
165 Result := nil;
167 TempDataBlocks := GetBlocks(BLOCK_ITEMS);
169 if TempDataBlocks = nil then Exit;
171 size := SizeOf(TItemRec_1);
173 for a := 0 to High(TempDataBlocks) do
174 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
175 begin
176 SetLength(Result, Length(Result)+1);
177 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
178 end;
180 TempDataBlocks := nil;
181 end;
183 function TMapReader_1.GetMapHeader(): TMapHeaderRec_1;
184 var
185 TempDataBlocks: TDataBlocksArray;
186 begin
187 ZeroMemory(@Result, SizeOf(TMapHeaderRec_1));
189 TempDataBlocks := GetBlocks(BLOCK_HEADER);
191 if TempDataBlocks = nil then Exit;
193 CopyMemory(@Result, TempDataBlocks[0].Data, SizeOf(TMapHeaderRec_1));
195 TempDataBlocks := nil;
196 end;
198 function TMapReader_1.GetMonsters(): TMonsterRec1Array;
199 var
200 TempDataBlocks: TDataBlocksArray;
201 a: Integer;
202 b, Size: LongWord;
203 begin
204 Result := nil;
206 TempDataBlocks := GetBlocks(BLOCK_MONSTERS);
208 if TempDataBlocks = nil then Exit;
210 size := SizeOf(TMonsterRec_1);
212 for a := 0 to High(TempDataBlocks) do
213 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
214 begin
215 SetLength(Result, Length(Result)+1);
216 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
217 end;
219 TempDataBlocks := nil;
220 end;
222 function TMapReader_1.GetPanels(): TPanelsRec1Array;
223 var
224 TempDataBlocks: TDataBlocksArray;
225 a: Integer;
226 b, Size: LongWord;
227 begin
228 Result := nil;
230 TempDataBlocks := GetBlocks(BLOCK_PANELS);
232 if TempDataBlocks = nil then Exit;
234 size := SizeOf(TPanelRec_1);
236 for a := 0 to High(TempDataBlocks) do
237 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
238 begin
239 SetLength(Result, Length(Result)+1);
240 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
241 end;
243 TempDataBlocks := nil;
244 end;
246 function TMapReader_1.GetTextures(): TTexturesRec1Array;
247 var
248 TempDataBlocks: TDataBlocksArray;
249 a: Integer;
250 b, Size: LongWord;
251 begin
252 Result := nil;
254 TempDataBlocks := GetBlocks(BLOCK_TEXTURES);
256 if TempDataBlocks = nil then Exit;
258 size := SizeOf(TTextureRec_1);
260 for a := 0 to High(TempDataBlocks) do
261 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
262 begin
263 SetLength(Result, Length(Result)+1);
264 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
265 end;
267 TempDataBlocks := nil;
268 end;
270 function TMapReader_1.GetTriggers(): TTriggersRec1Array;
271 var
272 TempDataBlocks: TDataBlocksArray;
273 a: Integer;
274 b, Size: LongWord;
275 begin
276 Result := nil;
278 TempDataBlocks := GetBlocks(BLOCK_TRIGGERS);
280 if TempDataBlocks = nil then Exit;
282 size := SizeOf(TTriggerRec_1);
284 for a := 0 to High(TempDataBlocks) do
285 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
286 begin
287 SetLength(Result, Length(Result)+1);
288 CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
289 end;
291 TempDataBlocks := nil;
292 end;
294 function TMapReader_1.HandledVersion: Byte;
295 begin
296 Result := $01;
297 end;
299 { T M a p R e a d e r : }
301 constructor TMapReader.Create();
302 begin
303 FDataBlocks := nil;
304 FError := MAP_ERROR_NONE;
305 FVersion := $00;
306 end;
308 destructor TMapReader.Destroy();
309 begin
310 FreeMap();
312 inherited;
313 end;
315 procedure TMapReader.FreeMap();
316 var
317 a: Integer;
318 begin
319 if FDataBlocks <> nil then
320 for a := 0 to High(FDataBlocks) do
321 if FDataBlocks[a].Data <> nil then FreeMem(FDataBlocks[a].Data);
323 FDataBlocks := nil;
324 FVersion := $00;
325 FError := MAP_ERROR_NONE;
326 end;
328 function TMapReader.GetBlocks(BlocksType: Byte): TDataBlocksArray;
329 var
330 a: Integer;
331 begin
332 Result := nil;
334 if FDataBlocks = nil then Exit;
336 for a := 0 to High(FDataBlocks) do
337 if FDataBlocks[a].Block.BlockType = BlocksType then
338 begin
339 SetLength(Result, Length(Result)+1);
340 Result[High(Result)] := FDataBlocks[a];
341 end;
342 end;
344 function TMapReader.HandledVersion(): Byte;
345 begin
346 Result := $00;
347 end;
349 function TMapReader.LoadMap(Data: Pointer): Boolean;
350 var
351 adr: LongWord;
352 _id: Integer;
353 Sign: array[0..2] of Char;
354 Ver: Byte;
355 begin
356 Result := False;
358 CopyMemory(@Sign[0], Data, 3);
359 if Sign <> MAP_SIGNATURE then
360 begin
361 FError := MAP_ERROR_SIGNATURE;
362 Exit;
363 end;
364 adr := 3;
366 CopyMemory(@Ver, Pointer(LongWord(Data)+adr), 1);
367 FVersion := Ver;
368 if Ver > HandledVersion() then
369 begin
370 FError := MAP_ERROR_VERSION;
371 Exit;
372 end;
373 adr := adr+1;
375 repeat
376 SetLength(FDataBlocks, Length(FDataBlocks)+1);
377 _id := High(FDataBlocks);
379 CopyMemory(@FDataBlocks[_id].Block, Pointer(LongWord(Data)+adr), SizeOf(TBlock));
380 adr := adr+SizeOf(TBlock);
382 FDataBlocks[_id].Data := GetMemory(FDataBlocks[_id].Block.BlockSize);
384 CopyMemory(FDataBlocks[_id].Data, Pointer(LongWord(Data)+adr), FDataBlocks[_id].Block.BlockSize);
386 adr := adr+FDataBlocks[_id].Block.BlockSize;
387 until FDataBlocks[_id].Block.BlockType = BLOCK_NONE;
389 Result := True;
390 end;
392 end.