📄 cliutil.pas
字号:
end else begin
srcleft := ssufleft;
srcwidth := ssufwidth;
end;
if y < 0 then begin
srctop := -y;
srcbottom := ssufheight;
y := 0;
end else begin
srctop := ssuftop;
srcbottom := srctop + ssufheight;
end;
if srcleft + srcwidth > ssuf.Width then srcwidth := ssuf.Width-srcleft;
if srcbottom > ssuf.Height then
srcbottom := ssuf.Height;//-srcheight;
if x + srcwidth > dsuf.Width then srcwidth := (dsuf.Width-x) div 4 * 4;
if y + srcbottom - srctop > dsuf.Height then
srcbottom := dsuf.Height-y+srctop;
if (x+srcwidth) * (y+srcbottom-srctop) > dsuf.Width * dsuf.Height then
srcbottom := srctop + (srcbottom-srctop) div 2;
if (srcwidth <= 0) or (srcbottom <= 0) or (srcleft >= ssuf.Width) or (srctop >= ssuf.Height) then exit;
// if srcWidth > 900 then exit;
if srcWidth > SCREENWIDTH + 100 then exit;
if ssuf.Height > 350 then begin
//TfrmMain.DScreen.AddChatBoardString('test; ' + InttoStr(srcwidth) + ' ' + InttoStr(srcbottom) + ' ' + InttoStr(srctop),clWhite, clBlack);
end;
try
sddsd.dwSize := SizeOf(sddsd);
dddsd.dwSize := SizeOf(dddsd);
ssuf.Lock (TRect(nil^), sddsd);
dsuf.Lock (TRect(nil^), dddsd);
awidth := srcwidth div 4; //ssuf.Width div 4;
bwidth := srcwidth; //ssuf.Width;
srclen := srcwidth; //ssuf.Width;
destlen := srcwidth; //ssuf.Width;
case blendmode of
0: pmix := @Color256Mix[0,0];
else pmix := @Color256Anti[0,0];
end;
for i:=srctop to srcbottom-1 do begin
sptr := PBYTE(integer(sddsd.lpSurface) + sddsd.lPitch * i + srcleft);
dptr := PBYTE(integer(dddsd.lpSurface) + (y+i-srctop) * dddsd.lPitch + x);
asm
mov scount, 0
mov esi, sptr
lea edi, source
mov ebx, scount //ebx = scount
@@CopySource:
cmp ebx, srclen
jae @@EndSourceCopy
db $0F,$6F,$04,$1E /// movq mm0, [esi+ebx]
db $0F,$7F,$04,$1F /// movq [edi+ebx], mm0
add ebx, 8
jmp @@CopySource
@@EndSourceCopy:
mov dcount, 0
mov esi, dptr
lea edi, dest
mov ebx, dcount
@@CopyDest:
cmp ebx, destlen
jae @@EndDestCopy
db $0F,$6F,$04,$1E /// movq mm0, [esi+ebx]
db $0F,$7F,$04,$1F /// movq [edi+ebx], mm0
add ebx, 8
jmp @@CopyDest
@@EndDestCopy:
lea esi, source
lea edi, dest
mov wcount, 0
@@BlendNext:
mov ebx, wcount
cmp [esi+ebx].byte, 0 //if _src[bitindex] > 0
jz @@EndBlend
movzx eax, [esi+ebx].byte //sidx := _src[bitindex]
shl eax, 8 //sidx * 256
mov sidx, eax
movzx eax, [edi+ebx].byte //didx := _dest[bitindex]
add sidx, eax
mov edx, pmix
mov ecx, sidx
movzx eax, [edx+ecx].byte //
mov [edi+ebx], al
@@EndBlend:
inc wcount
mov eax, bwidth
cmp wcount, eax
jb @@BlendNext
lea esi, dest //Move (_src, dptr^, 4)
mov edi, dptr
mov ecx, awidth
cld
rep movsd
end;
end;
asm
db $0F,$77 /// emms
end;
finally
ssuf.UnLock();
dsuf.UnLock();
end;
end;
procedure Drawex (dsuf: TDirectDrawSurface; x, y: integer; ssuf: TDirectDrawSurface; ssufleft, ssuftop, ssufwidth, ssufheight, blendmode: integer);
var
i, j, srcleft, srctop, srcwidth, srcbottom, sidx, didx: integer;
sddsd, dddsd: TDDSurfaceDesc;
sptr, dptr, pmix: PByte;
source, dest: array[0..910] of byte;
bitindex, scount, dcount, srclen, destlen, wcount, awidth, bwidth: integer;
begin
if (dsuf.canvas = nil) or (ssuf.canvas = nil) then exit;
if x >= dsuf.Width then exit;
if y >= dsuf.Height then exit;
if x < 0 then begin
srcleft := -x;
srcwidth := ssufwidth + x;
x := 0;
end else begin
srcleft := ssufleft;
srcwidth := ssufwidth;
end;
if y < 0 then begin
srctop := -y;
srcbottom := ssufheight;
y := 0;
end else begin
srctop := ssuftop;
srcbottom := srctop + ssufheight;
end;
if srcleft + srcwidth > ssuf.Width then srcwidth := ssuf.Width-srcleft;
if srcbottom > ssuf.Height then
srcbottom := ssuf.Height;//-srcheight;
if x + srcwidth > dsuf.Width then srcwidth := (dsuf.Width-x) div 4 * 4;
if y + srcbottom - srctop > dsuf.Height then
srcbottom := dsuf.Height-y+srctop;
if (x+srcwidth) * (y+srcbottom-srctop) > dsuf.Width * dsuf.Height then
srcbottom := srctop + (srcbottom-srctop) div 2;
if (srcwidth <= 0) or (srcbottom <= 0) or (srcleft >= ssuf.Width) or (srctop >= ssuf.Height) then exit;
// if srcWidth > 900 then exit;
if srcWidth > SCREENWIDTH + 100 then exit;
if ssuf.Height > 350 then begin
//TfrmMain.DScreen.AddChatBoardString('test; ' + InttoStr(srcwidth) + ' ' + InttoStr(srcbottom) + ' ' + InttoStr(srctop),clWhite, clBlack);
end;
try
sddsd.dwSize := SizeOf(sddsd);
dddsd.dwSize := SizeOf(dddsd);
ssuf.Lock (TRect(nil^), sddsd);
dsuf.Lock (TRect(nil^), dddsd);
awidth := srcwidth div 4; //ssuf.Width div 4;
bwidth := srcwidth; //ssuf.Width;
srclen := srcwidth; //ssuf.Width;
destlen := srcwidth; //ssuf.Width;
pmix := @Color256real[0,0];
for i:=srctop to srcbottom-1 do begin
sptr := PBYTE(integer(sddsd.lpSurface) + sddsd.lPitch * i + srcleft);
dptr := PBYTE(integer(dddsd.lpSurface) + (y+i-srctop) * dddsd.lPitch + x);
asm
mov scount, 0
mov esi, sptr
lea edi, source
mov ebx, scount //ebx = scount
@@CopySource:
cmp ebx, srclen
jae @@EndSourceCopy
db $0F,$6F,$04,$1E /// movq mm0, [esi+ebx]
db $0F,$7F,$04,$1F /// movq [edi+ebx], mm0
add ebx, 8
jmp @@CopySource
@@EndSourceCopy:
mov dcount, 0
mov esi, dptr
lea edi, dest
mov ebx, dcount
@@CopyDest:
cmp ebx, destlen
jae @@EndDestCopy
db $0F,$6F,$04,$1E /// movq mm0, [esi+ebx]
db $0F,$7F,$04,$1F /// movq [edi+ebx], mm0
add ebx, 8
jmp @@CopyDest
@@EndDestCopy:
lea esi, source
lea edi, dest
mov wcount, 0
@@BlendNext:
mov ebx, wcount
cmp [esi+ebx].byte, 0 //if _src[bitindex] > 0
jz @@EndBlend
movzx eax, [esi+ebx].byte //sidx := _src[bitindex]
shl eax, 8 //sidx * 256
mov sidx, eax
movzx eax, [edi+ebx].byte //didx := _dest[bitindex]
add sidx, eax
mov edx, pmix
mov ecx, sidx
movzx eax, [edx+ecx].byte //
mov [edi+ebx], al
@@EndBlend:
inc wcount
mov eax, bwidth
cmp wcount, eax
jb @@BlendNext
lea esi, dest //Move (_src, dptr^, 4)
mov edi, dptr
mov ecx, awidth
cld
rep movsd
end;
end;
asm
db $0F,$77 /// emms
end;
finally
ssuf.UnLock();
dsuf.UnLock();
end;
end;
procedure SpriteCopy(DestX, DestY : integer;
SourX, SourY : integer;
Size : TPoint;
Sour, Dest : TDirectDrawSurface);
const
TRANSPARENCY_VALUE = 0;
var
SourDesc, DestDesc : TDDSurfaceDesc;
pSour, pDest, pMask : PByte;
Transparency : array[1..8] of byte;
begin
FillChar(Transparency,8,TRANSPARENCY_VALUE);
SourDesc.dwSize := SizeOf(SourDesc);
Sour.Lock (TRect(nil^), SourDesc);
DestDesc.dwSize := SizeOf(DestDesc);
Dest.Lock (TRect(nil^), DestDesc);
// pSour := PByte(DWORD(SourDesc.lpSurface)+SourY*SourDesc.lPitch+SourX);
// pDest := PByte(DWORD(DestDesc.lpSurface)+DestY*DestDesc.lPitch+DestX);
pSour := PByte(DWORD(SourDesc.lpSurface)+Byte(SourY*SourDesc.lPitch+SourX));
pDest := PByte(DWORD(DestDesc.lpSurface)+Byte(DestY*DestDesc.lPitch+DestX));
pMask := Pointer(@Transparency);
asm
push esi
push edi
mov esi, pMask
db $0F,$6F,$26 /// movq mm4, [esi]
// mm4
mov esi, pSour
mov edi, pDest
mov ecx, Size.Y
@@LOOP_Y:
push ecx
mov ecx, Size.X
shr ecx, 3
@@LOOP_X:
db $0F,$6F,$07 /// movq mm0, [edi]
// mm0 Destination
db $0F,$6F,$0E /// movq mm1, [esi]
// mm1 Source
db $0F,$6F,$D1 /// movq mm2, mm1
// mm2 Source
db $0F,$74,$D4 /// pcmpeqb mm2, mm4
// mm2
db $0F,$6F,$DA /// movq mm3, mm2
// mm3
db $0F,$DF,$D1 /// pandn mm2, mm1
// Source
db $0F,$DB,$D8 /// pand mm3, mm0
// Destination
db $0F,$EB,$D3 /// por mm2, mm3
// Source Destination
db $0F,$7F,$17 /// movq [edi], mm2
// Destination
add esi, 8
// 8 bytes
add edi, 8
loop @@LOOP_X
add esi, SourDesc.lPitch
sub esi, Size.X
add edi, DestDesc.lPitch
sub edi, Size.X
pop ecx
loop @@LOOP_Y
db $0F,$77 /// emms
pop edi
pop esi
end;
Sour.UnLock();
Dest.UnLock();
end;
procedure DrawEffect (x, y, width, height: integer; ssuf: TDirectDrawSurface; eff: TColorEffect);
var
i, j, n, scount, srclen: integer;
sddsd: TDDSurfaceDesc;
sptr, peff: PByte;
//source: array[0..810] of byte;
source: array[0..SCREENWIDTH + 10] of byte;
begin
if Width > SCREENWIDTH then exit;
// if Width > 800 then exit;
if eff = ceNone then exit;
peff := nil;
case eff of
ceGrayScale: peff := @GrayScaleLevel;
ceBright: peff := @BrightColorLevel;
ceBlack: peff := @BlackColorLevel;
ceWhite: peff := @WhiteColorLevel;
ceRed: peff := @RedishColorLevel;
ceGreen: peff := @GreenColorLevel;
ceBlue: peff := @BlueColorLevel;
ceYellow: peff := @YellowColorLevel;
ceFuchsia: peff := @FuchsiaColorLevel;
//else exit;
end;
if peff = nil then begin
peff := nil;
exit;
end;
try
sddsd.dwSize := SizeOf(sddsd);
ssuf.Lock (TRect(nil^), sddsd);
srclen := width;
for i:=0 to height-1 do begin
sptr := PBYTE(integer(sddsd.lpSurface) + (y+i) * sddsd.lPitch + x);
asm
mov scount, 0
mov esi, sptr
lea edi, source
@@CopySource:
mov ebx, scount //ebx = scount
cmp ebx, srclen
jae @@EndSourceCopy
db $0F,$6F,$04,$1E /// movq mm0, [esi+ebx]
db $0F,$7F,$07 /// movq [edi], mm0
mov ebx, 0
@@Loop8:
cmp ebx, 8
jz @@EndLoop8
movzx eax, [edi+ebx].byte
mov edx, peff
movzx eax, [edx+eax].byte //
mov [edi+ebx], al
inc ebx
jmp @@Loop8
@@EndLoop8:
mov ebx, scount
db $0F,$6F,$07 /// movq mm0, [edi]
db $0F,$7F,$04,$1E /// movq [esi+ebx], mm0
add edi, 8
add scount, 8
jmp @@CopySource
@@EndSourceCopy:
db $0F,$77 /// emms
end;
end;
finally
ssuf.UnLock();
end;
end;
procedure DrawLine(Surface: TDirectDrawSurface);
var
I: Integer;
nX,nY:Integer;
begin
for nX := 0 to Surface.Width - 1 do begin
Surface.Pixels[nX,0]:=255;
end;
for nY := 0 to Surface.Height - 1 do begin
Surface.Pixels[0,nY]:=255;
end;
Surface.Height
end;
procedure buildrealrgb(ctable: TRGBQuads);
var
r, g, b, rr, gg, bb, color, MinDif, ColDif: Integer;
MatchColor: Byte;
pal0, pal1, pal2: TRGBQuad;
i, j, n: integer;
begin
for i:=0 to 255 do begin
pal0 := ctable[i];
for j:=0 to 255 do begin
pal1 := ctable[j];
pal1.rgbRed := pal0.rgbRed;
pal1.rgbGreen := pal0.rgbGreen;
pal1.rgbBlue := pal0.rgbBlue;
MinDif := 1;
MatchColor := 0;
for n:=0 to 255 do begin
pal2 := ctable[n];
ColDif := Abs(pal2.rgbRed - pal1.rgbRed) +
Abs(pal2.rgbGreen - pal1.rgbGreen) +
Abs(pal2.rgbBlue - pal1.rgbBlue);
if ColDif < MinDif then begin
MinDif := ColDif;
MatchColor := n;
end;
end;
Color256real[i, j] := MatchColor;
end;
end;
end;
{---- Adjust global SVN revision ----}
initialization
SVNRevision('$Id: cliUtil.pas 121 2006-08-06 01:10:41Z Dataforce $');
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -