Recent

Author Topic: I need a pointer to screen_buffer_start for asm  (Read 3815 times)

RWC

  • Jr. Member
  • **
  • Posts: 92
I need a pointer to screen_buffer_start for asm
« on: October 10, 2015, 06:46:58 pm »
OS   : Windows Vista 32bit Home Premium SP2.
LAZ  : Lazarus-1.4.2-fpc-2.6.4-win32.
CPU  : Intel Core2 Quad CPU Q6600 2.4GHz. RAM : 3GB.
PCIE : NVIDIA GeForce GT610. Audo : NVIDIA HD Audio.

Dear coders
 Many years ago I coded in DOS using microsoft assembler 'masm'.
 When Windows XP arrived I learnt some Delphi (on a very basic level) but was
 able to mix my old asm code with Pascal.

 You can see in the code below that in Delphi I got pointers to buffers e.g 'TextrBufferStart: PByteArray'
 by using: 'TextrBufferStart := Image2.Picture.Bitmap.ScanLine[TmpBitmap2.height-1]'
 And then I could do:
             
             asm  //move all 3byte rgb+0 into 4byte array Texture Map
             mov esi,TmpBufferStart     //load colour source pointer.
             mov edi,TextrBufferStart   //load destination pointer.
             etc....




Two questions.
1. Can anyone show me how to get the pointers in Lazarus as it doesn't have
   the 'ScanLine' option.

 Also, I've read the screen handling examples - flipping etc. and my 3D stuff needs
 a fast method without flicker.
 In Delphi I used:
   
   InvalidateRect(Form1.Handle,NIL,False); //If draw=True Use API calls to avoid flicker.

2. From your experience with Lazarus, can you show me the best way to do this (for Windows only).

Kind regards
Roy Campbell.
Code: Pascal  [Select][+][-]
  1. //***************************************
  2. Part of Delphi4  - unit Unit1;
  3. interface
  4. type
  5.   TForm1 = class(TForm)
  6.     Image1: TImage;
  7.     Image2: TImage;
  8.     etc...
  9.   private
  10.     procedure MakeScreen;
  11.     Procedure LoadTexture;
  12.     procedure MakeMyTable;
  13. end.
  14.  
  15. var
  16.   Form1: TForm1;
  17.   ScreenBuffer,TmpBitmap,TmpBitmap2: Tbitmap;
  18.   ScreenBufferStart,TmpBufferStart,TextrBufferStart: PByteArray;
  19.   MyBuffer: Array[0..8191] of Byte;
  20.   MybufferStart: PByteArray;
  21.   etc...
  22.  
  23. implementation
  24.  
  25. procedure TForm1.MakeScreen;
  26. begin
  27.   ScreenBuffer := TBitmap.create;
  28.   try
  29.      ScreenBuffer.width  := 512;        //make a screen buffer use
  30.      ScreenBuffer.height := 384;        //binary sizes and 32bit pixels
  31.      ScreenBuffer.PixelFormat:=pf32bit; //for easier and faster addressing.
  32.      Image1.height := ScreenBuffer.height;  //assign to image1 and get screen
  33.      Image1.width := ScreenBuffer.width;    //buffer start address
  34.      Image1.Picture.Bitmap := ScreenBuffer; //pointer - ScreenBufferStart.
  35.      ScreenBufferStart := Image1.Picture.Bitmap.ScanLine[ScreenBuffer.height-1]; //got pointer
  36.   finally
  37.      ScreenBuffer.free;
  38.   end;
  39. end;
  40.  
  41. procedure TForm1.LoadTexture;   //make a texture buffer - same size as bmp but 32bit
  42. begin            //pixels for easier addressing - ORGB extra byte is zero.
  43.   TmpBitmap := TBitMap.create;
  44.   TmpBitmap2 := TBitMap.create;
  45.   try
  46.      TmpBitmap.LoadFromFile('test.bmp');  //256x256 Windows bmp 24bit rgb.
  47.      TmpBufferStart := TmpBitmap.ScanLine[TmpBitmap.height-1];
  48.      TmpBitmap2.width  := TmpBitmap.width;     //create 32bit ORGB array for pic
  49.      TmpBitmap2.height := TmpBitmap.height;
  50.      TmpBitmap2.PixelFormat:=pf32bit;
  51.      Image2.width := TmpBitmap2.width;         //assign to image2 and get screen
  52.      Image2.height := TmpBitmap2.height;       //buffer start address
  53.      Image2.Picture.Bitmap := TmpBitmap2;      //pointer - TextrBufferStart
  54.      TextrBufferStart := Image2.Picture.Bitmap.ScanLine[TmpBitmap2.height-1]; //got pointer
  55.  
  56.      asm    //move all 3byte rgb+0 into 4byte array Texture Map
  57.      pushad  //save registers - push all double
  58.      mov esi,TmpBufferStart    //load index colour source pointer.
  59.      mov edi,TextrBufferStart   //load destination pointer.
  60.      mov ecx,256*256  //load number of pixels
  61.   @Texture_Loop:
  62.      mov bx,[esi]       //read 1st Green Blue as word (reading the triples...
  63.      add esi,2          //set source to 1st Red     ...with eax will cause a..
  64.      mov al,[esi]       //read 1st Red as byte       ..read violation on the..
  65.      inc esi            //set source for next read rgb     ..last rgb read)
  66.      shl eax,16         //move Red into correct place
  67.      mov ax,bx          //move Green Blue into correct place=XRGB
  68.      and eax,$00ffffff  //AND out top byte = 0RGB
  69.      mov [edi],eax      //write colour to Texture Map
  70.      add edi,4          //set dest for next write doubleword
  71.      loop @Texture_Loop
  72.      popad  //restore registers - pop all double.
  73.      end;
  74.   finally
  75.      TmpBitmap.free;
  76.      TmpBitmap2.free;
  77.   end;
  78. end;
  79.  
  80. //*******************************
  81.  
