source: oup/releases/0.32a/Unit9_data_structures.pas@ 864

Last change on this file since 864 was 35, checked in by alloc, 18 years ago
File size: 16.6 KB
RevLine 
[35]1UNIT Unit9_data_structures;
2INTERFACE
3USES SysUtils, Classes, Unit3_data, Dialogs, StrUtils;
4
5TYPE
6 Tstructure_entry=RECORD
7 name:String;
8 offset:LongWord;
9 datatype:Word; // 1..4 : Integer[1..4] dec
10 // 5..8 : Integer[1..4] hex
11 // 9 : float
12 // 10 : bitset
13 // 11 : raw-addr
14 // 12 : dat-file-ID
15 // 13..16: Signed Integer[1..4]
16 // 17 : level-ID
17 // 100..300: dat-file-name[0..200]
18 // 1000..9999: Unused data[0-8999]
19 // 10000+: string[0+]
20 description:String;
21 END;
22 TStructDefSub=RECORD
23 SubName:String;
24 SubDesc:String;
25 Entries:Array OF TStructure_entry;
26 END;
27 TStructDef=RECORD
28 Data:Boolean;
29 Global:Array OF TStructure_entry;
30 Subs:Array OF TStructDefSub;
31 END;
32 THandler=FUNCTION(fileid:LongWord):TRawList;
33 TRawListHandlers=RECORD
34 Ext:String[4];
35 needed:Boolean;
36 Handler:THandler;
37 END;
38
39VAR
40 RawListHandlers:Array OF TRawListHandlers;
41 Raws:String;
42
43
44FUNCTION LoadStructureDefinition(fileid:LongWord):TStructDef;
45FUNCTION GetDataType(typeid:Word):String;
46FUNCTION GetTypeDataLength(datatype:Word):Word;
47
48IMPLEMENTATION
49USES Unit2_functions, Unit15_Classes, Forms;
50
51FUNCTION GetTypeDataLength(datatype:Word):Word;
52 BEGIN
53 CASE datatype OF
54 1..4: Result:=datatype;
55 5..8: Result:=datatype-4;
56 9: Result:=4;
57 10: Result:=1;
58 11: Result:=4;
59 12: Result:=4;
60 13..16: Result:=datatype-12;
61 17: Result:=4;
62 100..300: Result:=datatype-100;
63 1000..9999: Result:=datatype-1000;
64 10000..65535: Result:=datatype-10000;
65 END;
66 END;
67
68FUNCTION GetDataType(typeid:Word):String;
69 BEGIN
70 CASE typeid OF
71 1..4: Result:='Int'+IntToStr(typeid*8);
72 5..8: Result:='Int'+IntToStr((typeid-4)*8);
73 9: Result:='Float';
74 10: Result:='BitSet';
75 11: Result:='Raw-Address';
76 12: Result:='.dat-file-ID';
77 13..16: Result:='SignedInt'+IntToStr((typeid-12)*8);
78 17: Result:='LevelID';
79 100..300: Result:='.dat-file-name('+IntToStr(typeid-100)+')';
80 1000..9999: Result:='Unused('+IntToStr(typeid-1000)+')';
81 10000..65535: Result:='String('+IntToStr(typeid-10000)+')';
82 END;
83 END;
84
85
86
87
88FUNCTION AGDB(fileid:LongWord):TRawList;
89 VAR
90 link:LongWord;
91 links:LongWord;
92 i:LongWord;
93 BEGIN
94 IF NOT OniDataConnection.OSisMac THEN BEGIN
95 OniDataConnection.LoadDatFilePart(fileid,$1C,4,@links);
96 links:=links*2;
97 SetLength(Result,links);
98 FOR i:=0 TO links-1 DO BEGIN
99 Result[i].src_offset:=$20+i*4;
100 OniDataConnection.LoadDatFilePart(fileid,$20+i*4,4,@link);
101 Result[i].raw_addr:=link;
102 Result[i].raw_size:=0{????????????????????????????????};
103 Result[i].loc_sep:=False;
104 END;
105 END;
106 END;
107FUNCTION AKVA(fileid:LongWord):TRawList;
108 VAR
109 link:LongWord;
110 links:LongWord;
111 i:LongWord;
112 BEGIN
113 IF NOT OniDataConnection.OSisMac THEN BEGIN
114 OniDataConnection.LoadDatFilePart(fileid,$1C,4,@links);
115 SetLength(Result,links);
116 FOR i:=0 TO links-1 DO BEGIN
117 Result[i].src_offset:=$20+i*$74+$24;
118 OniDataConnection.LoadDatFilePart(fileid,$20+i*$74+$24,4,@link);
119 Result[i].raw_addr:=link;
120 OniDataConnection.LoadDatFilePart(fileid,$20+i*$74+$28,4,@link);
121 Result[i].raw_size:=link;
122 Result[i].loc_sep:=False;
123 END;
124 END;
125 END;
126FUNCTION BINA(fileid:LongWord):TRawList;
127 VAR
128 link:LongWord;
129 datasize:LongWord;
130 BEGIN
131 OniDataConnection.LoadDatFilePart(fileid,$0C,4,@link);
132 OniDataConnection.LoadDatFilePart(fileid,$08,4,@datasize);
133 SetLength(Result,1);
134 Result[0].src_offset:=$0C;
135 Result[0].raw_addr:=link;
136 Result[0].raw_size:=datasize;
137 Result[0].loc_sep:=OniDataConnection.OSisMac;
138 END;
139FUNCTION OSBD(fileid:LongWord):TRawList;
140 VAR
141 link:LongWord;
142 datasize:LongWord;
143 BEGIN
144 OniDataConnection.LoadDatFilePart(fileid,$08,4,@datasize);
145 OniDataConnection.LoadDatFilePart(fileid,$0C,4,@link);
146 SetLength(Result,1);
147 Result[0].src_offset:=$0C;
148 Result[0].raw_addr:=link;
149 Result[0].raw_size:=datasize;
150 Result[0].loc_sep:=OniDataConnection.OSisMac;
151 END;
152FUNCTION SNDD(fileid:LongWord):TRawList;
153 VAR
154 link:LongWord;
155 datasize:LongWord;
156 BEGIN
157 SetLength(Result,1);
158 IF NOT OniDataConnection.OSisMac THEN BEGIN
159 OniDataConnection.LoadDatFilePart(fileid,$40,4,@datasize);
160 OniDataConnection.LoadDatFilePart(fileid,$44,4,@link);
161 Result[0].src_offset:=$44;
162 END ELSE BEGIN
163 OniDataConnection.LoadDatFilePart(fileid,$10,4,@datasize);
164 OniDataConnection.LoadDatFilePart(fileid,$14,4,@link);
165 Result[0].src_offset:=$14;
166 END;
167 Result[0].raw_addr:=link;
168 Result[0].raw_size:=datasize;
169 Result[0].loc_sep:=False;
170 END;
171FUNCTION SUBT(fileid:LongWord):TRawList;
172 VAR
173 baselink,lastlink:LongWord;
174 links:LongWord;
175 j,k:LongWord;
176 data:Tdata;
177 BEGIN
178 OniDataConnection.LoadDatFilePart(fileid,$18,4,@baselink);
179 OniDataConnection.LoadDatFilePart(fileid,$1C,4,@links);
180 IF links>0 THEN BEGIN
181 OniDataConnection.LoadDatFilePart(fileid,$20+(links-1)*4,4,@lastlink);
182 SetLength(data,lastlink+1024);
183 TOniDataDat(OniDataConnection).LoadRawOffset(false, baselink,lastlink+1024,data);
184// OniDataConnection.LoadRawFile(fileid,$1C,baselink,lastlink+1024,False,@data[0]);
185 k:=0;
186 FOR j:=0 TO 1024 DO BEGIN
187 IF (data[lastlink+j]=$00) OR (j=1024) THEN BEGIN
188 IF j<1024 THEN BEGIN
189 IF k=0 THEN BEGIN
190 k:=1;
191 END ELSE BEGIN
192 SetLength(Result,1);
193 Result[0].src_offset:=$18;
194 Result[0].raw_addr:=baselink;
195 Result[0].raw_size:=lastlink+j;
196 Break;
197 END;
198 END;
199 END;
200 END;
201 END;
202 END;
203FUNCTION TRAM(fileid:LongWord):TRawList;
204 VAR
205 i:Integer;
206 link:LongWord;
207 frames:Word;
208 tempb:Byte;
209 tempw:Word;
210 templ:LongWord;
211 data:Tdata;
212 offset:Word;
213 frame_count:Byte;
214 BEGIN
215 SetLength(Result,13);
216 OniDataConnection.LoadDatFilePart(fileid,$16C,2,@frames);
217 {y-pos}
218 OniDataConnection.LoadDatFilePart(fileid,$0C,4,@link);
219 Result[0].src_offset:=$0C;
220 Result[0].raw_addr:=link;
221 Result[0].raw_size:=frames*4;
222 {x-z-pos}
223 OniDataConnection.LoadDatFilePart(fileid,$10,4,@link);
224 Result[1].src_offset:=$10;
225 Result[1].raw_addr:=link;
226 Result[1].raw_size:=frames*8;
227 {attacks}
228 OniDataConnection.LoadDatFilePart(fileid,$182,1,@tempb);
229 OniDataConnection.LoadDatFilePart(fileid,$14,4,@link);
230 Result[2].src_offset:=$14;
231 Result[2].raw_addr:=link;
232 Result[2].raw_size:=tempb*32;
233 {damage}
234 OniDataConnection.LoadDatFilePart(fileid,$183,1,@tempb);
235 OniDataConnection.LoadDatFilePart(fileid,$18,4,@link);
236 Result[3].src_offset:=$18;
237 Result[3].raw_addr:=link;
238 Result[3].raw_size:=tempb*8;
239 {motionblur}
240 OniDataConnection.LoadDatFilePart(fileid,$184,1,@tempb);
241 OniDataConnection.LoadDatFilePart(fileid,$1C,4,@link);
242 Result[4].src_offset:=$1C;
243 Result[4].raw_addr:=link;
244 Result[4].raw_size:=tempb*8;
245 {shortcut}
246 OniDataConnection.LoadDatFilePart(fileid,$185,1,@tempb);
247 OniDataConnection.LoadDatFilePart(fileid,$20,4,@link);
248 Result[5].src_offset:=$20;
249 Result[5].raw_addr:=link;
250 Result[5].raw_size:=tempb*8;
251 {throw}
252 OniDataConnection.LoadDatFilePart(fileid,$24,4,@link);
253 Result[6].src_offset:=$24;
254 Result[6].raw_addr:=link;
255 IF link>0 THEN
256 Result[6].raw_size:=24
257 ELSE
258 Result[6].raw_size:=0;
259 {footstep}
260 OniDataConnection.LoadDatFilePart(fileid,$186,1,@tempb);
261 OniDataConnection.LoadDatFilePart(fileid,$28,4,@link);
262 Result[7].src_offset:=$28;
263 Result[7].raw_addr:=link;
264 Result[7].raw_size:=tempb*4;
265 {particle}
266 OniDataConnection.LoadDatFilePart(fileid,$187,1,@tempb);
267 OniDataConnection.LoadDatFilePart(fileid,$2C,4,@link);
268 Result[8].src_offset:=$2C;
269 Result[8].raw_addr:=link;
270 Result[8].raw_size:=tempb*24;
271 {position}
272 OniDataConnection.LoadDatFilePart(fileid,$30,4,@link);
273 Result[9].src_offset:=$30;
274 Result[9].raw_addr:=link;
275 Result[9].raw_size:=frames*8;
276 {particle}
277 OniDataConnection.LoadDatFilePart(fileid,$154,2,@tempw);
278 OniDataConnection.LoadDatFilePart(fileid,$38,4,@link);
279 Result[11].src_offset:=$38;
280 Result[11].raw_addr:=link;
281 Result[11].raw_size:=tempw*34;
282 {extent}
283 OniDataConnection.LoadDatFilePart(fileid,$138,4,@templ);
284 OniDataConnection.LoadDatFilePart(fileid,$13C,4,@link);
285 Result[12].src_offset:=$13C;
286 Result[12].raw_addr:=link;
287 Result[12].raw_size:=templ*12;
288
289 OniDataConnection.LoadDatFilePart(fileid,$34,4,@link);
290 IF link>0 THEN BEGIN
291 OniDataConnection.LoadDatFilePart(fileid,$160,2,@tempw);
292 frame_count:=0;
293 i:=0;
294 SetLength(data,$FFFF);
295 TOniDataDat(OniDataConnection).LoadRawOffset(false,link,$FFFF,data);
296 offset:=data[$24]+data[$25]*256;
297 WHILE (offset+i<Length(data)) AND (frame_count<frames-1) DO BEGIN
298 Inc(i,tempw);
299 frame_count:=frame_count+data[offset+i];
300 Inc(i);
301 END;
302 IF offset+i<Length(data) THEN BEGIN
303 Inc(i,tempw);
304 Result[10].raw_size:=offset+i;
305 END ELSE BEGIN
306 Result[10].raw_size:=0;
307 END;
308 END;
309 Result[10].src_offset:=$34;
310 Result[10].raw_addr:=link;
311 END;
312FUNCTION TXMP(fileid:LongWord):TRawList;
313 VAR
314 link_pc:LongWord;
315 link_mac:LongWord;
316 x,y:Word;
317 storetype:Byte;
318 datasize:LongWord;
319 BEGIN
320 OniDataConnection.LoadDatFilePart(fileid,$8C,SizeOf(x),@x);
321 OniDataConnection.LoadDatFilePart(fileid,$8E,SizeOf(y),@y);
322 OniDataConnection.LoadDatFilePart(fileid,$90,SizeOf(storetype),@storetype);
323 OniDataConnection.LoadDatFilePart(fileid,$9C,4,@link_pc);
324 OniDataConnection.LoadDatFilePart(fileid,$A0,4,@link_mac);
325 CASE storetype OF
326 0,1,2: datasize:=x*y*2;
327 8: datasize:=x*y*4;
328 9: datasize:=x*y DIV 2;
329 END;
330 SetLength(Result,1);
331 IF NOT OniDataConnection.OSisMac THEN BEGIN
332 Result[0].src_offset:=$9C;
333 Result[0].raw_addr:=link_pc
334 END ELSE BEGIN
335 Result[0].src_offset:=$A0;
336 Result[0].raw_addr:=link_mac;
337 END;
338 Result[0].raw_size:=datasize;
339 Result[0].loc_sep:=OniDataConnection.OSisMac;
340 END;
341
342
343PROCEDURE InsertRawListHandler(ext:String; needed:Boolean; handler:THandler);
344 BEGIN
345 SetLength(RawListHandlers,Length(RawListHandlers)+1);
346 RawListHandlers[High(RawListHandlers)].Ext:=ext;
347 RawListHandlers[High(RawListHandlers)].needed:=needed;
348 RawListHandlers[High(RawListHandlers)].handler:=handler;
349 Raws:=Raws+ext;
350 END;
351
352
353
354FUNCTION LoadStructureDefinition(fileid:LongWord):TStructDef;
355 VAR
356 i:LongWord;
357 current_type:Byte; //0: Global, 1: Undynamic, 2: Dynamic
358 current_base,current_package,current_package_size:LongWord;
359 packages:LongWord;
360 deffile:Text;
361 structentry:TStructure_Entry;
362 fields:TStringArray;
363 filename:String;
364 ext:String[4];
365 temps:String;
366 data:TData;
367 BEGIN
368 SetLength(Result.Global,0);
369 SetLength(Result.Subs,0);
370 Result.Data:=False;
371 ext:=OniDataConnection.GetFileInfo(fileid).Extension;
372 filename:=ExtractFilePath(Application.ExeName)+'\StructDefs\'+ext+'.txt';
373 IF FileExists(filename) THEN BEGIN
374 data:=OniDataConnection.LoadDatFile(fileid);
375 AssignFile(deffile,filename);
376 Reset(deffile);
377 current_type:=0;
378 Result.Data:=True;
379 IF NOT EoF(deffile) THEN BEGIN
380 ReadLn(deffile,temps);
381 WHILE NOT EoF(deffile) DO BEGIN
382 ReadLn(deffile,temps);
383 IF (Length(temps)>0) AND (temps[1]<>'#') THEN BEGIN
384 IF temps[1]='*' THEN BEGIN
385 fields:=Explode(temps,#9);
386 CASE Length(fields) OF
387 1..2: BEGIN
388 current_type:=1;
389 current_base:=0;
390 SetLength(Result.Subs, Length(Result.Subs)+1);
391 Result.Subs[High(Result.Subs)].SubName:=MidStr(fields[0],2,Length(fields[0])-1);
392 IF Length(fields)=2 THEN
393 Result.Subs[High(Result.Subs)].SubDesc:=fields[1];
394 END;
395 3: BEGIN
396 current_type:=1;
397 current_base:=HexToLong(fields[2]);
398 SetLength(Result.Subs, Length(Result.Subs)+1);
399 Result.Subs[High(Result.Subs)].SubName:=MidStr(fields[0],2,Length(fields[0])-1);
400 Result.Subs[High(Result.Subs)].SubDesc:=fields[1];
401 END;
402 6: BEGIN
403 current_type:=2;
404 current_base:=HexToLong(fields[2]);
405 current_package:=0;
406 current_package_size:=StrToInt(fields[5]);
407 IF fields[4][1]<>'$' THEN BEGIN
408 CASE StrToInt(fields[4]) OF
409 1: packages:=data[HexToLong(fields[3])];
410 2: packages:=data[HexToLong(fields[3])]+data[HexToLong(fields[3])+1]*256;
411 4: packages:=data[HexToLong(fields[3])]+data[HexToLong(fields[3])+1]*256+data[HexToLong(fields[3])+2]*256*256+data[HexToLong(fields[3])+3]*256*256*256;
412 END;
413 END ELSE BEGIN
414 packages:=HexToLong(fields[4]);
415 END;
416 SetLength(Result.Subs, Length(Result.Subs)+packages);
417 FOR current_package:=0 TO packages-1 DO BEGIN
418 Result.Subs[High(Result.Subs)-packages+current_package+1].SubName:=
419 MidStr(fields[0],2,Length(fields[0])-1)+'['+IntToStr(current_package)+']'+
420 '#'+IntToHex(current_base+current_package*current_package_size,8)+
421 '#'+IntToHex(current_package_size,8);
422 Result.Subs[High(Result.Subs)-packages+current_package+1].SubDesc:=
423 fields[1];
424 END;
425 END;
426 END;
427 END ELSE BEGIN
428 fields:=Explode(temps,#9);
429 IF (Length(fields)=3) OR (Length(fields)=4) THEN BEGIN
430 IF NOT AppSettings.HideUnusedData OR ((StrToInt(fields[2])<1000) OR (StrToInt(fields[2])>9999)) THEN BEGIN
431 structentry.name:=fields[0];
432 structentry.datatype:=StrToInt(fields[2]);
433 IF Length(fields)=4 THEN
434 structentry.description:=fields[3]
435 ELSE
436 structentry.description:='';
437 IF current_type IN [0,1] THEN BEGIN
438 structentry.offset:=HexToLong(fields[1])+current_base;
439 IF Length(Result.Subs)=0 THEN BEGIN
440 SetLength(Result.Global,Length(Result.Global)+1);
441 Result.Global[High(Result.Global)]:=structentry;
442 END ELSE BEGIN
443 SetLength(Result.Subs[High(Result.Subs)].Entries,Length(Result.Subs[High(Result.Subs)].Entries)+1);
444 Result.Subs[High(Result.Subs)].Entries[High(Result.Subs[High(Result.Subs)].Entries)]:=structentry;
445 END;
446 END ELSE BEGIN
447 FOR current_package:=0 TO packages-1 DO BEGIN
448 structentry.offset:=current_base+current_package*current_package_size+HexToLong(fields[1]);
449 WITH Result.Subs[High(Result.Subs)-packages+current_package+1] DO BEGIN
450 SetLength(Entries,Length(Entries)+1);
451 Entries[High(Entries)]:=structentry;
452 END;
453 END;
454 END;
455 END;
456 END;
457 END;
458 END;
459 END;
460 END;
461 CloseFile(deffile);
462 END;
463 END;
464
465
466BEGIN
467 Raws:='';
468// InsertRawListHandler('AGDB',True,AGDB);
469 InsertRawListHandler('AKVA',True,AKVA);
470 InsertRawListHandler('BINA',True,BINA);
471 InsertRawListHandler('OSBD',True,OSBD);
472 InsertRawListHandler('SNDD',True,SNDD);
473 InsertRawListHandler('SUBT',True,SUBT);
474 InsertRawListHandler('TRAM',True,TRAM);
475 InsertRawListHandler('TXMP',True,TXMP);
476END.
Note: See TracBrowser for help on using the repository browser.