Changeset 46


Ignore:
Timestamp:
Jan 11, 2017, 8:12:01 AM (7 years ago)
Author:
chronos
Message:
  • Fixed: Some graphic drawing problems caused by different pixel byte width of bitmaps under Linux.
Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/ScreenTools.pas

    r43 r46  
    1919  end;
    2020
     21  TColor32 = type Cardinal;
     22  TColor32Component = (ccBlue, ccGreen, ccRed, ccAlpha);
     23  TPixel32 = packed record
     24   case Integer of
     25     0: (B, G, R, A: Byte);
     26     1: (ARGB: TColor32);
     27     2: (Planes: array[0..3] of Byte);
     28     3: (Components: array[TColor32Component] of Byte);
     29  end;
     30  PPixel32 = ^TPixel32;
     31
    2132{$IFDEF WINDOWS}
    2233function ChangeResolution(x, y, bpp, freq: integer): boolean;
    2334{$ENDIF}
     35function GetBitmapPixelPtr(Bitmap: TBitmap; X, Y: Integer): PPixel32;
    2436procedure RestoreResolution;
    2537function Play(Item: string; Index: integer = -1): boolean;
     
    272284end;
    273285
     286function GetBitmapPixelPtr(Bitmap: TBitmap; X, Y: Integer): PPixel32;
     287begin
     288  Result := Pointer(Bitmap.RawImage.Data) + X * (Bitmap.RawImage.Description.BitsPerPixel shr 3) + Y * Bitmap.RawImage.Description.BytesPerLine;
     289end;
     290
    274291procedure EmptyMenu(MenuItems: TMenuItem; Keep: integer = 0);
    275292var
     
    514531
    515532function LoadGraphicSet(Name: string): integer;
    516 type
    517   TLine = array [0 .. 999, 0 .. 2] of Byte;
    518533var
    519534  i, x, y, xmax, OriginalColor: integer;
    520535  FileName: string;
    521536  Source: TBitmap;
    522   DataLine, MaskLine: ^TLine;
     537  DataPixel, MaskPixel: PPixel32;
    523538begin
    524539  i := 0;
     
    556571    for y := 0 to Source.Height - 1 do
    557572    begin
    558       DataLine := GrExt[nGrExt].Data.ScanLine[y];
    559       MaskLine := GrExt[nGrExt].Mask.ScanLine[y];
    560573      for x := 0 to xmax - 1 do
    561574      begin
    562         OriginalColor := Cardinal((@DataLine[x])^) and $FFFFFF;
     575        DataPixel := GetBitmapPixelPtr(GrExt[nGrExt].Data, x, y);
     576        MaskPixel := GetBitmapPixelPtr(GrExt[nGrExt].Mask, x, Y);
     577
     578        OriginalColor := DataPixel^.ARGB and $FFFFFF;
    563579        if (OriginalColor = $FF00FF) or (OriginalColor = $7F007F) then
    564580        begin // transparent
    565           Cardinal((@MaskLine[x])^) := $FFFFFF;
    566           Cardinal((@DataLine[x])^) := Cardinal((@DataLine[x])^) and $FF000000
     581          MaskPixel^.ARGB := $FFFFFF;
     582          DataPixel^.ARGB := DataPixel^.ARGB and $FF000000
    567583        end
    568584        else
    569585        begin
    570           Cardinal((@MaskLine[x])^) := $000000; // non-transparent
     586          MaskPixel^.ARGB := $000000; // non-transparent
    571587          if Gamma <> 100 then
    572588          begin
    573             DataLine[x, 0] := GammaLUT[DataLine[x, 0]];
    574             DataLine[x, 1] := GammaLUT[DataLine[x, 1]];
    575             DataLine[x, 2] := GammaLUT[DataLine[x, 2]];
     589            DataPixel^.B := GammaLUT[DataPixel^.B];
     590            DataPixel^.G := GammaLUT[DataPixel^.G];
     591            DataPixel^.R := GammaLUT[DataPixel^.R];
    576592          end
    577593        end
     
    621637// Src is template
    622638// X channel = background amp (old Dst content), 128=original brightness
    623 type
    624   TPixel = array [0 .. 2] of Byte;
    625639var
    626640  i, Brightness, test: integer;
    627641  PixelSrc: ^Byte;
    628   PixelDst: ^TPixel;
     642  PixelDst: PPixel32;
    629643begin
    630644  {TODO assert(Src.PixelFormat = pf8bit);}
     
    654668  while yDst < h do
    655669  begin
    656     PixelDst := dst.ScanLine[yDst] + 3 * xDst;
     670    PixelDst := GetBitmapPixelPtr(dst, xDst, yDst);
    657671    PixelSrc := Src.ScanLine[ySrc] + xSrc;
    658672    for i := 0 to w - 1 do
    659673    begin
    660674      Brightness := PixelSrc^;
    661       test := (PixelDst[2] * Brightness) shr 7;
     675      test := (PixelDst^.R * Brightness) shr 7;
     676      if test >= 256 then PixelDst^.R := 255
     677        else PixelDst^.R := test; // Red
     678      test := (PixelDst^.G * Brightness) shr 7;
     679      if test >= 256 then PixelDst^.G := 255
     680        else PixelDst^.G := test; // Green
     681      test := (PixelDst^.B * Brightness) shr 7;
    662682      if test >= 256 then
    663         PixelDst[2] := 255
     683        PixelDst^.R := 255
    664684      else
    665         PixelDst[2] := test; // Red
    666       test := (PixelDst[1] * Brightness) shr 7;
    667       if test >= 256 then
    668         PixelDst[1] := 255
    669       else
    670         PixelDst[1] := test; // Green
    671       test := (PixelDst[0] * Brightness) shr 7;
    672       if test >= 256 then
    673         PixelDst[2] := 255
    674       else
    675         PixelDst[0] := test; // Blue
    676       PixelDst := Pointer(PixelDst) + 3;
     685        PixelDst^.B := test; // Blue
     686      PixelDst := Pointer(PixelDst) + (Dst.RawImage.Description.BitsPerPixel shr 3);
    677687      PixelSrc := Pointer(PixelSrc) + 1;
    678688    end;
     
    690700// G channel = Color1 amp, 128=original brightness
    691701// R channel = Color2 amp, 128=original brightness
    692 type
    693   TLine = array [0 .. 9999, 0 .. 2] of Byte;
    694702var
    695703  ix, iy, amp1, amp2, trans, Value: integer;
    696   SrcLine, DstLine: ^TLine;
     704  SrcPixel, DstPixel: PPixel32;
    697705begin
    698706  if xDst < 0 then begin
     
    717725  for iy := 0 to h - 1 do
    718726  begin
    719     SrcLine := Src.ScanLine[ySrc + iy];
    720     DstLine := dst.ScanLine[yDst + iy];
    721727    for ix := 0 to w - 1 do
    722728    begin
    723       trans := SrcLine[xSrc + ix, 0] * 2; // green channel = transparency
    724       amp1 := SrcLine[xSrc + ix, 1] * 2;
    725       amp2 := SrcLine[xSrc + ix, 2] * 2;
     729      SrcPixel := GetBitmapPixelPtr(Src, xSrc + ix, ySrc + iy);
     730      DstPixel := GetBitmapPixelPtr(Dst, xDst + ix, yDst + iy);
     731      trans := SrcPixel^.B * 2; // green channel = transparency
     732      amp1 := SrcPixel^.G * 2;
     733      amp2 := SrcPixel^.R * 2;
    726734      if trans <> $FF then
    727735      begin
    728         Value := (DstLine[xDst + ix][0] * trans + ((Color2 shr 16) and $FF) * amp2
     736        Value := (DstPixel^.B * trans + ((Color2 shr 16) and $FF) * amp2
    729737          + ((Color1 shr 16) and $FF) * amp1) div $FF;
    730         if Value < 256 then
    731           DstLine[xDst + ix][0] := Value
    732         else
    733           DstLine[xDst + ix][0] := 255;
    734         Value := (DstLine[xDst + ix][1] * trans + ((Color2 shr 8) and $FF) * amp2
     738        if Value < 256 then DstPixel^.B := Value
     739        else DstPixel^.B := 255;
     740        Value := (DstPixel^.G * trans + ((Color2 shr 8) and $FF) * amp2
    735741          + ((Color1 shr 8) and $FF) * amp1) div $FF;
    736         if Value < 256 then
    737           DstLine[xDst + ix][1] := Value
    738         else
    739           DstLine[xDst + ix][1] := 255;
    740         Value := (DstLine[xDst + ix][2] * trans + (Color2 and $FF) * amp2 +
     742        if Value < 256 then DstPixel^.G := Value
     743          else DstPixel^.G := 255;
     744        Value := (DstPixel^.R * trans + (Color2 and $FF) * amp2 +
    741745          (Color1 and $FF) * amp1) div $FF;
    742         if Value < 256 then
    743           DstLine[xDst + ix][2] := Value
    744         else
    745           DstLine[xDst + ix][2] := 255;
    746       end
    747     end
     746        if Value < 256 then DstPixel^.R := Value
     747          else DstPixel^.R := 255;
     748      end;
     749    end;
    748750  end;
    749751  Src.EndUpdate;
     
    757759// G channel = Color1 amp, 128=original brightness
    758760// R channel = Color2 amp, 128=original brightness
    759 type
    760   TPixel = array [0 .. 2] of Byte;
    761761var
    762762  i, Red, Green: integer;
    763   Pixel: ^TPixel;
     763  Pixel: PPixel32;
    764764begin
    765765  bmp.BeginUpdate;
     
    768768  while y < h do
    769769  begin
    770     Pixel := pointer(bmp.ScanLine[y]) + 3 * x;
     770    Pixel := GetBitmapPixelPtr(Bmp, x, y);
    771771    for i := 0 to w - 1 do
    772772    begin
    773       Red := ((Pixel[0] * (Color0 and $0000FF) + Pixel[1] * (Color1 and $0000FF)
    774         + Pixel[2] * (Color2 and $0000FF)) shr 8) and $ff;
    775       Green := ((Pixel[0] * (Color0 shr 8 and $0000FF) + Pixel[1] *
    776         ((Color1 shr 8) and $0000FF) + Pixel[2] * ((Color2 shr 8) and
     773      Red := ((Pixel^.B * (Color0 and $0000FF) + Pixel^.G * (Color1 and $0000FF)
     774        + Pixel^.R * (Color2 and $0000FF)) shr 8) and $ff;
     775      Green := ((Pixel^.B * ((Color0 shr 8) and $0000FF) + Pixel^.G *
     776        ((Color1 shr 8) and $0000FF) + Pixel^.R * ((Color2 shr 8) and
    777777        $0000FF)) shr 8) and $ff;
    778       Pixel[0] := ((Pixel[0] * (Color0 shr 16 and $0000FF) + Pixel[1] *
    779         ((Color1 shr 16) and $0000FF) + Pixel[2] * ((Color2 shr 16) and $0000FF))
     778      Pixel^.B := ((Pixel^.B * ((Color0 shr 16) and $0000FF) + Pixel^.G *
     779        ((Color1 shr 16) and $0000FF) + Pixel^.R * ((Color2 shr 16) and $0000FF))
    780780        shr 8) and $ff; // Blue
    781       Pixel[1] := Green;
    782       Pixel[2] := Red;
    783       Pixel := pointer(Pixel) + 3;
     781      Pixel^.G := Green;
     782      Pixel^.R := Red;
     783      Pixel := pointer(Pixel) + (Bmp.RawImage.Description.BitsPerPixel shr 3);
    784784    end;
    785785    inc(y);
  • trunk/Start.pas

    r41 r46  
    55
    66uses
    7   GameServer, Messg, ButtonBase, ButtonA, ButtonC, ButtonB, Area,
    8 
    9   LCLIntf, LCLType, LMessages, Messages, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls,
     7  GameServer, Messg, ButtonBase, ButtonA, ButtonC, ButtonB, Area, Math,
     8  LCLIntf, LCLType, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls,
    109  Menus, Registry;
    1110
     
    451450    BiColorTextOut(Canvas, Colors.Canvas.Pixels[clkAge0 - 1, cliDimmedText],
    452451      $000000, xAction, y + 21, Phrases2.Lookup(TextItem));
    453     BitBlt(LogoBuffer.Canvas.Handle, 0, 0, 50, 50, Canvas.Handle,
     452    BitBltCanvas(LogoBuffer.Canvas, 0, 0, 50, 50, Canvas,
    454453      xActionIcon - 2, y - 2, SRCCOPY);
    455454    GlowFrame(LogoBuffer, 8, 8, 34, 34, $202020);
     
    566565          h := ClientHeight - ActionBottomBorder -
    567566            (yAction + SelectedAction * ActionPitch - 8);
    568         BitBlt(LogoBuffer.Canvas.Handle, 0, 0, w, h, Canvas.Handle,
     567        BitBltCanvas(LogoBuffer.Canvas, 0, 0, w, h, Canvas,
    569568          ActionSideBorder + i * wBuffer, yAction + SelectedAction * ActionPitch
    570569          - 8, SRCCOPY);
     
    822821
    823822procedure TStartDlg.FormShow(Sender: TObject);
    824 type
    825   TLine = array [0 .. 99999999] of Byte;
    826 var
    827   i, x, y: integer;
    828   PictureLine: ^TLine;
     823var
     824  x, y: integer;
     825  PicturePixel: PPixel32;
    829826begin
    830827  SetMainTextureByAge(-1);
     
    836833  for y := 0 to 63 do
    837834  begin // darken texture for empty slot
    838     PictureLine := EmptyPicture.ScanLine[y];
    839     for x := 0 to 64 * 3 - 1 do
    840     begin
    841       i := integer(PictureLine[x]) - 28;
    842       if i < 0 then
    843         i := 0;
    844       PictureLine[x] := i;
     835    for x := 0 to 64 - 1 do
     836    begin
     837      PicturePixel := GetBitmapPixelPtr(EmptyPicture, x, y);
     838      PicturePixel^.B := Max(PicturePixel^.B - 28, 0);
     839      PicturePixel^.G := Max(PicturePixel^.G - 28, 0);
     840      PicturePixel^.R := Max(PicturePixel^.R - 28, 0);
    845841    end
    846842  end;
     
    10041000
    10051001  procedure PaintRandomMini(Brightness: integer);
    1006   type
    1007     TLine = array [0 .. lxmax * 2, 0 .. 2] of Byte;
    10081002  var
    10091003    i, x, y, xm, cm: integer;
    1010     MiniLine: ^TLine;
     1004    MiniPixel: PPixel32;
    10111005    Map: ^TTileList;
    10121006  begin
     
    10161010
    10171011    Mini.PixelFormat := pf24bit;
    1018     Mini.width := MiniWidth * 2;
    1019     Mini.height := MiniHeight;
     1012    Mini.SetSize(MiniWidth * 2, MiniHeight);
    10201013    Mini.BeginUpdate;
    1021     for y := 0 to MiniHeight - 1 do
    1022     begin
    1023       MiniLine := Mini.ScanLine[y];
    1024       for x := 0 to MiniWidth - 1 do
    1025         for i := 0 to 1 do
    1026         begin
     1014    for y := 0 to MiniHeight - 1 do begin
     1015      for x := 0 to MiniWidth - 1 do begin
     1016        for i := 0 to 1 do begin
    10271017          xm := (x * 2 + i + y and 1) mod (MiniWidth * 2);
     1018          MiniPixel := GetBitmapPixelPtr(Mini, xm, y);
    10281019          cm := MiniColors
    10291020            [Map[x * lxmax div MiniWidth + lxmax *
    10301021            ((y * (lymax - 1) + MiniHeight div 2) div (MiniHeight - 1))] and
    10311022            fTerrain, i];
    1032           MiniLine[xm, 0] := cm shr 16 * Brightness div 3;
    1033           MiniLine[xm, 1] := cm shr 8 and $FF * Brightness div 3;
    1034           MiniLine[xm, 2] := cm and $FF * Brightness div 3;
     1023          MiniPixel^.B := ((cm shr 16) and $FF) * Brightness div 3;
     1024          MiniPixel^.G := ((cm shr 8) and $FF) * Brightness div 3;
     1025          MiniPixel^.R := ((cm shr 0) and $FF) * Brightness div 3;
    10351026        end;
     1027      end;
    10361028    end;
    10371029    Mini.EndUpdate;
Note: See TracChangeset for help on using the changeset viewer.