source: oup/releases/0.31a/Unit9_data_structures.pas@ 1003

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