-
procedure CopySwapPixel(const Source, Destination : Pointer);
asm
push ebx
mov bl,[eax+0]
mov bh,[eax+1]
mov [edx+2],bl
mov [edx+1],bh
mov bl,[eax+2]
mov bh,[eax+3]
mov [edx+0],bl
mov [edx+3],bh
pop ebx
end;
А то вот решил модуль портировать под FreePascal, а там ASM, в котором я не рублю...
-
Этот код лучше не переводить на Pascal :) А если всё-таки горит, то надо увидеть весь сырец, чтобы правильно перевести. Надо знать в каких функциях изменяются регистры ebx, eax, и определить их как переменные... но это так, на вскидку... надо код смотреть.
-
Ну, можно и на FPC сразу, он ведь вроде как тоже ASM держит. Это функция из модуля Texture.pas... Позже выложу контекст, в котором эта фуцнкция применяется...
-
Вот исходна функция загрузки TGA изображения. Нужно бы это всё перевести на FPC, и всем будет счастье... (:
function LoadTGATexture( Filename: String; var Texture: GLuint ): Boolean;
var
TGAHeader : packed record FileType : Byte;
ColorMapType : Byte;
ImageType : Byte;
ColorMapSpec : Array[0..4] of Byte;
OrigX : Array [0..1] of Byte;
OrigY : Array [0..1] of Byte;
Width : Array [0..1] of Byte;
Height : Array [0..1] of Byte;
BPP : Byte;
ImageInfo : Byte;
end;
TGAFile : File;
bytesRead : Integer;
image : Pointer;
CompImage : Pointer;
Width, Height : Integer;
ColorDepth : Integer;
ImageSize : Integer;
BufferIndex : Integer;
currentByte : Integer;
CurrentPixel : Integer;
I : Integer;
Front: ^Byte;
Back: ^Byte;
Temp: Byte;
procedure CopySwapPixel(const Source, Destination : Pointer);
asm
push ebx
mov bl,[eax+0]
mov bh,[eax+1]
mov [edx+2],bl
mov [edx+1],bh
mov bl,[eax+2]
mov bh,[eax+3]
mov [edx+0],bl
mov [edx+3],bh
pop ebx
end;
begin
result :=FALSE;
GetMem(Image, 0);
AssignFile(TGAFile, Filename);
Reset(TGAFile, 1);
BlockRead(TGAFile, TGAHeader, SizeOf(TGAHeader));
result :=TRUE;
if Result = TRUE then
begin
Result :=FALSE;
if (TGAHeader.ImageType <> 2) AND
(TGAHeader.ImageType <> 10) then
begin
Result := False;
CloseFile(tgaFile);
MessageBox(0, PChar('Couldn''t load \"'+ Filename +'\". Only 24 and 32bit TGA supported.'), PChar('TGA File Error'), MB_OK);
Exit;
end;
if TGAHeader.ColorMapType <> 0 then
begin
Result := False;
CloseFile(TGAFile);
MessageBox(0, PChar('Couldn''t load "'+ Filename +'". Colormapped TGA files not supported.'), PChar('TGA File Error'), MB_OK);
Exit;
end;
// Get the width, height, and color depth
Width := TGAHeader.Width[0] + TGAHeader.Width[1] * 256;
Height := TGAHeader.Height[0] + TGAHeader.Height[1] * 256;
ColorDepth := TGAHeader.BPP;
ImageSize := Width*Height*(ColorDepth div 8);
if ColorDepth < 24 then
begin
Result := False;
CloseFile(TGAFile);
MessageBox(0, PChar('Couldn''t load "'+ Filename +'". Only 24 and 32 bit TGA files supported.'), PChar('TGA File Error'), MB_OK);
Exit;
end;
GetMem(Image, ImageSize);
if TGAHeader.ImageType = 2 then // Standard 24, 32 bit TGA file
begin
BlockRead(TGAFile, image^, ImageSize, bytesRead);
if bytesRead <> ImageSize then
begin
Result := False;
CloseFile(TGAFile);
MessageBox(0, PChar('Couldn''t read file "'+ Filename +'".'), PChar('TGA File Error'), MB_OK);
Exit;
end;
// TGAs are stored BGR and not RGB, so swap the R and B bytes.
// 32 bit TGA files have alpha channel and gets loaded differently
if TGAHeader.BPP = 24 then
begin
for I :=0 to Width * Height - 1 do
begin
Front := Pointer(Integer(Image) + I*3);
Back := Pointer(Integer(Image) + I*3 + 2);
Temp := Front^;
Front^ := Back^;
Back^ := Temp;
end;
Texture :=CreateTexture(Width, Height, GL_RGB, Image);
end
else
begin
for I :=0 to Width * Height - 1 do
begin
Front := Pointer(Integer(Image) + I*4);
Back := Pointer(Integer(Image) + I*4 + 2);
Temp := Front^;
Front^ := Back^;
Back^ := Temp;
end;
Texture :=CreateTexture(Width, Height, GL_RGBA, Image);
end;
end;
// Compressed 24, 32 bit TGA files
if TGAHeader.ImageType = 10 then
begin
ColorDepth :=ColorDepth DIV 8;
CurrentByte :=0;
CurrentPixel :=0;
BufferIndex :=0;
GetMem(CompImage, FileSize(TGAFile)-sizeOf(TGAHeader));
BlockRead(TGAFile, CompImage^, FileSize(TGAFile)-sizeOf(TGAHeader), BytesRead); // load compressed data into memory
if bytesRead <> FileSize(TGAFile)-sizeOf(TGAHeader) then
begin
Result := False;
CloseFile(TGAFile);
MessageBox(0, PChar('Couldn''t read file "'+ Filename +'".'), PChar('TGA File Error'), MB_OK);
Exit;
end;
repeat
Front := Pointer(Integer(CompImage) + BufferIndex);
Inc(BufferIndex);
if Front^ < 128 then
begin
For I := 0 to Front^ do
begin
CopySwapPixel(Pointer(Integer(CompImage)+BufferIndex+I*ColorDepth), Pointer(Integer(image)+CurrentByte));
CurrentByte := CurrentByte + ColorDepth;
inc(CurrentPixel);
end;
BufferIndex :=BufferIndex + (Front^+1)*ColorDepth
end
else
begin
For I := 0 to Front^ -128 do
begin
CopySwapPixel(Pointer(Integer(CompImage)+BufferIndex), Pointer(Integer(image)+CurrentByte));
CurrentByte := CurrentByte + ColorDepth;
inc(CurrentPixel);
end;
BufferIndex :=BufferIndex + ColorDepth
end;
until CurrentPixel >= Width*Height;
if ColorDepth = 3 then
Texture :=CreateTexture(Width, Height, GL_RGB, Image)
else
Texture :=CreateTexture(Width, Height, GL_RGBA, Image);
end;
Result :=TRUE;
FreeMem(Image);
end;
end;
-
Начните вот с такого: {$asmmode Intel} Если после этого проблемы и останутся, все-таки с ними справиться будет легче.
-
Shiza (19.10.04 15:08) [1] Этот код лучше не переводить на Pascal :) А если всё-таки горит, то надо увидеть весь сырец, чтобы правильно перевести. Надо знать в каких функциях изменяются регистры ebx, eax, и определить их как переменные... но это так, на вскидку... надо код смотреть.
Если не знаеш ассемблер, то не пиши глупости.
Для сведения: EAX - Source EBX - используйтся как промежуточный регистр (в начале он сохраняется а потом востанавливается)
-
П7
Эту процедуру можно перевести в pascal, если надо - напиши. Но я рекомендую тебе оставить как есть, так как на pascal она будет дольше выполнятся. И по коду видно что она специально была написана на ассемблере, чтобы выполнялась быстрее.
Если пишеш в free pascal нужно поставить дериктиву использования ассемблера синтексиса Intel, как описывал PVOzerski.
-
П7
А еще, что вспомнил если в free pascal то будет немного по другому:
procedure CopySwapPixel(const Source, Destination : Pointer); asm push eax push ebx mov eax, source mov bl,[eax+0] mov bh,[eax+1] mov [edx+2],bl mov [edx+1],bh mov bl,[eax+2] mov bh,[eax+3] mov [edx+0],bl mov [edx+3],bh pop ebx pop eax end;
так как, только в Delphi первые три параметра передаются через регистры. Удачи тебе!
-
Спасибо. Сегодня потестю... (: А то с директивой нужной всё откомпилилось, а толку нет. Вместо текстуры чёрный квадрат... (:
-
Сорри, я забыл destination добавить в регистр, вот правильный листинг
procedure CopySwapPixel(const source, destination: Pointer); asm push eax push edx push ebx mov eax, source mov edx, destination mov bl,[eax+0] mov bh,[eax+1] mov [edx+2],bl mov [edx+1],bh mov bl,[eax+2] mov bh,[eax+3] mov [edx+0],bl mov [edx+3],bh pop ebx pop edx pop eax end;
-
а лучше перевести в родной синтаксис AT&T для free pascal. будет меньше проблем.
сегодня вечером переведу, если надо
-
можеш попробывать и это, но без дериктивы {$asmmode Intel} Но мне кажется в самой процедуре какая та ошибка
procedure CopySwapPixel(const Source, Destination: Pointer); asm movl $source, %eax movl $destination, %edx movb 0(%eax), %bl movb 1(%eax), %bh movb %bl, 2(%edx) movb %bh, 1(%edx) movb 2(%eax), %bl movb 3(%eax), %bh movb %bl, 0(%edx) movb %bh, 3(%edx) end ['EAX','EBX','EDX'];
-
Ребята, имейте в виду вот какую вещь. В нестабильной (разрабатываемой) версии 1.9.x на этапе какого-то из снапшотов было в 2 этапа осуществлено изменение соглашений о передаче параметров по умолчанию. Сначала (как это и есть в 1.0.x) это был упрощенный stdcall, потом - stdcall с сохранением части регистров согласно спецификации и, наконец, register как в Delphi. Сами понимаете, если мы пишем обращение к параметрам на асме, уходя от использования имен переменных, это может быть критично. Конечно, номера соответствующих билдов компилятора я уже не помню и восстановить их не берусь. Во всяком случае, проверьте, с чем имеете дело (хотя бы путем генерации asm-кода).
-
функция загрузки TGA изображения. Нужно бы это всё перевести на FPC, и всем будет счастье
Загрузка TGA на Паскале (без asm) есть в PowerDraw (в 2.80 во всяком случае). Там, конечно, грузится в какой-то свой класс, но переделать недолго.
-
>procedure CopySwapPixel(const source, destination: Pointer); >asm >..... Раз первые два паремтра передаются в регистры, то > mov eax, source > mov edx, destination можно вобще не писать! и правильно описание должно так выглядеть: procedure CopySwapPixel(source, destination: Pointer), чтобы Source и Destination содержали ЗНАЧЕНИЯ, а не адресы.
-
// not shure about fpc but in delphi it would be: procedure CopySwapPixel(const Source, Destination : Pointer); var SrcPix :array[0..3] of Byte absolute Source; DestPix:array[0..3] of byte absolute Destination; begin DestPix[3]:=SrcPix[0]; DestPix[2]:=SrcPix[1]; DestPix[1]:=SrcPix[2]; DestPix[0]:=SrcPix[3]; end;
-
Better: call should remove const and be var with type cardinal, not pointer
-
> PVOzerski © (20.10.04 12:33) [4] > Начните вот с такого:{$asmmode Intel}Если после этого проблемы > и останутся, все-таки с ними справиться будет легче.
хороший совет, очень помогло :) час не мог ошибку найти первый раз на фри паскале сижу, перешел с делфи
-
Удалено модератором
-
Удалено модератором
|