ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/oup/current/DataAccess/Access_OniArchive.pas
(Generate patch)

Comparing:
oup/rewrite/DataAccess/Access_OniArchive.pas (file contents), Revision 101 by alloc, Tue Feb 20 20:43:29 2007 UTC vs.
oup/current/DataAccess/Access_OniArchive.pas (file contents), Revision 209 by alloc, Mon Jun 4 22:07:29 2007 UTC

# Line 15 | Line 15 | type
15      FDatOpened:          Boolean;
16      FRawOpened:          Boolean;
17      FSepOpened:          Boolean;
18 +    procedure SetUnloadWhenUnused(doit: Boolean);
19    protected
20    public
21 <    property UnloadWhenUnused: Boolean Read FUnloadWhenUnused Write FUnloadWhenUnused;
21 >    property UnloadWhenUnused: Boolean Read FUnloadWhenUnused Write SetUnloadWhenUnused;
22  
23      constructor Create(DatFilename: String; ConnectionID: Integer; var Msg: TStatusMessages); override;
24      procedure Close; override;
# Line 33 | Line 34 | type
34      procedure LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream); overload; override;
35      procedure UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream); overload; override;
36  
37 +    function GetDatLinks(FileID: Integer): TDatLinkList; override;
38 +    function GetDatLink(FileID, DatOffset: Integer): TDatLink; override;
39      function GetRawList(FileID: Integer): TRawDataList; override;
40      function GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo; override;
41  
42 <    procedure LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer);
42 >    procedure LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; var target: TStream); overload;
43 >    procedure LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer); overload;
44      procedure LoadRawFile(FileID, DatOffset: Integer; var Target: TStream); overload; override;
45      procedure UpdateRawFile(FileID, DatOffset: Integer; Src: TStream); overload; override;
46      procedure LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream); overload; override;
47      procedure UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream); overload; override;
48  
49 <    function AppendRawFile(LocSep: Boolean; Size: Integer; Src: TStream): Integer; overload; override;
49 >    function AppendRawFile(LocSep: Boolean; Src: TStream): Integer; overload; override;
50    published
51    end;
52  
53   implementation
54  
55   uses
56 <  SysUtils, StrUtils, Data, Functions, RawList;
56 >  SysUtils, StrUtils, Data, Functions, RawList, DatLinks, Math;
57  
58  
59   (*
# Line 59 | Line 63 | uses
63  
64  
65   constructor TAccess_OniArchive.Create(DatFilename: String; ConnectionID: Integer; var Msg: TStatusMessages);
62 type
63  THeader = packed record
64    Ident:      array[0..$13] of Byte;
65    Files:      Integer;
66    NamedFiles: Integer;
67    Extensions: Integer;
68    DataAddr:   Integer;
69    DataSize:   Integer;
70    NamesAddr:  Integer;
71    NamesSize:  Integer;
72    Ident2:     array[0..$F] of Byte;
73  end;
74  TFilesMap = array of packed record
75    Extension: array[0..$3] of Char;
76    DataAddr:  Integer;
77    NameAddr:  Integer;
78    FileSize:  Integer;
79    FileType:  LongWord;
80  end;
81  TNamedFilesMap = array of packed record
82    FileNumber: Integer;
83    blubb:      Integer;
84  end;
85 const
86  header_ident1_pc: array[0..$13] of Byte =
87    ($1F, $27, $DC, $33, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
88    $14, $00, $10, $00, $08, $00);
89  header_ident1_mac: array[0..$13] of Byte =
90    ($61, $30, $C1, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
91    $14, $00, $10, $00, $08, $00);
92  header_ident1_macbeta: array[0..$13] of Byte =
93    ($81, $11, $8D, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
94    $14, $00, $10, $00, $08, $00);
95  header_ident2: array[0..$F] of Byte =
96    ($99, $CF, $40, $00, $90, $4F, $63, $00, $F4, $55, $5F, $00, $90, $4F, $63, $00);
66   var
67    i: Integer;
68    header_pc, header_mac, header_macbeta: Boolean;
# Line 116 | Line 85 | begin
85    header_pc  := True;
86    header_mac := True;
87    header_macbeta := True;
88 <  for i := 0 to High(Fdat_header.Ident) do
88 >  for i := 0 to High(Fdat_header.GlobalIdent) do
89 >    if Fdat_header.GlobalIdent[i] <> HeaderGlobalIdent[i] then
90 >    begin
91 >      Msg := SM_IncompatibleFile;
92 >      Exit;
93 >    end;
94 >
95 >  for i := 0 to High(Fdat_header.OSIdent) do
96    begin
97 < //    FLevelInfo.Ident[i] := Fdat_header.Ident[i];
122 <    if Fdat_header.Ident[i] <> header_ident1_pc[i] then
97 >    if Fdat_header.OSIdent[i] <> HeaderOSIdentWin[i] then
98        header_pc := False;
99 <    if Fdat_header.Ident[i] <> header_ident1_mac[i] then
99 >    if Fdat_header.OSIdent[i] <> HeaderOSIdentMac[i] then
100        header_mac := False;
101 <    if Fdat_header.Ident[i] <> header_ident1_macbeta[i] then
101 >    if Fdat_header.OSIdent[i] <> HeaderOSIdentMacBeta[i] then
102        header_macbeta := False;
103    end;
104    if not (header_pc xor header_mac xor header_macbeta) then
# Line 183 | Line 158 | begin
158  
159    Msg := SM_OK;
160    FBackend := DB_ONI;
161 +  FConnectionID := ConnectionID;
162    FChangeRights := [CR_EditDat, CR_EditRaw, CR_AppendRaw];
163   end;
164  
165  
166  
167  
168 + procedure TAccess_OniArchive.SetUnloadWhenUnused(doit: Boolean);
169 + begin
170 +  FUnloadWhenUnused := doit;
171 +  if FUnloadWhenUnused then
172 +  begin
173 +    if FDatOpened then
174 +    begin
175 +      FDatOpened := False;
176 +      Fdat_file.Free;
177 +    end;
178 +    if FRawOpened then
179 +    begin
180 +      FRawOpened := False;
181 +      Fraw_file.Free;
182 +    end;
183 +    if FSepOpened then
184 +    begin
185 +      FSepOpened := False;
186 +      Fsep_file.Free;
187 +    end;
188 +  end
189 +  else
190 +  begin
191 +    if not FDatOpened then
192 +    begin
193 +      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
194 +      FDatOpened := True;
195 +    end;
196 +    if not FRawOpened then
197 +    begin
198 +      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
199 +        fmOpenReadWrite);
200 +      FRawOpened := True;
201 +    end;
202 +    if (not FSepOpened) and (FDataOS <> DOS_WIN) then
203 +    begin
204 +      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
205 +        fmOpenReadWrite);
206 +      FSepOpened := True;
207 +    end;
208 +  end;
209 + end;
210 +
211 +
212 +
213 +
214 +
215   procedure TAccess_OniArchive.Close;
216   begin
217    if FDatOpened then
# Line 248 | Line 271 | var
271        name := fields.Strings[2];
272        extension := fields.Strings[0];
273      end;
274 +    if SortType in [ST_ExtNameAsc, ST_ExtNameDesc] then
275 +    begin
276 +      id := fields.Strings[2];
277 +      name := fields.Strings[1];
278 +      extension := fields.Strings[0];
279 +    end;
280    end;
281  
282   begin
# Line 261 | Line 290 | begin
290      begin
291        if (NoEmptyFiles = False) or ((Fdat_files[i].FileType and $02) = 0) then
292        begin
293 <        if AppSettings.FilenumbersAsHex then
265 <          id := IntToHex(Fdat_files[i].ID, 4)
266 <        else
267 <          id := FormatNumber(Fdat_files[i].ID, 5, '0');
293 >        id := FormatNumber(Fdat_files[i].ID, 5, '0');
294          name := Fdat_files[i].Name;
295          extension := Fdat_files[i].Extension;
296  
# Line 272 | Line 298 | begin
298            ST_IDAsc, ST_IDDesc:     list.Add(id + ';' + name + ';' + extension);
299            ST_NameAsc, ST_NameDesc: list.Add(name + ';' + id + ';' + extension);
300            ST_ExtAsc, ST_ExtDesc:   list.Add(extension + ';' + id + ';' + name);
301 +          ST_ExtNameAsc, ST_ExtNameDesc: list.Add(name + ';' + extension + ';' + id);
302          end;
303        end;
304      end;
305    end;
306 <  Result := TStringList.Create;
306 >  if not Assigned(Result) then
307 >    Result := TStringList.Create;
308    if list.Count > 0 then
309    begin
310      fields := TStringList.Create;
311 <    if SortType in [ST_IDAsc, ST_NameAsc, ST_ExtAsc] then
311 >    if SortType in [ST_IDAsc, ST_NameAsc, ST_ExtAsc, ST_ExtNameAsc] then
312        for i := 0 to list.Count - 1 do
313        begin
314          getfields;
# Line 312 | Line 340 | function TAccess_OniArchive.GetExtension
340   var
341    i: Integer;
342   begin
343 <  Result := TStringList.Create;
343 >  if not Assigned(Result) then
344 >    Result := TStringList.Create;
345 >  if Result is TStringList then
346 >    TStringList(Result).Sorted := True;
347    for i := 0 to Length(Fdat_extensionsmap) - 1 do
348    begin
349      with Fdat_extensionsmap[i] do
# Line 416 | Line 447 | end;
447  
448  
449  
450 + function TAccess_OniArchive.GetDatLink(FileID, DatOffset: Integer): TDatLink;
451 + var
452 +  link: Integer;
453 + begin
454 +  Result := DatLinksManager.GetDatLink(FConnectionID, FileID, DatOffset);
455 +  LoadDatFilePart(fileid, Result.SrcOffset, 4, @link);
456 +  if link > 0 then
457 +    Result.DestID := link div 256
458 +  else
459 +    Result.DestID := -1;
460 + end;
461 +
462 +
463 + function TAccess_OniArchive.GetDatLinks(FileID: Integer): TDatLinkList;
464 + var
465 +  i: Integer;
466 +  link: Integer;
467 + begin
468 +  Result := DatLinksManager.GetDatLinks(FConnectionID, FileID);
469 +  if Length(Result) > 0 then
470 +  begin
471 +    for i := 0 to High(Result) do
472 +    begin
473 +      LoadDatFilePart(fileid, Result[i].SrcOffset, 4, @link);
474 +      if link > 0 then
475 +        Result[i].DestID := link div 256
476 +      else
477 +        Result[i].DestID := -1;
478 +    end;
479 +  end;
480 + end;
481 +
482 +
483   function TAccess_OniArchive.GetRawList(FileID: Integer): TRawDataList;
484   begin
485    Result := RawLists.GetRawList(FConnectionID, FileID);
# Line 429 | Line 493 | end;
493  
494  
495  
496 <
433 < procedure TAccess_OniArchive.LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer);
496 > procedure TAccess_OniArchive.LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; var target: TStream);
497   begin
498 +  if not Assigned(Target) then
499 +    Target := TMemoryStream.Create;
500    if not LocSep then
501    begin
502      if not FRawOpened then
# Line 440 | Line 505 | begin
505      if RawAddr <= Fraw_file.Size then
506      begin
507        Fraw_file.Seek(RawAddr, soFromBeginning);
508 <      Fraw_file.Read(target^, size);
508 >      Target.CopyFrom(Fraw_file, size);
509 >      Target.Seek(0, soFromBeginning);
510      end;
511      if UnloadWhenUnused then
512      begin
# Line 458 | Line 524 | begin
524      if RawAddr <= Fsep_file.Size then
525      begin
526        Fsep_file.Seek(RawAddr, soFromBeginning);
527 <      Fsep_file.Read(target^, size);
527 >      Target.CopyFrom(Fsep_file, size);
528 >      Target.Seek(0, soFromBeginning);
529      end;
530      if UnloadWhenUnused then
531      begin
# Line 470 | Line 537 | begin
537    end;
538   end;
539  
540 + procedure TAccess_OniArchive.LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer);
541 + var
542 +  data: TStream;
543 + begin
544 +  data := nil;
545 +  LoadRawOffset(LocSep, RawAddr, Size, data);
546 +  data.Read(Target^, Size);
547 +  data.Free;
548 + end;
549 +
550   procedure TAccess_OniArchive.LoadRawFile(FileID, DatOffset: Integer; var Target: TStream);
551   var
552    raw_info: TRawDataInfo;
# Line 530 | Line 607 | begin
607          Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
608            fmOpenReadWrite);
609        Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
610 <      Fraw_file.CopyFrom(Src, raw_info.RawSize);
610 >      Fraw_file.CopyFrom(Src, Min(raw_info.RawSize, Src.Size));
611        if UnloadWhenUnused then
612        begin
613          FRawOpened := False;
# Line 575 | Line 652 | begin
652    end;
653   end;
654  
655 +
656   procedure TAccess_OniArchive.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream);
657   var
658    raw_info: TRawDataInfo;
# Line 615 | Line 693 | begin
693    end;
694   end;
695  
696 < function TAccess_OniArchive.AppendRawFile(LocSep: Boolean; Size: Integer; Src: TStream): Integer;
696 > function TAccess_OniArchive.AppendRawFile(LocSep: Boolean; Src: TStream): Integer;
697 > const
698 >  EmptyBytes: Array[0..31] of Byte = (
699 >      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 );
700   begin
701    if not LocSep then
702    begin
703      if not FRawOpened then
704        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
705          fmOpenReadWrite);
706 +    if (Fraw_file.Size mod 32) > 0 then
707 +      Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
708      Result := Fraw_file.Size;
709      Fraw_file.Seek(0, soFromEnd);
710 <    Fraw_file.CopyFrom(Src, Size);
710 >    Fraw_file.CopyFrom(Src, Src.Size);
711 >    if (Fraw_file.Size mod 32) > 0 then
712 >      Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
713      if UnloadWhenUnused then
714      begin
715        FRawOpened := False;
# Line 638 | Line 723 | begin
723      if not FSepOpened then
724        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
725          fmOpenReadWrite);
726 +    if (Fsep_file.Size mod 32) > 0 then
727 +      Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
728      Result := Fsep_file.Size;
729      Fsep_file.Seek(0, soFromEnd);
730 <    Fsep_file.CopyFrom(Src, Size);
730 >    Fsep_file.CopyFrom(Src, Src.Size);
731 >    if (Fsep_file.Size mod 32) > 0 then
732 >      Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
733      if UnloadWhenUnused then
734      begin
735        FSepOpened := False;

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)