alexione: Thanks a ton! I've managed to incorporate a few of these already.

Jason F.: I'll try. Whats the version of JEDI-SDL files you are currently using? I'm using sort of a hybrid of my 0.5 modifications (sdlutils.pas file only) with JEDI-SDL 1.0 Beta


After working with these a bit, here are the functions as they exist right now.

SDL_RotateDeg_AddAlpha();
[pascal]procedure SDL_RotateDeg_AddAlpha(DstSurface, SrcSurface: PSDL_Surface; SrcRect: PSDL_Rect;
DestX, DestY, OffsetX, OffsetY: Integer; Angle: Integer;
Alpha: UInt;
var
aSin, aCos: Single;
MX, MY, DX, DY, NX, NY, OX, OY, Width, Height, TX, TY, RX, RY, ROX, ROY: Integer;
startDX, endDX, startDY, endDY: Integer;
SrcColor, DstColor: UInt32;
srcRR, srcGG, srcBB: UInt8;
TempTransparentColour: UInt32;
MAXX, MAXY: Integer;
begin
// Rotate the surface to the target surface.
TempTransparentColour := SrcSurface.format.colorkey;

maxx := DstSurface.w;
maxy := DstSurface.h;
aCos := degCOS[Angle];
aSin := degSIN[Angle];

Width := Round(abs(srcrect.h * aCos) + abs(srcrect.w * aSin));
Height := Round(abs(srcrect.h * aSin) + abs(srcrect.w * aCos));

OX := Width shr 1;
OY := Height shr 1;
MX := (srcRect.x + (srcRect.x + srcRect.w)) shr 1;
MY := (srcRect.y + (srcRect.y + srcRect.h)) shr 1;
ROX := (-(srcRect.w shr 1)) + Offsetx;
ROY := (-(srcRect.h shr 1)) + OffsetY;
Tx := ox + round(ROX * aSin - ROY * aCos);
Ty := oy + round(ROY * aSin + ROX * aCos);
RX := -OX;

startDX := DestX - TX;
if (startDX <= 0) then
begin
RX := RX + 1 - startDX;
startDX := 1;
end;

endDX := DestX - TX + Width;
if (endDX >= MAXX) then endDX := MAXX - 1;

for DX := startDX to endDX do
begin
inc(RX);
RY := -OY;

startDY := DestY - TY;
if (startDY <= 0) then
begin
RY := RY + 1 - startDY;
startDY := 1;
end;

endDY := DestY - TY + Height;
if (endDY >= MAXY) then
endDY := MAXY - 1;

for DY := startDY to endDY do
begin
NX := mx + Round(RX * aSin + RY * aCos); //
NY := my + Round(RY * aSin - RX * aCos); //

if (UInt32(NX - srcRect.x) <= UInt32(srcRect.w)) then
begin
if (UInt32(NY - srcRect.y) <= UInt32(srcRect.h)) then
begin
SrcColor := SDL_GetPixel(SrcSurface, NX, NY);
if (SrcColor <> TempTransparentColour) then
begin
SDL_GetRGB(SrcColor, SrcSurface.format, @srcRR, @srcGG, @srcBB);

SDL_AddPixel(DstSurface, DX, DY,
SDL_MapRGB(DstSurface.format,
(Alpha * srcRR) shr 8,
(Alpha * srcGG) shr 8,
(Alpha * srcBB) shr );
end;
end;
end;
inc(RY);
end;
end;
end;[/pascal]

SDL_RotateDeg_Alpha();
[pascal]procedure SDL_RotateDeg_Alpha(DstSurface, SrcSurface: PSDL_Surface; SrcRect: PSDL_Rect;
DestX, DestY, OffsetX, OffsetY: Integer; Angle: Integer;
Alpha: UInt;
var
aSin, aCos: Single;
MX, MY, DX, DY, NX, NY, OX, OY, Width, Height, TX, TY, RX, RY, ROX, ROY: Integer;
startDX, endDX, startDY, endDY: Integer;
SrcColor, DstColor: UInt32;
srcRR, srcGG, srcBB, dstRR, dstGG, dstBB: UInt8;
TempTransparentColour: UInt32;
MAXX, MAXY: Integer;
begin
// Rotate the surface to the target surface.
TempTransparentColour := SrcSurface.format.colorkey;

maxx := DstSurface.w;
maxy := DstSurface.h;
aCos := degCOS[Angle];
aSin := degSIN[Angle];

Width := Round(abs(srcrect.h * aCos) + abs(srcrect.w * aSin));
Height := Round(abs(srcrect.h * aSin) + abs(srcrect.w * aCos));

OX := Width shr 1;
OY := Height shr 1;
MX := (srcRect.x + (srcRect.x + srcRect.w)) shr 1;
MY := (srcRect.y + (srcRect.y + srcRect.h)) shr 1;
ROX := (-(srcRect.w shr 1)) + Offsetx;
ROY := (-(srcRect.h shr 1)) + OffsetY;
Tx := ox + round(ROX * aSin - ROY * aCos);
Ty := oy + round(ROY * aSin + ROX * aCos);
RX := -OX;

startDX := DestX - TX;
if (startDX <= 0) then
begin
RX := RX + 1 - startDX;
startDX := 1;
end;

endDX := DestX - TX + Width;
if (endDX >= MAXX) then endDX := MAXX - 1;

for DX := startDX to endDX do
begin
inc(RX);
RY := -OY;

startDY := DestY - TY;
if (startDY <= 0) then
begin
RY := RY + 1 - startDY;
startDY := 1;
end;

endDY := DestY - TY + Height;
if (endDY >= MAXY) then
endDY := MAXY - 1;

for DY := startDY to endDY do
begin
NX := mx + Round(RX * aSin + RY * aCos); //
NY := my + Round(RY * aSin - RX * aCos); //

if (UInt32(NX - srcRect.x) <= UInt32(srcRect.w)) then
begin
if (UInt32(NY - srcRect.y) <= UInt32(srcRect.h)) then
begin
SrcColor := SDL_GetPixel(SrcSurface, NX, NY);
if (SrcColor <> TempTransparentColour) then
begin
SDL_GetRGB(SrcColor, SrcSurface.format, @srcRR, @srcGG, @srcBB);

DstColor := SDL_GetPixel(DstSurface, DX, DY);
SDL_GetRGB(DstColor, DstSurface.format, @dstRR, @dstGG, @dstBB);

SDL_PutPixel(DstSurface, DX, DY,
SDL_MapRGB(DstSurface.format,
(Alpha * (srcRR - dstRR)) shr 8 + dstRR,
(Alpha * (srcGG - dstGG)) shr 8 + dstGG,
(Alpha * (srcBB - dstBB)) shr 8 + dstBB));
end;
end;
end;
inc(RY);
end;
end;
end;[/pascal]


Notes on alexione's Suggestions:

I was able to incorporate (4) + (5) without any trouble at all. (3) caused a small issue with the offset of the image's dst orientation until I factored in RX and RY into it. Works fine now. (1) I didn't fully understand... I think I need it explained to me in detail. And (2) I understand, but haven't been able to properly incorporate it without major issues [size=9px](the function stops working all together so far)[/size]

Overall you actually notice a small bit or an improvement. Testing with about 11 60x60 textures you get about 3-5 frames difference. [size=9px](on top of whats already in my game engine: background+2 tile layers+2 sprites+3 lines of rastered font text)[/size] But I think with (2) implimented I can squeeze a bit more.


There is one thing I'd like to try... and thats to replace SDL_AddPixel in form SDL_RotateDeg_AddAlpha() to try and optimize the calculation of the RGB values. Something I noticed was that the most intensive part of both of these functions is the calculation of the new color. And here I'm trying to do 2 sets of calculations instead of just one.


Here is the existing SDL_AddPixel(); function:
[pascal]procedure SDL_AddPixel( DstSurface : PSDL_Surface; x : cardinal; y : cardinal; Color :
cardinal );
var
SrcColor : cardinal;
Addr : cardinal;
R, G, B : cardinal;
begin
if Color = 0 then
exit;
with DstSurface^ do
begin
Addr := cardinal( Pixels ) + y * Pitch + x * format.BytesPerPixel;
SrcColor := PUInt32( Addr )^;
case format.BitsPerPixel of
8 :
begin
R := SrcColor and $E0 + Color and $E0;
G := SrcColor and $1C + Color and $1C;
B := SrcColor and $03 + Color and $03;
if R > $E0 then
R := $E0;
if G > $1C then
G := $1C;
if B > $03 then
B := $03;
PUInt8( Addr )^ := R or G or B;
end;
15 :
begin
R := SrcColor and $7C00 + Color and $7C00;
G := SrcColor and $03E0 + Color and $03E0;
B := SrcColor and $001F + Color and $001F;
if R > $7C00 then
R := $7C00;
if G > $03E0 then
G := $03E0;
if B > $001F then
B := $001F;
PUInt16( Addr )^ := R or G or B;
end;
16 :
begin
R := SrcColor and $F800 + Color and $F800;
G := SrcColor and $07C0 + Color and $07C0;
B := SrcColor and $001F + Color and $001F;
if R > $F800 then
R := $F800;
if G > $07C0 then
G := $07C0;
if B > $001F then
B := $001F;
PUInt16( Addr )^ := R or G or B;
end;
24 :
begin
R := SrcColor and $00FF0000 + Color and $00FF0000;
G := SrcColor and $0000FF00 + Color and $0000FF00;
B := SrcColor and $000000FF + Color and $000000FF;
if R > $FF0000 then
R := $FF0000;
if G > $00FF00 then
G := $00FF00;
if B > $0000FF then
B := $0000FF;
PUInt32( Addr )^ := SrcColor and $FF000000 or R or G or B;
end;
32 :
begin
R := SrcColor and $00FF0000 + Color and $00FF0000;
G := SrcColor and $0000FF00 + Color and $0000FF00;
B := SrcColor and $000000FF + Color and $000000FF;
if R > $FF0000 then
R := $FF0000;
if G > $00FF00 then
G := $00FF00;
if B > $0000FF then
B := $0000FF;
PUInt32( Addr )^ := R or G or B;
end;
end;
end;
end;[/pascal]