source: oup/releases/0.29a3/Unit9_data_structures.pas@ 36

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