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

Comparing oup/current/DataAccess/Access_OniArchive.pas (file contents):
Revision 112 by alloc, Thu Feb 22 00:37:39 2007 UTC vs.
Revision 231 by alloc, Wed Jun 20 22:24:04 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;
# Line 49 | Line 53 | type
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 const
63  header_ident1_pc: array[0..$13] of Byte =
64    ($1F, $27, $DC, $33, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
65    $14, $00, $10, $00, $08, $00);
66  header_ident1_mac: array[0..$13] of Byte =
67    ($61, $30, $C1, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
68    $14, $00, $10, $00, $08, $00);
69  header_ident1_macbeta: array[0..$13] of Byte =
70    ($81, $11, $8D, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
71    $14, $00, $10, $00, $08, $00);
72  header_ident2: array[0..$F] of Byte =
73    ($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 93 | 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];
99 <    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 162 | Line 160 | begin
160    FBackend := DB_ONI;
161    FConnectionID := ConnectionID;
162    FChangeRights := [CR_EditDat, CR_EditRaw, CR_AppendRaw];
163 +
164 +  inherited;
165   end;
166  
167  
168  
169  
170 + procedure TAccess_OniArchive.SetUnloadWhenUnused(doit: Boolean);
171 + begin
172 +  FUnloadWhenUnused := doit;
173 +  if FUnloadWhenUnused then
174 +  begin
175 +    if FDatOpened then
176 +    begin
177 +      FDatOpened := False;
178 +      Fdat_file.Free;
179 +    end;
180 +    if FRawOpened then
181 +    begin
182 +      FRawOpened := False;
183 +      Fraw_file.Free;
184 +    end;
185 +    if FSepOpened then
186 +    begin
187 +      FSepOpened := False;
188 +      Fsep_file.Free;
189 +    end;
190 +  end
191 +  else
192 +  begin
193 +    if not FDatOpened then
194 +    begin
195 +      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
196 +      FDatOpened := True;
197 +    end;
198 +    if not FRawOpened then
199 +    begin
200 +      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
201 +        fmOpenReadWrite);
202 +      FRawOpened := True;
203 +    end;
204 +    if (not FSepOpened) and (FDataOS <> DOS_WIN) then
205 +    begin
206 +      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
207 +        fmOpenReadWrite);
208 +      FSepOpened := True;
209 +    end;
210 +  end;
211 + end;
212 +
213 +
214 +
215 +
216 +
217   procedure TAccess_OniArchive.Close;
218   begin
219    if FDatOpened then
# Line 258 | Line 305 | begin
305        end;
306      end;
307    end;
308 <  Result := TStringList.Create;
308 >  if not Assigned(Result) then
309 >    Result := TStringList.Create;
310    if list.Count > 0 then
311    begin
312      fields := TStringList.Create;
# Line 294 | Line 342 | function TAccess_OniArchive.GetExtension
342   var
343    i: Integer;
344   begin
345 <  Result := TStringList.Create;
345 >  if not Assigned(Result) then
346 >    Result := TStringList.Create;
347 >  if Result is TStringList then
348 >    TStringList(Result).Sorted := True;
349    for i := 0 to Length(Fdat_extensionsmap) - 1 do
350    begin
351      with Fdat_extensionsmap[i] do
# Line 318 | Line 369 | var
369   begin
370    if fileid < GetFileCount then
371    begin
372 <    if not Assigned(Target) then
322 <      Target := TMemoryStream.Create;
323 <    if not FDatOpened then
324 <      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
325 <    Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
326 <    streampos := Target.Position;
327 <    Target.CopyFrom(Fdat_file, Fdat_files[fileid].Size);
328 <    Target.Seek(streampos, soFromBeginning);
329 <    if UnloadWhenUnused then
372 >    if GetFileInfo(FileID).Size > 0 then
373      begin
374 <      Fdat_file.Free;
375 <      FDatOpened := False;
376 <    end
377 <    else
378 <      FDatOpened := True;
374 >      if not Assigned(Target) then
375 >        Target := TMemoryStream.Create;
376 >      if not FDatOpened then
377 >        Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
378 >      Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
379 >      streampos := Target.Position;
380 >      Target.CopyFrom(Fdat_file, Fdat_files[fileid].Size);
381 >      Target.Seek(streampos, soFromBeginning);
382 >      if UnloadWhenUnused then
383 >      begin
384 >        Fdat_file.Free;
385 >        FDatOpened := False;
386 >      end
387 >      else
388 >        FDatOpened := True;
389 >    end;
390    end;
391   end;
392  
# Line 398 | Line 452 | end;
452  
453  
454  
455 + function TAccess_OniArchive.GetDatLink(FileID, DatOffset: Integer): TDatLink;
456 + var
457 +  link: Integer;
458 + begin
459 +  Result := DatLinksManager.GetDatLink(FConnectionID, FileID, DatOffset);
460 +  LoadDatFilePart(fileid, Result.SrcOffset, 4, @link);
461 +  if link > 0 then
462 +    Result.DestID := link div 256
463 +  else
464 +    Result.DestID := -1;
465 + end;
466 +
467 +
468 + function TAccess_OniArchive.GetDatLinks(FileID: Integer): TDatLinkList;
469 + var
470 +  i: Integer;
471 +  link: Integer;
472 + begin
473 +  Result := DatLinksManager.GetDatLinks(FConnectionID, FileID);
474 +  if Length(Result) > 0 then
475 +  begin
476 +    for i := 0 to High(Result) do
477 +    begin
478 +      LoadDatFilePart(fileid, Result[i].SrcOffset, 4, @link);
479 +      if link > 0 then
480 +        Result[i].DestID := link div 256
481 +      else
482 +        Result[i].DestID := -1;
483 +    end;
484 +  end;
485 + end;
486 +
487 +
488   function TAccess_OniArchive.GetRawList(FileID: Integer): TRawDataList;
489   begin
490    Result := RawLists.GetRawList(FConnectionID, FileID);
# Line 411 | Line 498 | end;
498  
499  
500  
501 <
415 < procedure TAccess_OniArchive.LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer);
501 > procedure TAccess_OniArchive.LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; var target: TStream);
502   begin
503 +  if not Assigned(Target) then
504 +    Target := TMemoryStream.Create;
505    if not LocSep then
506    begin
507      if not FRawOpened then
# Line 422 | Line 510 | begin
510      if RawAddr <= Fraw_file.Size then
511      begin
512        Fraw_file.Seek(RawAddr, soFromBeginning);
513 <      Fraw_file.Read(target^, size);
513 >      Target.CopyFrom(Fraw_file, size);
514 >      Target.Seek(0, soFromBeginning);
515      end;
516      if UnloadWhenUnused then
517      begin
# Line 440 | Line 529 | begin
529      if RawAddr <= Fsep_file.Size then
530      begin
531        Fsep_file.Seek(RawAddr, soFromBeginning);
532 <      Fsep_file.Read(target^, size);
532 >      Target.CopyFrom(Fsep_file, size);
533 >      Target.Seek(0, soFromBeginning);
534      end;
535      if UnloadWhenUnused then
536      begin
# Line 452 | Line 542 | begin
542    end;
543   end;
544  
545 + procedure TAccess_OniArchive.LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer);
546 + var
547 +  data: TStream;
548 + begin
549 +  data := nil;
550 +  LoadRawOffset(LocSep, RawAddr, Size, data);
551 +  data.Read(Target^, Size);
552 +  data.Free;
553 + end;
554 +
555   procedure TAccess_OniArchive.LoadRawFile(FileID, DatOffset: Integer; var Target: TStream);
556   var
557    raw_info: TRawDataInfo;
# Line 512 | Line 612 | begin
612          Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
613            fmOpenReadWrite);
614        Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
615 <      Fraw_file.CopyFrom(Src, raw_info.RawSize);
615 >      Fraw_file.CopyFrom(Src, Min(raw_info.RawSize, Src.Size));
616        if UnloadWhenUnused then
617        begin
618          FRawOpened := False;
# Line 557 | Line 657 | begin
657    end;
658   end;
659  
660 +
661   procedure TAccess_OniArchive.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream);
662   var
663    raw_info: TRawDataInfo;
# Line 598 | Line 699 | begin
699   end;
700  
701   function TAccess_OniArchive.AppendRawFile(LocSep: Boolean; Src: TStream): Integer;
702 + const
703 +  EmptyBytes: Array[0..31] of Byte = (
704 +      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 );
705   begin
706    if not LocSep then
707    begin
708      if not FRawOpened then
709        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
710          fmOpenReadWrite);
711 +    if (Fraw_file.Size mod 32) > 0 then
712 +      Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
713      Result := Fraw_file.Size;
714      Fraw_file.Seek(0, soFromEnd);
715      Fraw_file.CopyFrom(Src, Src.Size);
716 +    if (Fraw_file.Size mod 32) > 0 then
717 +      Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
718      if UnloadWhenUnused then
719      begin
720        FRawOpened := False;
# Line 620 | Line 728 | begin
728      if not FSepOpened then
729        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
730          fmOpenReadWrite);
731 +    if (Fsep_file.Size mod 32) > 0 then
732 +      Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
733      Result := Fsep_file.Size;
734      Fsep_file.Seek(0, soFromEnd);
735      Fsep_file.CopyFrom(Src, Src.Size);
736 +    if (Fsep_file.Size mod 32) > 0 then
737 +      Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
738      if UnloadWhenUnused then
739      begin
740        FSepOpened := False;

Diff Legend

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