DEADSOFTWARE

mplat fixes
[d2df-sdl.git] / src / shared / MAPDEF.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 {$M+}
18 unit MAPDEF;
20 interface
22 uses
23 xdynrec;
26 const
27 MAP_SIGNATURE = 'MAP';
30 const
31 TEXTURE_NAME_WATER = '_water_0';
32 TEXTURE_NAME_ACID1 = '_water_1';
33 TEXTURE_NAME_ACID2 = '_water_2';
36 type
37 TDFPoint = packed record
38 public
39 X, Y: LongInt;
41 public
42 constructor Create (ax, ay: LongInt);
44 function isZero (): Boolean; inline;
45 end;
47 TDFSize = packed record
48 public
49 w, h: LongInt;
51 public
52 constructor Create (aw, ah: LongInt);
54 function isZero (): Boolean; inline;
55 function isValid (): Boolean; inline;
56 end;
58 Char16 = packed array[0..15] of Char;
59 Char32 = packed array[0..31] of Char;
60 Char64 = packed array[0..63] of Char;
61 Char100 = packed array[0..99] of Char;
62 Char256 = packed array[0..255] of Char;
63 Byte128 = packed array[0..127] of Byte;
65 {$INCLUDE mapdef.inc}
67 // various helpers to access map structures
68 type
69 TDynRecordHelper = class helper for TDynRecord
70 private
71 function getFieldWithType (const aname: AnsiString; atype: TDynField.TType): TDynField; inline;
73 function getPanelByIdx (idx: Integer): TDynRecord; inline;
75 function getPanelId (): Integer; inline;
76 //procedure setPanelId (v: Integer); inline;
78 function getTexturePanel (): Integer; inline;
79 //procedure setTexturePanel (v: Integer); inline;
81 function getPanelIndex (pan: TDynRecord): Integer;
83 function getPointField (const aname: AnsiString): TDFPoint; inline;
84 function getSizeField (const aname: AnsiString): TDFSize; inline;
86 public
87 function panelCount (): Integer; inline;
89 // header
90 function mapName (): AnsiString; inline;
91 function mapAuthor (): AnsiString; inline;
92 function mapDesc (): AnsiString; inline;
93 function musicName (): AnsiString; inline;
94 function skyName (): AnsiString; inline;
96 // panel
97 function X (): Integer; inline;
98 function Y (): Integer; inline;
99 function Width (): Word; inline;
100 function Height (): Word; inline;
101 function TextureNum (): Word; inline;
102 function TextureRec (): TDynRecord; inline;
103 function PanelType (): Word; inline;
104 function Alpha (): Byte; inline;
105 function Flags (): Byte; inline;
107 function moveSpeed (): TDFPoint; inline;
108 function moveStart (): TDFPoint; inline;
109 function moveEnd (): TDFPoint; inline;
111 function moveOnce (): Boolean; inline;
113 function sizeSpeed (): TDFSize; inline;
114 function sizeEnd (): TDFSize; inline;
116 function endPosTrig (): Integer; inline;
117 function endSizeTrig (): Integer; inline;
119 // texture
120 function Resource (): AnsiString; inline;
121 function Anim (): Boolean; inline;
123 // item
124 function ItemType (): Byte; inline;
125 function Options (): Byte; inline;
127 // monster
128 function MonsterType (): Byte; inline; // type, ubyte
129 function Direction (): Byte; inline; // direction, ubyte
131 // area
132 function AreaType (): Byte; inline; // type, ubyte
133 //function Direction (): Byte; inline; // direction, ubyte
135 // trigger
136 function trigRec (): TDynRecord; inline;
137 function Enabled (): Boolean; inline; // enabled, bool
138 function TriggerType (): Byte; inline; // type, ubyte
139 function ActivateType (): Byte; inline; // activatetype, ubyte
140 function Keys (): Byte; inline; // keys, ubyte
141 //function DATA (): Byte128; inline; // triggerdata, trigdata[128]; // the only special nested structure
143 {$INCLUDE mapdef_help.inc}
144 function trigMonsterId (): Integer; inline;
145 function trigPanelId (): Integer; inline; // panel index in list
147 private
148 // user fields
149 function getUserPanelId (): Integer; inline;
150 procedure setUserPanelId (v: Integer); inline;
152 function getUserTrigRef (): Boolean; inline;
153 procedure setUserTrigRef (v: Boolean); inline;
155 public
156 property panel[idx: Integer]: TDynRecord read getPanelByIdx;
157 property panelIndex[pan: TDynRecord]: Integer read getPanelIndex;
158 // triggers
159 property tgPanelID: Integer read getPanelId {write setPanelId};
160 property tgShotPanelID: Integer read getPanelId {write setPanelId};
161 property TexturePanel: Integer read getTexturePanel {write setTexturePanel}; // texturepanel, int
162 // user fields
163 property userPanelId: Integer read getUserPanelId write setUserPanelId;
164 property userPanelTrigRef: Boolean read getUserTrigRef write setUserTrigRef;
165 end;
167 implementation
169 uses
170 SysUtils, {e_log,} utils, xparser, xstreams;
173 // ////////////////////////////////////////////////////////////////////////// //
174 constructor TDFPoint.Create (ax, ay: LongInt); begin X := ax; Y := ay; end;
175 function TDFPoint.isZero (): Boolean; inline; begin result := (X = 0) and (Y = 0); end;
178 constructor TDFSize.Create (aw, ah: LongInt); begin w := aw; h := ah; end;
179 function TDFSize.isZero (): Boolean; inline; begin result := (w = 0) and (h = 0); end;
180 function TDFSize.isValid (): Boolean; inline; begin result := (w > 0) and (h > 0); end;
183 // ////////////////////////////////////////////////////////////////////////// //
184 function TDynRecordHelper.getUserPanelId (): Integer; inline;
185 var
186 fld: TDynField;
187 begin
188 fld := field['userPanelId'];
189 //if (fld = nil) or (fld.baseType <> TDynField.TType.TInt) then result := -1 else result := fld.ival;
190 if (fld = nil) then result := -1 else result := Integer(fld.varvalue);
191 end;
194 procedure TDynRecordHelper.setUserPanelId (v: Integer); inline;
195 begin
196 user['userPanelId'] := v;
197 end;
200 function TDynRecordHelper.getUserTrigRef (): Boolean; inline;
201 var
202 fld: TDynField;
203 begin
204 fld := field['userPanelTrigRef'];
205 if (fld = nil) then result := false else result := Boolean(fld.varvalue);
206 //if (fld = nil) or (fld.baseType <> TDynField.TType.TBool) then result := false else result := (fld.ival <> 0);
207 end;
210 procedure TDynRecordHelper.setUserTrigRef (v: Boolean); inline;
211 begin
212 user['userPanelTrigRef'] := v;
213 end;
216 // ////////////////////////////////////////////////////////////////////////// //
217 function TDynRecordHelper.moveSpeed (): TDFPoint; inline; begin result := getPointField('move_speed'); end;
218 function TDynRecordHelper.moveStart (): TDFPoint; inline; begin result := getPointField('move_start'); end;
219 function TDynRecordHelper.moveEnd (): TDFPoint; inline; begin result := getPointField('move_end'); end;
221 function TDynRecordHelper.sizeSpeed (): TDFSize; inline; begin result := getSizeField('size_speed'); end;
222 function TDynRecordHelper.sizeEnd (): TDFSize; inline; begin result := getSizeField('size_end'); end;
224 function TDynRecordHelper.moveOnce (): Boolean; inline; begin result := (getFieldWithType('move_once', TDynField.TType.TBool).ival <> 0); end;
227 function TDynRecordHelper.endPosTrig (): Integer; inline;
228 var
229 fld: TDynField;
230 begin
231 fld := getFieldWithType('end_pos_trigger', TDynField.TType.TInt);
232 result := fld.recrefIndex;
233 end;
235 function TDynRecordHelper.endSizeTrig (): Integer; inline;
236 var
237 fld: TDynField;
238 begin
239 fld := getFieldWithType('end_size_trigger', TDynField.TType.TInt);
240 result := fld.recrefIndex;
241 end;
244 // ////////////////////////////////////////////////////////////////////////// //
245 function TDynRecordHelper.getFieldWithType (const aname: AnsiString; atype: TDynField.TType): TDynField; inline;
246 begin
247 result := field[aname];
248 if (result = nil) then raise Exception.Create(Format('field ''%s'' not found in record ''%s'' of type ''%s''', [aname, name, id]));
249 if (result.baseType <> atype) then raise Exception.Create(Format('field ''%s'' in record ''%s'' of type ''%s'' has invalid data type', [aname, name, id]));
250 end;
253 function TDynRecordHelper.getPointField (const aname: AnsiString): TDFPoint; inline;
254 var
255 fld: TDynField;
256 begin
257 fld := field[aname];
258 if (fld = nil) then raise Exception.Create(Format('field ''%s'' not found in record ''%s'' of type ''%s''', [aname, name, id]));
259 if (fld.baseType <> TPoint) then raise Exception.Create(Format('field ''%s'' in record ''%s'' of type ''%s'' has invalid data type', [aname, name, id]));
260 result := TDFPoint.Create(fld.ival, fld.ival2);
261 end;
264 function TDynRecordHelper.getSizeField (const aname: AnsiString): TDFSize; inline;
265 var
266 fld: TDynField;
267 begin
268 fld := field[aname];
269 if (fld = nil) then raise Exception.Create(Format('field ''%s'' not found in record ''%s'' of type ''%s''', [aname, name, id]));
270 if (fld.baseType <> TSize) and (fld.baseType <> TPoint) then raise Exception.Create(Format('field ''%s'' in record ''%s'' of type ''%s'' has invalid data type', [aname, name, id]));
271 result := TDFSize.Create(fld.ival, fld.ival2);
272 end;
275 function TDynRecordHelper.getPanelByIdx (idx: Integer): TDynRecord; inline;
276 var
277 fld: TDynField;
278 begin
279 fld := headerRec['panel'];
280 if (fld <> nil) then result := fld.item[idx] else result := nil;
281 end;
284 function TDynRecordHelper.getPanelIndex (pan: TDynRecord): Integer;
285 var
286 fld: TDynField;
287 f: Integer;
288 begin
289 result := -1;
290 if (pan <> nil) then
291 begin
292 fld := headerRec['panel'];
293 if (fld <> nil) then
294 begin
295 for f := 0 to fld.count-1 do if (fld.item[f] = pan) then begin result := f; exit; end;
296 end;
297 end;
298 end;
301 function TDynRecordHelper.panelCount (): Integer; inline;
302 var
303 fld: TDynField;
304 begin
305 fld := headerRec['panel'];
306 if (fld <> nil) then result := fld.count else result := 0;
307 end;
310 function TDynRecordHelper.TextureNum (): Word; inline;
311 var
312 idx: Integer;
313 fld: TDynField;
314 begin
315 fld := getFieldWithType('texture', TDynField.TType.TUShort);
316 idx := fld.recrefIndex;
317 if (idx < 0) then result := Word(TEXTURE_NONE) else result := Word(idx);
318 end;
321 // ////////////////////////////////////////////////////////////////////////// //
322 // trigger
323 function TDynRecordHelper.trigRec (): TDynRecord; inline;
324 var
325 fld: TDynField;
326 begin
327 fld := getFieldWithType('triggerdata', TDynField.TType.TTrigData);
328 if (fld <> nil) then result := fld.recref else result := nil;
329 end;
332 function TDynRecordHelper.trigMonsterId (): Integer; inline;
333 var
334 fld: TDynField;
335 begin
336 fld := getFieldWithType('monsterid', TDynField.TType.TInt);
337 result := fld.recrefIndex;
338 end;
341 // panel index in list
342 function TDynRecordHelper.trigPanelId (): Integer; inline;
343 var
344 fld: TDynField;
345 begin
346 fld := getFieldWithType('panelid', TDynField.TType.TInt);
347 result := fld.recrefIndex;
348 end;
351 // ////////////////////////////////////////////////////////////////////////// //
352 function TDynRecordHelper.mapName (): AnsiString; inline; begin result := utf2win(getFieldWithType('name', TDynField.TType.TChar).sval); end;
353 function TDynRecordHelper.mapAuthor (): AnsiString; inline; begin result := utf2win(getFieldWithType('author', TDynField.TType.TChar).sval); end;
354 function TDynRecordHelper.mapDesc (): AnsiString; inline; begin result := utf2win(getFieldWithType('description', TDynField.TType.TChar).sval); end;
355 function TDynRecordHelper.musicName (): AnsiString; inline; begin result := utf2win(getFieldWithType('music', TDynField.TType.TChar).sval); end;
356 function TDynRecordHelper.skyName (): AnsiString; inline; begin result := utf2win(getFieldWithType('sky', TDynField.TType.TChar).sval); end;
357 function TDynRecordHelper.X (): Integer; inline; begin result := getFieldWithType('position', TDynField.TType.TPoint).ival; end;
358 function TDynRecordHelper.Y (): Integer; inline; begin result := getFieldWithType('position', TDynField.TType.TPoint).ival2; end;
359 function TDynRecordHelper.Width (): Word; inline; begin result := Word(getFieldWithType('size', TDynField.TType.TSize).ival); end;
360 function TDynRecordHelper.Height (): Word; inline; begin result := Word(getFieldWithType('size', TDynField.TType.TSize).ival2); end;
361 function TDynRecordHelper.PanelType (): Word; inline; begin result := Word(getFieldWithType('type', TDynField.TType.TUShort).ival); end;
362 function TDynRecordHelper.TextureRec (): TDynRecord; inline; begin result := getFieldWithType('texture', TDynField.TType.TUShort).recref; end;
363 function TDynRecordHelper.Alpha (): Byte; inline; begin result := Byte(getFieldWithType('alpha', TDynField.TType.TUByte).ival); end;
364 function TDynRecordHelper.Flags (): Byte; inline; begin result := Byte(getFieldWithType('flags', TDynField.TType.TUByte).ival); end;
365 function TDynRecordHelper.Resource (): AnsiString; inline; begin result := utf2win(getFieldWithType('path', TDynField.TType.TChar).sval); end;
366 function TDynRecordHelper.Anim (): Boolean; inline; begin result := (getFieldWithType('animated', TDynField.TType.TBool).ival <> 0); end;
367 function TDynRecordHelper.ItemType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
368 function TDynRecordHelper.Options (): Byte; inline; begin result := Byte(getFieldWithType('options', TDynField.TType.TUByte).ival); end;
369 function TDynRecordHelper.MonsterType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
370 function TDynRecordHelper.Direction (): Byte; inline; begin result := Byte(getFieldWithType('direction', TDynField.TType.TUByte).ival); end;
371 function TDynRecordHelper.AreaType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
372 function TDynRecordHelper.Enabled (): Boolean; inline; begin result := (getFieldWithType('enabled', TDynField.TType.TBool).ival <> 0); end;
373 function TDynRecordHelper.TriggerType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
374 function TDynRecordHelper.ActivateType (): Byte; inline; begin result := Byte(getFieldWithType('activatetype', TDynField.TType.TUByte).ival); end;
375 function TDynRecordHelper.Keys (): Byte; inline; begin result := Byte(getFieldWithType('keys', TDynField.TType.TUByte).ival); end;
377 function TDynRecordHelper.getPanelId (): Integer; inline; begin result := getFieldWithType('panelid', TDynField.TType.TInt).recrefIndex; end;
378 function TDynRecordHelper.getTexturePanel (): Integer; begin result := getFieldWithType('texturepanel', TDynField.TType.TInt).recrefIndex; end;
380 {$INCLUDE mapdef_impl.inc}
383 end.