⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dxrender.pas

📁 传奇源代码的delphi版本
💻 PAS
📖 第 1 页 / 共 5 页
字号:
          end;
        DXR_BLEND_SRCALPHA1:
          begin
            Col1_1 := [chRed, chGreen, chBlue];
            Col1_2 := [chAlpha];
            Col2_1 := [];
            Col2_2 := [];
          end;
        DXR_BLEND_SRCALPHA1_ADD_ONE2:
          begin
            Col1_1 := [chRed, chGreen, chBlue];
            Col1_2 := [chAlpha];
            Col2_1 := [chRed, chGreen, chBlue, chAlpha];
            Col2_2 := [];
          end;
        DXR_BLEND_ONE2_SUB_SRCALPHA1:
          begin
            Col1_1 := [chRed, chGreen, chBlue];
            Col1_2 := [chAlpha];
            Col2_1 := [chRed, chGreen, chBlue, chAlpha];
            Col2_2 := [];
          end;
        DXR_BLEND_SRCALPHA1_ADD_INVSRCALPHA2:
          begin
            Col1_1 := [chRed, chGreen, chBlue];
            Col1_2 := [chAlpha];
            Col2_1 := [chRed, chGreen, chBlue, chAlpha];
            Col2_2 := [];
          end;
        DXR_BLEND_INVSRCALPHA1_ADD_SRCALPHA2:
          begin
            Col1_1 := [chRed, chGreen, chBlue];
            Col1_2 := [chAlpha];
            Col2_1 := [chRed, chGreen, chBlue, chAlpha];
            Col2_2 := [];
          end;

        DXR_BLEND_DECAL:
          begin
            Col1_1 := [chRed, chGreen, chBlue, chAlpha];
            Col1_2 := [];
            Col2_1 := [];
            Col2_2 := [];
          end;
        DXR_BLEND_DECALALPHA:
          begin
            Col1_1 := [chRed, chGreen, chBlue];
            Col1_2 := [];
            Col2_1 := [];
            Col2_2 := [chAlpha];
          end;
        DXR_BLEND_MODULATE:
          begin
            Col1_1 := [chRed, chGreen, chBlue, chAlpha];
            Col1_2 := [];
            Col2_1 := [chRed, chGreen, chBlue, chAlpha];
            Col2_2 := [];
          end;
        DXR_BLEND_MODULATEALPHA:
          begin
            Col1_1 := [chRed, chGreen, chBlue];
            Col1_2 := [chAlpha];
            Col2_1 := [chRed, chGreen, chBlue];
            Col2_2 := [chAlpha];
          end;
        DXR_BLEND_ADD:
          begin
            Col1_1 := [chRed, chGreen, chBlue, chAlpha];
            Col1_2 := [];
            Col2_1 := [chRed, chGreen, chBlue, chAlpha];
            Col2_2 := [];
          end;
      end;
    end;

  var
    c: TDXRColorChannels;
    Col1_1, Col1_2, Col2_1, Col2_2: TDXRColorChannels;
  begin
    case Tree.Typ of
      DXR_TREETYPE_LOADBLACK:
          begin
            // Load black color
          end;
      DXR_TREETYPE_LOADCOLOR:
          begin
            // Load color
          end;
      DXR_TREETYPE_LOADTEXTURE:
          begin
            // Load texel
          end;
      DXR_TREETYPE_LOADBUMPTEXTURE:
          begin
            // Load texel with Bump mapping
          end;
      DXR_TREETYPE_LOADDESTPIXEL:
          begin
            // Load dest pixel
          end;
      DXR_TREETYPE_BLEND:
          begin
            // Blend color
            GetBlendChannels(Tree.Blend, Col1_1, Col1_2, Col2_1, Col2_2);

            Tree.BlendTree1.Channels := Tree.Channels*Col1_1+Col1_2;
            Tree.BlendTree2.Channels := Tree.Channels*Col2_1+Col2_2;

            OptimizeTree(Tree.BlendTree1);
            OptimizeTree(Tree.BlendTree2);

            if (Tree.Blend=DXR_BLEND_ZERO) then
            begin
              c := Tree.Channels; Tree^.Typ := DXR_TREETYPE_LOADBLACK; Tree.Channels := c;
            end else
            if (Tree.Blend in [DXR_BLEND_ONE1, DXR_BLEND_DECAL]) then
            begin
              c := Tree.Channels; Tree := Tree.BlendTree1; Tree.Channels := c;
            end else
            if (Tree.Blend=DXR_BLEND_ONE2) then
            begin
              c := Tree.Channels; Tree := Tree.BlendTree2; Tree.Channels := c;
            end else
            if (Tree.Blend in [DXR_BLEND_ONE1_ADD_ONE2, DXR_BLEND_ONE2_SUB_ONE1]) and
              (Tree.BlendTree2.Typ=DXR_TREETYPE_LOADBLACK) then
            begin
              c := Tree.Channels; Tree := Tree.BlendTree1; Tree.Channels := c;
            end else
            if (Tree.Blend in [DXR_BLEND_ONE1_ADD_ONE2, DXR_BLEND_ONE2_SUB_ONE1]) and
              (Tree.BlendTree1.Typ=DXR_TREETYPE_LOADBLACK) then
            begin
              c := Tree.Channels; Tree := Tree.BlendTree2; Tree.Channels := c;
            end else
            begin
              if (Col1_1=[]) and (Col1_2=[]) then Tree.BlendTree1 := nil;
              if (Col2_1=[]) and (Col2_2=[]) then Tree.BlendTree2 := nil;
            end;
          end;
    end;
  end;

  procedure GetEnableChannels(Tree: PDXRMachine_Tree);
  begin
    case Tree.Typ of
      DXR_TREETYPE_LOADBLACK:
          begin
            // Load black color
          end;
      DXR_TREETYPE_LOADCOLOR:
          begin
            // Load color
            ColorList[Tree.Color].Channels := ColorList[Tree.Color].Channels + Tree.Channels;
            ColorList[Tree.Color].Enable := ColorList[Tree.Color].Channels<>[];
          end;
      DXR_TREETYPE_LOADTEXTURE:
          begin
            // Load texel
            TextureList[Tree.Texture].EnableChannels := TextureList[Tree.Texture].EnableChannels +
              Tree.Channels*GetSurfaceChannels(TextureList[Tree.Texture].Surface^);
            TextureList[Tree.Texture].Enable := TextureList[Tree.Texture].EnableChannels<>[];
          end;
      DXR_TREETYPE_LOADBUMPTEXTURE:
          begin
            // Load texel with Bump mapping
            TextureList[Tree.Texture].EnableChannels := TextureList[Tree.Texture].EnableChannels +
              Tree.Channels*GetSurfaceChannels(TextureList[Tree.Texture].Surface^);
            TextureList[Tree.Texture].Enable := TextureList[Tree.Texture].EnableChannels<>[];
            TextureList[Tree.BumpTexture].Enable := True;
          end;
      DXR_TREETYPE_LOADDESTPIXEL:
          begin
            // Load dest pixel
          end;
      DXR_TREETYPE_BLEND:
          begin
            // Blend color
            if Tree.BlendTree1<>nil then GetEnableChannels(Tree.BlendTree1);
            if Tree.BlendTree2<>nil then GetEnableChannels(Tree.BlendTree2);
          end;
    end;
  end;

