unit DXRender;
interface
{$INCLUDE DelphiXcfg.inc}
uses
Windows, DirectX;
const
DXR_MAXTEXTURE = 4;
type
TDXR_Value = Double;
TDXR_Color = DWORD;
TDXR_SurfaceColor = DWORD;
{ TDXR_ShadeMode }
TDXR_ShadeMode = (
DXR_SHADEMODE_FLAT,
DXR_SHADEMODE_GOURAUD
);
{ TDXR_Blend }
TDXR_Blend = (
// for blending
DXR_BLEND_ZERO, // r=0
DXR_BLEND_ONE1, // r=c1
DXR_BLEND_ONE2, // r=c2
DXR_BLEND_ONE1_ADD_ONE2, // r=c1+c2
DXR_BLEND_ONE1_SUB_ONE2, // r=c1-c2
DXR_BLEND_ONE2_SUB_ONE1, // r=c2-c1
DXR_BLEND_ONE1_MUL_ONE2, // r=c1*c2
DXR_BLEND_SRCALPHA1, // r=c1*a1
DXR_BLEND_SRCALPHA1_ADD_ONE2, // r=c1*a1+c2
DXR_BLEND_ONE2_SUB_SRCALPHA1, // r=c2-c1*a1
DXR_BLEND_SRCALPHA1_ADD_INVSRCALPHA2, // r=c1*a1+c2*(1-a2)
DXR_BLEND_INVSRCALPHA1_ADD_SRCALPHA2, // r=c1*(1-a1)+c2*a2
// for lighting
DXR_BLEND_DECALALPHA, // r=c1 ra=a2
DXR_BLEND_MODULATE, // r=c1*c2 ra=a2
DXR_BLEND_ADD // r=c1+c2 ra=a2
);
{ TDXR_TextureFilter }
TDXR_TextureFilter = (
DXR_TEXTUREFILTER_NEAREST,
DXR_TEXTUREFILTER_LINEAR
);
{ TDXR_TextureAddress }
TDXR_TextureAddress = (
DXR_TEXTUREADDRESS_TILE, // tx=tx and WidthMask ty=ty and HeightMask
DXR_TEXTUREADDRESS_DONOTCLIP // tx=tx ty=ty
);
{ TDXR_ColorType }
TDXR_ColorType = (
DXR_COLORTYPE_INDEXED, // Palette indexed color
DXR_COLORTYPE_RGB // RGB color
);
{ TDXR_ColorChannel }
TDXR_ColorChannel = record
Mask: DWORD; // Bit Mask
BitCount: DWORD; // Number of bit
rshift: DWORD;
lshift: DWORD;
end;
{ TDXR_Surface }
PDXR_Surface = ^TDXR_Surface;
TDXR_Surface = record
ColorType: TDXR_ColorType; // Color type
Width, Height: DWORD; // Size of surface
WidthBit, HeightBit: DWORD; // Size of surface (Number of bit)
Width2, Height2: DWORD; // 1 shl WidthBit, 1 shl HeightBit
WidthMask, HeightMask: DWORD;// Bit Mask of size of surface
BitCount: DWORD; // BitCount per Pixel(1, 2, 4, 8, 16, 24, 32 only)
Bits: Pointer; // Pointer to pixeldata(x:0 y:0)
Pitch: Integer; // Offset of next scanline
PitchBit: Integer; // Offset of next scanline (Number of bit)
case Integer of
0: (
{ Indexed color }
idx_index: TDXR_ColorChannel; // Index channel
idx_alpha: TDXR_ColorChannel; // Alpha channel
idx_palette: array[0..255] of TPaletteEntry;
// Palette
);
1: (
{ RGB color }
rgb_red: TDXR_ColorChannel; // Red channel
rgb_green: TDXR_ColorChannel; // Green channel
rgb_blue: TDXR_ColorChannel; // Blue channel
rgb_alpha: TDXR_ColorChannel; // Alpha channel
);
end;
{ TDXR_Vertex }
PDXR_Vertex = ^TDXR_Vertex;
TDXR_Vertex = record
sx: TDXR_Value; // Screen coordinates
sy: TDXR_Value;
sz: TDXR_Value;
color: TDXR_Color;
specular: TDXR_Color;
tu, tv: array[0..DXR_MAXTEXTURE-1] of TDXR_Value;
end;
PPDXR_Vertex = ^PDXR_Vertex;
{ TDXR_PrimitiveType }
TDXR_PrimitiveType = (
DXR_PRIMITIVETYPE_TRIANGLELIST,
DXR_PRIMITIVETYPE_TRIANGLESTRIP
);
{ TDXR_TextureLayerBlend }
TDXR_TextureLayerBlend = (
DXR_TEXTURELAYERBLEND_TEXTURE,
DXR_TEXTURELAYERBLEND_LAST,
DXR_TEXTURELAYERBLEND_NOBLEND
);
{ TDXR_TextureLayer }
PDXR_TextureLayer = ^TDXR_TextureLayer;
TDXR_TextureLayer = record
Surface: PDXR_Surface;
LayerBlend: TDXR_TextureLayerBlend;
Blend: TDXR_Blend;
ColorKeyEnable: Boolean;
ColorKey: TDXR_SurfaceColor;
TextureAddress: TDXR_TextureAddress;
end;
{ TDXR_Cull }
TDXR_Cull = (
DXR_CULL_NONE,
DXR_CULL_CW,
DXR_CULL_CCW
);
{ TDXR_RenderStates }
TDXR_RenderStates = record
DitherEnable: Boolean;
SpecularEnable: Boolean;
CullMode: TDXR_Cull;
Shade: TDXR_ShadeMode;
TexBlend: TDXR_Blend;
Blend: TDXR_Blend;
TextureEnable: Boolean;
TextureList: array[0..DXR_MAXTEXTURE-1] of TDXR_TextureLayer;
TextureFilter: TDXR_TextureFilter;
EnableDrawLine: DWORD;
end;
procedure dxrMakeIndexedSurface(var Surface: TDXR_Surface; Width, Height, BitCount: DWORD;
Bits: Pointer; pitch: Integer; idx_index, idx_alpha: DWORD);
procedure dxrMakeRGBSurface(var Surface: TDXR_Surface; Width, Height, BitCount: DWORD;
Bits: Pointer; pitch: Integer; rgb_red, rgb_green, rgb_blue, rgb_alpha: DWORD);
function dxrScanLine(const Surface: TDXR_Surface; y: DWORD): Pointer;
function dxrDDSurfaceLock(DDSurface: IDirectDrawSurface; var Surface: TDXR_Surface): Boolean;
function dxrDDSurfaceLock2(DDSurface: IDirectDrawSurface; var ddsd: TDDSurfaceDesc;
var Surface: TDXR_Surface): Boolean;
procedure dxrDDSurfaceUnLock(DDSurface: IDirectDrawSurface; const Surface: TDXR_Surface);
procedure dxrDefRenderStates(var States: TDXR_RenderStates);
procedure dxrDrawPrimitive(const Dest: TDXR_Surface; const States: TDXR_RenderStates; PrimitiveType: TDXR_PrimitiveType;
VertexList: PDXR_Vertex; VertexCount: DWORD);
procedure dxrDrawPointeredPrimitive(const Dest: TDXR_Surface; const States: TDXR_RenderStates; PrimitiveType: TDXR_PrimitiveType;
VertexList: PPDXR_Vertex; VertexCount: DWORD);
procedure dxrDrawIndexedPrimitive(const Dest: TDXR_Surface; const States: TDXR_RenderStates; PrimitiveType: TDXR_PrimitiveType;
VertexList: PDXR_Vertex; VertexCount: DWORD; IndexList: PDWORD; IndexCount: DWORD);
procedure dxrCopyRectBlend(const Dest, Src: TDXR_Surface;
const DestRect, SrcRect: TRect; Blend: TDXR_Blend; Alpha: Integer;
ColorKeyEnable: Boolean; ColorKey: DWORD);
procedure dxrFillRectColorBlend(const Dest: TDXR_Surface;
const DestRect: TRect; Blend: TDXR_Blend; Col: COLORREF);
procedure dxrDrawWaveXBlend(const Dest, Src: TDXR_Surface;
X, Y, Width, Height: Integer; const SrcRect: TRect; amp, Len, ph: Integer;
Blend: TDXR_Blend; Alpha: Integer;
ColorKeyEnable: Boolean; ColorKey: DWORD);
procedure dxrDrawRotateBlend(const Dest, Src: TDXR_Surface;
X, Y, Width, Height: Integer; const SrcRect: TRect; CenterX, CenterY: Double;
Angle: Integer; Blend: TDXR_Blend; Alpha: Integer;
ColorKeyEnable: Boolean; ColorKey: DWORD);
implementation
const
TextureAxisFloatBit = 16;
TextureAxisFloat = 1 shl TextureAxisFloatBit;
ColorFloatBit = 8;
ColorFloat = 1 shl ColorFloatBit;
type
PInteger = ^Integer;
{ TDXR_CmpFunc }
TDXR_CmpFunc = (
DXR_CMPFUNC_NEVER,
DXR_CMPFUNC_LESS,
DXR_CMPFUNC_EQUAL,
DXR_CMPFUNC_LESSEQUAL,
DXR_CMPFUNC_GREATER,
DXR_CMPFUNC_NOTEQUAL,
DXR_CMPFUNC_GREATEREQUAL,
DXR_CMPFUNC_ALWAYS
);
{ TDXRMachine }
TDXRMachine_TreeType = (
DXR_TREETYPE_LOADBLACK, // Load black color
DXR_TREETYPE_LOADCOLOR, // Load vertex color
DXR_TREETYPE_LOADCONSTCOLOR, // Load constant color
DXR_TREETYPE_LOADTEXTURE, // Load texel
DXR_TREETYPE_LOADDESTPIXEL, // Load dest pixel
DXR_TREETYPE_BLEND // Blend color
);
TDXRColorChannel = (chRed, chGreen, chBlue, chAlpha);
TDXRColorChannels = set of TDXRColorChannel;
PDXRMachine_Color = ^TDXRMachine_Color;
TDXRMachine_Color = packed record
R, G, B, A: WORD;
end;
PDXRMachine_Axis = ^TDXRMachine_Axis;
TDXRMachine_Axis = packed record
X, Y: Integer;
end;
PDXRMachine_Int64 = ^TDXRMachine_Int64;
TDXRMachine_Int64 = Comp;
PDXRMachine_Reg_Color = ^TDXRMachine_Reg_Color;
TDXRMachine_Reg_Color = record
Enable: Boolean;
nColor: TDXRMachine_Color;
iColor: TDXRMachine_Color;
Gouraud: Boolean;
Channels: TDXRColorChannels;
end;
PDXRMachine_Reg_Texture = ^TDXRMachine_Reg_Texture;
TDXRMachine_Reg_Texture = record
Enable: Boolean;
Surface: PDXR_Surface;
nAxis: TDXRMachine_Axis;
iAxis: TDXRMachine_Axis;
iAxisConstant: Boolean;
Filter: TDXR_TextureFilter;
ColorKeyEnable: Boolean;
ColorKey: TDXR_SurfaceColor;
EnableChannels: TDXRColorChannels;
TextureAddress: TDXR_TextureAddress;
DefaultColor: TDXRMachine_Color;
end;
TDXRMachine_Reg_Dither = record
Enable: Boolean;
end;
TDXRMachine_Reg_Axis = record
Axis: TDXRMachine_Axis;
IncEnable: Boolean;
end;
PDXRMachine_Tree = ^TDXRMachine_Tree;
TDXRMachine_Tree = record
Typ: TDXRMachine_TreeType;
Channels: TDXRColorChannels;
case TDXRMachine_TreeType of
DXR_TREETYPE_LOADBLACK: (
);
DXR_TREETYPE_LOADCOLOR: (
Color: Integer
);
DXR_TREETYPE_LOADCONSTCOLOR: (
ConstColor: TDXRMachine_Color;
);
DXR_TREETYPE_LOADTEXTURE: (
Texture: Integer
);
DXR_TREETYPE_LOADDESTPIXEL: (
);
DXR_TREETYPE_BLEND: (
Blend: TDXR_Blend;
BlendTree1: PDXRMachine_Tree;
BlendTree2: PDXRMachine_Tree;
);
end;
TDXRMachine = class
private
FBuf: Pointer;
FCall: Pointer;
FCompiled: Boolean;
FTreeCount: Integer;
FTreeList: array[0..127] of TDXRMachine_Tree;
FMMXUsed: Boolean;
F_BiLinearAxis: TDXRMachine_Axis;
F_BiLinearCol1: TDXRMachine_Color;
F_BiLinearCol2: TDXRMachine_Color;
F_BiLinearCol3: TDXRMachine_Color;
F_BiLinearCol4: TDXRMachine_Color;
FStack: array[0..255] of TDXRMachine_Color;
procedure GenerateCode(var Code: Pointer; Tree: PDXRMachine_Tree);
public
Dest: PDXR_Surface;
ColorList: array[0..7] of TDXRMachine_Reg_Color;
ColorIndex: array[0..7] of Integer;
ColorIndexCount: Integer;
TextureList: array[0..7] of TDXRMachine_Reg_Texture;
TextureIndex: array[0..7] of Integer;
TextureIndexCount: Integer;
Dither: TDXRMachine_Reg_Dither;
Axis: TDXRMachine_Reg_Axis;
constructor Create;
destructor Destroy; override;
function CreateTree: PDXRMachine_Tree;
function CreateTree2(Typ: TDXRMachine_TreeType): PDXRMachine_Tree;
function CreateTree_LoadColor(Color: DWORD): PDXRMachine_Tree;
function CreateTree_LoadConstColor(R, G, B, A: Byte): PDXRMachine_Tree;
function CreateTree_LoadTexture(Texture: DWORD): PDXRMachine_Tree;
function CreateTree_Blend(Blend: TDXR_Blend; BlendTree1, BlendTree2: PDXRMachine_Tree): PDXRMachine_Tree;
procedure Initialize;
procedure Compile(Tree: PDXRMachine_Tree);
procedure Run(Count: Integer);
property Compiled: Boolean read FCompiled write FCompiled;
end;
const
CPUIDF_FPU = 1 shl 0; { Floating-point unit on-chip }
CPUIDF_VME = 1 shl 1; { Virtual Mode Extension }
CPUIDF_DE = 1 shl 2; { Debugging Extension }
CPUIDF_PSE = 1 shl 3; { Page Size Extension }
CPUIDF_TSC = 1 shl 4; { Time Stamp Counter }
CPUIDF_MSR = 1 shl 5; { Mode Spacific Registers }
CPUIDF_PAE = 1 shl 6; { Physical Address Extension }
CPUIDF_MCE = 1 shl 7; { Machine Check Exception }
CPUIDF_CX8 = 1 shl 8; { CMPXCHG8 Instruction Supported }
CPUIDF_APIC = 1 shl 9; { On-chip APIC Hardware Supported }
CPUIDF_MTRR = 1 shl 12; { Memory Type Range Registers }
CPUIDF_PGE = 1 shl 13; { Page Global Enable }
CPUIDF_MCA = 1 shl 14; { Machine Check Architecture }
CPUIDF_CMOV = 1 shl 15; { Conditional Move Instruction Supported }
CPUIDF_MMX = 1 shl 23; { Intel Architecture MMX Technology supported }
var
CPUIDVendor: array[0..11] of Char;
CPUIDSignature: Integer;
CPUIDFeatures: Integer;
UseMMX: Boolean;
RenderPrimitiveCount: Integer;
procedure ReadCPUID;
begin
asm
push ebx
pushfd
pop eax
mov ecx,eax
xor eax,$200000
push eax
popfd
pushfd
pop eax
xor eax,ecx
jz @@exit
mov eax,0
db $0F,$A2 ///cpuid
cmp eax,1
jl @@exit
{ Vendor ID }
mov eax,0
db $0F,$A2 ///cpuid
mov dword ptr [CPUIDVendor], ebx
mov dword ptr [CPUIDVendor+4], edx
mov dword ptr [CPUIDVendor+8], ecx
{ Features, Signature }
mov eax,1
db $0F,$A2 ///cpuid
mov CPUIDSignature,eax
mov CPUIDFeatures,edx
@@exit:
pop ebx
end;
UseMMX := CPUIDFeatures and CPUIDF_MMX<>0;
end;
function GetBitCount(B: Integer): DWORD;
begin
Result := 31;
while (Result>0) and (((1 shl Result) and B)=0) do Dec(Result);
end;
function GetFirstZeroBitCount(B: Integer): DWORD;
begin
Result := 0;
while (Result<31) and (((1 shl Result) and B)=0) do Inc(Result);
end;
function GetOneBitCount(B: Integer): DWORD;
var
i: Integer;
begin
Result := 0;
for i:=0 to 31 do
Inc(Result, Ord(b and (1 shl i)<>0));
end;
function dxrMakeColorChannel(Mask: DWORD; indexed: Boolean): TDXR_ColorChannel;
var
i: Integer;
begin
Result.BitCount := GetOneBitCount(Mask shr (GetFirstZeroBitCount(Mask)));
Result.Mask := Mask;
if indexed then
begin
Result.rshift := GetFirstZeroBitCount(Mask);
Result.lshift := 0;
end else
begin
i := GetFirstZeroBitCount(Mask)-(8-Result.BitCount);
if i<0 then
begin
Result.lshift := -i;
Result.rshift := 0;
end else
begin
Result.lshift := 0;
Result.rshift := DWORD(i);
end;
end;
end;
procedure dxrMakeIndexedSurface(var Surface: TDXR_Surface; Width, Height, BitCount: DWORD;
Bits: Pointer; pitch: Integer; idx_index, idx_alpha: DWORD);
begin
FillChar(Surface, SizeOf(Surface), 0);
Surface.ColorType := DXR_COLORTYPE_INDEXED;
Surface.Width := Width;
Surface.Height := Height;
Surface.WidthBit := GetBitCount(Width);
Surface.HeightBit := GetBitCount(Height);
Surface.Width2 := 1 shl Surface.WidthBit;
Surface.Height2 := 1 shl Surface.HeightBit;
Surface.WidthMask := Surface.Width-1;
Surface.HeightMask := Surface.Height2-1;
Surface.BitCount := BitCount;
Surface.Bits := Bits;
Surface.Pitch := Pitch;
Surface.PitchBit := GetBitCount(Abs(Pitch));
Surface.idx_index := dxrMakeColorChannel(idx_index, True);
Surface.idx_alpha := dxrMakeColorChannel(idx_alpha, False);
end;
procedure dxrMakeRGBSurface(var Surface: TDXR_Surface; Width, Height, BitCount: DWORD;
Bits: Pointer; pitch: Integer; rgb_red, rgb_green, rgb_blue, rgb_alpha: DWORD);
begin
FillChar(Surface, SizeOf(Surface), 0);
Surface.ColorType := DXR_COLORTYPE_RGB;
Surface.Width := Width;
Surface.Height := Height;
Surface.WidthBit := GetBitCount(Width);
Surface.HeightBit := GetBitCount(Height);
Surface.Width2 := 1 shl Surface.WidthBit;
Surface.Height2 := 1 shl Surface.HeightBit;
Surface.WidthMask := Surface.Width-1;
Surface.HeightMask := Surface.Height2-1;
Surface.BitCount := BitCount;
Surface.Bits := Bits;
Surface.Pitch := Pitch;
Surface.PitchBit := GetBitCount(Abs(Pitch));
Surface.rgb_red := dxrMakeColorChannel(rgb_red, False);
Surface.rgb_green := dxrMakeColorChannel(rgb_green, False);
Surface.rgb_blue := dxrMakeColorChannel(rgb_blue, False);
Surface.rgb_alpha := dxrMakeColorChannel(rgb_alpha, False);
end;
function dxrCompareSurface(const Surface1, Surface2: TDXR_Surface): Boolean;
begin
if Surface1.ColorType=DXR_COLORTYPE_INDEXED then
begin
Result := (Surface2.ColorType=DXR_COLORTYPE_INDEXED) and
(Surface1.idx_index.Mask=Surface2.idx_index.Mask) and
(Surface1.idx_alpha.Mask=Surface2.idx_alpha.Mask);
end else if Surface1.ColorType=DXR_COLORTYPE_RGB then
begin
Result := (Surface2.ColorType=DXR_COLORTYPE_RGB) and
(Surface1.rgb_red.Mask=Surface2.rgb_red.Mask) and
(Surface1.rgb_green.Mask=Surface2.rgb_green.Mask) and
(Surface1.rgb_blue.Mask=Surface2.rgb_blue.Mask) and
(Surface1.rgb_alpha.Mask=Surface2.rgb_alpha.Mask);
end else
Result := False;
end;
function dxrDDSurfaceLock(DDSurface: IDirectDrawSurface; var Surface: TDXR_Surface): Boolean;
var
ddsd: TDDSurfaceDesc;
begin
Result := dxrDDSurfaceLock2(DDSurface, ddsd, Surface);
end;
function dxrDDSurfaceLock2(DDSurface: IDirectDrawSurface; var ddsd: TDDSurfaceDesc;
var Surface: TDXR_Surface): Boolean;
const
DDPF_PALETTEINDEXED = DDPF_PALETTEINDEXED1 or DDPF_PALETTEINDEXED2 or
DDPF_PALETTEINDEXED4 or DDPF_PALETTEINDEXED8;
begin
ddsd.dwSize := SizeOf(ddsd);
Result := DDSurface.Lock(nil, ddsd, DDLOCK_WAIT, 0)=DD_OK;
if Result then
begin
FillChar(Surface, SizeOf(Surface), 0);
if ddsd.ddpfPixelFormat.dwFlags and DDPF_PALETTEINDEXED<>0 then
begin
dxrMakeIndexedSurface(Surface, ddsd.dwWidth, ddsd.dwHeight, ddsd.ddpfPixelFormat.dwRGBBitCount,
ddsd.lpSurface, ddsd.lPitch, (1 shl ddsd.ddpfPixelFormat.dwRGBBitCount)-1, 0);
end else
begin
{if ddsd.ddpfPixelFormat.dwFlags and DDPF_ALPHAPIXELS<>0 then
begin
dxrMakeRGBSurface(Surface, ddsd.dwWidth, ddsd.dwHeight, ddsd.ddpfPixelFormat.dwRGBBitCount,
ddsd.lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRBitMask, ddsd.ddpfPixelFormat.dwGBitMask,
ddsd.ddpfPixelFormat.dwBBitMask, ddsd.ddpfPixelFormat.dwRGBAlphaBitMask);
end else}
begin
dxrMakeRGBSurface(Surface, ddsd.dwWidth, ddsd.dwHeight, ddsd.ddpfPixelFormat.dwRGBBitCount,
ddsd.lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRBitMask, ddsd.ddpfPixelFormat.dwGBitMask,
ddsd.ddpfPixelFormat.dwBBitMask, 0);
end;
end;
end;
end;
procedure dxrDDSurfaceUnLock(DDSurface: IDirectDrawSurface; const Surface: TDXR_Surface);
begin
DDSurface.Unlock(Surface.Bits);
end;
function dxrScanLine(const Surface: TDXR_Surface; y: DWORD): Pointer;
begin
Result := Pointer(Integer(Surface.Bits)+Surface.Pitch*Integer(y));
end;
{ TDXRMachine }
constructor TDXRMachine.Create;
begin
inherited Create;
FBuf := VirtualAlloc(nil, 2048, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
end;
destructor TDXRMachine.Destroy;
begin
VirtualFree(FBuf, 0, MEM_RELEASE);
inherited Destroy;
end;
procedure TDXRMachine.Initialize;
begin
FCall := nil;
ColorIndexCount := 0;
TextureIndexCount := 0;
FTreeCount := 0;
Dest := nil;
FCompiled := False;
FMMXUsed := False;
FillChar(ColorList, SizeOf(ColorList), 0);
FillChar(TextureList, SizeOf(TextureList), 0);
FillChar(Dither, SizeOf(Dither), 0);
FillChar(Axis, SizeOf(Axis), 0);
end;
function TDXRMachine.CreateTree: PDXRMachine_Tree;
begin
Result := @FTreeList[FTreeCount];
FillChar(Result^, SizeOf(Result^), 0);
Inc(FTreeCount);
end;
function TDXRMachine.CreateTree2(Typ: TDXRMachine_TreeType): PDXRMachine_Tree;
begin
Result := CreateTree;
Result.Typ := Typ;
end;
function TDXRMachine.CreateTree_LoadColor(Color: DWORD): PDXRMachine_Tree;
begin
Result := CreateTree;
Result.Typ := DXR_TREETYPE_LOADCOLOR;
Result.Color := Color;
end;
function TDXRMachine.CreateTree_LoadConstColor(R, G, B, A: Byte): PDXRMachine_Tree;
begin
Result := CreateTree;
Result.Typ := DXR_TREETYPE_LOADCONSTCOLOR;
Result.ConstColor.R := R shl 8;
Result.ConstColor.G := G shl 8;
Result.ConstColor.B := B shl 8;
Result.ConstColor.A := A shl 8;
end;
function TDXRMachine.CreateTree_LoadTexture(Texture: DWORD): PDXRMachine_Tree;
begin
Result := CreateTree;
Result.Typ := DXR_TREETYPE_LOADTEXTURE;
Result.Texture := Texture;
end;
function TDXRMachine.CreateTree_Blend(Blend: TDXR_Blend; BlendTree1, BlendTree2: PDXRMachine_Tree): PDXRMachine_Tree;
begin
Result := CreateTree;
Result.Typ := DXR_TREETYPE_BLEND;
Result.Blend := Blend;
Result.BlendTree1 := BlendTree1;
Result.BlendTree2 := BlendTree2;
end;
procedure TDXRMachine.Compile;
function GetSurfaceChannels(const Surface: TDXR_Surface): TDXRColorChannels;
begin
Result := [];
if Surface.ColorType=DXR_COLORTYPE_INDEXED then
begin
if Surface.idx_index.Mask<>0 then Result := Result + [chRed, chGreen, chBlue];
if Surface.idx_alpha.Mask<>0 then Result := Result + [chAlpha];
end else
begin
if Surface.rgb_red.Mask<>0 then Result := Result + [chRed];
if Surface.rgb_green.Mask<>0 then Result := Result + [chGreen];
if Surface.rgb_blue.Mask<>0 then Result := Result + [chBlue];
if Surface.rgb_alpha.Mask<>0 then Result := Result + [chAlpha];
end;
end;
procedure OptimizeTree(var Tree: PDXRMachine_Tree);
procedure GetBlendChannels(Blend: TDXR_Blend; var Col1_1, Col1_2, Col2_1, Col2_2: TDXRColorChannels);
begin
case Blend of
DXR_BLEND_ZERO:
begin
Col1_1 := [];
Col1_2 := [];
Col2_1 := [];
Col2_2 := [];
end;
DXR_BLEND_ONE1:
begin
Col1_1 := [chRed, chGreen, chBlue, chAlpha];
Col1_2 := [];
Col2_1 := [];
Col2_2 := [];
end;
DXR_BLEND_ONE2:
begin
Col1_1 := [];
Col1_2 := [];
Col2_1 := [chRed, chGreen, chBlue, chAlpha];
Col2_2 := [];
end;
DXR_BLEND_ONE1_ADD_ONE2,
DXR_BLEND_ONE1_SUB_ONE2,
DXR_BLEND_ONE2_SUB_ONE1,
DXR_BLEND_ONE1_MUL_ONE2:
begin
Col1_1 := [chRed, chGreen, chBlue, chAlpha];
Col1_2 := [];
Col2_1 := [chRed, chGreen, chBlue, chAlpha];
Col2_2 := [];
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_DECALALPHA:
begin
Col1_1 := [chRed, chGreen, chBlue];
Col1_2 := [];
Col2_1 := [];
Col2_2 := [chAlpha];
end;
DXR_BLEND_MODULATE:
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_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]) 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_ONE1_SUB_ONE2]) 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_ONE1_SUB_ONE2]) 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_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;
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 }
mov eax,ByteCount
mov edx,offset @@ByteCount-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@Pitch }
mov eax,Pitch
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Bits
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
procedure genReadDestPixel(var Code: Pointer);
begin
case Dest.BitCount of
8: begin
asm
jmp @@EndCode
@@StartCode:
movzx eax,byte ptr [edi]
@@EndCode:
{$I DXRender.inc}
end;
end;
16: begin
asm
jmp @@EndCode
@@StartCode:
movzx eax,word ptr [edi]
@@EndCode:
{$I DXRender.inc}
end;
end;
24: begin
asm
jmp @@EndCode
@@StartCode:
movzx eax,byte ptr [edi+2]
shl eax,16
mov ax,word ptr [edi]
@@EndCode:
{$I DXRender.inc}
end;
end;
32: begin
asm
jmp @@EndCode
@@StartCode:
mov eax,dword ptr [edi]
@@EndCode:
{$I DXRender.inc}
end;
end;
end;
end;
procedure genWriteDestPixel(var Code: Pointer);
begin
case Dest.BitCount of
8: begin
asm
jmp @@EndCode
@@StartCode:
mov byte ptr [edi],al
@@EndCode:
{$I DXRender.inc}
end;
end;
16: begin
asm
jmp @@EndCode
@@StartCode:
mov word ptr [edi],ax
@@EndCode:
{$I DXRender.inc}
end;
end;
24: begin
asm
jmp @@EndCode
@@StartCode:
mov word ptr [edi],ax
bswap eax
mov byte ptr [edi+2],ah
@@EndCode:
{$I DXRender.inc}
end;
end;
32: begin
asm
jmp @@EndCode
@@StartCode:
mov dword ptr [edi],eax
@@EndCode:
{$I DXRender.inc}
end;
end;
end;
end;
procedure genUpdateDestAddress(var Code: Pointer);
var
ByteCount: DWORD;
begin
ByteCount := Dest.BitCount shr 3;
if ByteCount=1 then
begin
asm
jmp @@EndCode
@@StartCode:
inc edi
@@EndCode:
{$I DXRender.inc}
end;
end else
begin
asm
jmp @@EndCode
@@StartCode:
add edi,$11{}@@ByteCount: // Dest.BitCount div 8;
@@EndCode:
{$I DXRender.inc}
{ @@ByteCount }
mov eax,ByteCount
mov edx,offset @@ByteCount-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
end;
end;
end;
procedure genReadSurfacePixel_Tile(var Code: Pointer; const Source: TDXR_Surface; Axis: PDXRMachine_Axis);
begin
case Source.BitCount of
1: begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}//TexY
@@TexY:
shr esi,16
and esi,$11111111{} @@MaskY: // Source.HeightMask
imul esi,$11111111{}@@Pitch: // Source.pitch
mov edx,dword ptr [offset _null]{}//TexX
@@TexX:
shr edx,16
and edx,$11111111{} @@MaskX: // Source.WidthMask
mov ebx,edx
shr edx,3
and ebx,7
movzx eax,byte ptr [esi+edx+$11111111]
@@Bits: // Source.Bits
and eax,dword ptr [offset Mask1+ebx*4]
push ecx
mov ecx,dword ptr [offset Shift1+ebx*4]
shr eax,cl
pop ecx
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskY }
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
2: begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}//TexY
@@TexY:
shr esi,16
and esi,$11111111{} @@MaskY: // Source.HeightMask
imul esi,$11111111{}@@Pitch: // Source.pitch
mov edx,dword ptr [offset _null]{}//TexX
@@TexX:
shr edx,16
and edx,$11111111{} @@MaskX: // Source.WidthMask
mov ebx,edx
shr edx,2
and ebx,3
movzx eax,byte ptr [esi+edx+$11111111]
@@Bits: // Source.Bits
and eax,dword ptr [offset Mask2+ebx*4]
push ecx
mov ecx,dword ptr [offset Shift2+ebx*4]
shr eax,cl
pop ecx
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskY }
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
4: begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}//TexY
@@TexY:
shr esi,16
and esi,$11111111{} @@MaskY: // Source.HeightMask
imul esi,$11111111{}@@Pitch: // Source.pitch
mov edx,dword ptr [offset _null]{}//TexX
@@TexX:
shr edx,16
and edx,$11111111{} @@MaskX: // Source.WidthMask
mov ebx,edx
shr edx,1
and ebx,1
movzx eax,byte ptr [esi+edx+$11111111]
@@Bits: // Source.Bits
and eax,dword ptr [offset Mask4+ebx*4]
push ecx
mov ecx,dword ptr [offset Shift4+ebx*4]
shr eax,cl
pop ecx
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskY }
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
8: begin
if Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,$11{} @@YShift: // 16-Source.PitchBit
shr edx,16
and esi,$11111111{} @@MaskY: // Source.HeightMask shl Source.PitchBit
and edx,$11111111{} @@MaskX: // Source.WidthMask
movzx eax,byte ptr [$11111111+esi+edx]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@YShift }
push ebx
mov eax,16
mov ebx,Source; sub eax,[ebx + TDXR_Surface.PitchBit]
pop ebx
mov edx,offset @@YShift-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@MaskY }
push ecx
mov ecx,Source; mov ecx,[ecx + TDXR_Surface.PitchBit]
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
shl eax,cl
pop ecx
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
if -Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,$11{} @@YShift: // 16-Source.PitchBit
shr edx,16
and esi,$11111111{} @@MaskY: // Source.HeightMask shl Source.PitchBit
and edx,$11111111{} @@MaskX: // Source.WidthMask
neg esi
movzx eax,byte ptr [$11111111+esi+edx]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@YShift }
push ebx
mov eax,16
mov ebx,Source; sub eax,[ebx + TDXR_Surface.PitchBit]
pop ebx
mov edx,offset @@YShift-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@MaskY }
push ecx
mov ecx,Source; mov ecx,[ecx + TDXR_Surface.PitchBit]
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
shl eax,cl
pop ecx
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
and esi,$11111111{} @@MaskY: // Source.HeightMask
and edx,$11111111{} @@MaskX: // Source.WidthMask
imul esi,$11111111{}@@Pitch: // Source.pitch
movzx eax,byte ptr [esi+edx+$11111111]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskY }
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
end;
16: begin
if Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,$11{} @@YShift: // 16-Source.PitchBit
shr edx,16
and esi,$11111111{} @@MaskY: // Source.HeightMask shl Source.PitchBit
and edx,$11111111{} @@MaskX: // Source.WidthMask
movzx eax,word ptr [$11111111+esi+edx*2]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@YShift }
push ebx
mov eax,16
mov ebx,Source; sub eax,[ebx + TDXR_Surface.PitchBit]
pop ebx
mov edx,offset @@YShift-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@MaskY }
push ecx
mov ecx,Source; mov ecx,[ecx + TDXR_Surface.PitchBit]
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
shl eax,cl
pop ecx
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
if -Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,$11{} @@YShift: // 16-Source.PitchBit
shr edx,16
and esi,$11111111{} @@MaskY: // Source.HeightMask shl Source.PitchBit
and edx,$11111111{} @@MaskX: // Source.WidthMask
neg esi
movzx eax,word ptr [$11111111+esi+edx*2]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@YShift }
push ebx
mov eax,16
mov ebx,Source; sub eax,[ebx + TDXR_Surface.PitchBit]
pop ebx
mov edx,offset @@YShift-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@MaskY }
push ecx
mov ecx,Source; mov ecx,[ecx + TDXR_Surface.PitchBit]
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
shl eax,cl
pop ecx
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
and esi,$11111111{} @@MaskY: // Source.HeightMask
and edx,$11111111{} @@MaskX: // Source.WidthMask
imul esi,$11111111{}@@Pitch: // Source.pitch
movzx eax,word ptr [esi+edx*2+$11111111]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskY }
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
end;
24: begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}//TexY
@@TexY:
mov edx,dword ptr [offset _null]{}//TexX
@@TexX:
shr esi,16
shr edx,16
and esi,$11111111{} @@MaskY: // Source.HeightMask
and edx,$11111111{} @@MaskX: // Source.WidthMask
imul esi,$11111111{}@@Pitch: // Source.pitch
lea edx,[edx+edx*2+$11111111] // Source.Bits
@@Bits:
movzx eax,byte ptr [esi+edx+2]
shl eax,16
mov ax,word ptr [esi+edx]
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskY }
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
32: begin
if Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,$11{} @@YShift: // 16-Source.PitchBit
shr edx,16
and esi,$11111111{} @@MaskY: // Source.HeightMask shl Source.PitchBit
and edx,$11111111{} @@MaskX: // Source.WidthMask
mov eax,dword ptr [$11111111+esi+edx*4]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@YShift }
push ebx
mov eax,16
mov ebx,Source; sub eax,[ebx + TDXR_Surface.PitchBit]
pop ebx
mov edx,offset @@YShift-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@MaskY }
push ecx
mov ecx,Source; mov ecx,[ecx + TDXR_Surface.PitchBit]
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
shl eax,cl
pop ecx
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
if -Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,$11{} @@YShift: // 16-Source.PitchBit
shr edx,16
and esi,$11111111{} @@MaskY: // Source.HeightMask shl Source.PitchBit
and edx,$11111111{} @@MaskX: // Source.WidthMask
neg esi
mov eax,dword ptr [$11111111+esi+edx*4]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@YShift }
push ebx
mov eax,16
mov ebx,Source; sub eax,[ebx + TDXR_Surface.PitchBit]
pop ebx
mov edx,offset @@YShift-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@MaskY }
push ecx
mov ecx,Source; mov ecx,[ecx + TDXR_Surface.PitchBit]
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
shl eax,cl
pop ecx
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
and esi,$11111111{} @@MaskY: // Source.HeightMask
and edx,$11111111{} @@MaskX: // Source.WidthMask
imul esi,$11111111{}@@Pitch: // Source.pitch
mov eax,dword ptr [esi+edx*4+$11111111]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskY }
mov eax,Source; mov eax,[eax + TDXR_Surface.HeightMask]
mov edx,offset @@MaskY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@MaskX }
mov eax,Source; mov eax,[eax + TDXR_Surface.WidthMask]
mov edx,offset @@MaskX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
end;
end;
end;
procedure genReadSurfacePixel_DoNotClip(var Code: Pointer; const Source: TDXR_Surface; Axis: PDXRMachine_Axis);
begin
case Source.BitCount of
1: begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}//TexY
@@TexY:
shr esi,16
imul esi,$11111111{}@@Pitch: // Source.pitch
mov edx,dword ptr [offset _null]{}//TexX
@@TexX:
shr edx,16
mov ebx,edx
shr edx,3
and ebx,7
movzx eax,byte ptr [esi+edx+$11111111]
@@Bits: // Source.Bits
and eax,dword ptr [offset Mask1+ebx*4]
push ecx
mov ecx,dword ptr [offset Shift1+ebx*4]
shr eax,cl
pop ecx
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
2: begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}//TexY
@@TexY:
shr esi,16
imul esi,$11111111{}@@Pitch: // Source.pitch
mov edx,dword ptr [offset _null]{}//TexX
@@TexX:
shr edx,16
mov ebx,edx
shr edx,2
and ebx,3
movzx eax,byte ptr [esi+edx+$11111111]
@@Bits: // Source.Bits
and eax,dword ptr [offset Mask2+ebx*4]
push ecx
mov ecx,dword ptr [offset Shift2+ebx*4]
shr eax,cl
pop ecx
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
4: begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}//TexY
@@TexY:
shr esi,16
imul esi,$11111111{}@@Pitch: // Source.pitch
mov edx,dword ptr [offset _null]{}//TexX
@@TexX:
shr edx,16
mov ebx,edx
shr edx,1
and ebx,1
movzx eax,byte ptr [esi+edx+$11111111]
@@Bits: // Source.Bits
and eax,dword ptr [offset Mask4+ebx*4]
push ecx
mov ecx,dword ptr [offset Shift4+ebx*4]
shr eax,cl
pop ecx
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
8: begin
if Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
shl esi,$11{} @@PitchBit: // Source.PitchBit
movzx eax,byte ptr [$11111111+esi+edx]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@PitchBit }
mov eax,Source; mov eax,[eax + TDXR_Surface.PitchBit]
mov edx,offset @@PitchBit-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
if -Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
shl esi,$11{} @@PitchBit: // Source.PitchBit
neg esi
movzx eax,byte ptr [$11111111+esi+edx]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@PitchBit }
mov eax,Source; mov eax,[eax + TDXR_Surface.PitchBit]
mov edx,offset @@PitchBit-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
imul esi,$11111111{}@@Pitch: // Source.pitch
movzx eax,byte ptr [esi+edx+$11111111]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
end;
16: begin
if Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
shl esi,$11{} @@PitchBit: // Source.PitchBit
movzx eax,word ptr [$11111111+esi+edx*2]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@PitchBit }
mov eax,Source; mov eax,[eax + TDXR_Surface.PitchBit]
mov edx,offset @@PitchBit-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
if -Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
shl esi,$11{} @@PitchBit: // Source.PitchBit
neg esi
movzx eax,word ptr [$11111111+esi+edx*2]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@PitchBit }
mov eax,Source; mov eax,[eax + TDXR_Surface.PitchBit]
mov edx,offset @@PitchBit-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
imul esi,$11111111{}@@Pitch: // Source.pitch
movzx eax,word ptr [esi+edx*2+$11111111]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
end;
24: begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}//TexY
@@TexY:
mov edx,dword ptr [offset _null]{}//TexX
@@TexX:
shr esi,16
shr edx,16
imul esi,$11111111{}@@Pitch: // Source.pitch
lea edx,[edx+edx*2+$11111111] // Source.Bits
@@Bits:
movzx eax,byte ptr [esi+edx+2]
shl eax,16
mov ax,word ptr [esi+edx]
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
32: begin
if Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
shl esi,$11{} @@PitchBit: // Source.PitchBit
mov eax,dword ptr [$11111111+esi+edx*4]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@PitchBit }
mov eax,Source; mov eax,[eax + TDXR_Surface.PitchBit]
mov edx,offset @@PitchBit-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
if -Source.pitch=(1 shl Source.PitchBit) then
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
shl esi,$11{} @@PitchBit: // Source.PitchBit
neg esi
mov eax,dword ptr [$11111111+esi+edx*4]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@PitchBit }
mov eax,Source; mov eax,[eax + TDXR_Surface.PitchBit]
mov edx,offset @@PitchBit-1
sub edx,offset @@StartCode
mov byte ptr [ecx+edx],al
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end else
begin
asm
jmp @@EndCode
@@StartCode:
mov esi,dword ptr [offset _null]{}@@TexY: //TexY
mov edx,dword ptr [offset _null]{}@@TexX: //TexX
shr esi,16
shr edx,16
imul esi,$11111111{}@@Pitch: // Source.pitch
mov eax,dword ptr [esi+edx*4+$11111111]
@@Bits: // Source.Bits
@@EndCode:
{$I DXRender.inc}
{ @@TexX }
mov eax,Axis; add eax,TDXRMachine_Axis.X
mov edx,offset @@TexX-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@TexY }
mov eax,Axis; add eax,TDXRMachine_Axis.Y
mov edx,offset @@TexY-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Pitch }
mov eax,Source; mov eax,[eax + TDXR_Surface.Pitch]
mov edx,offset @@Pitch-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@Bits }
mov eax,Source; mov eax,[eax + TDXR_Surface.Bits]
mov edx,offset @@Bits-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
end;
end;
end;
end;
end;
procedure genReadSurfacePixel(var Code: Pointer; const Texture: TDXRMachine_Reg_Texture; Axis: PDXRMachine_Axis);
begin
case Texture.TextureAddress of
DXR_TEXTUREADDRESS_TILE : genReadSurfacePixel_Tile(Code, Texture.Surface^, Axis);
DXR_TEXTUREADDRESS_DONOTCLIP: genReadSurfacePixel_DoNotClip(Code, Texture.Surface^, Axis);
end;
end;
procedure genDecodeColor(var Code: Pointer; const Surface: TDXR_Surface; Dest: PDXRMachine_Color;
EnableChannels: TDXRColorChannels; DefaultColor: TDXRMachine_Color);
var
dcR, dcG, dcB, dcA: Word;
begin
if EnableChannels=[] then Exit;
dcR := DefaultColor.R;
dcG := DefaultColor.G;
dcB := DefaultColor.B;
dcA := DefaultColor.A;
if Surface.ColorType=DXR_COLORTYPE_INDEXED then
begin
{ Index Channel }
if EnableChannels*[chRed, chGreen, chBlue]<>[] then
begin
if Surface.idx_index.Mask<>0 then
begin
if (Surface.idx_index.rshift=0) and (Surface.idx_index.lshift=0) and
(Surface.idx_index.Mask=DWORD((1 shl Surface.BitCount)-1)) and (Surface.idx_alpha.Mask=0) then
begin
asm
jmp @@EndCode
@@StartCode:
{ Index channel }
mov edx,dword ptr [eax*4+$11111111]
{}@@idx_indexPal:// @Surface.idx_palette
mov byte ptr [offset _null],dl{}@@DestR:// @Dest.R
mov byte ptr [offset _null],dh{}@@DestG:// @Dest.G
bswap edx
mov byte ptr [offset _null],dh{}@@DestB:// @Dest.B
@@EndCode:
{$I DXRender.inc}
{ @@idx_indexPal }
mov eax,Surface; lea eax,dword ptr [eax + TDXR_Surface.idx_palette]
mov edx,offset @@idx_indexPal-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@DestR }
mov eax,Dest; add eax,BYTE(TDXRMachine_Color.R+1)
mov edx,offset @@DestR-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@DestG }
mov eax,Dest; add eax,BYTE(TDXRMachine_Color.G+1)
mov edx,offset @@DestG-4
sub edx,offset @@StartCode
mov dword ptr [ecx+edx],eax
{ @@DestB }
mov eax,Dest; add eax,BYTE(TDXRMachine_Color.B+1)
mov edx,offset @@DestB-