Итогом:
- В интерфейсной секции просто не были указаны ни LCLType, ни LCLIntf. LCLType нужен для части констант, LCLIntf для функции SetBkMode (и, возможно, для ещё каких-нибудь).
- В конечном итоге отказался от ассемблерной конструкции, заменив её аналогичной по логике, но гораздо более читабельной паскальной
- Градиент заработал, что смог проверил. Выношу на суд общественности исправленную версию.
P.S. Проверял под x86_64 linux + FPC 2.5.1 svn r15177 + Lazarus svn r24946. Огромная просьба погонять под другими версиями...
Добавлено спустя 6 часов 55 минут 14 секунд:
Теперь чуть подробнее про изменения. Что было поправлено:
- Процедура InitPixArray;
В ней, перед вызовом функции, определяющий цвет пиксела в текущей позиции, я поставил преобразование из TColor в RGB.
Для чего: В LCL/FCL TColor = longint с присущими ему (longint'у) отрицательными значениями, и, соответственно при отрицательных значениях на входе будет инверсия битов, что нам не надо. - Процедура GetColorBetween.
Замена ассемблерной вставки- Код: Выделить всё
asm
mov EAX, Startcolor
cmp EAX, endColor
je @@exit
mov r1, AL
shr EAX,8
mov g1, AL
shr Eax,8
mov b1, AL
mov Eax, endcolor
mov r2, AL
shr EAX,8
mov g2, AL
shr EAX,8
mov b2, AL
push ebp
mov al, r1
mov dl, r2
call CalcColorBytes
pop ecx
push ebp
Mov r3, al
mov dL, g2
mov al, g1
call CalcColorBytes
pop ecx
push ebp
mov g3, Al
mov dL, B2
mov Al, B1
call CalcColorBytes
pop ecx
mov b3, al
XOR EAX,EAX
mov AL, B3
shl EAX,8
mov AL, G3
shl EAX,8
mov AL, R3
@@Exit:
mov @result, eax
end;
на вот такую вот конструкцию (одинаковая часть кода пропущена)- Код: Выделить всё
type
ptRGB=^tRGB;
tRGB=array[1..4] of byte;
{..............}
var
{.........}
Color1,Color2 : ptRGB;
begin
{...........}
Color1:=@StartC;
Color2:=@FinalC;
GetColorBetween:=(CalcColorBytes(Color1^[1],Color2^[1]) and $000000FF) or
((CalcColorBytes(Color1^[2],Color2^[2]) shl 8) and $0000FF00) or
((CalcColorBytes(Color1^[3],Color2^[3]) shl 16) and $00FF0000);
end;
Для чего. Ассемблер хорош тогда, когда известна машина, на которой написанный код будет работать. В нашем случае это совсем не так. Есть i386, x86_64, mips, arm... Регистры и работа с ними слегка отличается. Мало того, та asm вставка, что была по сути ничего не считала, потому как сразу после загрузки в EAX начального цвета выполнялся переход в конец кода. (je @@exit; --> @@Exit: mov @result, eax). А этот код успешно соберётся на любой машине, где будет fpc/lazarus. Причём компилируется этот код по-разному в зависимости от установок компилятора, но работает одинаково .
Добавлено спустя 3 часа 41 минуту 59 секунд:
Попробовал под win32 (fpc 2.4.1 + Lazarus 0.9.29 r24946). Без замечаний.