OBasics.pas
上传用户:yj_qiu
上传日期:2022-08-08
资源大小:23636k
文件大小:6k
源码类别:

游戏引擎

开发平台:

Delphi

  1. (*
  2.  !!! The unit will be replaced with Basics !!!
  3.  Oberon basics unit
  4.  (C) 2004-2007 George "Mirage" Bakhtadze.
  5.  The source code may be used under either MPL 1.1 or LGPL 2.1 license. See included license.txt file <br>
  6.  The unit contains compiler basic functions and classes
  7. *)
  8. unit OBasics;
  9. interface
  10. uses SysUtils;
  11. const
  12. // File errors
  13.   feOK = 0; feNotFound = -1; feCannotRead = -2; feCannotWrite = -3; feInvalidFileFormat = -4; feCannotSeek = -5; feCannotOpen = -6;
  14. // File usage modes
  15.   fuRead = 1; fuWrite = 2; fuAppend = 3;
  16.   OneAsInt: LongWord = $3F800000;
  17.   OneAsInt2: LongWord = $3F800000 shl 1;
  18. type
  19.   TDStream = class                                // All these stream classes can be replaced with standard TStream
  20.     Position, Size: Cardinal;
  21.     function Open(const Usage: Integer = fuRead; const Mode: Integer = fmOpenReadWrite or fmShareDenyWrite): Integer; virtual; abstract;
  22.     function Seek(const NewPos: Cardinal): Integer; virtual; abstract;
  23.     function Read(var Buffer; const Count: Cardinal): Integer; virtual; abstract;
  24.     function Write(const Buffer; const Count: Cardinal): Integer; virtual; abstract;
  25.     function Close: Integer; virtual; abstract;
  26.   end;
  27.   TFileDStream = class(TDStream)
  28.     Filename: string;
  29.     FHandle, FMode: Integer;
  30.     constructor Create(const AFileName: string; const Usage: Integer = fuRead; const Mode: Integer = fmOpenReadWrite or fmShareDenyWrite);
  31.     function Open(const Usage: Integer = fuRead; const Mode: Integer = fmOpenReadWrite or fmShareDenyWrite): Integer; override;
  32.     function Seek(const NewPos: Cardinal): Integer; override;
  33.     function Read(var Buffer; const Count: Cardinal): Integer; override;
  34.     function Write(const Buffer; const Count: Cardinal): Integer; override;
  35.     function Close: Integer; override;
  36.     destructor Free;
  37.   end;
  38.   function MaxS(V1, V2: Single): Single;
  39.   function MinS(V1, V2: Single): Single;
  40.   function InvSqrt(x: Single): Single;   // Fast inverse square root. Depends on float numbers representation
  41.   function AddColorW(Color1, Color2: Cardinal; W1, W2: Single): Cardinal;
  42.   function BlendColor(Color1, Color2: Cardinal; K: Single): Cardinal;
  43. implementation
  44. { TFileDStream }
  45. constructor TFileDStream.Create(const AFileName: string; const Usage: Integer = fuRead; const Mode: Integer = fmOpenReadWrite or fmShareDenyWrite);
  46. begin
  47.   Filename := ExpandFileName(AFileName);
  48.   Open(Usage, Mode);
  49. end;
  50. function TFileDStream.Open(const Usage, Mode: Integer): Integer;
  51. var F: file;
  52. begin
  53.   Result := feCannotOpen;
  54.   FMode := Mode;
  55.   if (Usage = fuWrite) or (not FileExists(FileName)) then begin
  56.     if Usage = fuRead then Exit;
  57.     FHandle := FileCreate(FileName); FileClose(FHandle);
  58.   end;
  59.   if (Usage = fuRead) or (Usage = fuAppend) then begin
  60.     Assign(F, FileName); Reset(F, 1);
  61.     Size := FileSize(F);
  62.     CloseFile(F);
  63.   end;
  64.   Position := 0;
  65.   FHandle := FileOpen(FileName, Mode);
  66.   if Usage = fuAppend then Seek(Size);
  67.   if FHandle >= 0 then Result := feOK;
  68. end;
  69. function TFileDStream.Read(var Buffer; const Count: Cardinal): Integer;
  70. var BytesRead: Integer;
  71. begin
  72.   BytesRead := FileRead(FHandle, Buffer, Count);
  73.   if BytesRead >= 0 then Inc(Position, BytesRead);
  74.   if BytesRead = Count then Result := feOK else Result := feCannotRead;
  75. end;
  76. function TFileDStream.Seek(const NewPos: Cardinal): Integer;
  77. begin
  78.   Result := 0;
  79.   if FileSeek(FHandle, NewPos, 0) < 0 then Result := -feCannotSeek else Position := NewPos;
  80. end;
  81. function TFileDStream.Write(const Buffer; const Count: Cardinal): Integer;
  82. var BytesWrite: Integer;
  83. begin
  84.   BytesWrite := FileWrite(FHandle, Buffer, Count);
  85.   if BytesWrite >= 0 then Inc(Position, BytesWrite);
  86.   Size := Position;
  87.   if BytesWrite = Count then Result := feOK else Result := feCannotWrite;
  88. end;
  89. function TFileDStream.Close: Integer;
  90. begin
  91.   Result := feOK;
  92.   FileClose(FHandle);
  93. end;
  94. destructor TFileDStream.Free;
  95. begin
  96.   Close;
  97. end;
  98. {$IFDEF USEP6ASM}
  99. function MaxS(V1, V2: Single): Single; assembler;
  100. asm
  101.   fld     dword ptr [ebp+$08]
  102.   fld     dword ptr [ebp+$0c]
  103.   fcomi   st(0), st(1)
  104.   fcmovb  st(0), st(1)
  105.   ffree   st(1)
  106. end;
  107. function MinS(V1, V2: Single): Single; assembler;
  108. asm
  109.   fld     dword ptr [ebp+$08]
  110.   fld     dword ptr [ebp+$0c]
  111.   fcomi   st(0), st(1)
  112.   fcmovnb st(0), st(1)
  113.   ffree   st(1)
  114. end;
  115. {$ELSE}
  116. function MaxS(V1, V2: Single): Single;
  117. begin
  118.   if V1 > V2 then Result := V1 else Result := V2;
  119. end;
  120. function MinS(V1, V2: Single): Single;
  121. begin
  122.   if V1 < V2 then Result := V1 else Result := V2;
  123. end;
  124. {$ENDIF}
  125. function InvSqrt(x: Single): Single;   // Fast inverse square root. Depends on float numbers representation
  126. var tmp: LongWord;
  127. begin
  128.   asm
  129.     mov        eax, OneAsInt
  130.     sub        eax, x
  131.     add        eax, OneAsInt2
  132.     shr        eax, 1
  133.     mov        tmp, eax
  134.   end;
  135.   Result := Single((@tmp)^) * (1.47 - 0.47 * x * Single((@tmp)^) * Single((@tmp)^));
  136. end;
  137. function AddColorW(Color1, Color2: Cardinal; W1, W2: Single): Cardinal;
  138. begin
  139.   Result := Cardinal(Trunc(0.5+MinS(255, (Color1 and 255)*W1 + (Color2 and 255)*W2))) +
  140.             Cardinal(Trunc(0.5+MinS(255, ((Color1 shr 8) and 255)*W1 + ((Color2 shr 8) and 255)*W2))) shl 8 +
  141.             Cardinal(Trunc(0.5+MinS(255, ((Color1 shr 16) and 255)*W1 + ((Color2 shr 16) and 255)*W2))) shl 16 +
  142.             Cardinal(Trunc(0.5+MinS(255, ((Color1 shr 24) and 255)*W1 + ((Color2 shr 24) and 255)*W2))) shl 24;
  143. end;
  144. function BlendColor(Color1, Color2: Cardinal; K: Single): Cardinal;
  145. begin
  146.   if K > 1 then K := 1; if K < 0 then K := 0;
  147.   Result := AddColorW(Color1, Color2, 1-K, K);
  148. end;
  149. end.