SRL Archive - Delphi/FPC Help and Tutorials

Scanline with assembly


DatSik

2014-02-10 14:21:21

Has anyone here experimented with implenting ASM with Scanline functions?

Brandon

2014-02-10 17:21:29

From: DatSik
Has anyone here experimented with implenting ASM with Scanline functions?


Are you asking out of just sheer curiousity? Also.. What does "Scanline functions" mean? :l Not familiar with the terminology here..

Do you mean like scanf? getline? or Pixels[(Height - y) * Width + x]?

This is also in the delphi/fpc section so.. Are you sure you're talking about just ASM? Intel, AT&T, Mips, etc???? Missing a lot of details..

I'm really missing the question/reason..

DatSik

2014-02-14 12:27:12

Oh yes im very sorry, I do not mean strictley ASM, i meant Delphi + asm , and here is the scanline function i am speaking of. http://docwiki.embarcadero.com/CodeExamples/XE5/en/ScanLine_(Delphi) I was just wondering if anyone had ever mixed the 2 in order to get a more responsive function or any kind of Asm with it. I appreciate you help

Frement

2014-02-14 20:28:03

You can look at the Simba sources, I think it uses scanline, or if not at the moment, at some point maybe it did.

Brandon

2014-02-15 16:51:15

From: DatSik
Oh yes im very sorry, I do not mean strictley ASM, i meant Delphi + asm , and here is the scanline function i am speaking of. http://docwiki.embarcadero.com/CodeExamples/XE5/en/ScanLine_(Delphi) I was just wondering if anyone had ever mixed the 2 in order to get a more responsive function or any kind of Asm with it. I appreciate you help



I'd need an assembler to check this but here goes (notepad ftw):



asm
mov ecx, 0

@@HeightLoop:
cmp ecx, BmpHeight
je @@EndHeight
mov ebx, 0

mov P, [ScanLine]
add P, Y

@@WidthLoop:
mov eax, ecx
add eax, ebx


push ecx
mov ecx, x
mul ecx, $2
mov x, ecx

mov ecx, y
mul ecx, $2
mov y, ecx
pop ecx

mov bigP, [BigScanLine + $4]
//.........
//.........
//.........

cmp ebx, BmpWidth
je @@EndWidth
inc ebx
jmp @@WidthLoop


@@EndWidth:
inc ecx
jmp @@HeightLoop

@@EndHeight:
end;

The above probably has some errors.. I'm rusty :(


I can write it in NASM syntax and you can translate that to Delphi's Assembly.. but.. too much work.

DatSik

2014-03-26 16:10:37

From: Brandon
I'd need an assembler to check this but here goes (notepad ftw):



asm
mov ecx, 0

@@HeightLoop:
cmp ecx, BmpHeight
je @@EndHeight
mov ebx, 0

mov P, [ScanLine]
add P, Y

@@WidthLoop:
mov eax, ecx
add eax, ebx


push ecx
mov ecx, x
mul ecx, $2
mov x, ecx

mov ecx, y
mul ecx, $2
mov y, ecx
pop ecx

mov bigP, [BigScanLine + $4]
//.........
//.........
//.........

cmp ebx, BmpWidth
je @@EndWidth
inc ebx
jmp @@WidthLoop


@@EndWidth:
inc ecx
jmp @@HeightLoop

@@EndHeight:
end;

The above probably has some errors.. I'm rusty :(


I can write it in NASM syntax and you can translate that to Delphi's Assembly.. but.. too much work.


Thats a fantastic example, Thank you very much.. it has been very helpful you actualy inspired me to mess with some animations , here is a little section of what i have so far..excuse my documentation i try to heavily document because as you know im still learning with asm and scanline/Delphi.
procedure TForm1.Button2Click(Sender: TObject);
var
y,x,b,b2,z,ti: integer;
p: pointer; // used to solve compatabilty problems between pa and pba
pba: pbytearray;
// used to temperarily store the address of the start of a row of pixels
begin
panel1.hide;
// -- store the information into arrays
bit.pixelformat:=pf32bit; // make it so each pixel is stored in 4 bytes
setlength(pa,bit.height);
for x:=bit.height-1 downto 0 do
begin // update pa
pba:=bit.scanline[x]; // get the address of a row of pixels
asm
mov eax,dword ptr (pba);
mov p,eax; // move the pointer value into p
// this temperary value in p is just there because I don't know how
// to move an address from a PByteArray into a normal pointer without
// having incompatable errors
end;
pa[x]:=p;
end;
// -- finished storing the pointers
x:=bit.width-1; // initial value in the loop through x-coordinates
y:=high(pa); // initial value in the loop through y-coordinates
ti:=gettickcount; // store the time
for z:=0 to 300 do
// loop through frames in the animation
begin
if z mod 10=0 then
caption:='frame='+inttostr(z);
asm
// EAX stores the frame number
// EBX stores the y-coordinate and the pixel colour
// ECX stores the address of each row of pixels
// EDX stores the x-coordinates
mov b,ebx;
// Ebx should be temperarily stored because Delphi uses its value.
// If assembly code modifies ebx, it creates errors.
mov ebx,y;
mov eax,z;
imul eax,eax; // eax:=sqr(eax);
// this is used to define the changing colours of the pixels for each frame
@bigstart: // loop through y-coordinates
mov ecx,dword ptr (pa); // get address of the contents of the array
mov ecx,dword ptr (ecx+ebx*4);
// get the address of a row of pixels

mov b2,ebx; // temperarily store the value of ebx

mov edx,x;
@startloop: // loop through x-coordinates
mov ebx,edx;
imul ebx,eax; // eax's value is based on the frame number
// this is what causes the colour for each frame to be different
mov dword ptr (ecx+edx*4),ebx; // set the pixel
dec edx;
cmp edx,0;
jg @startloop;

mov ebx,b2; // restore the value of ebx to the y-coordniate

dec ebx;
cmp ebx,0;
jg @bigstart;
mov ebx,b; // restore the value of ebx to its original value
end;
canvas.draw(0,0,bit); // draw the frame on the form
// this draw sometimes is almost as time consuming as creating the frame
end;
ti:=gettickcount-ti; // get the number of miliseconds since the beginning of the animation
canvas.draw(0,0,bit);
caption:='animation took '+inttostr(ti)+'ms, height='+inttostr(bit.height)+
', width='+inttostr(bit.width)+', '+floattostr(ti/(bit.width*bit.height*z)*1000000)+'ns/pixel';
panel1.Visible:=true;
end;

Ive been able to create some pretty nice stuff so far. Thank you again you were a big help