source: oup/releases/0.28a/Unit9_data_structures.pas@ 1051

Last change on this file since 1051 was 27, checked in by alloc, 18 years ago
File size: 13.3 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; 5..8: Integer[1..4] hex; 9: float; 10: bitset; 11: raw-addr; 10000+: string[0+]
10 description:String;
11 END;
12 Tstructure_info=RECORD
13 extension:String;
14 typedesc:String;
15 entries:Array OF Tstructure_entry;
16 END;
17 Tstructures=Array OF Tstructure_info;
18 THandler=FUNCTION(fileid:LongWord):TRawList;
19 TRawListHandlers=RECORD
20 Ext:String[4];
21 needed:Boolean;
22 Handler:THandler;
23 END;
24
25VAR
26 structure_infos:Tstructures;
27 RawListHandlers:Array OF TRawListHandlers;
28
29
30FUNCTION GetDataType(typeid:Word):String;
31FUNCTION GetStructureInfoId(ext:String):Integer;
32FUNCTION GetTypeDataLength(datatype:Word):Word;
33FUNCTION GetRawInfo(fileid,dat_offset:LongWord):TRawInfo;
34FUNCTION GetRawList(fileid:LongWord):TRawList;
35
36PROCEDURE LoadStructureDefinitions(defdir:String);
37
38
39IMPLEMENTATION
40USES Unit2_functions;
41
42FUNCTION GetTypeDataLength(datatype:Word):Word;
43 BEGIN
44 CASE datatype OF
45 1..4: Result:=datatype;
46 5..8: Result:=datatype-4;
47 9: Result:=4;
48 10: Result:=1;
49 11: Result:=4;
50 10000..65535: Result:=datatype-10000;
51 END;
52 END;
53
54
55FUNCTION GetStructureInfoId(ext:String):Integer;
56 VAR
57 i:Integer;
58 BEGIN
59 FOR i:=0 TO High(structure_infos) DO BEGIN
60 IF structure_infos[i].extension=ext THEN BEGIN
61 Result:=i;
62 Exit;
63 END;
64 END;
65 Result:=-1;
66 END;
67
68
69FUNCTION GetDataType(typeid:Word):String;
70 BEGIN
71 CASE typeid OF
72 1..4: Result:='Int'+IntToStr(typeid*8);
73 5..8: Result:='Int'+IntToStr((typeid-4)*8);
74 9: Result:='Float';
75 10: Result:='BitSet';
76 11: Result:='Raw-Address';
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 LoadDatFilePart(fileid,$40,4,@datasize);
209 LoadDatFilePart(fileid,$44,4,@link);
210 SetLength(Result,1);
211 Result[0].src_offset:=$44;
212 Result[0].raw_addr:=link;
213 Result[0].raw_size:=datasize;
214 END;
215FUNCTION SUBT(fileid:LongWord):TRawList;
216 VAR
217 baselink,link:LongWord;
218 links:LongWord;
219 i,j,k:LongWord;
220 data:Tdata;
221 BEGIN
222 LoadDatFilePart(fileid,$18,4,@baselink);
223 LoadDatFilePart(fileid,$1C,4,@links);
224 IF links>0 THEN BEGIN
225 LoadDatFilePart(fileid,$20+(links-1)*4,4,@link);
226 SetLength(data,link+1024);
227 LoadRawFile(fileid,$1C,baselink,link+1024,False,@data[0]);
228 k:=0;
229 FOR j:=0 TO 1024 DO BEGIN
230 IF (data[link+j]=$00) OR (j=1024) THEN BEGIN
231 IF j<1024 THEN BEGIN
232 IF k=0 THEN BEGIN
233 k:=1;
234 END ELSE BEGIN
235 SetLength(Result,1);
236 Result[0].src_offset:=$18;
237 Result[0].raw_addr:=baselink;
238 Result[0].raw_size:=link+j;
239 Break;
240 END;
241 END;
242 END;
243 END;
244 END;
245 END;
246FUNCTION TRAM(fileid:LongWord):TRawList;
247 VAR
248 i:Byte;
249 link:LongWord;
250 frames:Word;
251 tempb:Byte;
252 tempw:Word;
253 templ:LongWord;
254 data:Tdata;
255 offset:Word;
256 BEGIN
257 SetLength(Result,13);
258 LoadDatFilePart(fileid,$16C,2,@frames);
259 {y-pos}
260 LoadDatFilePart(fileid,$0C,4,@link);
261 Result[0].src_offset:=$0C;
262 Result[0].raw_addr:=link;
263 Result[0].raw_size:=frames*4;
264 {x-z-pos}
265 LoadDatFilePart(fileid,$10,4,@link);
266 Result[1].src_offset:=$10;
267 Result[1].raw_addr:=link;
268 Result[1].raw_size:=frames*8;
269 {attacks}
270 LoadDatFilePart(fileid,$182,1,@tempb);
271 LoadDatFilePart(fileid,$14,4,@link);
272 Result[2].src_offset:=$14;
273 Result[2].raw_addr:=link;
274 Result[2].raw_size:=tempb*32;
275 {damage}
276 LoadDatFilePart(fileid,$183,1,@tempb);
277 LoadDatFilePart(fileid,$18,4,@link);
278 Result[3].src_offset:=$18;
279 Result[3].raw_addr:=link;
280 Result[3].raw_size:=tempb*8;
281 {motionblur}
282 LoadDatFilePart(fileid,$184,1,@tempb);
283 LoadDatFilePart(fileid,$1C,4,@link);
284 Result[4].src_offset:=$1C;
285 Result[4].raw_addr:=link;
286 Result[4].raw_size:=tempb*8;
287 {shortcut}
288 LoadDatFilePart(fileid,$185,1,@tempb);
289 LoadDatFilePart(fileid,$20,4,@link);
290 Result[5].src_offset:=$20;
291 Result[5].raw_addr:=link;
292 Result[5].raw_size:=tempb*8;
293 {throw}
294 LoadDatFilePart(fileid,$24,4,@link);
295 Result[6].src_offset:=$24;
296 Result[6].raw_addr:=link;
297 IF link>0 THEN
298 Result[6].raw_size:=24
299 ELSE
300 Result[6].raw_size:=0;
301 {footstep}
302 LoadDatFilePart(fileid,$186,1,@tempb);
303 LoadDatFilePart(fileid,$28,4,@link);
304 Result[7].src_offset:=$28;
305 Result[7].raw_addr:=link;
306 Result[7].raw_size:=tempb*4;
307 {particle}
308 LoadDatFilePart(fileid,$187,1,@tempb);
309 LoadDatFilePart(fileid,$2C,4,@link);
310 Result[8].src_offset:=$2C;
311 Result[8].raw_addr:=link;
312 Result[8].raw_size:=tempb*24;
313 {position}
314 LoadDatFilePart(fileid,$30,4,@link);
315 Result[9].src_offset:=$30;
316 Result[9].raw_addr:=link;
317 Result[9].raw_size:=frames*8;
318 {particle}
319 LoadDatFilePart(fileid,$154,2,@tempw);
320 LoadDatFilePart(fileid,$38,4,@link);
321 Result[11].src_offset:=$38;
322 Result[11].raw_addr:=link;
323 Result[11].raw_size:=tempw*34;
324 {extent}
325 LoadDatFilePart(fileid,$138,4,@templ);
326 LoadDatFilePart(fileid,$13C,4,@link);
327 Result[12].src_offset:=$13C;
328 Result[12].raw_addr:=link;
329 Result[12].raw_size:=templ*12;
330
331 LoadDatFilePart(fileid,$34,4,@link);
332 tempw:=0;
333 IF link>0 THEN BEGIN
334 {BODY ANIMATIONS PART DECODE!!!}
335 SetLength(data,$FFFF);
336 LoadRawFile(fileid,$34,link,$FFFF,False,@data[0]);
337 offset:=data[24]+data[25]*255;
338 {}
339 END;
340 Result[10].src_offset:=$34;
341 Result[10].raw_addr:=link;
342 Result[10].raw_size:=tempw;
343 END;
344FUNCTION TXMP(fileid:LongWord):TRawList;
345 VAR
346 link_pc:LongWord;
347 link_mac:LongWord;
348 x,y:Word;
349 storetype:Byte;
350 datasize:LongWord;
351 BEGIN
352 LoadDatFilePart(fileid,$8C,SizeOf(x),@x);
353 LoadDatFilePart(fileid,$8E,SizeOf(y),@y);
354 LoadDatFilePart(fileid,$90,SizeOf(storetype),@storetype);
355 LoadDatFilePart(fileid,$9C,4,@link_pc);
356 LoadDatFilePart(fileid,$A0,4,@link_mac);
357 CASE storetype OF
358 0,1,2: datasize:=x*y*2;
359 8: datasize:=x*y*4;
360 9: datasize:=x*y DIV 2;
361 END;
362 SetLength(Result,1);
363 IF NOT dat_os_mac THEN BEGIN
364 Result[0].src_offset:=$9C;
365 Result[0].raw_addr:=link_pc
366 END ELSE BEGIN
367 Result[0].src_offset:=$A0;
368 Result[0].raw_addr:=link_mac;
369 END;
370 Result[0].raw_size:=datasize;
371 Result[0].loc_sep:=dat_os_mac;
372 END;
373
374
375
376PROCEDURE AddEntry(_ext:String; _name:String; _offset:LongWord; _datatype:Word; _description:String);
377 VAR
378 sid:Integer;
379 BEGIN
380 sid:=GetStructureInfoId(_ext);
381 IF sid>=0 THEN BEGIN
382 WITH structure_infos[sid] DO BEGIN
383 SetLength(entries,Length(entries)+1);
384 WITH entries[High(entries)] DO BEGIN
385 name:=_name;
386 offset:=_offset;
387 datatype:=_datatype;
388 description:=_description;
389 END;
390 END;
391 END;
392 END;
393
394PROCEDURE AddExtension(_ext:String; _typedesc:String);
395 BEGIN
396 IF GetStructureInfoId(_ext)<0 THEN BEGIN
397 SetLength(structure_infos,Length(structure_infos)+1);
398 WITH structure_infos[High(structure_infos)] DO BEGIN
399 extension:=_ext;
400 typedesc:=_typedesc;
401 END;
402 END;
403 END;
404
405PROCEDURE InsertRawListHandler(ext:String; needed:Boolean; handler:THandler);
406 BEGIN
407 SetLength(RawListHandlers,Length(RawListHandlers)+1);
408 RawListHandlers[High(RawListHandlers)].Ext:=ext;
409 RawListHandlers[High(RawListHandlers)].needed:=needed;
410 RawListHandlers[High(RawListHandlers)].handler:=handler;
411 END;
412
413PROCEDURE LoadStructureDefinitionFile(filename:String);
414 VAR
415 temps:String;
416 deffile:Text;
417 ext:String;
418 fields:TStringList;
419 fieldname:String;
420 fieldoffset:LongWord;
421 fieldtype:Word;
422 fielddesc:String;
423 BEGIN
424 ext:=MidStr(ExtractFileName(filename),1,4);
425 AssignFile(deffile,filename);
426 Reset(deffile);
427 IF NOT EoF(deffile) THEN BEGIN
428 ReadLn(deffile,temps);
429 AddExtension(ext,temps);
430 WHILE NOT EoF(deffile) DO BEGIN
431 ReadLn(deffile,temps);
432 fields:=Explode(temps,#9);
433 IF (Length(fields)=3) OR (Length(fields)=4) THEN BEGIN
434 fieldname:=fields[0];
435 fieldoffset:=HexToLong(fields[1]);
436 fieldtype:=StrToInt(fields[2]);
437 IF Length(fields)=4 THEN
438 fielddesc:=fields[3]
439 ELSE
440 fielddesc:='';
441// ShowMessage(fieldname+' - '+IntToHex(fieldoffset,4)+' - '+IntToStr(fieldtype)+' - '+fielddesc);
442 AddEntry(ext,fieldname,fieldoffset,fieldtype,fielddesc);
443 END;
444 END;
445 END;
446 CloseFile(deffile);
447 END;
448
449PROCEDURE LoadStructureDefinitions(defdir:String);
450 VAR
451 SR:TSearchRec;
452 BEGIN
453 IF DirectoryExists(defdir) THEN BEGIN
454 IF FindFirst(defdir+'\*.txt', faAnyFile, SR)=0 THEN BEGIN
455 REPEAT
456 IF (SR.Attr AND faDirectory) <> faDirectory THEN BEGIN
457 LoadStructureDefinitionFile(defdir+'\'+SR.Name);
458 END;
459 UNTIL FindNext(SR)<>0;
460 END;
461 FindClose(SR);
462 END;
463 END;
464
465BEGIN
466// InsertRawListHandler('AGDB',True,AGDB);
467 InsertRawListHandler('AKVA',True,AKVA);
468 InsertRawListHandler('BINA',True,BINA);
469 InsertRawListHandler('OSBD',True,OSBD);
470 InsertRawListHandler('SNDD',True,SNDD);
471 InsertRawListHandler('SUBT',True,SUBT);
472 InsertRawListHandler('TRAM',True,TRAM);
473 InsertRawListHandler('TXMP',True,TXMP);
474END.
Note: See TracBrowser for help on using the repository browser.