DEADSOFTWARE

6c9e86326551d7b0d24ba7e8151aed028e565c01
[d2df-sdl.git] / src / shared / MAPREADER.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 {$MODE DELPHI}
17 unit MAPREADER;
19 {
20 -----------------------------------
21 MAPREADER.PAS ÂÅÐÑÈß ÎÒ 13.11.07
23 Ïîääåðæêà êàðò âåðñèè 1
24 -----------------------------------
25 }
27 interface
29 uses
30 MAPSTRUCT;
32 type
33 TDataBlock = packed record
34 Block: TBlock;
35 Data: Pointer;
36 end;
38 TDataBlocksArray = packed array of TDataBlock;
40 TMapReader = class(TObject)
41 private
42 FError: Byte;
43 FVersion: Byte;
44 FDataBlocks: TDataBlocksArray;
45 function GetBlocks(BlocksType: Byte): TDataBlocksArray;
46 public
47 constructor Create();
48 destructor Destroy(); override;
49 function LoadMap(Data: Pointer): Boolean;
50 procedure FreeMap();
51 function HandledVersion(): Byte; virtual;
53 property GetError: Byte read FError;
54 property GetVersion: Byte read FVersion;
55 end;
57 TMapReader_1 = class(TMapReader)
58 private
59 public
60 function GetMapHeader(): TMapHeaderRec_1;
61 function GetTextures(): TTexturesRec1Array;
62 function GetPanels(): TPanelsRec1Array;
63 function GetItems(): TItemsRec1Array;
64 function GetAreas(): TAreasRec1Array;
65 function GetMonsters(): TMonsterRec1Array;
66 function GetTriggers(): TTriggersRec1Array;
67 function HandledVersion(): Byte; override;
68 end;
70 const
71 MAP_ERROR_NONE = $00;
72 MAP_ERROR_SIGNATURE = $01;
73 MAP_ERROR_VERSION = $02;
75 NNF_NO_NAME = 0;
76 NNF_NAME_BEFORE = 1;
77 NNF_NAME_EQUALS = 2;
78 NNF_NAME_AFTER = 3;
80 function g_Texture_NumNameFindStart(name: String): Boolean;
81 function g_Texture_NumNameFindNext(var newName: String): Byte;
83 implementation
85 uses
86 SysUtils, BinEditor, MAPDEF;
88 var
89 NNF_PureName: String; // Èìÿ òåêñòóðû áåç öèôð â êîíöå
90 NNF_FirstNum: Integer; // ×èñëî ó íà÷àëüíîé òåêñòóðû
91 NNF_CurrentNum: Integer; // Ñëåäóþùåå ÷èñëî ó òåêñòóðû
93 function g_Texture_NumNameFindStart(name: String): Boolean;
94 var
95 i: Integer;
97 begin
98 Result := False;
99 NNF_PureName := '';
100 NNF_FirstNum := -1;
101 NNF_CurrentNum := -1;
103 for i := Length(name) downto 1 do
104 if (name[i] = '_') then // "_" - ñèìâîë íà÷àëà íîìåðíîãî ïîñòôèêñà
105 begin
106 if i = Length(name) then
107 begin // Íåò öèôð â êîíöå ñòðîêè
108 Exit;
109 end
110 else
111 begin
112 NNF_PureName := Copy(name, 1, i);
113 Delete(name, 1, i);
114 Break;
115 end;
116 end;
118 // Íå ïåðåâåñòè â ÷èñëî:
119 if not TryStrToInt(name, NNF_FirstNum) then
120 Exit;
122 NNF_CurrentNum := 0;
124 Result := True;
125 end;
127 function g_Texture_NumNameFindNext(var newName: String): Byte;
128 begin
129 if (NNF_PureName = '') or (NNF_CurrentNum < 0) then
130 begin
131 newName := '';
132 Result := NNF_NO_NAME;
133 Exit;
134 end;
136 newName := NNF_PureName + IntToStr(NNF_CurrentNum);
138 if NNF_CurrentNum < NNF_FirstNum then
139 Result := NNF_NAME_BEFORE
140 else
141 if NNF_CurrentNum > NNF_FirstNum then
142 Result := NNF_NAME_AFTER
143 else
144 Result := NNF_NAME_EQUALS;
146 Inc(NNF_CurrentNum);
147 end;
149 { T M a p R e a d e r _ 1 : }
151 function TMapReader_1.GetAreas(): TAreasRec1Array;
152 var
153 TempDataBlocks: TDataBlocksArray;
154 a: Integer;
155 b, Size: LongWord;
156 begin
157 Result := nil;
159 TempDataBlocks := GetBlocks(BLOCK_AREAS);
161 if TempDataBlocks = nil then Exit;
163 size := SizeOf_TAreaRec_1;
165 for a := 0 to High(TempDataBlocks) do
166 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
167 begin
168 SetLength(Result, Length(Result)+1);
169 //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
170 mb_Read_TAreaRec_1(Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size)^, size);
171 end;
173 TempDataBlocks := nil;
174 end;
176 function TMapReader_1.GetItems(): TItemsRec1Array;
177 var
178 TempDataBlocks: TDataBlocksArray;
179 a: Integer;
180 b, Size: LongWord;
181 begin
182 Result := nil;
184 TempDataBlocks := GetBlocks(BLOCK_ITEMS);
186 if TempDataBlocks = nil then Exit;
188 size := SizeOf_TItemRec_1;
190 for a := 0 to High(TempDataBlocks) do
191 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
192 begin
193 SetLength(Result, Length(Result)+1);
194 //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
195 mb_Read_TItemRec_1(Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size)^, size);
196 end;
198 TempDataBlocks := nil;
199 end;
201 function TMapReader_1.GetMapHeader(): TMapHeaderRec_1;
202 var
203 TempDataBlocks: TDataBlocksArray;
204 begin
205 ZeroMemory(@Result, SizeOf(TMapHeaderRec_1));
207 TempDataBlocks := GetBlocks(BLOCK_HEADER);
209 if TempDataBlocks = nil then Exit;
211 //CopyMemory(@Result, TempDataBlocks[0].Data, SizeOf(TMapHeaderRec_1));
212 mb_Read_TMapHeaderRec_1(Result, TempDataBlocks[0].Data^, SizeOf_TMapHeaderRec_1);
214 TempDataBlocks := nil;
215 end;
217 function TMapReader_1.GetMonsters(): TMonsterRec1Array;
218 var
219 TempDataBlocks: TDataBlocksArray;
220 a: Integer;
221 b, Size: LongWord;
222 begin
223 Result := nil;
225 TempDataBlocks := GetBlocks(BLOCK_MONSTERS);
227 if TempDataBlocks = nil then Exit;
229 size := SizeOf_TMonsterRec_1;
231 for a := 0 to High(TempDataBlocks) do
232 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
233 begin
234 SetLength(Result, Length(Result)+1);
235 //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
236 mb_Read_TMonsterRec_1(Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size)^, size);
237 end;
239 TempDataBlocks := nil;
240 end;
242 function TMapReader_1.GetPanels(): TPanelsRec1Array;
243 var
244 TempDataBlocks: TDataBlocksArray;
245 a: Integer;
246 b, Size: LongWord;
247 begin
248 Result := nil;
250 TempDataBlocks := GetBlocks(BLOCK_PANELS);
252 if TempDataBlocks = nil then Exit;
254 size := SizeOf_TPanelRec_1;
256 for a := 0 to High(TempDataBlocks) do
257 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
258 begin
259 SetLength(Result, Length(Result)+1);
260 //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
261 mb_Read_TPanelRec_1(Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size)^, size);
262 end;
264 TempDataBlocks := nil;
265 end;
267 function TMapReader_1.GetTextures(): TTexturesRec1Array;
268 var
269 TempDataBlocks: TDataBlocksArray;
270 a: Integer;
271 b, Size: LongWord;
272 begin
273 Result := nil;
275 TempDataBlocks := GetBlocks(BLOCK_TEXTURES);
277 if TempDataBlocks = nil then Exit;
279 size := SizeOf_TTextureRec_1;
281 for a := 0 to High(TempDataBlocks) do
282 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
283 begin
284 SetLength(Result, Length(Result)+1);
285 //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
286 mb_Read_TTextureRec_1(Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size)^, size);
287 end;
289 TempDataBlocks := nil;
290 end;
292 function TMapReader_1.GetTriggers(): TTriggersRec1Array;
293 var
294 TempDataBlocks: TDataBlocksArray;
295 a: Integer;
296 b, Size: LongWord;
297 trdata: TTriggerData;
298 begin
299 Result := nil;
301 TempDataBlocks := GetBlocks(BLOCK_TRIGGERS);
303 if TempDataBlocks = nil then Exit;
305 size := SizeOf_TTriggerRec_1;
307 for a := 0 to High(TempDataBlocks) do
308 for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
309 begin
310 SetLength(Result, Length(Result)+1);
311 //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
312 mb_Read_TTriggerRec_1(Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size)^, size);
313 if (Result[High(Result)].TriggerType <> 0) then
314 begin
315 // preprocess trigger data
316 ZeroMemory(@trdata, SizeOf(trdata));
317 mb_Read_TriggerData(trdata, Result[High(Result)].TriggerType, Result[High(Result)].DATA, sizeof(trdata));
318 Result[High(Result)].DATA := trdata.Default;
319 end;
320 end;
322 TempDataBlocks := nil;
323 end;
325 function TMapReader_1.HandledVersion: Byte;
326 begin
327 Result := $01;
328 end;
330 { T M a p R e a d e r : }
332 constructor TMapReader.Create();
333 begin
334 FDataBlocks := nil;
335 FError := MAP_ERROR_NONE;
336 FVersion := $00;
337 end;
339 destructor TMapReader.Destroy();
340 begin
341 FreeMap();
343 inherited;
344 end;
346 procedure TMapReader.FreeMap();
347 var
348 a: Integer;
349 begin
350 if FDataBlocks <> nil then
351 for a := 0 to High(FDataBlocks) do
352 if FDataBlocks[a].Data <> nil then FreeMem(FDataBlocks[a].Data);
354 FDataBlocks := nil;
355 FVersion := $00;
356 FError := MAP_ERROR_NONE;
357 end;
359 function TMapReader.GetBlocks(BlocksType: Byte): TDataBlocksArray;
360 var
361 a: Integer;
362 begin
363 Result := nil;
365 if FDataBlocks = nil then Exit;
367 for a := 0 to High(FDataBlocks) do
368 if FDataBlocks[a].Block.BlockType = BlocksType then
369 begin
370 SetLength(Result, Length(Result)+1);
371 Result[High(Result)] := FDataBlocks[a];
372 end;
373 end;
375 function TMapReader.HandledVersion(): Byte;
376 begin
377 Result := $00;
378 end;
380 function TMapReader.LoadMap(Data: Pointer): Boolean;
381 var
382 adr: LongWord;
383 _id: Integer;
384 Sign: array[0..2] of Char;
385 Ver: Byte;
386 begin
387 Result := False;
389 CopyMemory(@Sign[0], Data, 3);
390 if Sign <> MAP_SIGNATURE then
391 begin
392 FError := MAP_ERROR_SIGNATURE;
393 Exit;
394 end;
395 adr := 3;
397 CopyMemory(@Ver, Pointer(LongWord(Data)+adr), 1);
398 FVersion := Ver;
399 if Ver > HandledVersion() then
400 begin
401 FError := MAP_ERROR_VERSION;
402 Exit;
403 end;
404 adr := adr+1;
406 repeat
407 SetLength(FDataBlocks, Length(FDataBlocks)+1);
408 _id := High(FDataBlocks);
410 CopyMemory(@FDataBlocks[_id].Block, Pointer(LongWord(Data)+adr), SizeOf(TBlock));
411 adr := adr+SizeOf(TBlock);
413 FDataBlocks[_id].Data := GetMemory(FDataBlocks[_id].Block.BlockSize);
415 CopyMemory(FDataBlocks[_id].Data, Pointer(LongWord(Data)+adr), FDataBlocks[_id].Block.BlockSize);
417 adr := adr+FDataBlocks[_id].Block.BlockSize;
418 until FDataBlocks[_id].Block.BlockType = BLOCK_NONE;
420 Result := True;
421 end;
423 end.