LAZARUS  : Lazarus-1.4.2-fpc-2.6.4-win32. OS   : Windows Vista 32bit Home Premium SP2.
CPU  : Intel Core2 Quad CPU Q6600 2.4GHz. RAM : 3GB. PCIE : NVIDIA GeForce GT610. Audo : NVIDIA HD Audio.

balazsszekely

  • Guest
Re: I need a pointer to screen_buffer_start for asm
« Reply #1 on: October 11, 2015, 10:11:36 am »
Hi RWC,

Maybe I misunderstood the question but there is a ScanLine method for Bitmaps:
   Image1.Picture.Bitmap.ScanLine
alternatively you can use the
   Image1.Picture.Bitmap.RawImage.Data;
If you add windows to the uses clauses, function InvalidateRect is also available. Your delphi code should work just fine

regards,
GetMem

RWC

  • Jr. Member
  • **
  • Posts: 92
Re: I need a pointer to screen_buffer_start for asm
« Reply #2 on: October 11, 2015, 07:53:53 pm »
Hi GetMem,
When I convert my Delphi code in Lazarus I get an error on ...Scanline but I've just found this

On freepascal.org/Fast_direct_pixel_access#TBGRABitmap.ScanLine:

TBitmap.ScanLine was a method used frequently on Delphi. But TBitmap.ScanLine is not supported by

LCL. There is graphic library BGRABitmap which allows access to scan lines. TBGRABitmap.ScanLine

So I could try BGRABitmap but as I only need the start address I'll also look into your second
suggestion  TBitmap.RawImage.

Many thanks for your reply.

best regards
RWC.
LAZARUS  : Lazarus-1.4.2-fpc-2.6.4-win32. OS   : Windows Vista 32bit Home Premium SP2.
CPU  : Intel Core2 Quad CPU Q6600 2.4GHz. RAM : 3GB. PCIE : NVIDIA GeForce GT610. Audo : NVIDIA HD Audio.

RWC

  • Jr. Member
  • **
  • Posts: 92
Re: I need a pointer to screen_buffer_start for asm
« Reply #3 on: October 16, 2015, 03:51:15 am »
Hello again - I think I've cracked it? maybe.

Load 'maptile1.bmp' into a TBitmap
Then  converted TBitmap to TLazIntfImage using:
 
    IntfImage1 := TempBitmap.CreateIntfImage;

That lets me get a pointer to the TLazIntfImage using:

    TmpMapStart := IntfImage1.GetDataLineStart(0); //..like Delphi ScanLine   

The code below compiles successfully and runs but I can't display a screen image to
test it.

I've spent days going through the help files and wiki examples but I can't find
any reference to simply loading a bitmap and displying it on the screen?
(without using BGRABitmap or TLazIntfImage) 

Also, I don't want the displayed image area to stretch or resize but I will
need to put some Toolbox panels either side of it.
Any help would be welcomed.

regards
RWC.

Code: Pascal  [Select][+][-]
  1.  
  2. var
  3.   Form1: TForm1;
  4.   ColMapArray: array[0..4194304] of Byte;  //1024 x 1024 x 32bit
  5.   ColMapStart: ^integer;
  6.   etc...
  7.  
  8. procedure TForm1.FormCreate(Sender: TObject);
  9. begin
  10.   ColMapStart := @ColMapArray; // pointer needed until close.
  11.   LoadTextures;
  12. end;              
  13.  
  14. procedure TForm1.LoadTextures;
  15. var
  16.    IntfImage1: TLazIntfImage;
  17.    TempBitmap: TBitmap;
  18.    TmpMapStart: ^Integer;
  19. begin
  20.    IntfImage1 := TLazIntfImage.Create(0,0);
  21.    TempBitmap := TBitmap.Create;
  22.    try
  23.     TempBitmap.LoadFromFile('maptile1.bmp'); //24bit Windows bitmap uncompressed
  24.     IntfImage1 := TempBitmap.CreateIntfImage; //convert TBitmap to TLazIntfImage
  25.     TmpMapStart := IntfImage1.GetDataLineStart(0); //..like Delphi ScanLine
  26.  
  27.     //Canvas.Draw(0,0,TempBitmap);      // Gray screen??
  28.     //TempBitmap.Draw(Canvas,0,0,True);    //'Draw' not identified??
  29.    
  30.     asm    //move 1024x1024 3byte rgb's into 4byte array ground Map
  31.      pushad  //save registers - push all double
  32.      mov esi,TmpMapStart    //load index colour source pointer.
  33.      mov edi,ColMapStart   //load destination pointer.
  34.      mov ecx,1024*1024  //load number of pixels
  35.      etc...
  36.     end;
  37.    finally
  38.     IntfImage1.Free;
  39.     TempBitmap.Free;
  40.   end;
  41. end;                              
  42.  
  43.  
LAZARUS  : Lazarus-1.4.2-fpc-2.6.4-win32. OS   : Windows Vista 32bit Home Premium SP2.
CPU  : Intel Core2 Quad CPU Q6600 2.4GHz. RAM : 3GB. PCIE : NVIDIA GeForce GT610. Audo : NVIDIA HD Audio.

 

TinyPortal © 2005-2018