source: oup/releases/0.29a2/Unit9_data_structures.pas@ 455

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