Ignore:
Timestamp:
Apr 6, 2021, 8:11:02 PM (3 years ago)
Author:
chronos
Message:
  • Modified: Merged trunk branch version r348 into highdpi branch.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/highdpi/LocalPlayer/IsoEngine.pas

    r303 r349  
    55
    66uses
    7   UDpiControls, Protocol, ClientTools, ScreenTools, Tribes, {$IFNDEF SCR}Term, {$ENDIF}
    8   LCLIntf, LCLType, SysUtils, Classes, Graphics, UPixelPointer;
     7  UDpiControls, Protocol, ClientTools, ScreenTools, Tribes,
     8  LCLIntf, LCLType, SysUtils, Classes, Graphics, UPixelPointer, UGraphicSet;
     9
     10const
     11  TerrainIconLines = 21;
     12  TerrainIconCols = 9;
    913
    1014type
    1115  TInitEnemyModelEvent = function(emix: integer): boolean;
     16  TTileSize = (tsSmall, tsMedium, tsBig);
     17
     18  TTerrainSpriteSize = array of TRect;
     19
     20  { TCitiesPictures }
     21
     22  TCitiesPictures = class
     23    Pictures: array [2..3, 0..3] of TCityPicture;
     24    procedure Prepare(HGrCities: TGraphicSet; xxt, yyt: Integer);
     25  end;
    1226
    1327  { TIsoMap }
    1428
    1529  TIsoMap = class
     30  private
     31    FTileSize: TTileSize;
     32    const
     33      Dirx: array [0..7] of Integer = (1, 2, 1, 0, -1, -2, -1, 0);
     34      Diry: array [0..7] of Integer = (-1, 0, 1, 2, 1, 0, -1, -2);
     35    procedure CityGrid(xm, ym: integer; CityAllowClick: Boolean);
     36    function IsShoreTile(Loc: integer): boolean;
     37    procedure MakeDark(Line: PPixelPointer; Length: Integer);
     38    procedure SetTileSize(AValue: TTileSize);
     39    procedure ShadeOutside(x0, y0, Width, Height, xm, ym: integer);
     40  protected
     41    FOutput: TDpiBitmap;
     42    FLeft: Integer;
     43    FTop: Integer;
     44    FRight: Integer;
     45    FBottom: Integer;
     46    RealTop: Integer;
     47    RealBottom: Integer;
     48    AttLoc: Integer;
     49    DefLoc: Integer;
     50    DefHealth: Integer;
     51    FAdviceLoc: Integer;
     52    DataCanvas: TDpiCanvas;
     53    MaskCanvas: TDpiCanvas;
     54    LandPatch: TDpiBitmap;
     55    OceanPatch: TDpiBitmap;
     56    Borders: TDpiBitmap;
     57    BordersOK: PInteger;
     58    CitiesPictures: TCitiesPictures;
     59    ShowLoc: Boolean;
     60    ShowCityNames: Boolean;
     61    ShowObjects: Boolean;
     62    ShowBorder: Boolean;
     63    ShowMyBorder: Boolean;
     64    ShowGrWall: Boolean;
     65    ShowDebug: Boolean;
     66    FoW: Boolean;
     67    function Connection4(Loc, Mask, Value: integer): integer;
     68    function Connection8(Loc, Mask: integer): integer;
     69    function OceanConnection(Loc: integer): integer;
     70    procedure PaintShore(x, y, Loc: integer);
     71    procedure PaintTileExtraTerrain(x, y, Loc: integer);
     72    procedure PaintTileObjects(x, y, Loc, CityLoc, CityOwner: integer;
     73      UseBlink: boolean);
     74    procedure PaintGrid(x, y, nx, ny: integer);
     75    procedure FillRect(x, y, Width, Height, Color: integer);
     76    procedure Textout(x, y, Color: integer; const s: string);
     77    procedure Sprite(HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
     78    procedure TSprite(xDst, yDst, grix: integer; PureBlack: boolean = false);
     79    procedure ApplyTileSize(ATileSize: TTileSize);
     80  public
     81    xxt: Integer; // half of tile size x/y
     82    yyt: Integer; // half of tile size x/y
     83    TSpriteSize: TTerrainSpriteSize;
     84    HGrTerrain: TGraphicSet;
     85    HGrCities: TGraphicSet;
     86    pDebugMap: Integer; // -1 for off
    1687    constructor Create;
     88    destructor Destroy; override;
     89    procedure Reset;
    1790    procedure SetOutput(Output: TDpiBitmap);
    1891    procedure SetPaintBounds(Left, Top, Right, Bottom: integer);
     
    2598    procedure BitBltBitmap(Src: TDpiBitmap; x, y, Width, Height, xSrc, ySrc,
    2699      Rop: integer);
    27 
    28100    procedure AttackBegin(const ShowMove: TShowMove);
    29101    procedure AttackEffect(const ShowMove: TShowMove);
    30102    procedure AttackEnd;
    31 
    32   private
    33     procedure CityGrid(xm, ym: integer; CityAllowClick: Boolean);
    34     function IsShoreTile(Loc: integer): boolean;
    35     procedure MakeDark(Line: PPixelPointer; Length: Integer);
    36     procedure ShadeOutside(x0, y0, Width, Height, xm, ym: integer);
    37   protected
    38     FOutput: TDpiBitmap;
    39     FLeft, FTop, FRight, FBottom, RealTop, RealBottom, AttLoc, DefLoc,
    40       DefHealth, FAdviceLoc: integer;
    41     DataCanvas: TDpiCanvas;
    42     MaskCanvas: TDpiCanvas;
    43     function Connection4(Loc, Mask, Value: integer): integer;
    44     function Connection8(Loc, Mask: integer): integer;
    45     function OceanConnection(Loc: integer): integer;
    46     procedure PaintShore(x, y, Loc: integer);
    47     procedure PaintTileExtraTerrain(x, y, Loc: integer);
    48     procedure PaintTileObjects(x, y, Loc, CityLoc, CityOwner: integer;
    49       UseBlink: boolean);
    50     procedure PaintGrid(x, y, nx, ny: integer);
    51     procedure FillRect(x, y, Width, Height, Color: integer);
    52     procedure Textout(x, y, Color: integer; const s: string);
    53     procedure Sprite(HGr, xDst, yDst, Width, Height, xGr, yGr: integer);
    54     procedure TSprite(xDst, yDst, grix: integer; PureBlack: boolean = false);
    55 
    56   public
     103    procedure ReduceTerrainIconsSize;
    57104    property AdviceLoc: integer read FAdviceLoc write FAdviceLoc;
     105    property TileSize: TTileSize read FTileSize write SetTileSize;
     106  end;
     107
     108  { TIsoMapCache }
     109
     110  TIsoMapCache = class
     111    LandPatch: TDpiBitmap;
     112    OceanPatch: TDpiBitmap;
     113    Borders: TDpiBitmap;
     114    BordersOk: Integer;
     115    TSpriteSize: TTerrainSpriteSize;
     116    HGrTerrain: TGraphicSet;
     117    HGrCities: TGraphicSet;
     118    CitiesPictures: TCitiesPictures;
     119    procedure AssignToIsoMap(IsoMap: TIsoMap);
     120    constructor Create;
     121    destructor Destroy; override;
    58122  end;
    59123
    60124const
    61   // options switched by buttons
    62   moPolitical = 0;
    63   moCityNames = 1;
    64   moGreatWall = 4;
    65   moGrid = 5;
    66   moBareTerrain = 6;
    67 
    68   // other options
    69   moEditMode = 16;
    70   moLocCodes = 17;
    71 
    72 var
    73   NoMap: TIsoMap;
    74   Options: integer;
    75   pDebugMap: integer; // -1 for off
     125  DefaultTileSize: TTileSize = tsMedium;
     126  TileSizes: array [TTileSize] of TPoint = ((X: 33; Y: 16), (X: 48; Y: 24),
     127    (X: 72; Y: 36));
    76128
    77129function IsJungle(y: integer): boolean;
    78130procedure Init(InitEnemyModelHandler: TInitEnemyModelEvent);
    79 function ApplyTileSize(xxtNew, yytNew: integer): boolean;
    80 procedure Done;
    81 procedure Reset;
     131
     132var
     133  MapOptions: TMapOptions;
     134
    82135
    83136implementation
     137
     138uses
     139  Term;
    84140
    85141const
    86142  ShoreDither = fGrass;
    87   TerrainIconLines = 21;
    88   TerrainIconCols = 9;
    89143
    90144  // sprites indexes
     
    115169
    116170var
    117   BordersOK: integer;
    118171  OnInitEnemyModel: TInitEnemyModelEvent;
    119   LandPatch, OceanPatch, Borders: TDpiBitmap;
    120   TSpriteSize: array [0 .. TerrainIconLines * 9 - 1] of TRect;
    121172  DebugMap: ^TTileList;
    122   CitiesPictures: array [2 .. 3, 0 .. 3] of TCityPicture;
    123   FoW, ShowLoc, ShowCityNames, ShowObjects, ShowBorder, ShowMyBorder,
    124     ShowGrWall, ShowDebug: boolean;
     173  IsoMapCache: array[TTileSize] of TIsoMapCache;
    125174
    126175function IsJungle(y: integer): boolean;
     
    132181begin
    133182  OnInitEnemyModel := InitEnemyModelHandler;
    134   if NoMap <> nil then
    135     FreeAndNil(NoMap);
    136   NoMap := TIsoMap.Create;
    137 end;
    138 
    139 function ApplyTileSize(xxtNew, yytNew: integer): boolean;
    140 var
    141   i, x, y, xSrc, ySrc, HGrTerrainNew, HGrCitiesNew, age, size: integer;
    142   LandMore, OceanMore, DitherMask, Mask24: TDpiBitmap;
    143   MaskLine: array [0 .. 50 * 3 - 1] of TPixelPointer; // 32 = assumed maximum for yyt
    144   Border: boolean;
    145 begin
    146   result := false;
    147   HGrTerrainNew := LoadGraphicSet(Format('Terrain%dx%d.png',
    148     [xxtNew * 2, yytNew * 2]));
    149   if HGrTerrainNew < 0 then
    150     exit;
    151   HGrCitiesNew := LoadGraphicSet(Format('Cities%dx%d.png',
    152     [xxtNew * 2, yytNew * 2]));
    153   if HGrCitiesNew < 0 then
    154     exit;
    155   xxt := xxtNew;
    156   yyt := yytNew;
    157   HGrTerrain := HGrTerrainNew;
    158   HGrCities := HGrCitiesNew;
    159   result := true;
    160 
     183end;
     184
     185{ TCitiesPictures }
     186
     187procedure TCitiesPictures.Prepare(HGrCities: TGraphicSet; xxt, yyt: Integer);
     188var
     189  Age: Integer;
     190  Size: Integer;
     191begin
    161192  // prepare age 2+3 cities
    162193  for age := 2 to 3 do
    163194    for size := 0 to 3 do
    164       with CitiesPictures[age, size] do
    165         FindPosition(HGrCities, size * (xxt * 2 + 1), (age - 2) * (yyt * 3 + 1),
     195      with Pictures[Age, Size] do
     196        FindPosition(HGrCities, Size * (xxt * 2 + 1), (Age - 2) * (yyt * 3 + 1),
    166197          xxt * 2 - 1, yyt * 3 - 1, $00FFFF, xShield, yShield);
    167 
    168   { prepare dithered ground tiles }
    169   if LandPatch <> nil then
    170     FreeAndNil(LandPatch);
     198end;
     199
     200{ TIsoMapCache }
     201
     202procedure TIsoMapCache.AssignToIsoMap(IsoMap: TIsoMap);
     203begin
     204  IsoMap.HGrTerrain := HGrTerrain;
     205  IsoMap.HGrCities := HGrCities;
     206  IsoMap.Borders := Borders;
     207  IsoMap.BordersOK := @BordersOk;
     208  IsoMap.LandPatch := LandPatch;
     209  IsoMap.OceanPatch := OceanPatch;
     210  IsoMap.TSpriteSize := TSpriteSize;
     211  IsoMap.CitiesPictures := CitiesPictures;
     212end;
     213
     214constructor TIsoMapCache.Create;
     215begin
    171216  LandPatch := TDpiBitmap.Create;
    172217  LandPatch.PixelFormat := pf24bit;
    173   LandPatch.Canvas.Brush.Color := 0;
    174   LandPatch.SetSize(xxt * 18, yyt * 9);
    175   LandPatch.Canvas.FillRect(0, 0, LandPatch.Width, LandPatch.Height);
    176   if OceanPatch <> nil then
    177     FreeAndNil(OceanPatch);
    178218  OceanPatch := TDpiBitmap.Create;
    179219  OceanPatch.PixelFormat := pf24bit;
    180   OceanPatch.Canvas.Brush.Color := 0;
    181   OceanPatch.SetSize(xxt * 8, yyt * 4);
    182   OceanPatch.Canvas.FillRect(0, 0, OceanPatch.Width, OceanPatch.Height);
    183   LandMore := TDpiBitmap.Create;
    184   LandMore.PixelFormat := pf24bit;
    185   LandMore.Canvas.Brush.Color := 0;
    186   LandMore.SetSize(xxt * 18, yyt * 9);
    187   LandMore.Canvas.FillRect(0, 0, LandMore.Width, LandMore.Height);
    188   OceanMore := TDpiBitmap.Create;
    189   OceanMore.PixelFormat := pf24bit;
    190   OceanMore.Canvas.Brush.Color := 0;
    191   OceanMore.SetSize(xxt * 8, yyt * 4);
    192   OceanMore.Canvas.FillRect(0, 0, OceanMore.Width, OceanMore.Height);
    193   DitherMask := TDpiBitmap.Create;
    194   DitherMask.PixelFormat := pf24bit;
    195   DitherMask.SetSize(xxt * 2, yyt * 2);
    196   DitherMask.Canvas.FillRect(0, 0, DitherMask.Width, DitherMask.Height);
    197   DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt * 2,
    198     GrExt[HGrTerrain].Mask.Canvas, 1 + 7 * (xxt * 2 + 1),
    199     1 + yyt + 15 * (yyt * 3 + 1), SRCAND);
    200 
    201   for x := -1 to 6 do
    202   begin
    203     if x = -1 then
    204     begin
    205       xSrc := ShoreDither * (xxt * 2 + 1) + 1;
    206       ySrc := 1 + yyt
    207     end
    208     else if x = 6 then
    209     begin
    210       xSrc := 1 + (xxt * 2 + 1) * 2;
    211       ySrc := 1 + yyt + (yyt * 3 + 1) * 2
    212     end
    213     else
    214     begin
    215       xSrc := (x + 2) * (xxt * 2 + 1) + 1;
    216       ySrc := 1 + yyt
    217     end;
    218     for y := -1 to 6 do
    219       DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
    220         xxt * 2, yyt, GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc);
    221     for y := -2 to 6 do
    222       DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt, xxt,
    223         yyt, GrExt[HGrTerrain].Data.Canvas, xSrc + xxt, ySrc + yyt,
    224         SRCPAINT);
    225     for y := -2 to 6 do
    226       DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2) + xxt, (y + 2) * yyt,
    227         xxt, yyt, GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc + yyt,
    228         SRCPAINT);
    229     for y := -2 to 6 do
    230       DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt, xxt,
    231         yyt, DitherMask.Canvas, xxt, yyt, SRCAND);
    232     for y := -2 to 6 do
    233       DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2) + xxt, (y + 2) * yyt,
    234         xxt, yyt, DitherMask.Canvas, 0, yyt, SRCAND);
    235   end;
    236 
    237   for y := -1 to 6 do
    238   begin
    239     if y = -1 then
    240     begin
    241       xSrc := ShoreDither * (xxt * 2 + 1) + 1;
    242       ySrc := 1 + yyt
    243     end
    244     else if y = 6 then
    245     begin
    246       xSrc := 1 + 2 * (xxt * 2 + 1);
    247       ySrc := 1 + yyt + 2 * (yyt * 3 + 1)
    248     end
    249     else
    250     begin
    251       xSrc := (y + 2) * (xxt * 2 + 1) + 1;
    252       ySrc := 1 + yyt
    253     end;
    254     for x := -2 to 6 do
    255       DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
    256         xxt * 2, yyt, GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc);
    257     DpiBitCanvas(LandMore.Canvas, xxt * 2, (y + 2) * yyt, xxt, yyt,
    258       GrExt[HGrTerrain].Data.Canvas, xSrc + xxt, ySrc + yyt, SRCPAINT);
    259     for x := 0 to 7 do
    260       DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2) - xxt, (y + 2) * yyt,
    261         xxt * 2, yyt, GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc + yyt,
    262         SRCPAINT);
    263     for x := -2 to 6 do
    264       DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
    265         xxt * 2, yyt, DitherMask.Canvas, 0, 0, SRCAND);
    266   end;
    267 
    268   for x := 0 to 3 do
    269     for y := 0 to 3 do
    270     begin
    271       if (x = 1) and (y = 1) then
    272         xSrc := 1
    273       else
    274         xSrc := (x mod 2) * (xxt * 2 + 1) + 1;
    275       ySrc := 1 + yyt;
    276       if (x >= 1) = (y >= 2) then
    277         DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
    278           GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc);
    279       if (x >= 1) and ((y < 2) or (x >= 2)) then
    280       begin
    281         DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt, yyt,
    282           GrExt[HGrTerrain].Data.Canvas, xSrc + xxt, ySrc + yyt,
    283           SRCPAINT);
    284         DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2) + xxt, y * yyt, xxt, yyt,
    285           GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc + yyt, SRCPAINT);
    286       end;
    287       DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt, yyt,
    288         DitherMask.Canvas, xxt, yyt, SRCAND);
    289       DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2) + xxt, y * yyt, xxt, yyt,
    290         DitherMask.Canvas, 0, yyt, SRCAND);
    291     end;
    292 
    293   for y := 0 to 3 do
    294     for x := 0 to 3 do
    295     begin
    296       if (x = 1) and (y = 1) then
    297         xSrc := 1
    298       else
    299         xSrc := (y mod 2) * (xxt * 2 + 1) + 1;
    300       ySrc := 1 + yyt;
    301       if (x < 1) or (y >= 2) then
    302         DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
    303           GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc);
    304       if (x = 1) and (y < 2) or (x >= 2) and (y >= 1) then
    305       begin
    306         DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2), y * yyt, xxt, yyt,
    307           GrExt[HGrTerrain].Data.Canvas, xSrc + xxt, ySrc + yyt,
    308           SRCPAINT);
    309         DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2) + xxt, y * yyt, xxt, yyt,
    310           GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc + yyt, SRCPAINT);
    311       end;
    312       DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
    313         DitherMask.Canvas, 0, 0, SRCAND);
    314     end;
    315 
    316   DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt * 2,
    317     DitherMask.Canvas, 0, 0, DSTINVERT); { invert dither mask }
    318   DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt * 2,
    319     GrExt[HGrTerrain].Mask.Canvas, 1, 1 + yyt, SRCPAINT);
    320 
    321   for x := -1 to 6 do
    322     for y := -2 to 6 do
    323       DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
    324         xxt * 2, yyt, DitherMask.Canvas, 0, 0, SRCAND);
    325 
    326   for y := -1 to 6 do
    327     for x := -2 to 7 do
    328       DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2) - xxt, (y + 2) * yyt,
    329         xxt * 2, yyt, DitherMask.Canvas, 0, yyt, SRCAND);
    330 
    331   DpiBitCanvas(LandPatch.Canvas, 0, 0, (xxt * 2) * 9, yyt * 9,
    332     LandMore.Canvas, 0, 0, SRCPAINT);
    333 
    334   for x := 0 to 3 do
    335     for y := 0 to 3 do
    336       DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
    337         DitherMask.Canvas, 0, 0, SRCAND);
    338 
    339   for y := 0 to 3 do
    340     for x := 0 to 4 do
    341       DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2) - xxt, y * yyt, xxt * 2,
    342         yyt, DitherMask.Canvas, 0, yyt, SRCAND);
    343 
    344   DpiBitCanvas(OceanPatch.Canvas, 0, 0, (xxt * 2) * 4, yyt * 4,
    345     OceanMore.Canvas, 0, 0, SRCPAINT);
    346 
    347   with DitherMask.Canvas do
    348   begin
    349     Brush.Color := $FFFFFF;
    350     FillRect(Rect(0, 0, xxt * 2, yyt));
    351   end;
    352   DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt,
    353     GrExt[HGrTerrain].Mask.Canvas, 1, 1 + yyt);
    354 
    355   for x := 0 to 6 do
    356     DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), yyt, xxt * 2, yyt,
    357       DitherMask.Canvas, 0, 0, SRCAND);
    358   DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt, DitherMask.Canvas,
    359     0, 0, DSTINVERT);
    360 
    361   for y := 0 to 6 do
    362     DpiBitCanvas(LandPatch.Canvas, xxt * 2, (y + 2) * yyt, xxt * 2, yyt,
    363       DitherMask.Canvas, 0, 0, SRCAND);
    364 
    365   FreeAndNil(LandMore);
    366   FreeAndNil(OceanMore);
    367   FreeAndNil(DitherMask);
     220  Borders := TDpiBitmap.Create;
     221  Borders.PixelFormat := pf24bit;
     222  HGrTerrain := nil;
     223  HGrCities := nil;
     224  SetLength(TSpriteSize, TerrainIconLines * TerrainIconCols);
     225  CitiesPictures := TCitiesPictures.Create;
     226end;
     227
     228destructor TIsoMapCache.Destroy;
     229begin
     230  FreeAndNil(CitiesPictures);
     231  FreeAndNil(LandPatch);
     232  FreeAndNil(OceanPatch);
     233  FreeAndNil(Borders);
     234  inherited;
     235end;
     236
     237procedure TIsoMap.ReduceTerrainIconsSize;
     238var
     239  MaskLine: array of TPixelPointer;
     240  Mask24: TDpiBitmap;
     241  xSrc: Integer;
     242  ySrc: Integer;
     243  I: Integer;
     244  X: Integer;
     245  Y: Integer;
     246  Border: Boolean;
     247begin
     248  SetLength(MaskLine, yyt * 3);
    368249
    369250  // reduce size of terrain icons
    370251  Mask24 := TDpiBitmap.Create;
    371   Mask24.Assign(GrExt[HGrTerrain].Mask);
     252  Mask24.Assign(HGrTerrain.Mask);
    372253  Mask24.PixelFormat := pf24bit;
    373254  Mask24.BeginUpdate;
    374   for ySrc := 0 to TerrainIconLines - 1 do
    375   begin
     255  for ySrc := 0 to TerrainIconLines - 1 do begin
    376256    for i := 0 to yyt * 3 - 1 do
    377       MaskLine[i] := PixelPointer(Mask24, 0, ScaleToNative(1 + ySrc * (yyt * 3 + 1) + i));
     257      MaskLine[i] := PixelPointer(Mask24, ScaleToNative(0),
     258        ScaleToNative(1 + ySrc * (yyt * 3 + 1) + i));
    378259    for xSrc := 0 to TerrainIconCols - 1 do begin
    379       i := ySrc * TerrainIconCols + xSrc;
     260      i := ySrc * 9 + xSrc;
    380261      TSpriteSize[i].Left := 0;
    381262      repeat
     
    414295        if Border then Dec(TSpriteSize[i].Bottom);
    415296      until not Border or (TSpriteSize[i].Bottom = TSpriteSize[i].Top);
    416     end
     297    end;
    417298  end;
    418299  Mask24.EndUpdate;
    419300  FreeAndNil(Mask24);
    420 
    421   if Borders <> nil then
    422     FreeAndNil(Borders);
    423   Borders := TDpiBitmap.Create;
    424   Borders.PixelFormat := pf24bit;
     301end;
     302
     303procedure TIsoMap.ApplyTileSize(ATileSize: TTileSize);
     304var
     305  x: Integer;
     306  y: Integer;
     307  xSrc: Integer;
     308  ySrc: Integer;
     309  LandMore: TDpiBitmap;
     310  OceanMore: TDpiBitmap;
     311  DitherMask: TDpiBitmap;
     312  FileName: string;
     313begin
     314  FTileSize := ATileSize;
     315  xxt := TileSizes[ATileSize].X;
     316  yyt := TileSizes[ATileSize].Y;
     317
     318  if Assigned(IsoMapCache[ATileSize]) then begin
     319    IsoMapCache[ATileSize].AssignToIsoMap(Self);
     320    Exit;
     321  end;
     322  IsoMapCache[ATileSize] := TIsoMapCache.Create;
     323
     324  FileName := Format('Terrain%dx%d.png', [xxt * 2, yyt * 2]);
     325  IsoMapCache[ATileSize].HGrTerrain := LoadGraphicSet(FileName);
     326  if not Assigned(IsoMapCache[ATileSize].HGrTerrain) then
     327    raise Exception.Create(FileName + ' not found.');
     328
     329  FileName := Format('Cities%dx%d.png', [xxt * 2, yyt * 2]);
     330  IsoMapCache[ATileSize].HGrCities := LoadGraphicSet(FileName);
     331  if not Assigned(IsoMapCache[ATileSize].HGrCities) then
     332    raise Exception.Create(FileName + ' not found.');
     333
     334  IsoMapCache[ATileSize].AssignToIsoMap(Self);
     335
     336  CitiesPictures.Prepare(HGrCities, xxt, yyt);
     337
     338  { prepare dithered ground tiles }
     339  LandPatch.Canvas.Brush.Color := 0;
     340  LandPatch.SetSize(xxt * 18, yyt * 9);
     341  LandPatch.Canvas.FillRect(0, 0, LandPatch.Width, LandPatch.Height);
     342  OceanPatch.Canvas.Brush.Color := 0;
     343  OceanPatch.SetSize(xxt * 8, yyt * 4);
     344  OceanPatch.Canvas.FillRect(0, 0, OceanPatch.Width, OceanPatch.Height);
     345  LandMore := TDpiBitmap.Create;
     346  LandMore.PixelFormat := pf24bit;
     347  LandMore.Canvas.Brush.Color := 0;
     348  LandMore.SetSize(xxt * 18, yyt * 9);
     349  LandMore.Canvas.FillRect(0, 0, LandMore.Width, LandMore.Height);
     350  OceanMore := TDpiBitmap.Create;
     351  OceanMore.PixelFormat := pf24bit;
     352  OceanMore.Canvas.Brush.Color := 0;
     353  OceanMore.SetSize(xxt * 8, yyt * 4);
     354  OceanMore.Canvas.FillRect(0, 0, OceanMore.Width, OceanMore.Height);
     355  DitherMask := TDpiBitmap.Create;
     356  DitherMask.PixelFormat := pf24bit;
     357  DitherMask.SetSize(xxt * 2, yyt * 2);
     358  DitherMask.Canvas.FillRect(0, 0, DitherMask.Width, DitherMask.Height);
     359  DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt * 2,
     360    HGrTerrain.Mask.Canvas, 1 + 7 * (xxt * 2 + 1),
     361    1 + yyt + 15 * (yyt * 3 + 1), SRCAND);
     362
     363  for x := -1 to 6 do begin
     364    if x = -1 then begin
     365      xSrc := ShoreDither * (xxt * 2 + 1) + 1;
     366      ySrc := 1 + yyt;
     367    end
     368    else if x = 6 then begin
     369      xSrc := 1 + (xxt * 2 + 1) * 2;
     370      ySrc := 1 + yyt + (yyt * 3 + 1) * 2;
     371    end else begin
     372      xSrc := (x + 2) * (xxt * 2 + 1) + 1;
     373      ySrc := 1 + yyt;
     374    end;
     375    for y := -1 to 6 do
     376      DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
     377        xxt * 2, yyt, HGrTerrain.Data.Canvas, xSrc, ySrc);
     378    for y := -2 to 6 do
     379      DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt, xxt,
     380        yyt, HGrTerrain.Data.Canvas, xSrc + xxt, ySrc + yyt,
     381        SRCPAINT);
     382    for y := -2 to 6 do
     383      DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2) + xxt, (y + 2) * yyt,
     384        xxt, yyt, HGrTerrain.Data.Canvas, xSrc, ySrc + yyt,
     385        SRCPAINT);
     386    for y := -2 to 6 do
     387      DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt, xxt,
     388        yyt, DitherMask.Canvas, xxt, yyt, SRCAND);
     389    for y := -2 to 6 do
     390      DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2) + xxt, (y + 2) * yyt,
     391        xxt, yyt, DitherMask.Canvas, 0, yyt, SRCAND);
     392  end;
     393
     394  for y := -1 to 6 do begin
     395    if y = -1 then begin
     396      xSrc := ShoreDither * (xxt * 2 + 1) + 1;
     397      ySrc := 1 + yyt;
     398    end
     399    else if y = 6 then begin
     400      xSrc := 1 + 2 * (xxt * 2 + 1);
     401      ySrc := 1 + yyt + 2 * (yyt * 3 + 1);
     402    end else begin
     403      xSrc := (y + 2) * (xxt * 2 + 1) + 1;
     404      ySrc := 1 + yyt;
     405    end;
     406    for x := -2 to 6 do
     407      DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
     408        xxt * 2, yyt, HGrTerrain.Data.Canvas, xSrc, ySrc);
     409    DpiBitCanvas(LandMore.Canvas, xxt * 2, (y + 2) * yyt, xxt, yyt,
     410      HGrTerrain.Data.Canvas, xSrc + xxt, ySrc + yyt, SRCPAINT);
     411    for x := 0 to 7 do
     412      DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2) - xxt, (y + 2) * yyt,
     413        xxt * 2, yyt, HGrTerrain.Data.Canvas, xSrc, ySrc + yyt,
     414        SRCPAINT);
     415    for x := -2 to 6 do
     416      DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
     417        xxt * 2, yyt, DitherMask.Canvas, 0, 0, SRCAND);
     418  end;
     419
     420  for x := 0 to 3 do begin
     421    for y := 0 to 3 do begin
     422      if (x = 1) and (y = 1) then xSrc := 1
     423      else
     424        xSrc := (x mod 2) * (xxt * 2 + 1) + 1;
     425      ySrc := 1 + yyt;
     426      if (x >= 1) = (y >= 2) then
     427        DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
     428          HGrTerrain.Data.Canvas, xSrc, ySrc);
     429      if (x >= 1) and ((y < 2) or (x >= 2)) then
     430      begin
     431        DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt, yyt,
     432          HGrTerrain.Data.Canvas, xSrc + xxt, ySrc + yyt,
     433          SRCPAINT);
     434        DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2) + xxt, y * yyt, xxt, yyt,
     435          HGrTerrain.Data.Canvas, xSrc, ySrc + yyt, SRCPAINT);
     436      end;
     437      DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt, yyt,
     438        DitherMask.Canvas, xxt, yyt, SRCAND);
     439      DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2) + xxt, y * yyt, xxt, yyt,
     440        DitherMask.Canvas, 0, yyt, SRCAND);
     441    end;
     442  end;
     443
     444  for y := 0 to 3 do begin
     445    for x := 0 to 3 do begin
     446      if (x = 1) and (y = 1) then xSrc := 1
     447      else
     448        xSrc := (y mod 2) * (xxt * 2 + 1) + 1;
     449      ySrc := 1 + yyt;
     450      if (x < 1) or (y >= 2) then
     451        DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
     452          HGrTerrain.Data.Canvas, xSrc, ySrc);
     453      if (x = 1) and (y < 2) or (x >= 2) and (y >= 1) then
     454      begin
     455        DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2), y * yyt, xxt, yyt,
     456          HGrTerrain.Data.Canvas, xSrc + xxt, ySrc + yyt,
     457          SRCPAINT);
     458        DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2) + xxt, y * yyt, xxt, yyt,
     459          HGrTerrain.Data.Canvas, xSrc, ySrc + yyt, SRCPAINT);
     460      end;
     461      DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
     462        DitherMask.Canvas, 0, 0, SRCAND);
     463    end;
     464  end;
     465
     466  DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt * 2,
     467    DitherMask.Canvas, 0, 0, DSTINVERT); { invert dither mask }
     468  DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt * 2,
     469    HGrTerrain.Mask.Canvas, 1, 1 + yyt, SRCPAINT);
     470
     471  for x := -1 to 6 do
     472    for y := -2 to 6 do
     473      DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
     474        xxt * 2, yyt, DitherMask.Canvas, 0, 0, SRCAND);
     475
     476  for y := -1 to 6 do
     477    for x := -2 to 7 do
     478      DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2) - xxt, (y + 2) * yyt,
     479        xxt * 2, yyt, DitherMask.Canvas, 0, yyt, SRCAND);
     480
     481  DpiBitCanvas(LandPatch.Canvas, 0, 0, (xxt * 2) * 9, yyt * 9,
     482    LandMore.Canvas, 0, 0, SRCPAINT);
     483
     484  for x := 0 to 3 do
     485    for y := 0 to 3 do
     486      DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
     487        DitherMask.Canvas, 0, 0, SRCAND);
     488
     489  for y := 0 to 3 do
     490    for x := 0 to 4 do
     491      DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2) - xxt, y * yyt, xxt * 2,
     492        yyt, DitherMask.Canvas, 0, yyt, SRCAND);
     493
     494  DpiBitCanvas(OceanPatch.Canvas, 0, 0, (xxt * 2) * 4, yyt * 4,
     495    OceanMore.Canvas, 0, 0, SRCPAINT);
     496
     497  with DitherMask.Canvas do begin
     498    Brush.Color := $FFFFFF;
     499    FillRect(Rect(0, 0, xxt * 2, yyt));
     500  end;
     501  DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt,
     502    HGrTerrain.Mask.Canvas, 1, 1 + yyt);
     503
     504  for x := 0 to 6 do
     505    DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), yyt, xxt * 2, yyt,
     506      DitherMask.Canvas, 0, 0, SRCAND);
     507  DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt, DitherMask.Canvas,
     508    0, 0, DSTINVERT);
     509
     510  for y := 0 to 6 do
     511    DpiBitCanvas(LandPatch.Canvas, xxt * 2, (y + 2) * yyt, xxt * 2, yyt,
     512      DitherMask.Canvas, 0, 0, SRCAND);
     513
     514  FreeAndNil(LandMore);
     515  FreeAndNil(OceanMore);
     516  FreeAndNil(DitherMask);
     517
     518  ReduceTerrainIconsSize;
     519
    425520  Borders.SetSize(xxt * 2, (yyt * 2) * nPl);
    426521  Borders.Canvas.FillRect(0, 0, Borders.Width, Borders.Height);
    427   BordersOK := 0;
    428 end;
    429 
    430 procedure Done;
    431 begin
    432   FreeAndNil(NoMap);
    433   FreeAndNil(LandPatch);
    434   FreeAndNil(OceanPatch);
    435   FreeAndNil(Borders);
    436 end;
    437 
    438 procedure Reset;
    439 begin
    440   BordersOK := 0;
     522  BordersOK^ := 0;
     523end;
     524
     525procedure TIsoMap.Reset;
     526begin
     527  BordersOK^ := 0;
    441528end;
    442529
     
    451538  DefLoc := -1;
    452539  FAdviceLoc := -1;
     540  TileSize := DefaultTileSize;
     541end;
     542
     543destructor TIsoMap.Destroy;
     544begin
     545  inherited;
    453546end;
    454547
     
    525618end;
    526619
    527 procedure TIsoMap.Sprite(HGr, xDst, yDst, Width, Height, xGr, yGr: integer);
    528 begin
    529   BitBltBitmap(GrExt[HGr].Mask, xDst, yDst, Width, Height, xGr, yGr, SRCAND);
    530   BitBltBitmap(GrExt[HGr].Data, xDst, yDst, Width, Height, xGr, yGr, SRCPAINT);
     620procedure TIsoMap.Sprite(HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
     621begin
     622  BitBltBitmap(HGr.Mask, xDst, yDst, Width, Height, xGr, yGr, SRCAND);
     623  BitBltBitmap(HGr.Data, xDst, yDst, Width, Height, xGr, yGr, SRCPAINT);
    531624end;
    532625
     
    534627  PureBlack: boolean = false);
    535628var
    536   Width, Height, xSrc, ySrc: integer;
     629  Width: Integer;
     630  Height: Integer;
     631  xSrc: Integer;
     632  ySrc: integer;
    537633begin
    538634  Width := TSpriteSize[grix].Right - TSpriteSize[grix].Left;
     
    542638  xDst := xDst + TSpriteSize[grix].Left;
    543639  yDst := yDst - yyt + TSpriteSize[grix].Top;
    544   if xDst < FLeft then
    545   begin
     640  if xDst < FLeft then begin
    546641    Width := Width - (FLeft - xDst);
    547642    xSrc := xSrc + (FLeft - xDst);
    548     xDst := FLeft
    549   end;
    550   if yDst < FTop then
    551   begin
     643    xDst := FLeft;
     644  end;
     645  if yDst < FTop then begin
    552646    Height := Height - (FTop - yDst);
    553647    ySrc := ySrc + (FTop - yDst);
    554     yDst := FTop
     648    yDst := FTop;
    555649  end;
    556650  if xDst + Width >= FRight then
     
    578672      else
    579673        mixShow := mix;
    580       if (Tribe[Owner].ModelPicture[mixShow].HGr = 0) and
     674      if (not Assigned(Tribe[Owner].ModelPicture[mixShow].HGr)) and
    581675        (@OnInitEnemyModel <> nil) then
    582676        if not OnInitEnemyModel(emix) then
     
    611705        xGr := 121 + j mod 7 * 9;
    612706        yGr := 1 + j div 7 * 9;
    613         BitBltBitmap(GrExt[HGrSystem].Mask, x + xsh + 3, y + ysh + 9, 8, 8, xGr,
     707        BitBltBitmap(HGrSystem.Mask, x + xsh + 3, y + ysh + 9, 8, 8, xGr,
    614708          yGr, SRCAND);
    615709        Sprite(HGrSystem, x + xsh + 2, y + ysh + 8, 8, 8, xGr, yGr);
     
    619713      if Flags and unFortified <> 0 then
    620714      begin
    621         { DataCanvas:=GrExt[HGrTerrain].Data.Canvas;
    622           MaskCanvas:=GrExt[HGrTerrain].Mask.Canvas;
     715        { DataCanvas:=HGrTerrain.Data.Canvas;
     716          MaskCanvas:=HGrTerrain.Mask.Canvas;
    623717          TSprite(x,y+16,12*9+7); }
    624718        Sprite(HGrStdUnits, x, y, xxu * 2, yyu * 2, 1 + 6 * (xxu * 2 + 1), 1);
     
    630724  accessory: boolean);
    631725var
    632   age, cHGr, cpix, xGr, xShield, yShield, LabelTextColor, LabelLength: integer;
     726  age: Integer;
     727  cHGr: TGraphicSet;
     728  cpix: Integer;
     729  xGr: Integer;
     730  xShield: Integer;
     731  yShield: Integer;
     732  LabelTextColor: Integer;
     733  LabelLength: Integer;
    633734  cpic: TCityPicture;
    634735  s: string;
     
    649750    cpix := Tribe[CityInfo.Owner].cpix;
    650751    if (ciWalled and CityInfo.Flags = 0) or
    651       (GrExt[cHGr].Data.Canvas.Pixels[(xGr + 4) * 65, cpix * 49 + 48] = $00FFFF)
     752      (cHGr.Data.Canvas.Pixels[(xGr + 4) * 65, cpix * 49 + 48] = $00FFFF)
    652753    then
    653754      Sprite(cHGr, x - xxc, y - 2 * yyc, xxc * 2, yyc * 3,
     
    685786    else
    686787    begin
    687       cpic := CitiesPictures[age, xGr];
     788      cpic := CitiesPictures.Pictures[age, xGr];
    688789      xShield := x - xxt + cpic.xShield;
    689790      yShield := y - 2 * yyt + cpic.yShield;
     
    718819      (MyMap[dLoc(Loc, -2, 2)] and fObserved <> 0) and
    719820      (MyMap[dLoc(Loc, 2, 2)] and fObserved <> 0) then
    720       result := result or fObserved
     821      result := result or fObserved;
    721822  end
    722823  else if Loc < 0 then
     
    727828    if (MyMap[dLoc(Loc, -1, 1)] and fObserved <> 0) and
    728829      (MyMap[dLoc(Loc, 1, 1)] and fObserved <> 0) then
    729       result := result or fObserved
     830      result := result or fObserved;
    730831  end
    731832  else if Loc < G.lx * (G.ly + 1) then
     
    736837    if (MyMap[dLoc(Loc, -1, -1)] and fObserved <> 0) and
    737838      (MyMap[dLoc(Loc, 1, -1)] and fObserved <> 0) then
    738       result := result or fObserved
     839      result := result or fObserved;
    739840  end
    740841  else if Loc < G.lx * (G.ly + 2) then
     
    747848      (MyMap[dLoc(Loc, -2, -2)] and fObserved <> 0) and
    748849      (MyMap[dLoc(Loc, 2, -2)] and fObserved <> 0) then
    749       result := result or fObserved
    750   end
    751 end;
    752 
    753 const
    754   Dirx: array [0 .. 7] of integer = (1, 2, 1, 0, -1, -2, -1, 0);
    755   Diry: array [0 .. 7] of integer = (-1, 0, 1, 2, 1, 0, -1, -2);
     850      result := result or fObserved;
     851  end;
     852end;
    756853
    757854function TIsoMap.Connection4(Loc, Mask, Value: integer): integer;
     
    771868    if MyMap[dLoc(Loc, -1, 1)] and Mask = Cardinal(Value) then
    772869      inc(result, 4);
    773   end
     870  end;
    774871end;
    775872
    776873function TIsoMap.Connection8(Loc, Mask: integer): integer;
    777874var
    778   Dir, ConnLoc: integer;
     875  Dir: Integer;
     876  ConnLoc: Integer;
    779877begin
    780878  result := 0;
     
    785883      (MyMap[ConnLoc] and Mask <> 0) then
    786884      inc(result, 1 shl Dir);
    787   end
     885  end;
    788886end;
    789887
    790888function TIsoMap.OceanConnection(Loc: integer): integer;
    791889var
    792   Dir, ConnLoc: integer;
     890  Dir: Integer;
     891  ConnLoc: Integer;
    793892begin
    794893  result := 0;
     
    799898      ((MyMap[ConnLoc] - 2) and fTerrain < 13) then
    800899      inc(result, 1 shl Dir);
    801   end
     900  end;
    802901end;
    803902
    804903procedure TIsoMap.PaintShore(x, y, Loc: integer);
    805904var
    806   Conn, Tile: integer;
     905  Conn: Integer;
     906  Tile: Integer;
    807907begin
    808908  if (y <= FTop - yyt * 2) or (y > FBottom) or (x <= FLeft - xxt * 2) or
     
    818918    exit;
    819919
    820   BitBltBitmap(GrExt[HGrTerrain].Data, x + xxt div 2, y, xxt, yyt,
     920  BitBltBitmap(HGrTerrain.Data, x + xxt div 2, y, xxt, yyt,
    821921    1 + (Conn shr 6 + Conn and 1 shl 2) * (xxt * 2 + 1),
    822922    1 + yyt + (16 + Tile and fTerrain) * (yyt * 3 + 1), SRCPAINT);
    823   BitBltBitmap(GrExt[HGrTerrain].Data, x + xxt, y + yyt div 2, xxt, yyt,
     923  BitBltBitmap(HGrTerrain.Data, x + xxt, y + yyt div 2, xxt, yyt,
    824924    1 + (Conn and 7) * (xxt * 2 + 1) + xxt,
    825925    1 + yyt * 2 + (16 + Tile and fTerrain) * (yyt * 3 + 1), SRCPAINT);
    826   BitBltBitmap(GrExt[HGrTerrain].Data, x + xxt div 2, y + yyt, xxt, yyt,
     926  BitBltBitmap(HGrTerrain.Data, x + xxt div 2, y + yyt, xxt, yyt,
    827927    1 + (Conn shr 2 and 7) * (xxt * 2 + 1) + xxt,
    828928    1 + yyt + (16 + Tile and fTerrain) * (yyt * 3 + 1), SRCPAINT);
    829   BitBltBitmap(GrExt[HGrTerrain].Data, x, y + yyt div 2, xxt, yyt,
     929  BitBltBitmap(HGrTerrain.Data, x, y + yyt div 2, xxt, yyt,
    830930    1 + (Conn shr 4 and 7) * (xxt * 2 + 1),
    831931    1 + yyt * 2 + (16 + Tile and fTerrain) * (yyt * 3 + 1), SRCPAINT);
    832932  Conn := Connection4(Loc, fTerrain, fUNKNOWN); { dither to black }
    833933  if Conn and 1 <> 0 then
    834     BitBltBitmap(GrExt[HGrTerrain].Mask, x + xxt, y, xxt, yyt, 1 + 7 * (xxt * 2 + 1) +
     934    BitBltBitmap(HGrTerrain.Mask, x + xxt, y, xxt, yyt, 1 + 7 * (xxt * 2 + 1) +
    835935      xxt, 1 + yyt + 15 * (yyt * 3 + 1), SRCAND);
    836936  if Conn and 2 <> 0 then
    837     BitBltBitmap(GrExt[HGrTerrain].Mask, x + xxt, y + yyt, xxt, yyt,
     937    BitBltBitmap(HGrTerrain.Mask, x + xxt, y + yyt, xxt, yyt,
    838938      1 + 7 * (xxt * 2 + 1) + xxt, 1 + yyt * 2 + 15 * (yyt * 3 + 1), SRCAND);
    839939  if Conn and 4 <> 0 then
    840     BitBltBitmap(GrExt[HGrTerrain].Mask, x, y + yyt, xxt, yyt, 1 + 7 * (xxt * 2 + 1),
     940    BitBltBitmap(HGrTerrain.Mask, x, y + yyt, xxt, yyt, 1 + 7 * (xxt * 2 + 1),
    841941      1 + yyt * 2 + 15 * (yyt * 3 + 1), SRCAND);
    842942  if Conn and 8 <> 0 then
    843     BitBltBitmap(GrExt[HGrTerrain].Mask, x, y, xxt, yyt, 1 + 7 * (xxt * 2 + 1),
     943    BitBltBitmap(HGrTerrain.Mask, x, y, xxt, yyt, 1 + 7 * (xxt * 2 + 1),
    844944      1 + yyt + 15 * (yyt * 3 + 1), SRCAND);
    845945end;
     
    9041004        if Conn and (1 shl Dir) <> 0 then { canal mouths }
    9051005          TSprite(x, y, spCanalMouths + 1 + Dir);
    906     end
     1006    end;
    9071007  end;
    9081008
     
    9671067  begin
    9681068    BehindCityInfo.Loc := Loc - 2 * G.lx;
    969     if ShowCityNames and (Options and (1 shl moEditMode) = 0) and
     1069    if ShowCityNames and not (moEditMode in MapOptions) and
    9701070      (BehindCityInfo.Loc >= 0) and (BehindCityInfo.Loc < G.lx * G.ly) and
    9711071      (MyMap[BehindCityInfo.Loc] and fCity <> 0) then
     
    9881088  procedure ShowSpacePort;
    9891089  begin
    990     if ShowObjects and (Options and (1 shl moEditMode) = 0) and
     1090    if ShowObjects and not (moEditMode in MapOptions) and
    9911091      (Tile and fCity <> 0) and (CityInfo.Flags and ciSpacePort <> 0) then
    9921092      TSprite(x + xxt, y - 6, spSpacePort);
     
    9961096  var
    9971097    dx, dy: integer;
    998     PixelPtr: TPixelPointer;
    9991098  begin
    10001099    if ShowBorder and (Loc >= 0) and (Loc < G.lx * G.ly) and
    1001       (Tile and fTerrain <> fUNKNOWN) then
    1002     begin
     1100      (Tile and fTerrain <> fUNKNOWN) then begin
    10031101      p1 := MyRO.Territory[Loc];
    1004       if (p1 >= 0) and (ShowMyBorder or (p1 <> me)) then
    1005       begin
    1006         if BordersOK and (1 shl p1) = 0 then
    1007         begin
    1008           // Clearing before BitBltBitmap SRCCOPY shouldn't be neccesary but for some
    1009           // reason without it code works different then under Delphi
    1010           Borders.Canvas.FillRect(Bounds(0, p1 * (yyt * 2), xxt * 2, yyt * 2));
    1011 
     1102      if (p1 >= 0) and (ShowMyBorder or (p1 <> me)) then begin
     1103        if BordersOK^ and (1 shl p1) = 0 then begin
     1104          UnshareBitmap(Borders);
    10121105          DpiBitCanvas(Borders.Canvas, 0, p1 * (yyt * 2), xxt * 2,
    1013             yyt * 2, GrExt[HGrTerrain].Data.Canvas,
     1106            yyt * 2, HGrTerrain.Data.Canvas,
    10141107            1 + 8 * (xxt * 2 + 1), 1 + yyt + 16 * (yyt * 3 + 1));
    1015           Borders.BeginUpdate;
    1016           PixelPtr := PixelPointer(Borders, ScaleToNative(0), ScaleToNative(p1 * (yyt * 2)));
    1017           for dy := 0 to ScaleToNative(yyt * 2) - 1 do begin
    1018             for dx := 0 to ScaleToNative(xxt * 2) - 1 do begin
    1019               if PixelPtr.Pixel^.B = 99 then begin
    1020                 PixelPtr.Pixel^.B := Tribe[p1].Color shr 16 and $FF;
    1021                 PixelPtr.Pixel^.G := Tribe[p1].Color shr 8 and $FF;
    1022                 PixelPtr.Pixel^.R := Tribe[p1].Color and $FF;
    1023               end;
    1024               PixelPtr.NextPixel;
    1025             end;
    1026             PixelPtr.NextLine;
    1027           end;
    1028           Borders.EndUpdate;
    1029           BordersOK := BordersOK or 1 shl p1;
     1108          BitmapReplaceColor(Borders, 0, p1 * (yyt * 2), xxt * 2, yyt * 2, $636363, Tribe[p1].Color);
     1109          BordersOK^ := BordersOK^ or 1 shl p1;
    10301110        end;
    10311111        for dy := 0 to 1 do
    1032           for dx := 0 to 1 do
    1033           begin
     1112          for dx := 0 to 1 do begin
    10341113            Loc1 := dLoc(Loc, dx * 2 - 1, dy * 2 - 1);
    10351114            begin
     
    10421121              if p2 <> p1 then
    10431122              begin
    1044                 BitBltBitmap(GrExt[HGrTerrain].Mask, x + dx * xxt, y + dy * yyt, xxt,
     1123                BitBltBitmap(HGrTerrain.Mask, x + dx * xxt, y + dy * yyt, xxt,
    10451124                  yyt, 1 + 8 * (xxt * 2 + 1) + dx * xxt,
    10461125                  1 + yyt + 16 * (yyt * 3 + 1) + dy * yyt, SRCAND);
    10471126                BitBltBitmap(Borders, x + dx * xxt, y + dy * yyt, xxt, yyt, dx * xxt,
    10481127                  p1 * (yyt * 2) + dy * yyt, SRCPAINT);
    1049               end
     1128              end;
    10501129            end;
    1051           end
    1052       end
     1130          end;
     1131      end;
    10531132    end;
    10541133  end;
     
    10591138  else
    10601139    Tile := MyMap[Loc];
    1061   if ShowObjects and (Options and (1 shl moEditMode) = 0) and
     1140  if ShowObjects and not (moEditMode in MapOptions) and
    10621141    (Tile and fCity <> 0) then
    10631142    GetCityInfo(Loc, cix, CityInfo);
     
    10731152    NameCity;
    10741153    ShowSpacePort;
    1075     exit
     1154    exit;
    10761155  end; { square not discovered }
    10771156
     
    11141193    TSprite(x, y, spMinerals + (Tile shr 25 and 3) * TerrainIconCols);
    11151194
    1116   if Options and (1 shl moEditMode) <> 0 then
     1195  if moEditMode in MapOptions then
    11171196    fog := (Loc < 0) or (Loc >= G.lx * G.ly)
    11181197    // else if CityLoc>=0 then
     
    11481227  end;
    11491228{$ENDIF}
    1150   if Options and (1 shl moEditMode) <> 0 then
     1229  if moEditMode in MapOptions then
    11511230  begin
    11521231    if Tile and fPrefStartPos <> 0 then
     
    12821361      moveto(x0, y + dy0 * yyt);
    12831362      lineto(x1, y + (dy0 + n) * yyt);
    1284     end
     1363    end;
    12851364  end;
    12861365
     
    13011380
    13021381function TIsoMap.IsShoreTile(Loc: integer): boolean;
    1303 const
    1304   Dirx: array [0 .. 7] of integer = (1, 2, 1, 0, -1, -2, -1, 0);
    1305   Diry: array [0 .. 7] of integer = (-1, 0, 1, 2, 1, 0, -1, -2);
    1306 var
    1307   Dir, ConnLoc: integer;
     1382var
     1383  Dir: Integer;
     1384  ConnLoc: integer;
    13081385begin
    13091386  result := false;
     
    13131390    if (ConnLoc < 0) or (ConnLoc >= G.lx * G.ly) or
    13141391      ((MyMap[ConnLoc] - 2) and fTerrain < 13) then
    1315       result := true
    1316   end
     1392      result := true;
     1393  end;
    13171394end;
    13181395
     
    13271404    Line^.NextPixel;
    13281405  end;
     1406end;
     1407
     1408procedure TIsoMap.SetTileSize(AValue: TTileSize);
     1409begin
     1410  if FTileSize = AValue then Exit;
     1411  FTileSize := AValue;
     1412  ApplyTileSize(AValue);
    13291413end;
    13301414
     
    13861470    lineto(xm + xxt * 4, ym - yyt * 1);
    13871471    pen.Width := 1;
    1388   end
     1472  end;
    13891473end;
    13901474
     
    13951479begin
    13961480  FoW := true;
    1397   ShowLoc := Options and (1 shl moLocCodes) <> 0;
     1481  ShowLoc := moLocCodes in MapOptions;
    13981482  ShowDebug := pDebugMap >= 0;
    1399   ShowObjects := (CityOwner >= 0) or (Options and (1 shl moBareTerrain) = 0);
     1483  ShowObjects := (CityOwner >= 0) or not (moBareTerrain in MapOptions);
    14001484  ShowCityNames := ShowObjects and (CityOwner < 0) and
    1401     (Options and (1 shl moCityNames) <> 0);
     1485    (moCityNames in MapOptions);
    14021486  ShowBorder := true;
    14031487  ShowMyBorder := CityOwner < 0;
    1404   ShowGrWall := (CityOwner < 0) and (Options and (1 shl moGreatWall) <> 0);
     1488  ShowGrWall := (CityOwner < 0) and (moGreatWall in MapOptions);
    14051489  if ShowDebug then
    14061490    Server(sGetDebugMap, me, pDebugMap, DebugMap)
     
    14691553                begin
    14701554                  Aix := 0;
    1471                   bix := 0
     1555                  bix := 0;
    14721556                end
    14731557                else
    14741558                begin
    14751559                  Aix := 0;
    1476                   bix := 1
     1560                  bix := 1;
    14771561                end
    14781562              else if bix = -1 then
     
    14801564                begin
    14811565                  Aix := 1;
    1482                   bix := 1
     1566                  bix := 1;
    14831567                end
    14841568                else
    14851569                begin
    14861570                  Aix := 1;
    1487                   bix := 0
     1571                  bix := 0;
    14881572                end;
    14891573              BitBltBitmap(OceanPatch, x + dx * xxt, y + dy * yyt, xxt, yyt,
     
    15221606            begin
    15231607              Aix := fDesert;
    1524               bix := fDesert
     1608              bix := fDesert;
    15251609            end
    15261610            else if Aix = -2 then
     
    15351619                bix := Aix;
    15361620            if Aix = -1 then
    1537               BitBltBitmap(GrExt[HGrTerrain].Data, x + dx * xxt, y + dy * yyt, xxt,
     1621              BitBltBitmap(HGrTerrain.Data, x + dx * xxt, y + dy * yyt, xxt,
    15381622                yyt, 1 + 6 * (xxt * 2 + 1) + (dx + dy + 1) and 1 * xxt, 1 + yyt,
    15391623                SRCCOPY) // arctic <-> ocean
    15401624            else if bix = -1 then
    1541               BitBltBitmap(GrExt[HGrTerrain].Data, x + dx * xxt, y + dy * yyt, xxt,
     1625              BitBltBitmap(HGrTerrain.Data, x + dx * xxt, y + dy * yyt, xxt,
    15421626                yyt, 1 + 6 * (xxt * 2 + 1) + xxt - (dx + dy + 1) and 1 * xxt,
    15431627                1 + yyt * 2, SRCCOPY) // arctic <-> ocean
     
    15451629              BitBltBitmap(LandPatch, x + dx * xxt, y + dy * yyt, xxt, yyt,
    15461630                Aix * (xxt * 2) + (dx + dy + 1) and 1 * xxt, bix * yyt, SRCCOPY)
    1547           end
     1631          end;
    15481632      end;
    15491633
    1550   DataCanvas := GrExt[HGrTerrain].Data.Canvas;
    1551   MaskCanvas := GrExt[HGrTerrain].Mask.Canvas;
     1634  DataCanvas := HGrTerrain.Data.Canvas;
     1635  MaskCanvas := HGrTerrain.Mask.Canvas;
    15521636  for dy := -2 to ny + 1 do
    15531637    for dx := -1 to nx do
     
    15591643        PaintTileExtraTerrain(x + xxt * dx, y + yyt + yyt * dy,
    15601644          dLoc(Loc, dx, dy));
    1561 
    15621645  if CityOwner >= 0 then
    15631646  begin
     
    15911674  else
    15921675  begin
    1593     if ShowLoc or (Options and (1 shl moEditMode) <> 0) or
    1594       (Options and (1 shl moGrid) <> 0) then
     1676    if ShowLoc or (moEditMode in MapOptions) or
     1677      (moGrid in MapOptions) then
    15951678      PaintGrid(x, y, nx, ny);
    15961679    for dy := -2 to ny + 1 do
     
    16221705end;
    16231706
    1624 initialization
    1625 
    1626 NoMap := nil;
    1627 LandPatch := nil;
    1628 OceanPatch := nil;
    1629 Borders := nil;
     1707procedure IsoEngineDone;
     1708var
     1709  I: TTileSize;
     1710begin
     1711  for I := Low(IsoMapCache) to High(IsoMapCache) do
     1712    FreeAndNil(IsoMapCache[I]);
     1713end;
     1714
     1715finalization
     1716
     1717IsoEngineDone;
    16301718
    16311719end.
Note: See TracChangeset for help on using the changeset viewer.