Ignore:
Timestamp:
Nov 5, 2018, 12:05:53 AM (6 years ago)
Author:
chronos
Message:
  • Fixed: Problem with offscreen bitmap handle causing to not show extra map objects on city map.
  • Modified: Added named constants for positions of terrain images.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/LocalPlayer/IsoEngine.pas

    r73 r150  
    1111type
    1212  TInitEnemyModelEvent = function(emix: integer): boolean;
     13
     14  { TIsoMap }
    1315
    1416  TIsoMap = class
     
    2931    procedure AttackEnd;
    3032
     33  private
     34    procedure CityGrid(xm, ym: integer; CityAllowClick: Boolean);
     35    function IsShoreTile(Loc: integer): boolean;
     36    procedure MakeDark(Line: PPixelPointer; Length: Integer);
     37    procedure ShadeOutside(x0, y0, x1, y1, xm, ym: integer);
    3138  protected
    3239    FOutput: TBitmap;
    3340    FLeft, FTop, FRight, FBottom, RealTop, RealBottom, AttLoc, DefLoc,
    3441      DefHealth, FAdviceLoc: integer;
    35     OutDC, DataDC, MaskDC: HDC;
     42    DataDC, MaskDC: HDC;
    3643    function Connection4(Loc, Mask, Value: integer): integer;
    3744    function Connection8(Loc, Mask: integer): integer;
     
    7986  ShoreDither = fGrass;
    8087  TerrainIconLines = 21;
     88  TerrainIconCols = 9;
     89
     90  // sprites indexes
     91  spDeadLands = 2 * TerrainIconCols + 6;
     92  spBlink1 = 1 * TerrainIconCols + 8;
     93  spBlink2 = 2 * TerrainIconCols + 8;
     94  spPrefStartPos = 1 * TerrainIconCols;
     95  spStartPos = 2 * TerrainIconCols;
     96  spPlain = 2 * TerrainIconCols + 7;
     97  spForest = 3 * TerrainIconCols;
     98  spRoad = 9 * TerrainIconCols;
     99  spRailRoad = 10 * TerrainIconCols;
     100  spCanal = 11 * TerrainIconCols;
     101  spIrrigation = 12 * TerrainIconCols;
     102  spFarmLand = 12 * TerrainIconCols + 1;
     103  spMine = 12 * TerrainIconCols + 2;
     104  spFortFront = 12 * TerrainIconCols + 3;
     105  spBase = 12 * TerrainIconCols + 4;
     106  spSpacePort = 12 * TerrainIconCols + 5;
     107  spPollution = 12 * TerrainIconCols + 6;
     108  spFortBack = 12 * TerrainIconCols + 7;
     109  spRiver = 13 * TerrainIconCols;
     110  spJungle = 18 * TerrainIconCols;
    81111
    82112var
     
    531561    exit;
    532562
    533   LCLIntf.BitBlt(OutDC, xDst, yDst, Width, Height, MaskDC, xSrc, ySrc, SRCAND);
     563  LCLIntf.BitBlt(FOutput.Canvas.Handle, xDst, yDst, Width, Height, MaskDC, xSrc, ySrc, SRCAND);
    534564  if not PureBlack then
    535     LCLIntf.BitBlt(OutDC, xDst, yDst, Width, Height, DataDC, xSrc, ySrc,
     565    LCLIntf.BitBlt(FOutput.Canvas.Handle, xDst, yDst, Width, Height, DataDC, xSrc, ySrc,
    536566      SRCPAINT);
    537567end;
     
    590620      if Flags and unFortified <> 0 then
    591621      begin
    592         { OutDC:=FOutput.Canvas.Handle;
    593           DataDC:=GrExt[HGrTerrain].Data.Canvas.Handle;
     622        { DataDC:=GrExt[HGrTerrain].Data.Canvas.Handle;
    594623          MaskDC:=GrExt[HGrTerrain].Mask.Canvas.Handle;
    595624          TSprite(x,y+16,12*9+7); }
     
    829858    yLoc := Loc div G.lx;
    830859    if IsJungle(yLoc) then
    831       yGr := 18
     860      yGr := spJungle
    832861    else
    833       yGr := 3;
     862      yGr := spForest;
    834863    Conn := Connection4(Loc, fTerrain, Tile and fTerrain);
    835864    if (yLoc = (G.ly - 2) div 4) or (G.ly - 1 - yLoc = (G.ly + 2) div 4) then
     
    838867    then
    839868      Conn := Conn and not 9; // no connection to north
    840     TSprite(x, y, Conn mod 8 + (yGr + Conn div 8) * 9);
     869    TSprite(x, y, yGr + Conn mod 8 + (Conn div 8) * TerrainIconCols);
    841870  end
    842871  else if Tile and fTerrain in [fHills, fMountains, fForest] then
     
    844873    yGr := 3 + 2 * (Tile and fTerrain - fForest);
    845874    Conn := Connection4(Loc, fTerrain, Tile and fTerrain);
    846     TSprite(x, y, Conn mod 8 + (yGr + Conn div 8) * 9);
     875    TSprite(x, y, Conn mod 8 + (yGr + Conn div 8) * TerrainIconCols);
    847876  end
    848877  else if Tile and fDeadLands <> 0 then
    849     TSprite(x, y, 2 * 9 + 6);
     878    TSprite(x, y, spDeadLands);
    850879
    851880  if ShowObjects then
    852881  begin
    853882    if Tile and fTerImp = tiFarm then
    854       TSprite(x, y, 109) { farmland }
     883      TSprite(x, y, spFarmLand)
    855884    else if Tile and fTerImp = tiIrrigation then
    856       TSprite(x, y, 108); // irrigation
     885      TSprite(x, y, spIrrigation);
    857886  end;
    858887  if Tile and fRiver <> 0 then
     
    861890      Connection4(Loc, fTerrain, fShore) or Connection4(Loc, fTerrain,
    862891      fUNKNOWN);
    863     TSprite(x, y, Conn mod 8 + (13 + Conn div 8) * 9);
     892    TSprite(x, y, spRiver + Conn mod 8 + (Conn div 8) * TerrainIconCols);
    864893  end;
    865894
     
    869898    for Dir := 0 to 3 do
    870899      if Conn and (1 shl Dir) <> 0 then { river mouths }
    871         TSprite(x, y, 15 * 9 + Dir);
     900        TSprite(x, y, 15 * TerrainIconCols + Dir);
    872901    if ShowObjects then
    873902    begin
     
    875904      for Dir := 0 to 7 do
    876905        if Conn and (1 shl Dir) <> 0 then { canal mouths }
    877           TSprite(x, y, 20 * 9 + 1 + Dir);
     906          TSprite(x, y, 20 * TerrainIconCols + 1 + Dir);
    878907    end
    879908  end;
     
    889918      begin
    890919        if Tile and fCanal <> 0 then
    891           TSprite(x, y, 99)
     920          TSprite(x, y, spCanal)
    892921      end
    893922      else
    894923        for Dir := 0 to 7 do
    895924          if (1 shl Dir) and Conn <> 0 then
    896             TSprite(x, y, 100 + Dir);
     925            TSprite(x, y, spCanal + 1 + Dir);
    897926    end;
    898927    if Tile and (fRR or fCity) <> 0 then
     
    904933      Conn := Connection8(Loc, fRoad or fRR or fCity) and not RRConn;
    905934      if (Conn = 0) and (Tile and (fRR or fCity) = 0) then
    906         TSprite(x, y, 81)
     935        TSprite(x, y, spRoad)
    907936      else if Conn > 0 then
    908937        for Dir := 0 to 7 do
    909938          if (1 shl Dir) and Conn <> 0 then
    910             TSprite(x, y, 82 + Dir);
     939            TSprite(x, y, spRoad + 1 + Dir);
    911940    end;
    912941    // paint railroad connections
    913942    if (Tile and fRR <> 0) and (RRConn = 0) then
    914       TSprite(x, y, 90)
     943      TSprite(x, y, spRailRoad)
    915944    else if RRConn > 0 then
    916945      for Dir := 0 to 7 do
    917946        if (1 shl Dir) and RRConn <> 0 then
    918           TSprite(x, y, 91 + Dir);
     947          TSprite(x, y, spRailRoad + 1 + Dir);
    919948  end;
    920949end;
     
    928957  UnitInfo: TUnitInfo;
    929958  fog: boolean;
     959  SpecialRow: Integer;
     960  SpecialCol: Integer;
    930961
    931962  procedure NameCity;
     
    960991    if ShowObjects and (Options and (1 shl moEditMode) = 0) and
    961992      (Tile and fCity <> 0) and (CityInfo.Flags and ciSpacePort <> 0) then
    962       TSprite(x + xxt, y - 6, 12 * 9 + 5);
     993      TSprite(x + xxt, y - 6, spSpacePort);
    963994  end;
    964995
     
    10501081
    10511082  if (Loc >= 0) and (Loc < G.lx * G.ly) and (Loc = FAdviceLoc) then
    1052     TSprite(x, y, 7 + 9 * 2);
     1083    TSprite(x, y, spPlain);
    10531084
    10541085  if (Loc >= 0) and (Loc < G.lx * G.ly) and (Tile and fSpecial <> 0)
    1055   then { special ressources }
     1086  then { special resources }
    10561087  begin
    10571088    dy := Loc div G.lx;
    1058     if Tile and fTerrain < fForest then
    1059       TSprite(x, y, Tile and fTerrain + (Tile and fSpecial shr 5) * 9)
    1060     else if (Tile and fTerrain = fForest) and IsJungle(dy) then
    1061       TSprite(x, y, 8 + 17 * 9 + (Tile and fSpecial shr 5) * 9)
     1089    SpecialCol := Tile and fTerrain;
     1090    SpecialRow := Tile and fSpecial shr 5;
     1091    if SpecialCol < fForest then
     1092      TSprite(x, y, SpecialCol + SpecialRow * TerrainIconCols)
     1093    else if (SpecialCol = fForest) and IsJungle(dy) then
     1094      TSprite(x, y, 8 + 17 * TerrainIconCols + SpecialRow * TerrainIconCols)
    10621095    else
    1063       TSprite(x, y, 8 + 2 * 9 + ((Tile and fTerrain - fForest) * 2 + Tile and
    1064         fSpecial shr 5) * 9);
     1096      TSprite(x, y, 8 + 2 * TerrainIconCols + (SpecialCol - fForest) * 2 + SpecialRow * TerrainIconCols);
    10651097  end;
    10661098
     
    10681100  begin
    10691101    if Tile and fTerImp = tiMine then
    1070       TSprite(x, y, 2 + 9 * 12);
     1102      TSprite(x, y, spMine);
    10711103    if Tile and fTerImp = tiBase then
    1072       TSprite(x, y, 4 + 9 * 12);
     1104      TSprite(x, y, spBase);
    10731105    if Tile and fPoll <> 0 then
    1074       TSprite(x, y, 6 + 9 * 12);
     1106      TSprite(x, y, spPollution);
    10751107    if Tile and fTerImp = tiFort then
    10761108    begin
    1077       TSprite(x, y, 7 + 9 * 12);
     1109      TSprite(x, y, spFortBack);
    10781110      if Tile and fObserved = 0 then
    1079         TSprite(x, y, 3 + 9 * 12);
     1111        TSprite(x, y, spFortFront);
    10801112    end;
    10811113  end;
    10821114  if Tile and fDeadLands <> 0 then
    1083     TSprite(x, y, (12 + Tile shr 25 and 3) * 9 + 8);
     1115    TSprite(x, y, (12 + Tile shr 25 and 3) * TerrainIconCols + 8);
    10841116
    10851117  if Options and (1 shl moEditMode) <> 0 then
     
    10991131        1 + yyt + 15 * (yyt * 3 + 1))
    11001132    else
    1101       TSprite(x, y, 6 + 9 * 15, xxt <> 33);
     1133      TSprite(x, y, 6 + TerrainIconCols * 15, xxt <> 33);
    11021134
    11031135  if FoW and (Tile and fObserved = 0) then
     
    11121144    if (Destination = Loc) and (Destination <> MyUn[UnFocus].Loc) then
    11131145      if not UseBlink or BlinkOn then
    1114         TSprite(x, y, 8 + 9 * 1)
     1146        TSprite(x, y, spBlink1)
    11151147      else
    1116         TSprite(x, y, 8 + 9 * 2)
     1148        TSprite(x, y, spBlink2)
    11171149  end;
    11181150{$ENDIF}
     
    11201152  begin
    11211153    if Tile and fPrefStartPos <> 0 then
    1122       TSprite(x, y, 0 + 9 * 1)
     1154      TSprite(x, y, spPrefStartPos)
    11231155    else if Tile and fStartPos <> 0 then
    1124       TSprite(x, y, 0 + 9 * 2);
     1156      TSprite(x, y, spStartPos);
    11251157  end
    11261158  else if ShowObjects then
     
    11791211  if ShowObjects and (Tile and fTerImp = tiFort) and (Tile and fObserved <> 0)
    11801212  then
    1181     TSprite(x, y, 3 + 9 * 12);
     1213    TSprite(x, y, spFortFront);
    11821214
    11831215  if (Loc >= 0) and (Loc < G.lx * G.ly) then
     
    12691301end;
    12701302
     1303function TIsoMap.IsShoreTile(Loc: integer): boolean;
     1304const
     1305  Dirx: array [0 .. 7] of integer = (1, 2, 1, 0, -1, -2, -1, 0);
     1306  Diry: array [0 .. 7] of integer = (-1, 0, 1, 2, 1, 0, -1, -2);
     1307var
     1308  Dir, ConnLoc: integer;
     1309begin
     1310  result := false;
     1311  for Dir := 0 to 7 do
     1312  begin
     1313    ConnLoc := dLoc(Loc, Dirx[Dir], Diry[Dir]);
     1314    if (ConnLoc < 0) or (ConnLoc >= G.lx * G.ly) or
     1315      ((MyMap[ConnLoc] - 2) and fTerrain < 13) then
     1316      result := true
     1317  end
     1318end;
     1319
     1320procedure TIsoMap.MakeDark(Line: PPixelPointer; Length: Integer);
     1321var
     1322  I: Integer;
     1323begin
     1324  for I := 0 to Length - 1 do begin
     1325    Line^.Pixel^.B := (Line^.Pixel^.B shr 1) and $7f;
     1326    Line^.Pixel^.G := (Line^.Pixel^.G shr 1) and $7f;
     1327    Line^.Pixel^.R := (Line^.Pixel^.R shr 1) and $7f;
     1328    Line^.NextPixel;
     1329  end;
     1330end;
     1331
     1332procedure TIsoMap.ShadeOutside(x0, y0, x1, y1, xm, ym: integer);
     1333const
     1334  rShade = 3.75;
     1335var
     1336  y, wBright: integer;
     1337  y_n, w_n: single;
     1338  Line: TPixelPointer;
     1339begin
     1340  FOutput.BeginUpdate;
     1341  for y := y0 to y1 - 1 do begin
     1342    Line.Init(FOutput, 0, y);
     1343    y_n := (y - ym) / yyt;
     1344    if abs(y_n) < rShade then begin
     1345      // Darken left and right parts of elipsis
     1346      w_n := sqrt(sqr(rShade) - sqr(y_n));
     1347      wBright := trunc(w_n * xxt + 0.5);
     1348      Line.SetX(x0);
     1349      MakeDark(@Line, xm - x0 - wBright);
     1350      Line.SetX(xm + wBright);
     1351      MakeDark(@Line, x1 - xm - wBright);
     1352    end else begin
     1353      // Darken entire line
     1354      Line.SetX(x0);
     1355      MakeDark(@Line, x1 - x0);
     1356    end;
     1357  end;
     1358  FOutput.EndUpdate;
     1359end;
     1360
     1361procedure TIsoMap.CityGrid(xm, ym: integer; CityAllowClick: Boolean);
     1362var
     1363  i: integer;
     1364begin
     1365  with FOutput.Canvas do
     1366  begin
     1367    if CityAllowClick then
     1368      pen.Color := $FFFFFF
     1369    else
     1370      pen.Color := $000000;
     1371    pen.Width := 1;
     1372    for i := 0 to 3 do
     1373    begin
     1374      moveto(xm - xxt * (4 - i), ym + yyt * (1 + i));
     1375      lineto(xm + xxt * (1 + i), ym - yyt * (4 - i));
     1376      moveto(xm - xxt * (4 - i), ym - yyt * (1 + i));
     1377      lineto(xm + xxt * (1 + i), ym + yyt * (4 - i));
     1378    end;
     1379    moveto(xm - xxt * 4, ym + yyt * 1);
     1380    lineto(xm - xxt * 1, ym + yyt * 4);
     1381    moveto(xm + xxt * 1, ym + yyt * 4);
     1382    lineto(xm + xxt * 4, ym + yyt * 1);
     1383    moveto(xm - xxt * 4, ym - yyt * 1);
     1384    lineto(xm - xxt * 1, ym - yyt * 4);
     1385    moveto(xm + xxt * 1, ym - yyt * 4);
     1386    lineto(xm + xxt * 4, ym - yyt * 1);
     1387    pen.Width := 1;
     1388  end
     1389end;
     1390
    12711391procedure TIsoMap.Paint(x, y, Loc, nx, ny, CityLoc, CityOwner: integer;
    12721392  UseBlink: boolean; CityAllowClick: boolean);
    1273 
    1274   function IsShoreTile(Loc: integer): boolean;
    1275   const
    1276     Dirx: array [0 .. 7] of integer = (1, 2, 1, 0, -1, -2, -1, 0);
    1277     Diry: array [0 .. 7] of integer = (-1, 0, 1, 2, 1, 0, -1, -2);
    1278   var
    1279     Dir, ConnLoc: integer;
    1280   begin
    1281     result := false;
    1282     for Dir := 0 to 7 do
    1283     begin
    1284       ConnLoc := dLoc(Loc, Dirx[Dir], Diry[Dir]);
    1285       if (ConnLoc < 0) or (ConnLoc >= G.lx * G.ly) or
    1286         ((MyMap[ConnLoc] - 2) and fTerrain < 13) then
    1287         result := true
    1288     end
    1289   end;
    1290 
    1291   procedure ShadeOutside(x0, y0, x1, y1, xm, ym: integer);
    1292 
    1293     procedure MakeDark(Line: PPixelPointer; Length: Integer);
    1294     var
    1295       I: Integer;
    1296     begin
    1297       for I := 0 to Length - 1 do begin
    1298         Line^.Pixel^.B := (Line^.Pixel^.B shr 1) and $7f;
    1299         Line^.Pixel^.G := (Line^.Pixel^.G shr 1) and $7f;
    1300         Line^.Pixel^.R := (Line^.Pixel^.R shr 1) and $7f;
    1301         Line^.NextPixel;
    1302       end;
    1303     end;
    1304 
    1305   const
    1306     rShade = 3.75;
    1307   var
    1308     y, wBright: integer;
    1309     y_n, w_n: single;
    1310     Line: TPixelPointer;
    1311   begin
    1312     FOutput.BeginUpdate;
    1313     for y := y0 to y1 - 1 do begin
    1314       Line.Init(FOutput, 0, y);
    1315       y_n := (y - ym) / yyt;
    1316       if abs(y_n) < rShade then begin
    1317         // Darken left and right parts of elipsis
    1318         w_n := sqrt(sqr(rShade) - sqr(y_n));
    1319         wBright := trunc(w_n * xxt + 0.5);
    1320         Line.SetX(x0);
    1321         MakeDark(@Line, xm - x0 - wBright);
    1322         Line.SetX(xm + wBright);
    1323         MakeDark(@Line, x1 - xm - wBright);
    1324       end else begin
    1325         // Darken entire line
    1326         Line.SetX(x0);
    1327         MakeDark(@Line, x1 - x0);
    1328       end;
    1329     end;
    1330     FOutput.EndUpdate;
    1331   end;
    1332 
    1333   procedure CityGrid(xm, ym: integer);
    1334   var
    1335     i: integer;
    1336   begin
    1337     with FOutput.Canvas do
    1338     begin
    1339       if CityAllowClick then
    1340         pen.Color := $FFFFFF
    1341       else
    1342         pen.Color := $000000;
    1343       pen.Width := 1;
    1344       for i := 0 to 3 do
    1345       begin
    1346         moveto(xm - xxt * (4 - i), ym + yyt * (1 + i));
    1347         lineto(xm + xxt * (1 + i), ym - yyt * (4 - i));
    1348         moveto(xm - xxt * (4 - i), ym - yyt * (1 + i));
    1349         lineto(xm + xxt * (1 + i), ym + yyt * (4 - i));
    1350       end;
    1351       moveto(xm - xxt * 4, ym + yyt * 1);
    1352       lineto(xm - xxt * 1, ym + yyt * 4);
    1353       moveto(xm + xxt * 1, ym + yyt * 4);
    1354       lineto(xm + xxt * 4, ym + yyt * 1);
    1355       moveto(xm - xxt * 4, ym - yyt * 1);
    1356       lineto(xm - xxt * 1, ym - yyt * 4);
    1357       moveto(xm + xxt * 1, ym - yyt * 4);
    1358       lineto(xm + xxt * 4, ym - yyt * 1);
    1359       pen.Width := 1;
    1360     end
    1361   end;
    1362 
    13631393var
    13641394  dx, dy, xm, ym, ALoc, BLoc, ATer, BTer, Aix, bix: integer;
     
    15181548      end;
    15191549
    1520   OutDC := FOutput.Canvas.Handle;
    15211550  DataDC := GrExt[HGrTerrain].Data.Canvas.Handle;
    15221551  MaskDC := GrExt[HGrTerrain].Mask.Canvas.Handle;
     
    15481577    ym := y + (dy + 1) * yyt + yyt;
    15491578    ShadeOutside(FLeft, FTop, FRight, FBottom, xm, ym);
    1550     CityGrid(xm, ym);
     1579    CityGrid(xm, ym, CityAllowClick);
    15511580    for dy := -2 to ny + 1 do
    15521581      for dx := -2 to nx + 1 do
Note: See TracChangeset for help on using the changeset viewer.