source: oup/releases/0.30a/Unit9_data_structures.pas@ 901

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