var
  Code: Pointer;
  i: Integer;
begin
  {  Optimize tree  }
  Tree.Channels := GetSurfaceChannels(Dest^);
  OptimizeTree(Tree);

  {  Get enable channels  }
  GetEnableChannels(Tree);

  for i:=Low(ColorList) to High(ColorList) do
    if ColorList[i].Enable then
    begin
      ColorIndex[ColorIndexCount] := i;
      Inc(ColorIndexCount);
    end;

  for i:=Low(TextureList) to High(TextureList) do
    if TextureList[i].Enable then
    begin
      TextureIndex[TextureIndexCount] := i;
      Inc(TextureIndexCount);
    end;

  ZBuffer.Enable := ZBuffer.Surface<>nil;

  RHW.Enable := ZBuffer.Enable;
  Axis.IncEnable := Dither.Enable;

  {  Generate X86 code  }
  Code := FBuf; GenerateCode(Code, Tree);

  FCompiled := True;
end;

const
  Mask1: array[0..7] of DWORD= ($80, $40, $20, $10, $08, $04, $02, $01);
  Mask2: array[0..3] of DWORD= ($C0, $30, $0C, $03);
  Mask4: array[0..1] of DWORD= ($F0, $0F);

  Shift1: array[0..7] of DWORD= (7, 6, 5, 4, 3, 2, 1, 0);
  Shift2: array[0..3] of DWORD= (6, 4, 2, 0);
  Shift4: array[0..1] of DWORD= (4, 0);

var
  _null: Byte;

  // Saturation addition table
  //   Result := Min(n+j, 255)
  _AddTable: array[0..256*2-1] of Byte;
  _SubTable: array[-255..255] of Byte;

  // Byte to QWORD convert table
  //   Result := (n shl 56)+(n shl 48)+(n shl 32)+(n shl 24)+(n shl 16)+(n shl 8)+n
  _ByteToQWORDTable: array[0..255, 0..3] of WORD;

  _BlackColor: TDXRMachine_Color = (R: 0; G: 0; B: 0; A: 0);

procedure Init;
var
  i: Integer;
begin
  for i:=Low(_AddTable) to High(_AddTable) do
  begin
    if i>255 then
      _AddTable[i] := 255
    else
      _AddTable[i] := i;
  end;

  for i:=Low(_SubTable) to High(_SubTable) do
  begin
    if i<0 then
      _SubTable[i] := 0
    else
      _SubTable[i] := i;
  end;

  for i:=0 to 255 do
  begin
    _ByteToQWORDTable[i, 0] := i;
    _ByteToQWORDTable[i, 1] := i;
    _ByteToQWORDTable[i, 2] := i;
    _ByteToQWORDTable[i, 3] := i;
  end;
end;

procedure TDXRMachine.GenerateCode(var Code: Pointer; Tree: PDXRMachine_Tree);
var
  SkipAddress: Pointer;

  procedure genCmpFunc(var Code: Pointer; Func: TDXR_CmpFunc; JmpAdress: Pointer);

    procedure genShortJmp(var Code: Pointer; JmpCode: Pointer; sC: Byte);
    type
      PShortJmp = ^TShortJmp;
      TShortJmp = packed record
        c: Byte;
        A: ShortInt;
      end;
    begin
      with PShortJmp(Code)^ do
      begin
        c := sC;
        A := Integer(JmpCode)-(Integer(Code)+2);
      end;
      Inc(Integer(Code), 2);
    end;

    procedure genNearJmp(var Code: Pointer; JmpCode: Pointer; nC: Byte);
    type
      PNearJmp = ^TNearJmp;
      TNearJmp = packed record
        c: Byte;
        A: Integer;
      end;
    begin
      with PNearJmp(Code)^ do
      begin
        c := nC;
        A := Integer(JmpCode)-(Integer(Code)+5);
      end;
      Inc(Integer(Code), 5);
    end;

    procedure genNearJmp2(var Code: Pointer; JmpCode: Pointer; nC1, nC2: Byte);
    type
      PNearJmp2 = ^TNearJmp2;
      TNearJmp2 = packed record
        c1, c2: Byte;
        A: Integer;
      end;
    begin
      with PNearJmp2(Code)^ do
      begin
        c1 := nC1;
        c2 := nC2;
        A := Integer(JmpCode)-(Integer(Code)+6);
      end;
      Inc(Integer(Code), 6);
    end;

    procedure genFlagJmp(var Code: Pointer; JmpCode: Pointer; sC, nC1, nC2: Byte);
    var
      i: Integer;
    begin
      i := Integer(JmpCode)-(Integer(Code)+2);
      if abs(i)<128 then
        genShortJmp(Code, JmpCode, sC)
      else
        genNearJmp2(Code, JmpCode, nC1, nC2);
    end;

    procedure genJmp(var Code: Pointer; JmpCode: Pointer);
    var
      i: Integer;
    begin
      i := Integer(JmpCode)-(Integer(Code)+2);
      if abs(i)<128 then
        genShortJmp(Code, JmpCode, $EB)
      else
        genNearJmp(Code, JmpCode, $E9);
    end;

  begin
    case Func of
      DXR_CMPFUNC_NEVER:
          begin
            {  if (False) then Jump }
          end;
      DXR_CMPFUNC_LESS:
          begin
            {  if (New<Old) then Jump  }
            genFlagJmp(Code, JmpAdress, $7C, $0F, $8C);
          end;
      DXR_CMPFUNC_EQUAL:
          begin
            {  if (New=Old) then Jump  }
            genFlagJmp(Code, JmpAdress, $74, $0F, $84);
          end;
      DXR_CMPFUNC_LESSEQUAL:
          begin
            {  if (New<=Old) then Jump  }
            genFlagJmp(Code, JmpAdress, $7E, $0F, $8E);
          end;
      DXR_CMPFUNC_GREATER:
          begin
            {  if (New>Old) then Jump  }
            genFlagJmp(Code, JmpAdress, $7F, $0F, $8F);
          end;
      DXR_CMPFUNC_NOTEQUAL:
          begin
            {  if (New<>Old) then Jump  }
            genFlagJmp(Code, JmpAdress, $75, $0F, $85);
          end;
      DXR_CMPFUNC_GREATEREQUAL:
          begin
            {  if (New>=Old) then Jump  }
            genFlagJmp(Code, JmpAdress, $7D, $0F, $8D);
          end;
      DXR_CMPFUNC_ALWAYS:
          begin
            {  if (True) then Break }
            genJmp(Code, JmpAdress);
          end;
    end;
  end;

  procedure genInitDestAddress(var Code: Pointer);
  var
    _Axis: Pointer;
    ByteCount, Pitch: DWORD;
    Bits: Pointer;
  begin
    _Axis := @Axis.Axis;

    ByteCount := Dest.BitCount shr 3;
    Pitch := Dest.pitch;
    Bits := Dest.Bits;

    asm
      jmp @@EndCode
    @@StartCode:
      mov eax,dword ptr [offset _null]{}@@AxisX:
      imul eax,$11{}        @@ByteCount: // Dest.BitCount div 8
      mov edi,dword ptr [offset _null]{}@@AxisY:
      imul edi,$11111111{}  @@Pitch: // Dest.pitch
      add edi,$11111111{}   @@Bits:  // Dest.Bits
      add edi,eax
    @@EndCode:
      {$I DXRender.inc}
      {  @@AxisX  }
      mov eax,_Axis; add eax,TDXRMachine_Axis.X
      mov edx,offset @@AxisX-4
      sub edx,offset @@StartCode
      mov dword ptr [ecx+edx],eax

      {  @@AxisY  }
      mov eax,_Axis; add eax,TDXRMachine_Axis.Y
      mov edx,offset @@AxisY-4
      sub edx,offset @@StartCode
      mov dword ptr [ecx+edx],eax

      {  @@ByteCount  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -