Changeset 330 for trunk


Ignore:
Timestamp:
Mar 26, 2021, 2:16:04 PM (3 years ago)
Author:
chronos
Message:
  • Modified: Reworker IsoEngine unit to support multiple iso maps with different tile sizes.
  • Modified: Changing tile size in main windows map doesn't affect other tile drawing on panel and in other windows like help window.
  • Modified: Optimized tile size switching. Graphic assets needed for given tile size is prepared only once. Then switching between them is just about changing references to objects and redrawing.
  • Modified: Code cleanup.
Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LocalPlayer/Battle.pas

    r313 r330  
    66uses
    77  ScreenTools, Protocol, ButtonBase, ButtonA, Types, LCLIntf, LCLType,
    8   SysUtils, Classes, Graphics, Controls, Forms, DrawDlg;
     8  SysUtils, Classes, Graphics, Controls, Forms, DrawDlg, IsoEngine;
    99
    1010type
     11
     12  { TBattleDlg }
     13
    1114  TBattleDlg = class(TDrawDlg)
    1215    OKBtn: TButtonA;
    1316    CancelBtn: TButtonA;
     17    procedure FormDestroy(Sender: TObject);
    1418    procedure FormPaint(Sender: TObject);
    1519    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
     
    2125    procedure OKBtnClick(Sender: TObject);
    2226    procedure CancelBtnClick(Sender: TObject);
     27    procedure PaintBattleOutcome(ca: TCanvas; xm, ym, uix, ToLoc: Integer;
     28      Forecast: TBattleForecastEx);
     29  private
     30    IsoMap: TIsoMap;
    2331  public
    2432    uix, ToLoc: Integer;
     
    3038  BattleDlg: TBattleDlg;
    3139
    32 procedure PaintBattleOutcome(ca: TCanvas; xm, ym, uix, ToLoc: Integer;
    33   Forecast: TBattleForecastEx);
    34 
    3540implementation
    3641
    3742uses
    38   Term, ClientTools, IsoEngine;
     43  Term, ClientTools;
    3944
    4045{$R *.lfm}
     
    4853  FirstStrikeColor = $A0A0A0;
    4954
    50 procedure PaintBattleOutcome(ca: TCanvas; xm, ym, uix, ToLoc: Integer;
     55procedure TBattleDlg.PaintBattleOutcome(ca: TCanvas; xm, ym, uix, ToLoc: Integer;
    5156  Forecast: TBattleForecastEx);
    5257var
     
    172177      (LADamage - LAAvoidedDamage - TextSize.cy) div 2, LabelText);
    173178
    174   NoMap.SetOutput(Buffer);
     179  IsoMap.SetOutput(Buffer);
    175180  BitBltCanvas(Buffer.Canvas, 0, 0, 66, 48, ca, xm + 8 + 4,
    176181    ym - 8 - 12 - 48);
     
    184189    else Sprite(Buffer,HGrTerrain,0,16,66,32,1+7*(xxt*2+1),1+yyt+2*(2+TerrType-fForest)*(yyt*3+1));
    185190    end; }
    186   NoMap.PaintUnit(1, 0, UnitInfo, 0);
     191  IsoMap.PaintUnit(1, 0, UnitInfo, 0);
    187192  BitBltCanvas(ca, xm + 8 + 4, ym - 8 - 12 - 48, 66, 48, Buffer.Canvas,
    188193    0, 0);
     
    192197  MakeUnitInfo(me, MyUn[uix], UnitInfo);
    193198  UnitInfo.Flags := UnitInfo.Flags and not unFortified;
    194   NoMap.PaintUnit(1, 0, UnitInfo, 0);
     199  IsoMap.PaintUnit(1, 0, UnitInfo, 0);
    195200  BitBltCanvas(ca, xm - 8 - 4 - 66, ym + 8 + 12, 66, 48, Buffer.Canvas, 0, 0);
    196201end; { PaintBattleOutcome }
     
    198203procedure TBattleDlg.FormCreate(Sender: TObject);
    199204begin
     205  IsoMap := TIsoMap.Create;
    200206  OKBtn.Caption := Phrases.Lookup('BTN_YES');
    201207  CancelBtn.Caption := Phrases.Lookup('BTN_NO');
     
    276282end;
    277283
     284procedure TBattleDlg.FormDestroy(Sender: TObject);
     285begin
     286  FreeAndNil(IsoMap);
     287end;
     288
    278289procedure TBattleDlg.FormMouseDown(Sender: TObject; Button: TMouseButton;
    279290  Shift: TShiftState; X, Y: Integer);
  • trunk/LocalPlayer/CityScreen.pas

    r328 r330  
    407407    rare: boolean;
    408408  begin
     409    with AreaMap do begin
    409410    if Server(sGetCityTileInfo, me, Loc, TileInfo) <> eOk then
    410411    begin
     
    442443      Sprite(offscreen, HGrSystem, x + xxt - 5 + d * (2 * i + 1 - Total),
    443444        y + yyt - 5, 10, 10, xGr, yGr);
     445    end;
    444446    end;
    445447  end;
     
    593595  end;
    594596
     597  with AreaMap do begin
    595598  rx := (192 + xxt * 2 - 1) div (xxt * 2);
    596599  ry := (96 + yyt * 2 - 1) div (yyt * 2);
     
    619622              Loc1, (dx = 0) and (dy = 0));
    620623        end;
     624  end;
    621625
    622626  if Report.Working > 1 then
     
    930934            y := ((Cnt - 6 * Page) div 3) * 52 + yZoomMap + 20;
    931935            MakeUnitInfo(me, MyUn[i], UnitInfo);
    932             NoMap.SetOutput(offscreen);
    933             NoMap.PaintUnit(x, y, UnitInfo, MyUn[i].Status);
     936            AreaMap.SetOutput(offscreen);
     937            AreaMap.PaintUnit(x, y, UnitInfo, MyUn[i].Status);
    934938
    935939            for j := 0 to UnitReport.FoodSupport - 1 do
     
    13171321    else if (x >= xmArea - 192) and (x < xmArea + 192) and (y >= ymArea - 96)
    13181322      and (y < ymArea + 96) then
     1323    with AreaMap do
    13191324    begin
    13201325      qx := ((4000 * xxt * yyt) + (x - xmArea) * (yyt * 2) + (y - ymArea + yyt)
  • trunk/LocalPlayer/Enhance.pas

    r313 r330  
    77  ScreenTools, BaseWin, Protocol, ClientTools, Term, LCLIntf, LCLType,
    88
    9   SysUtils, Classes, Graphics, Controls, Forms,
     9  SysUtils, Classes, Graphics, Controls, Forms, IsoEngine,
    1010  ButtonB, ButtonC, Menus;
    1111
     
    2828    Popup: TPopupMenu;
    2929    procedure FormCreate(Sender: TObject);
     30    procedure FormDestroy(Sender: TObject);
    3031    procedure FormPaint(Sender: TObject);
    3132    procedure FormShow(Sender: TObject);
     
    3536    procedure JobClick(Sender: TObject);
    3637    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
     38  private
     39    NoMap: TIsoMap;
    3740  public
    3841    procedure ShowNewContent(NewMode: integer; TerrType: integer = -1);
     
    4750implementation
    4851
    49 uses Help;
     52uses
     53  Help;
    5054
    5155{$R *.lfm}
     
    5761begin
    5862  inherited;
     63  NoMap := TIsoMap.Create;
    5964  CaptionRight := CloseBtn.Left;
    6065  CaptionLeft := ToggleBtn.Left + ToggleBtn.Width;
     
    8590end;
    8691
     92procedure TEnhanceDlg.FormDestroy(Sender: TObject);
     93begin
     94  FreeAndNil(NoMap);
     95end;
     96
    8797procedure TEnhanceDlg.FormPaint(Sender: TObject);
    8898var
     
    129139  while (EndStage < 5) and (MyData.EnhancementJobs[Page, EndStage] <> jNone) do
    130140    inc(EndStage);
    131   x := InnerWidth div 2 - xxt - (xxt + 3) * EndStage;
     141  with NoMap do
     142    x := InnerWidth div 2 - xxt - (xxt + 3) * EndStage;
    132143
    133144  TerrType := Page;
     
    185196    end;
    186197
    187     if TerrType < fForest then
    188       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    189         1 + TerrType * (xxt * 2 + 1), 1 + yyt)
    190     else
    191     begin
    192       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    193         1 + 2 * (xxt * 2 + 1), 1 + yyt + 2 * (yyt * 3 + 1));
    194       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    195         1 + 7 * (xxt * 2 + 1), 1 + yyt + 2 * (2 + TerrType - fForest) *
    196         (yyt * 3 + 1));
    197     end;
    198     if TileImp and fTerImp = tiFarm then
    199       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    200         1 + (xxt * 2 + 1), 1 + yyt + 12 * (yyt * 3 + 1))
    201     else if TileImp and fTerImp = tiIrrigation then
    202       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2, 1,
    203         1 + yyt + 12 * (yyt * 3 + 1));
    204     if TileImp and fRR <> 0 then
    205     begin
    206       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    207         1 + 6 * (xxt * 2 + 1), 1 + yyt + 10 * (yyt * 3 + 1));
    208       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    209         1 + 2 * (xxt * 2 + 1), 1 + yyt + 10 * (yyt * 3 + 1));
    210     end
    211     else if TileImp and fRoad <> 0 then
    212     begin
    213       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    214         1 + 6 * (xxt * 2 + 1), 1 + yyt + 9 * (yyt * 3 + 1));
    215       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    216         1 + 2 * (xxt * 2 + 1), 1 + yyt + 9 * (yyt * 3 + 1));
    217     end;
    218     if TileImp and fTerImp = tiMine then
    219       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    220         1 + 2 * (xxt * 2 + 1), 1 + yyt + 12 * (yyt * 3 + 1));
    221     inc(x, xxt * 2 + 6)
     198    with NoMap do begin
     199      if TerrType < fForest then
     200        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     201          1 + TerrType * (xxt * 2 + 1), 1 + yyt)
     202      else
     203      begin
     204        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     205          1 + 2 * (xxt * 2 + 1), 1 + yyt + 2 * (yyt * 3 + 1));
     206        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     207          1 + 7 * (xxt * 2 + 1), 1 + yyt + 2 * (2 + TerrType - fForest) *
     208          (yyt * 3 + 1));
     209      end;
     210      if TileImp and fTerImp = tiFarm then
     211        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     212          1 + (xxt * 2 + 1), 1 + yyt + 12 * (yyt * 3 + 1))
     213      else if TileImp and fTerImp = tiIrrigation then
     214        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2, 1,
     215          1 + yyt + 12 * (yyt * 3 + 1));
     216      if TileImp and fRR <> 0 then
     217      begin
     218        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     219          1 + 6 * (xxt * 2 + 1), 1 + yyt + 10 * (yyt * 3 + 1));
     220        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     221          1 + 2 * (xxt * 2 + 1), 1 + yyt + 10 * (yyt * 3 + 1));
     222      end
     223      else if TileImp and fRoad <> 0 then
     224      begin
     225        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     226          1 + 6 * (xxt * 2 + 1), 1 + yyt + 9 * (yyt * 3 + 1));
     227        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     228          1 + 2 * (xxt * 2 + 1), 1 + yyt + 9 * (yyt * 3 + 1));
     229      end;
     230      if TileImp and fTerImp = tiMine then
     231        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     232          1 + 2 * (xxt * 2 + 1), 1 + yyt + 12 * (yyt * 3 + 1));
     233      inc(x, xxt * 2 + 6)
     234    end;
    222235  end;
    223236
  • trunk/LocalPlayer/Help.pas

    r328 r330  
    77  Protocol, ScreenTools, BaseWin, StringTables, Math, LCLIntf, LCLType,
    88  Messages, SysUtils, Classes, Graphics, Controls, Forms, ExtCtrls,
    9   ButtonB, PVSB, Types, fgl;
     9  ButtonB, PVSB, Types, fgl, IsoEngine;
    1010
    1111const
     
    102102    ExtPic, TerrIcon: TBitmap;
    103103    ScrollBar: TPVScrollbar;
     104    NoMap: TIsoMap;
    104105    x0: array [-2..180] of Integer;
    105106    procedure PaintTerrIcon(x, y, xSrc, ySrc: Integer);
     
    273274begin
    274275  inherited;
     276  NoMap := TIsoMap.Create;
     277
    275278  HistItems := THistItems.Create;
    276279
     
    331334  // FreeAndNil(CaptionFont);
    332335  FreeAndNil(HistItems);
     336  FreeAndNil(NoMap);
    333337end;
    334338
     
    502506procedure THelpDlg.PaintTerrIcon(x, y, xSrc, ySrc: integer);
    503507begin
    504   Frame(OffScreen.Canvas, x - 1, y - 1, x + xSizeBig, y + ySizeBig,
    505     $000000, $000000);
    506   if 2 * yyt < 40 then begin
    507     Sprite(OffScreen, HGrTerrain, x, y, 56, 2 * yyt, xSrc, ySrc);
    508     Sprite(OffScreen, HGrTerrain, x, y + 2 * yyt, 56, 40 - 2 * yyt,
     508  with NoMap do begin
     509    Frame(OffScreen.Canvas, x - 1, y - 1, x + xSizeBig, y + ySizeBig,
     510      $000000, $000000);
     511    if 2 * yyt < 40 then begin
     512      Sprite(OffScreen, HGrTerrain, x, y, 56, 2 * yyt, xSrc, ySrc);
     513      Sprite(OffScreen, HGrTerrain, x, y + 2 * yyt, 56, 40 - 2 * yyt,
     514        xSrc, ySrc);
     515    end else
     516      Sprite(OffScreen, HGrTerrain, x, y, 56, 40, xSrc, ySrc);
     517    Sprite(OffScreen, HGrTerrain, x, y, xxt, yyt, xSrc + xxt, ySrc + yyt);
     518    Sprite(OffScreen, HGrTerrain, x, y + yyt, xxt, 40 - yyt, xSrc + xxt, ySrc);
     519    Sprite(OffScreen, HGrTerrain, x + xxt, y, 56 - xxt, yyt, xSrc, ySrc + yyt);
     520    Sprite(OffScreen, HGrTerrain, x + xxt, y + yyt, 56 - xxt, 40 - yyt,
    509521      xSrc, ySrc);
    510   end else
    511     Sprite(OffScreen, HGrTerrain, x, y, 56, 40, xSrc, ySrc);
    512   Sprite(OffScreen, HGrTerrain, x, y, xxt, yyt, xSrc + xxt, ySrc + yyt);
    513   Sprite(OffScreen, HGrTerrain, x, y + yyt, xxt, 40 - yyt, xSrc + xxt, ySrc);
    514   Sprite(OffScreen, HGrTerrain, x + xxt, y, 56 - xxt, yyt, xSrc, ySrc + yyt);
    515   Sprite(OffScreen, HGrTerrain, x + xxt, y + yyt, 56 - xxt, 40 - yyt,
    516     xSrc, ySrc);
     522  end;
    517523end;
    518524
     
    605611                    12 + x0[i], -7 + i * 24, 56, 40, 137, 127);
    606612                1:
    607                   begin
     613                  with NoMap do begin
    608614                    PaintTerrIcon(12 + x0[i], -7 + i * 24,
    609615                      1 + 3 * (xxt * 2 + 1), 1 + yyt);
     
    618624                  end;
    619625                2:
    620                   begin
     626                  with NoMap do begin
    621627                    PaintTerrIcon(12 + x0[i], -7 + i * 24,
    622628                      1 + 7 * (xxt * 2 + 1), 1 + yyt + 4 * (yyt * 3 + 1));
     
    703709            end;
    704710          pkTer, pkBigTer:
    705             begin
     711            with NoMap do begin
    706712              if HelpLineInfo.Format = pkBigTer then
    707713                y := i * 24 - 3 + yyt
     
    758764            end;
    759765          pkTerImp:
    760             begin
     766            with NoMap do begin
    761767              ofs := 8;
    762768              if HelpLineInfo.Picpix = 5 then
  • trunk/LocalPlayer/IsoEngine.pas

    r327 r330  
    55
    66uses
    7   Protocol, ClientTools, ScreenTools, Tribes, {$IFNDEF SCR}Term, {$ENDIF}
     7  Protocol, ClientTools, ScreenTools, Tribes,
    88  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 }
     
    1529  TIsoMap = class
    1630  private
     31    FTileSize: TTileSize;
    1732    const
    1833      Dirx: array [0..7] of Integer = (1, 2, 1, 0, -1, -2, -1, 0);
     
    2136    function IsShoreTile(Loc: integer): boolean;
    2237    procedure MakeDark(Line: PPixelPointer; Length: Integer);
     38    procedure SetTileSize(AValue: TTileSize);
    2339    procedure ShadeOutside(x0, y0, Width, Height, xm, ym: integer);
    2440  protected
     
    3652    DataCanvas: TCanvas;
    3753    MaskCanvas: TCanvas;
     54    LandPatch: TBitmap;
     55    OceanPatch: TBitmap;
     56    Borders: TBitmap;
     57    BordersOK: PInteger;
     58    CitiesPictures: TCitiesPictures;
    3859    function Connection4(Loc, Mask, Value: integer): integer;
    3960    function Connection8(Loc, Mask: integer): integer;
     
    4869    procedure Sprite(HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
    4970    procedure TSprite(xDst, yDst, grix: integer; PureBlack: boolean = false);
     71    procedure ApplyTileSize(ATileSize: TTileSize);
    5072  public
     73    xxt: Integer; // half of tile size x/y
     74    yyt: Integer; // half of tile size x/y
     75    TSpriteSize: TTerrainSpriteSize;
     76    HGrTerrain: TGraphicSet;
     77    HGrCities: TGraphicSet;
     78    MapOptions: TMapOptions;
     79    pDebugMap: Integer; // -1 for off
    5180    constructor Create;
     81    destructor Destroy; override;
     82    procedure Reset;
    5283    procedure SetOutput(Output: TBitmap);
    5384    procedure SetPaintBounds(Left, Top, Right, Bottom: integer);
     
    6394    procedure AttackEffect(const ShowMove: TShowMove);
    6495    procedure AttackEnd;
     96    procedure ReduceTerrainIconsSize;
    6597    property AdviceLoc: integer read FAdviceLoc write FAdviceLoc;
    66   end;
    67 
    68 var
    69   NoMap: TIsoMap;
    70   MapOptions: TMapOptions;
    71   pDebugMap: Integer; // -1 for off
     98    property TileSize: TTileSize read FTileSize write SetTileSize;
     99  end;
     100
     101  { TIsoMapCache }
     102
     103  TIsoMapCache = class
     104    LandPatch: TBitmap;
     105    OceanPatch: TBitmap;
     106    Borders: TBitmap;
     107    BordersOk: Integer;
     108    TSpriteSize: TTerrainSpriteSize;
     109    HGrTerrain: TGraphicSet;
     110    HGrCities: TGraphicSet;
     111    CitiesPictures: TCitiesPictures;
     112    procedure AssignToIsoMap(IsoMap: TIsoMap);
     113    constructor Create;
     114    destructor Destroy; override;
     115  end;
     116
     117const
     118  DefaultTileSize: TTileSize = tsMedium;
     119  TileSizes: array [TTileSize] of TPoint = ((X: 33; Y: 16), (X: 48; Y: 24),
     120    (X: 72; Y: 36));
    72121
    73122function IsJungle(y: integer): boolean;
    74123procedure Init(InitEnemyModelHandler: TInitEnemyModelEvent);
    75 function ApplyTileSize(ATileSize: TTileSize): boolean;
    76 procedure Done;
    77 procedure IsoEngineReset;
     124
    78125
    79126implementation
     127
     128uses
     129  Term;
    80130
    81131const
    82132  ShoreDither = fGrass;
    83   TerrainIconLines = 21;
    84   TerrainIconCols = 9;
    85133
    86134  // sprites indexes
     
    111159
    112160var
    113   BordersOK: integer;
    114161  OnInitEnemyModel: TInitEnemyModelEvent;
    115   LandPatch: TBitmap;
    116   OceanPatch: TBitmap;
    117   Borders: TBitmap;
    118   TSpriteSize: array [0 .. TerrainIconLines * TerrainIconCols - 1] of TRect;
    119162  DebugMap: ^TTileList;
    120   CitiesPictures: array [2 .. 3, 0 .. 3] of TCityPicture;
    121163  FoW: Boolean;
    122164  ShowLoc: Boolean;
     
    127169  ShowGrWall: Boolean;
    128170  ShowDebug: Boolean;
     171  IsoMapCache: array[TTileSize] of TIsoMapCache;
    129172
    130173function IsJungle(y: integer): boolean;
     
    136179begin
    137180  OnInitEnemyModel := InitEnemyModelHandler;
    138   if NoMap <> nil then
    139     FreeAndNil(NoMap);
    140   NoMap := TIsoMap.Create;
    141 end;
    142 
    143 procedure ReduceTerrainIconsSize;
     181end;
     182
     183{ TCitiesPictures }
     184
     185procedure TCitiesPictures.Prepare(HGrCities: TGraphicSet; xxt, yyt: Integer);
     186var
     187  Age: Integer;
     188  Size: Integer;
     189begin
     190  // prepare age 2+3 cities
     191  for age := 2 to 3 do
     192    for size := 0 to 3 do
     193      with Pictures[Age, Size] do
     194        FindPosition(HGrCities, Size * (xxt * 2 + 1), (Age - 2) * (yyt * 3 + 1),
     195          xxt * 2 - 1, yyt * 3 - 1, $00FFFF, xShield, yShield);
     196end;
     197
     198{ TIsoMapCache }
     199
     200procedure TIsoMapCache.AssignToIsoMap(IsoMap: TIsoMap);
     201begin
     202  IsoMap.HGrTerrain := HGrTerrain;
     203  IsoMap.HGrCities := HGrCities;
     204  IsoMap.Borders := Borders;
     205  IsoMap.BordersOK := @BordersOk;
     206  IsoMap.LandPatch := LandPatch;
     207  IsoMap.OceanPatch := OceanPatch;
     208  IsoMap.TSpriteSize := TSpriteSize;
     209  IsoMap.CitiesPictures := CitiesPictures;
     210end;
     211
     212constructor TIsoMapCache.Create;
     213begin
     214  LandPatch := TBitmap.Create;
     215  LandPatch.PixelFormat := pf24bit;
     216  OceanPatch := TBitmap.Create;
     217  OceanPatch.PixelFormat := pf24bit;
     218  Borders := TBitmap.Create;
     219  Borders.PixelFormat := pf24bit;
     220  HGrTerrain := nil;
     221  HGrCities := nil;
     222  SetLength(TSpriteSize, TerrainIconLines * TerrainIconCols);
     223  CitiesPictures := TCitiesPictures.Create;
     224end;
     225
     226destructor TIsoMapCache.Destroy;
     227begin
     228  FreeAndNil(CitiesPictures);
     229  FreeAndNil(LandPatch);
     230  FreeAndNil(OceanPatch);
     231  FreeAndNil(Borders);
     232  inherited;
     233end;
     234
     235procedure TIsoMap.ReduceTerrainIconsSize;
    144236var
    145237  MaskLine: array of TPixelPointer;
     
    206298end;
    207299
    208 function ApplyTileSize(ATileSize: TTileSize): boolean;
     300procedure TIsoMap.ApplyTileSize(ATileSize: TTileSize);
    209301var
    210302  x: Integer;
     
    212304  xSrc: Integer;
    213305  ySrc: Integer;
    214   HGrTerrainNew: TGraphicSet;
    215   HGrCitiesNew: TGraphicSet;
    216   Age: Integer;
    217   Size: Integer;
    218306  LandMore: TBitmap;
    219307  OceanMore: TBitmap;
    220308  DitherMask: TBitmap;
    221   xxtNew: Integer;
    222   yytNew: Integer;
    223 begin
    224   xxtNew := TileSizes[ATileSize].X;
    225   yytNew := TileSizes[ATileSize].Y;
    226   result := false;
    227   HGrTerrainNew := LoadGraphicSet(Format('Terrain%dx%d.png',
    228     [xxtNew * 2, yytNew * 2]));
    229   if not Assigned(HGrTerrainNew) then
    230     exit;
    231   HGrCitiesNew := LoadGraphicSet(Format('Cities%dx%d.png',
    232     [xxtNew * 2, yytNew * 2]));
    233   if not Assigned(HGrCitiesNew) then
    234     exit;
    235   xxt := xxtNew;
    236   yyt := yytNew;
    237   TileSize := ATileSize;
    238   HGrTerrain := HGrTerrainNew;
    239   HGrCities := HGrCitiesNew;
    240   Result := true;
    241 
    242   // prepare age 2+3 cities
    243   for age := 2 to 3 do
    244     for size := 0 to 3 do
    245       with CitiesPictures[age, size] do
    246         FindPosition(HGrCities, size * (xxt * 2 + 1), (age - 2) * (yyt * 3 + 1),
    247           xxt * 2 - 1, yyt * 3 - 1, $00FFFF, xShield, yShield);
     309  FileName: string;
     310begin
     311  FTileSize := ATileSize;
     312  xxt := TileSizes[ATileSize].X;
     313  yyt := TileSizes[ATileSize].Y;
     314
     315  if Assigned(IsoMapCache[ATileSize]) then begin
     316    IsoMapCache[ATileSize].AssignToIsoMap(Self);
     317    Exit;
     318  end;
     319  IsoMapCache[ATileSize] := TIsoMapCache.Create;
     320
     321  FileName := Format('Terrain%dx%d.png', [xxt * 2, yyt * 2]);
     322  IsoMapCache[ATileSize].HGrTerrain := LoadGraphicSet(FileName);
     323  if not Assigned(IsoMapCache[ATileSize].HGrTerrain) then
     324    raise Exception.Create(FileName + ' not found.');
     325
     326  FileName := Format('Cities%dx%d.png', [xxt * 2, yyt * 2]);
     327  IsoMapCache[ATileSize].HGrCities := LoadGraphicSet(FileName);
     328  if not Assigned(IsoMapCache[ATileSize].HGrCities) then
     329    raise Exception.Create(FileName + ' not found.');
     330
     331  IsoMapCache[ATileSize].AssignToIsoMap(Self);
     332
     333  CitiesPictures.Prepare(HGrCities, xxt, yyt);
    248334
    249335  { prepare dithered ground tiles }
    250   if not Assigned(LandPatch) then begin
    251     LandPatch := TBitmap.Create;
    252     LandPatch.PixelFormat := pf24bit;
    253   end;
    254336  LandPatch.Canvas.Brush.Color := 0;
    255337  LandPatch.SetSize(xxt * 18, yyt * 9);
    256338  LandPatch.Canvas.FillRect(0, 0, LandPatch.Width, LandPatch.Height);
    257   if not Assigned(OceanPatch) then begin
    258     OceanPatch := TBitmap.Create;
    259     OceanPatch.PixelFormat := pf24bit;
    260   end;
    261339  OceanPatch.Canvas.Brush.Color := 0;
    262340  OceanPatch.SetSize(xxt * 8, yyt * 4);
     
    437515  ReduceTerrainIconsSize;
    438516
    439   if not Assigned(Borders) then begin
    440     Borders := TBitmap.Create;
    441     Borders.PixelFormat := pf24bit;
    442   end;
    443517  Borders.SetSize(xxt * 2, (yyt * 2) * nPl);
    444518  Borders.Canvas.FillRect(0, 0, Borders.Width, Borders.Height);
    445   BordersOK := 0;
    446 end;
    447 
    448 procedure Done;
    449 begin
    450   FreeAndNil(NoMap);
    451   FreeAndNil(LandPatch);
    452   FreeAndNil(OceanPatch);
    453   FreeAndNil(Borders);
    454 end;
    455 
    456 procedure IsoEngineReset;
    457 begin
    458   BordersOK := 0;
     519  BordersOK^ := 0;
     520end;
     521
     522procedure TIsoMap.Reset;
     523begin
     524  BordersOK^ := 0;
    459525end;
    460526
     
    469535  DefLoc := -1;
    470536  FAdviceLoc := -1;
     537  TileSize := DefaultTileSize;
     538end;
     539
     540destructor TIsoMap.Destroy;
     541begin
     542  inherited;
    471543end;
    472544
     
    711783    else
    712784    begin
    713       cpic := CitiesPictures[age, xGr];
     785      cpic := CitiesPictures.Pictures[age, xGr];
    714786      xShield := x - xxt + cpic.xShield;
    715787      yShield := y - 2 * yyt + cpic.yShield;
     
    10241096  begin
    10251097    if ShowBorder and (Loc >= 0) and (Loc < G.lx * G.ly) and
    1026       (Tile and fTerrain <> fUNKNOWN) then
    1027     begin
     1098      (Tile and fTerrain <> fUNKNOWN) then begin
    10281099      p1 := MyRO.Territory[Loc];
    1029       if (p1 >= 0) and (ShowMyBorder or (p1 <> me)) then
    1030       begin
    1031         if BordersOK and (1 shl p1) = 0 then
    1032         begin
     1100      if (p1 >= 0) and (ShowMyBorder or (p1 <> me)) then begin
     1101        if BordersOK^ and (1 shl p1) = 0 then begin
    10331102          UnshareBitmap(Borders);
    10341103          BitBltCanvas(Borders.Canvas, 0, p1 * (yyt * 2), xxt * 2,
     
    10491118          end;
    10501119          Borders.EndUpdate;
    1051           BordersOK := BordersOK or 1 shl p1;
     1120          BordersOK^ := BordersOK^ or 1 shl p1;
    10521121        end;
    10531122        for dy := 0 to 1 do
    1054           for dx := 0 to 1 do
    1055           begin
     1123          for dx := 0 to 1 do begin
    10561124            Loc1 := dLoc(Loc, dx * 2 - 1, dy * 2 - 1);
    10571125            begin
     
    10711139              end;
    10721140            end;
    1073           end
     1141          end;
    10741142      end;
    10751143    end;
     
    13471415    Line^.NextPixel;
    13481416  end;
     1417end;
     1418
     1419procedure TIsoMap.SetTileSize(AValue: TTileSize);
     1420begin
     1421  if FTileSize = AValue then Exit;
     1422  FTileSize := AValue;
     1423  ApplyTileSize(AValue);
    13491424end;
    13501425
     
    16411716end;
    16421717
    1643 initialization
    1644 
    1645 NoMap := nil;
    1646 LandPatch := nil;
    1647 OceanPatch := nil;
    1648 Borders := nil;
     1718procedure IsoEngineDone;
     1719var
     1720  I: TTileSize;
     1721begin
     1722  for I := Low(IsoMapCache) to High(IsoMapCache) do
     1723    FreeAndNil(IsoMapCache[I]);
     1724end;
     1725
     1726finalization
     1727
     1728IsoEngineDone;
    16491729
    16501730end.
  • trunk/LocalPlayer/Term.pas

    r329 r330  
    1414  LCLIntf, LCLType, SysUtils, Classes, Graphics, Controls, DrawDlg, Types,
    1515  Forms, Menus, ExtCtrls, dateutils, Platform, ButtonB, ButtonC, EOTButton, Area,
    16   UGraphicSet, UMiniMap;
     16  UGraphicSet, UMiniMap, IsoEngine;
    1717
    1818const
     
    2121type
    2222  TPaintLocTempStyle = (pltsNormal, pltsBlink);
    23   TTileSize = (tsSmall, tsMedium, tsBig);
    2423
    2524  TSoundBlock = (sbStart, sbWonder, sbScience, sbContact, sbTurn);
     
    270269    PrevWindowState: TWindowState;
    271270    CurrentWindowState: TWindowState;
     271    MainMap: TIsoMap;
     272    NoMap: TIsoMap;
     273    NoMapPanel: TIsoMap;
    272274    function ChooseUnusedTribe: integer;
    273275    procedure GetTribeList;
    274276    procedure InitModule;
     277    procedure DoneModule;
    275278    procedure InitTurn(NewPlayer: integer);
    276279    procedure SaveMenuItemsState;
     
    321324    procedure UpdateKeyShortcuts;
    322325    procedure SetFullScreen(Active: Boolean);
     326    procedure PaintZoomedTile(dst: TBitmap; x, y, Loc: integer);
    323327  public
    324328    UsedOffscreenWidth, UsedOffscreenHeight: integer;
     
    438442    'CITY_INVALIDTYPE');
    439443
    440   TileSizes: array [TTileSize] of TPoint = ((X: 33; Y: 16), (X: 48; Y: 24),
    441     (X: 72; Y: 36));
    442 
    443444type
    444445  TPersistentData = record
     
    477478  AdvIcon: array [0 .. nAdv - 1] of Integer;
    478479  { icons displayed with the technologies }
    479   xxt: Integer; // half of tile size x/y
    480   yyt: Integer; // half of tile size x/y
    481   TileSize: TTileSize;
    482480  GameMode: Integer;
    483481  ClientMode: Integer;
     
    491489  SoundPreloadDone: TSoundBlocks;
    492490  MarkCityLoc: Integer;
    493   HGrTerrain: TGraphicSet;
    494   HGrCities: TGraphicSet;
    495491  MovieSpeed: Integer;
    496492  CityRepMask: Cardinal;
     
    524520
    525521uses
    526   Directories, IsoEngine, CityScreen, Draft, MessgEx, Select, CityType, Help,
     522  Directories, CityScreen, Draft, MessgEx, Select, CityType, Help,
    527523  UnitStat, Log, Diagram, NatStat, Wonders, Enhance, Nego, UPixelPointer, Sound,
    528524  Battle, Rates, TechTree, Registry, Global, UKeyBindings;
     
    582578
    583579  SaveOption: array of Integer;
    584   MainMap: TIsoMap;
    585580  CurrentMoveInfo: TCurrentMoveInfo;
    586581
     
    925920end;
    926921
    927 procedure PaintZoomedTile(dst: TBitmap; x, y, Loc: integer);
     922procedure TMainScreen.PaintZoomedTile(dst: TBitmap; x, y, Loc: integer);
    928923
    929924  procedure TSprite(xDst, yDst, xSrc, ySrc: integer);
    930925  begin
    931     Sprite(dst, HGrTerrain, x + xDst, y + yDst, xxt * 2, yyt * 3,
    932       1 + xSrc * (xxt * 2 + 1), 1 + ySrc * (yyt * 3 + 1));
     926    with NoMapPanel do
     927      Sprite(dst, HGrTerrain, x + xDst, y + yDst, xxt * 2, yyt * 3,
     928        1 + xSrc * (xxt * 2 + 1), 1 + ySrc * (yyt * 3 + 1));
    933929  end;
    934930
    935931  procedure TSprite4(xSrc, ySrc: integer);
    936932  begin
    937     Sprite(dst, HGrTerrain, x + xxt, y + yyt + 2, xxt * 2, yyt * 2 - 2,
    938       1 + xSrc * (xxt * 2 + 1), 3 + yyt + ySrc * (yyt * 3 + 1));
    939     Sprite(dst, HGrTerrain, x + 4, y + 2 * yyt, xxt * 2 - 4, yyt * 2,
    940       5 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
    941     Sprite(dst, HGrTerrain, x + xxt * 2, y + 2 * yyt, xxt * 2 - 4, yyt * 2,
    942       1 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
    943     Sprite(dst, HGrTerrain, x + xxt, y + yyt * 3, xxt * 2, yyt * 2 - 2,
    944       1 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
     933    with NoMapPanel do begin
     934      Sprite(dst, HGrTerrain, x + xxt, y + yyt + 2, xxt * 2, yyt * 2 - 2,
     935        1 + xSrc * (xxt * 2 + 1), 3 + yyt + ySrc * (yyt * 3 + 1));
     936      Sprite(dst, HGrTerrain, x + 4, y + 2 * yyt, xxt * 2 - 4, yyt * 2,
     937        5 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
     938      Sprite(dst, HGrTerrain, x + xxt * 2, y + 2 * yyt, xxt * 2 - 4, yyt * 2,
     939        1 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
     940      Sprite(dst, HGrTerrain, x + xxt, y + yyt * 3, xxt * 2, yyt * 2 - 2,
     941        1 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
     942    end;
    945943  end;
    946944
     
    948946  cix, ySrc, Tile: integer;
    949947begin
    950   Tile := MyMap[Loc];
    951   if Tile and fCity <> 0 then
    952   begin
    953     if MyRO.Tech[adRailroad] >= tsApplicable then
    954       Tile := Tile or fRR
     948  with NoMapPanel do begin
     949    Tile := MyMap[Loc];
     950    if Tile and fCity <> 0 then
     951    begin
     952      if MyRO.Tech[adRailroad] >= tsApplicable then
     953        Tile := Tile or fRR
     954      else
     955        Tile := Tile or fRoad;
     956      if Tile and fOwned <> 0 then
     957      begin
     958        cix := MyRO.nCity - 1;
     959        while (cix >= 0) and (MyCity[cix].Loc <> Loc) do
     960          dec(cix);
     961        assert(cix >= 0);
     962        if MyCity[cix].Built[imSupermarket] > 0 then
     963          Tile := Tile or tiFarm
     964        else
     965          Tile := Tile or tiIrrigation;
     966      end
     967      else Tile := Tile or tiIrrigation;
     968    end;
     969
     970    if Tile and fTerrain >= fForest then
     971      TSprite4(2, 2)
    955972    else
    956       Tile := Tile or fRoad;
    957     if Tile and fOwned <> 0 then
    958     begin
    959       cix := MyRO.nCity - 1;
    960       while (cix >= 0) and (MyCity[cix].Loc <> Loc) do
    961         dec(cix);
    962       assert(cix >= 0);
    963       if MyCity[cix].Built[imSupermarket] > 0 then
    964         Tile := Tile or tiFarm
     973      TSprite4(Tile and fTerrain, 0);
     974    if Tile and fTerrain >= fForest then
     975    begin
     976      if (Tile and fTerrain = fForest) and IsJungle(Loc div G.lx) then
     977        ySrc := 18
    965978      else
    966         Tile := Tile or tiIrrigation;
    967     end
    968     else
    969       Tile := Tile or tiIrrigation;
    970   end;
    971 
    972   if Tile and fTerrain >= fForest then
    973     TSprite4(2, 2)
    974   else
    975     TSprite4(Tile and fTerrain, 0);
    976   if Tile and fTerrain >= fForest then
    977   begin
    978     if (Tile and fTerrain = fForest) and IsJungle(Loc div G.lx) then
    979       ySrc := 18
    980     else
    981       ySrc := 3 + 2 * (Tile and fTerrain - fForest);
    982     TSprite(xxt, 0, 6, ySrc);
    983     TSprite(0, yyt, 3, ySrc);
    984     TSprite((xxt * 2), yyt, 4, ySrc + 1);
    985     TSprite(xxt, (yyt * 2), 1, ySrc + 1);
    986   end;
    987 
    988   // irrigation
    989   case Tile and fTerImp of
    990     tiIrrigation:
    991       begin
     979        ySrc := 3 + 2 * (Tile and fTerrain - fForest);
     980      TSprite(xxt, 0, 6, ySrc);
     981      TSprite(0, yyt, 3, ySrc);
     982      TSprite((xxt * 2), yyt, 4, ySrc + 1);
     983      TSprite(xxt, (yyt * 2), 1, ySrc + 1);
     984    end;
     985
     986    // irrigation
     987    case Tile and fTerImp of
     988      tiIrrigation: begin
    992989        TSprite(xxt, 0, 0, 12);
    993990        TSprite(xxt * 2, yyt, 0, 12);
    994991      end;
    995     tiFarm:
    996       begin
     992      tiFarm: begin
    997993        TSprite(xxt, 0, 1, 12);
    998994        TSprite(xxt * 2, yyt, 1, 12);
    999       end
    1000   end;
    1001 
    1002   // river/canal/road/railroad
    1003   if Tile and fRiver <> 0 then
    1004   begin
    1005     TSprite(0, yyt, 2, 14);
    1006     TSprite(xxt, (yyt * 2), 2, 14);
    1007   end;
    1008   if Tile and fCanal <> 0 then
    1009   begin
    1010     TSprite(xxt, 0, 7, 11);
    1011     TSprite(xxt, 0, 3, 11);
    1012     TSprite(xxt * 2, yyt, 7, 11);
    1013     TSprite(xxt * 2, yyt, 3, 11);
    1014   end;
    1015   if Tile and fRR <> 0 then
    1016   begin
    1017     TSprite((xxt * 2), yyt, 1, 10);
    1018     TSprite((xxt * 2), yyt, 5, 10);
    1019     TSprite(xxt, (yyt * 2), 1, 10);
    1020     TSprite(xxt, (yyt * 2), 5, 10);
    1021   end
    1022   else if Tile and fRoad <> 0 then
    1023   begin
    1024     TSprite((xxt * 2), yyt, 8, 9);
    1025     TSprite((xxt * 2), yyt, 5, 9);
    1026     TSprite(xxt, (yyt * 2), 1, 9);
    1027     TSprite(xxt, (yyt * 2), 5, 9);
    1028   end;
    1029 
    1030   if Tile and fPoll <> 0 then
    1031     TSprite(xxt, (yyt * 2), 6, 12);
    1032 
    1033   // special
    1034   if Tile and (fTerrain or fSpecial) = fGrass or fSpecial1 then
    1035     TSprite4(2, 1)
    1036   else if Tile and fSpecial <> 0 then
    1037     if Tile and fTerrain < fForest then
    1038       TSprite(0, yyt, Tile and fTerrain, Tile and fSpecial shr 5)
    1039     else if (Tile and fTerrain = fForest) and IsJungle(Loc div G.lx) then
    1040       TSprite(0, yyt, 8, 17 + Tile and fSpecial shr 5)
    1041     else
    1042       TSprite(0, yyt, 8, 2 + (Tile and fTerrain - fForest) * 2 + Tile and
    1043         fSpecial shr 5)
    1044   else if Tile and fDeadLands <> 0 then
    1045   begin
    1046     TSprite4(6, 2);
    1047     TSprite(xxt, yyt, 8, 12 + Tile shr 25 and 3);
    1048   end;
    1049 
    1050   // other improvements
    1051   case Tile and fTerImp of
    1052     tiMine:
    1053       TSprite(xxt, 0, 2, 12);
    1054     tiFort:
    1055       begin
     995      end;
     996    end;
     997
     998    // river/canal/road/railroad
     999    if Tile and fRiver <> 0 then begin
     1000      TSprite(0, yyt, 2, 14);
     1001      TSprite(xxt, (yyt * 2), 2, 14);
     1002    end;
     1003    if Tile and fCanal <> 0 then begin
     1004      TSprite(xxt, 0, 7, 11);
     1005      TSprite(xxt, 0, 3, 11);
     1006      TSprite(xxt * 2, yyt, 7, 11);
     1007      TSprite(xxt * 2, yyt, 3, 11);
     1008    end;
     1009    if Tile and fRR <> 0 then begin
     1010      TSprite((xxt * 2), yyt, 1, 10);
     1011      TSprite((xxt * 2), yyt, 5, 10);
     1012      TSprite(xxt, (yyt * 2), 1, 10);
     1013      TSprite(xxt, (yyt * 2), 5, 10);
     1014    end
     1015    else if Tile and fRoad <> 0 then begin
     1016      TSprite((xxt * 2), yyt, 8, 9);
     1017      TSprite((xxt * 2), yyt, 5, 9);
     1018      TSprite(xxt, (yyt * 2), 1, 9);
     1019      TSprite(xxt, (yyt * 2), 5, 9);
     1020    end;
     1021
     1022    if Tile and fPoll <> 0 then
     1023      TSprite(xxt, (yyt * 2), 6, 12);
     1024
     1025    // special
     1026    if Tile and (fTerrain or fSpecial) = fGrass or fSpecial1 then TSprite4(2, 1)
     1027    else if Tile and fSpecial <> 0 then
     1028      if Tile and fTerrain < fForest then
     1029        TSprite(0, yyt, Tile and fTerrain, Tile and fSpecial shr 5)
     1030      else if (Tile and fTerrain = fForest) and IsJungle(Loc div G.lx) then
     1031        TSprite(0, yyt, 8, 17 + Tile and fSpecial shr 5)
     1032      else
     1033        TSprite(0, yyt, 8, 2 + (Tile and fTerrain - fForest) * 2 + Tile and
     1034          fSpecial shr 5)
     1035    else if Tile and fDeadLands <> 0 then begin
     1036      TSprite4(6, 2);
     1037      TSprite(xxt, yyt, 8, 12 + Tile shr 25 and 3);
     1038    end;
     1039
     1040    // other improvements
     1041    case Tile and fTerImp of
     1042      tiMine: TSprite(xxt, 0, 2, 12);
     1043      tiFort: begin
    10561044        TSprite(xxt, 0, 7, 12);
    10571045        TSprite(xxt, 0, 3, 12);
    10581046      end;
    1059     tiBase:
    1060       TSprite(xxt, 0, 4, 12);
     1047     tiBase: TSprite(xxt, 0, 4, 12);
     1048    end;
    10611049  end;
    10621050end;
     
    12681256begin
    12691257  MiniMap.MapOptions := MapOptionChecked;
    1270   IsoEngine.MapOptions := MapOptionChecked;
     1258  MainMap.MapOptions := MapOptionChecked;
    12711259  if ClientMode = cEditMap then
    1272     IsoEngine.MapOptions := IsoEngine.MapOptions + [moEditMode];
     1260    MainMap.MapOptions := MainMap.MapOptions + [moEditMode];
    12731261  if mLocCodes.Checked then
    1274     IsoEngine.MapOptions := IsoEngine.MapOptions + [moLocCodes];
     1262    MainMap.MapOptions := MainMap.MapOptions + [moLocCodes];
    12751263end;
    12761264
     
    16381626
    16391627  IsoEngine.Init(InitEnemyModel);
    1640   if not IsoEngine.ApplyTileSize(TileSize) and (TileSize <> tsMedium) then
    1641     ApplyTileSize(tsMedium);
    16421628  // non-default tile size is missing a file, switch to default
    1643   MainMap := TIsoMap.Create;
    16441629  MainMap.SetOutput(offscreen);
    16451630
     
    16541639  sb := TPVScrollbar.Create(Self);
    16551640  sb.OnUpdate := ScrollBarUpdate;
     1641end;
     1642
     1643procedure TMainScreen.DoneModule;
     1644begin
     1645  FreeAndNil(SmallImp);
     1646  FreeAndNil(UnusedTribeFiles);
     1647  FreeAndNil(TribeNames);
     1648  // AdvisorDlg.DeInit;
    16561649end;
    16571650
     
    18391832    Loc1 := MyCity[0].Loc;
    18401833    if (ClientMode = cTurn) and (MyRO.Turn = 0) then
    1841     begin // move city out of center to not be covered by welcome screen
     1834    with MainMap do begin // move city out of center to not be covered by welcome screen
    18421835      dx := MapWidth div (xxt * 5);
    18431836      if dx > 5 then
     
    25362529      end;
    25372530
    2538     cReleaseModule:
    2539       begin
    2540         FreeAndNil(SmallImp);
    2541         FreeAndNil(UnusedTribeFiles);
    2542         FreeAndNil(TribeNames);
    2543         FreeAndNil(MainMap);
    2544         IsoEngine.Done;
    2545         // AdvisorDlg.DeInit;
    2546       end;
     2531    cReleaseModule: DoneModule;
    25472532
    25482533    cHelpOnly, cStartHelp, cStartCredits:
     
    25732558        ClientMode := -1;
    25742559        SetMapOptions;
    2575         IsoEngine.pDebugMap := -1;
     2560        MainMap.pDebugMap := -1;
    25762561        idle := false;
    25772562        FillChar(Jump, SizeOf(Jump), 0);
     
    25802565        GameMode := Command;
    25812566        GrExt.ResetPixUsed;
    2582         IsoEngineReset;
     2567        MainMap.Reset;
     2568        NoMap.Reset;
    25832569        Tribes.Init;
    25842570        GetTribeList;
     
    28972883        ClientMode := cEditMap;
    28982884        SetMapOptions;
    2899         IsoEngine.pDebugMap := -1;
     2885        MainMap.pDebugMap := -1;
    29002886        ItsMeAgain(0);
    29012887        MyData := nil;
     
    33933379    cRefreshDebugMap:
    33943380      begin
    3395         if integer(Data) = IsoEngine.pDebugMap then
     3381        if integer(Data) = MainMap.pDebugMap then
    33963382        begin
    33973383          MapValid := false;
     
    34453431  i, j: integer;
    34463432begin
     3433  NoMap := TIsoMap.Create;
     3434  MainMap := TIsoMap.Create;
     3435  NoMapPanel := TIsoMap.Create;
     3436
    34473437  KeyBindings.LoadFromRegistry(HKEY_CURRENT_USER, AppRegistryKey + '\KeyBindings');
    34483438  UpdateKeyShortcuts;
     
    35593549      FreeAndNil(AILogo[I]);
    35603550  FreeAndNil(Offscreen);
     3551  FreeAndNil(MainMap);
     3552  FreeAndNil(NoMap);
     3553  FreeAndNil(NoMapPanel);
    35613554end;
    35623555
     
    35683561    Update;
    35693562  end else begin
    3570     if (WheelDelta > 0) and (TileSize < High(TTileSize)) then SetTileSize(Succ(TileSize))
    3571     else if (WheelDelta < 0) and (TileSize > Low(TTileSize)) then SetTileSize(Pred(TileSize));
     3563    if (WheelDelta > 0) and (MainMap.TileSize < High(TTileSize)) then
     3564      SetTileSize(Succ(MainMap.TileSize))
     3565    else if (WheelDelta < 0) and (MainMap.TileSize > Low(TTileSize)) then
     3566      SetTileSize(Pred(MainMap.TileSize));
    35723567  end;
    35733568end;
     
    35783573begin
    35793574  SmallScreen := ClientWidth < 1024;
    3580   MaxMapWidth := (G.lx * 2 - 3) * xxt;
    3581   // avoide the same tile being visible left and right
    3582   if ClientWidth <= MaxMapWidth then
    3583   begin
    3584     MapWidth := ClientWidth;
    3585     MapOffset := 0;
    3586   end
    3587   else
    3588   begin
    3589     MapWidth := MaxMapWidth;
    3590     MapOffset := (ClientWidth - MapWidth) div 2;
    3591   end;
    3592   MapHeight := ClientHeight - TopBarHeight - PanelHeight + overlap;
    3593   Panel.SetSize(ClientWidth, PanelHeight);
    3594   TopBar.SetSize(ClientWidth, TopBarHeight);
    3595   MiniFrame := (lxmax_xxx - G.ly) div 2;
    3596   xMidPanel := (G.lx + MiniFrame) * 2 + 1;
    3597   xRightPanel := ClientWidth - LeftPanelWidth - 10;
    3598   if ClientMode = cEditMap then
    3599     TrPitch := 2 * xxt
    3600   else
    3601     TrPitch := 66;
    3602   xMini := MiniFrame - 5;
    3603   yMini := (PanelHeight - 26 - lxmax_xxx) div 2 + MiniFrame;
    3604   ywmax := (G.ly - MapHeight div yyt + 1) and not 1;
    3605   ywcenter := -((MapHeight - yyt * (G.ly - 1)) div (4 * yyt)) * 2;
     3575  with MainMap do begin
     3576    MaxMapWidth := (G.lx * 2 - 3) * xxt;
     3577    // avoide the same tile being visible left and right
     3578    if ClientWidth <= MaxMapWidth then begin
     3579      MapWidth := ClientWidth;
     3580      MapOffset := 0;
     3581    end else begin
     3582      MapWidth := MaxMapWidth;
     3583      MapOffset := (ClientWidth - MapWidth) div 2;
     3584    end;
     3585    MapHeight := ClientHeight - TopBarHeight - PanelHeight + overlap;
     3586    Panel.SetSize(ClientWidth, PanelHeight);
     3587    TopBar.SetSize(ClientWidth, TopBarHeight);
     3588    MiniFrame := (lxmax_xxx - G.ly) div 2;
     3589    xMidPanel := (G.lx + MiniFrame) * 2 + 1;
     3590    xRightPanel := ClientWidth - LeftPanelWidth - 10;
     3591    if ClientMode = cEditMap then
     3592      TrPitch := 2 * xxt
     3593    else
     3594      TrPitch := 66;
     3595    xMini := MiniFrame - 5;
     3596    yMini := (PanelHeight - 26 - lxmax_xxx) div 2 + MiniFrame;
     3597    ywmax := (G.ly - MapHeight div yyt + 1) and not 1;
     3598    ywcenter := -((MapHeight - yyt * (G.ly - 1)) div (4 * yyt)) * 2;
     3599  end;
    36063600  // only for ywmax<=0
    36073601  if ywmax <= 0 then
     
    37053699    xTroop := xMidPanel + 15
    37063700  else
    3707   begin
     3701  with MainMap do begin
    37083702    if supervising then
    37093703      xTerrain := xMidPanel + 2 * xxt + 14
     
    39743968  xs, ys, xl, yl: integer;
    39753969begin
    3976   xl := nx * xxt + xxt;
    3977   yl := ny * yyt + yyt * 2;
    3978   xs := (x0 - xw) * (xxt * 2) + y0 and 1 * xxt - G.lx * (xxt * 2);
    3979   // |xs+xl/2-MapWidth/2| -> min
    3980   while abs(2 * (xs + G.lx * (xxt * 2)) + xl - MapWidth) <
    3981     abs(2 * xs + xl - MapWidth) do
    3982     inc(xs, G.lx * (xxt * 2));
    3983   ys := (y0 - yw) * yyt - yyt;
    3984   if xs + xl > MapWidth then
    3985     xl := MapWidth - xs;
    3986   if ys + yl > MapHeight then
    3987     yl := MapHeight - ys;
    3988   if (xl <= 0) or (yl <= 0) then
    3989     exit;
    3990   if Options and prPaint <> 0 then
    3991   begin
    3992     if Options and prAutoBounds <> 0 then
    3993       MainMap.SetPaintBounds(xs, ys, xs + xl, ys + yl);
    3994     MainMap.Paint(xs, ys, x0 + G.lx * y0, nx, ny, -1, -1);
    3995   end;
    3996   if Options and prInvalidate <> 0 then
    3997     RectInvalidate(MapOffset + xs, TopBarHeight + ys, MapOffset + xs + xl,
    3998       TopBarHeight + ys + yl)
     3970  with MainMap do begin
     3971    xl := nx * xxt + xxt;
     3972    yl := ny * yyt + yyt * 2;
     3973    xs := (x0 - xw) * (xxt * 2) + y0 and 1 * xxt - G.lx * (xxt * 2);
     3974    // |xs+xl/2-MapWidth/2| -> min
     3975    while abs(2 * (xs + G.lx * (xxt * 2)) + xl - MapWidth) <
     3976      abs(2 * xs + xl - MapWidth) do
     3977        inc(xs, G.lx * (xxt * 2));
     3978    ys := (y0 - yw) * yyt - yyt;
     3979    if xs + xl > MapWidth then
     3980      xl := MapWidth - xs;
     3981    if ys + yl > MapHeight then
     3982      yl := MapHeight - ys;
     3983    if (xl <= 0) or (yl <= 0) then
     3984      exit;
     3985    if Options and prPaint <> 0 then begin
     3986      if Options and prAutoBounds <> 0 then
     3987        MainMap.SetPaintBounds(xs, ys, xs + xl, ys + yl);
     3988      MainMap.Paint(xs, ys, x0 + G.lx * y0, nx, ny, -1, -1);
     3989    end;
     3990    if Options and prInvalidate <> 0 then
     3991      RectInvalidate(MapOffset + xs, TopBarHeight + ys, MapOffset + xs + xl,
     3992        TopBarHeight + ys + yl)
     3993  end;
    39993994end;
    40003995
     
    40033998  yLoc, x0: integer;
    40043999begin
    4005   if MapValid then
    4006   begin
     4000  if MapValid then begin
    40074001    yLoc := (Loc + G.lx * 1024) div G.lx - 1024;
    40084002    x0 := (Loc + (yLoc and 1 - 2 * Radius + G.lx * 1024) div 2) mod G.lx;
     
    40114005      prPaint or prAutoBounds or prInvalidate);
    40124006    Update;
    4013   end
     4007  end;
    40144008end;
    40154009
     
    40184012  y0, x0, xMap, yMap: integer;
    40194013begin
    4020   if not MapValid then
    4021     exit;
    4022   Buffer.Canvas.Font.Assign(UniFont[ftSmall]);
    4023   y0 := Loc div G.lx;
    4024   x0 := Loc mod G.lx;
    4025   xMap := (x0 - xw) * (xxt * 2) + y0 and 1 * xxt - G.lx * (xxt * 2);
    4026   // |xMap+xxt-MapWidth/2| -> min
    4027   while abs(2 * (xMap + G.lx * (xxt * 2)) + 2 * xxt - MapWidth) <
    4028     abs(2 * xMap + 2 * xxt - MapWidth) do
    4029     inc(xMap, G.lx * (xxt * 2));
    4030   yMap := (y0 - yw) * yyt - yyt;
    4031   NoMap.SetOutput(Buffer);
    4032   NoMap.SetPaintBounds(0, 0, 2 * xxt, 3 * yyt);
    4033   NoMap.Paint(0, 0, Loc, 1, 1, -1, -1, Style = pltsBlink);
    4034   PaintBufferToScreen(xMap, yMap, 2 * xxt, 3 * yyt);
     4014  with NoMap do begin
     4015    if not MapValid then
     4016      exit;
     4017    Buffer.Canvas.Font.Assign(UniFont[ftSmall]);
     4018    y0 := Loc div G.lx;
     4019    x0 := Loc mod G.lx;
     4020    xMap := (x0 - xw) * (xxt * 2) + y0 and 1 * xxt - G.lx * (xxt * 2);
     4021    // |xMap+xxt-MapWidth/2| -> min
     4022    while abs(2 * (xMap + G.lx * (xxt * 2)) + 2 * xxt - MapWidth) <
     4023      abs(2 * xMap + 2 * xxt - MapWidth) do
     4024      inc(xMap, G.lx * (xxt * 2));
     4025    yMap := (y0 - yw) * yyt - yyt;
     4026    NoMap.SetOutput(Buffer);
     4027    NoMap.SetPaintBounds(0, 0, 2 * xxt, 3 * yyt);
     4028    NoMap.Paint(0, 0, Loc, 1, 1, -1, -1, Style = pltsBlink);
     4029    PaintBufferToScreen(xMap, yMap, 2 * xxt, 3 * yyt);
     4030  end;
    40354031end;
    40364032
     
    40604056    else
    40614057      BitBltCanvas(Canvas, xMap + MapOffset, TopBarHeight, width,
    4062         height + yMap, Buffer.Canvas, 0, -yMap)
     4058        height + yMap, Buffer.Canvas, 0, -yMap);
    40634059  end
    40644060  else
     
    40704066      BitBltCanvas(Canvas, xMap + MapOffset, TopBarHeight + yMap, width,
    40714067        height, Buffer.Canvas, 0, 0);
    4072   end
     4068  end;
    40734069end;
    40744070
     
    41354131  end;
    41364132
    4137   if xw - xwd > G.lx div 2 then
    4138     xwd := xwd + G.lx
    4139   else if xwd - xw > G.lx div 2 then
    4140     xwd := xwd - G.lx;
    4141   if not MapValid or (xw - xwd > MapWidth div (xxt * 2)) or
    4142     (xwd - xw > MapWidth div (xxt * 2)) or (yw - ywd > MapHeight div yyt) or
    4143     (ywd - yw > MapHeight div yyt) then
    4144   begin
    4145     offscreen.Canvas.Font.Assign(UniFont[ftSmall]);
    4146     ProcessRect(xw, yw, MapWidth div xxt, MapHeight div yyt,
    4147       prPaint or prInvalidate);
    4148   end
    4149   else
    4150   begin
    4151     if (xwd = xw) and (ywd = yw) then
    4152       exit; { map window not moved }
    4153     offscreen.Canvas.Font.Assign(UniFont[ftSmall]);
    4154     rec := Rect(0, 0, MapWidth, MapHeight);
     4133  with MainMap do begin
     4134    if xw - xwd > G.lx div 2 then
     4135      xwd := xwd + G.lx
     4136    else if xwd - xw > G.lx div 2 then
     4137      xwd := xwd - G.lx;
     4138    if not MapValid or (xw - xwd > MapWidth div (xxt * 2)) or
     4139      (xwd - xw > MapWidth div (xxt * 2)) or (yw - ywd > MapHeight div yyt) or
     4140      (ywd - yw > MapHeight div yyt) then
     4141    begin
     4142      offscreen.Canvas.Font.Assign(UniFont[ftSmall]);
     4143      ProcessRect(xw, yw, MapWidth div xxt, MapHeight div yyt,
     4144        prPaint or prInvalidate);
     4145    end else begin
     4146      if (xwd = xw) and (ywd = yw) then
     4147        exit; { map window not moved }
     4148      offscreen.Canvas.Font.Assign(UniFont[ftSmall]);
     4149      rec := Rect(0, 0, MapWidth, MapHeight);
    41554150{$IFDEF WINDOWS}
    4156     ScrollDC(offscreen.Canvas.Handle, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt,
    4157       rec, rec, 0, nil);
     4151      ScrollDC(offscreen.Canvas.Handle, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt,
     4152        rec, rec, 0, nil);
    41584153{$ENDIF}
    41594154{$IFDEF LINUX}
    4160     ScrollDC(offscreen.Canvas, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt,
    4161       rec, rec, 0, nil);
     4155      ScrollDC(offscreen.Canvas, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt,
     4156        rec, rec, 0, nil);
    41624157{$ENDIF}
    4163     for DoInvalidate := false to FastScrolling do
    4164     begin
    4165       if DoInvalidate then
    4166       begin
    4167         rec.Bottom := MapHeight - overlap;
     4158      for DoInvalidate := false to FastScrolling do begin
     4159        if DoInvalidate then begin
     4160          rec.Bottom := MapHeight - overlap;
    41684161{$IFDEF WINDOWS}
    4169         ScrollDC(Canvas.Handle, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt, rec,
    4170           rec, 0, nil);
     4162          ScrollDC(Canvas.Handle, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt, rec,
     4163            rec, 0, nil);
    41714164{$ENDIF}
    41724165{$IFDEF LINUX}
    4173         ScrollDC(Canvas, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt,
    4174           rec, rec, 0, nil);
     4166          ScrollDC(Canvas, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt,
     4167            rec, rec, 0, nil);
    41754168{$ENDIF}
    4176         ProcessOptions := prInvalidate;
    4177       end
    4178       else
    4179         ProcessOptions := prPaint or prAutoBounds;
    4180       if yw < ywd then
    4181       begin
    4182         ProcessRect(xw, yw, MapWidth div xxt, ywd - yw - 1, ProcessOptions);
    4183         if xw < xwd then
    4184           ProcessRect(xw, ywd, (xwd - xw) * 2 - 1, MapHeight div yyt - ywd + yw,
     4169          ProcessOptions := prInvalidate;
     4170        end
     4171        else ProcessOptions := prPaint or prAutoBounds;
     4172        if yw < ywd then begin
     4173          ProcessRect(xw, yw, MapWidth div xxt, ywd - yw - 1, ProcessOptions);
     4174          if xw < xwd then
     4175            ProcessRect(xw, ywd, (xwd - xw) * 2 - 1, MapHeight div yyt - ywd + yw,
     4176              ProcessOptions)
     4177          else if xw > xwd then
     4178            ProcessRect((xwd + MapWidth div (xxt * 2)) mod G.lx, ywd,
     4179              (xw - xwd) * 2 + 1, MapHeight div yyt - ywd + yw, ProcessOptions)
     4180        end
     4181        else if yw > ywd then begin
     4182          if DoInvalidate then
     4183            RectInvalidate(MapOffset, TopBarHeight + MapHeight - overlap -
     4184              (yw - ywd) * yyt, MapOffset + MapWidth, TopBarHeight + MapHeight
     4185              - overlap)
     4186          else
     4187            ProcessRect(xw, (ywd + MapHeight div (yyt * 2) * 2), MapWidth div xxt,
     4188              yw - ywd + 1, ProcessOptions);
     4189          if xw < xwd then
     4190            ProcessRect(xw, yw, (xwd - xw) * 2 - 1, MapHeight div yyt - yw + ywd -
     4191              2, ProcessOptions)
     4192          else if xw > xwd then
     4193            ProcessRect((xwd + MapWidth div (xxt * 2)) mod G.lx, yw,
     4194              (xw - xwd) * 2 + 1, MapHeight div yyt - yw + ywd - 2,
     4195              ProcessOptions);
     4196        end
     4197        else if xw < xwd then
     4198          ProcessRect(xw, yw, (xwd - xw) * 2 - 1, MapHeight div yyt,
    41854199            ProcessOptions)
    41864200        else if xw > xwd then
    4187           ProcessRect((xwd + MapWidth div (xxt * 2)) mod G.lx, ywd,
    4188             (xw - xwd) * 2 + 1, MapHeight div yyt - ywd + yw, ProcessOptions)
    4189       end
    4190       else if yw > ywd then
    4191       begin
    4192         if DoInvalidate then
    4193           RectInvalidate(MapOffset, TopBarHeight + MapHeight - overlap -
    4194             (yw - ywd) * yyt, MapOffset + MapWidth, TopBarHeight + MapHeight
    4195             - overlap)
    4196         else
    4197           ProcessRect(xw, (ywd + MapHeight div (yyt * 2) * 2), MapWidth div xxt,
    4198             yw - ywd + 1, ProcessOptions);
    4199         if xw < xwd then
    4200           ProcessRect(xw, yw, (xwd - xw) * 2 - 1, MapHeight div yyt - yw + ywd -
    4201             2, ProcessOptions)
    4202         else if xw > xwd then
    42034201          ProcessRect((xwd + MapWidth div (xxt * 2)) mod G.lx, yw,
    4204             (xw - xwd) * 2 + 1, MapHeight div yyt - yw + ywd - 2,
    4205             ProcessOptions)
    4206       end
    4207       else if xw < xwd then
    4208         ProcessRect(xw, yw, (xwd - xw) * 2 - 1, MapHeight div yyt,
    4209           ProcessOptions)
    4210       else if xw > xwd then
    4211         ProcessRect((xwd + MapWidth div (xxt * 2)) mod G.lx, yw,
    4212           (xw - xwd) * 2 + 1, MapHeight div yyt, ProcessOptions);
    4213     end;
    4214     if not FastScrolling then
    4215       RectInvalidate(MapOffset, TopBarHeight, MapOffset + MapWidth,
    4216         TopBarHeight + MapHeight - overlap);
    4217     RectInvalidate(xMidPanel, TopBarHeight + MapHeight - overlap, xRightPanel,
    4218       TopBarHeight + MapHeight);
     4202            (xw - xwd) * 2 + 1, MapHeight div yyt, ProcessOptions);
     4203      end;
     4204      if not FastScrolling then
     4205        RectInvalidate(MapOffset, TopBarHeight, MapOffset + MapWidth,
     4206          TopBarHeight + MapHeight - overlap);
     4207      RectInvalidate(xMidPanel, TopBarHeight + MapHeight - overlap, xRightPanel,
     4208        TopBarHeight + MapHeight);
     4209    end;
    42194210  end;
    42204211  // if (xwd<>xw) or (ywd<>yw) then
     
    42274218procedure TMainScreen.MiniMapPaint;
    42284219begin
    4229   MiniMap.Paint(MyMap, MapWidth, ClientMode, xxt, xwMini);
     4220  with MainMap do
     4221    MiniMap.Paint(MyMap, MapWidth, ClientMode, xxt, xwMini);
    42304222end;
    42314223
     
    42534245procedure TMainScreen.CopyMiniToPanel;
    42544246begin
    4255   BitBltCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
    4256     MiniMap.Bitmap.Canvas, 0, 0);
    4257   if MarkCityLoc >= 0 then
    4258     Sprite(Panel, HGrSystem, xMini - 2 + (4 * G.lx + 2 * (MarkCityLoc mod G.lx)
    4259       + (G.lx - MapWidth div (xxt * 2)) - 2 * xwd) mod (2 * G.lx) +
    4260       MarkCityLoc div G.lx and 1, yMini - 3 + MarkCityLoc div G.lx, CityMark2.Width,
    4261       CityMark2.Height, CityMark2.Left, CityMark2.Top)
    4262   else if ywmax <= 0 then
    4263     Frame(Panel.Canvas,
    4264       xMini + 2 + G.lx - MapWidth div (xxt * 2), yMini + 2,
    4265       xMini + 1 + G.lx + MapWidth div (xxt * 2), yMini + 2 + G.ly - 1,
    4266       MainTexture.clMark, MainTexture.clMark)
    4267   else
    4268     Frame(Panel.Canvas,
    4269       xMini + 2 + G.lx - MapWidth div (xxt * 2), yMini + 2 + yw,
    4270       xMini + 1 + G.lx + MapWidth div (xxt * 2), yMini + yw + MapHeight div yyt,
    4271       MainTexture.clMark, MainTexture.clMark);
     4247  with MainMap do begin
     4248    BitBltCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
     4249      MiniMap.Bitmap.Canvas, 0, 0);
     4250    if MarkCityLoc >= 0 then
     4251      Sprite(Panel, HGrSystem, xMini - 2 + (4 * G.lx + 2 * (MarkCityLoc mod G.lx)
     4252        + (G.lx - MapWidth div (xxt * 2)) - 2 * xwd) mod (2 * G.lx) +
     4253        MarkCityLoc div G.lx and 1, yMini - 3 + MarkCityLoc div G.lx, CityMark2.Width,
     4254        CityMark2.Height, CityMark2.Left, CityMark2.Top)
     4255    else if ywmax <= 0 then
     4256      Frame(Panel.Canvas,
     4257        xMini + 2 + G.lx - MapWidth div (xxt * 2), yMini + 2,
     4258        xMini + 1 + G.lx + MapWidth div (xxt * 2), yMini + 2 + G.ly - 1,
     4259        MainTexture.clMark, MainTexture.clMark)
     4260    else
     4261      Frame(Panel.Canvas,
     4262        xMini + 2 + G.lx - MapWidth div (xxt * 2), yMini + 2 + yw,
     4263        xMini + 1 + G.lx + MapWidth div (xxt * 2), yMini + yw + MapHeight div yyt,
     4264        MainTexture.clMark, MainTexture.clMark);
     4265  end;
    42724266end;
    42734267
     
    44574451              end;
    44584452          end;
    4459           if xSrcBase >= 0 then
     4453          with MainMap do begin
     4454            if xSrcBase >= 0 then
     4455              Sprite(Panel, HGrTerrain, xTroop + 2 + x, yTroop + 9 - yyt, xxt * 2,
     4456                yyt * 3, 1 + xSrcBase * (xxt * 2 + 1),
     4457                1 + ySrcBase * (yyt * 3 + 1));
    44604458            Sprite(Panel, HGrTerrain, xTroop + 2 + x, yTroop + 9 - yyt, xxt * 2,
    4461               yyt * 3, 1 + xSrcBase * (xxt * 2 + 1),
    4462               1 + ySrcBase * (yyt * 3 + 1));
    4463           Sprite(Panel, HGrTerrain, xTroop + 2 + x, yTroop + 9 - yyt, xxt * 2,
    4464             yyt * 3, 1 + xSrc * (xxt * 2 + 1), 1 + ySrc * (yyt * 3 + 1));
    4465           if BrushTypes[i] = BrushType then
    4466           begin
    4467             ScreenTools.Frame(Panel.Canvas, xTroop + 2 + x,
    4468               yTroop + 7 - yyt div 2, xTroop + 2 * xxt + x,
    4469               yTroop + 2 * yyt + 11, $000000, $000000);
    4470             ScreenTools.Frame(Panel.Canvas, xTroop + 1 + x,
    4471               yTroop + 6 - yyt div 2, xTroop + 2 * xxt - 1 + x,
    4472               yTroop + 2 * yyt + 10, MainTexture.clMark, MainTexture.clMark);
    4473           end
     4459              yyt * 3, 1 + xSrc * (xxt * 2 + 1), 1 + ySrc * (yyt * 3 + 1));
     4460            if BrushTypes[i] = BrushType then begin
     4461              ScreenTools.Frame(Panel.Canvas, xTroop + 2 + x,
     4462                yTroop + 7 - yyt div 2, xTroop + 2 * xxt + x,
     4463                yTroop + 2 * yyt + 11, $000000, $000000);
     4464              ScreenTools.Frame(Panel.Canvas, xTroop + 1 + x,
     4465                yTroop + 6 - yyt div 2, xTroop + 2 * xxt - 1 + x,
     4466                yTroop + 2 * yyt + 10, MainTexture.clMark, MainTexture.clMark);
     4467            end;
     4468          end;
    44744469        end;
    44754470        inc(Count)
     
    46374632                          xTroop + 63 + x, yTroop + 46, 8, MainTexture.clMark);
    46384633                      end;
    4639                       NoMap.SetOutput(Panel);
    4640                       NoMap.PaintUnit(xTroop + 2 + x, yTroop + 1, UnitInfo,
     4634                      NoMapPanel.SetOutput(Panel);
     4635                      NoMapPanel.PaintUnit(xTroop + 2 + x, yTroop + 1, UnitInfo,
    46414636                        unx.Status);
    46424637                      if (ClientMode < scContact) and
     
    46554650                          xTroop + x + 34 - BiColorTextWidth(Panel.Canvas, s)
    46564651                          div 2, yTroop - 16, s);
    4657                       end
     4652                      end;
    46584653                    end;
    46594654                    inc(Count)
     
    46614656                end; // for uix:=0 to MyRO.nUn-1
    46624657            assert(Count = TrCnt);
    4663           end
     4658          end;
    46644659        end
    46654660        else
     
    46734668              trix[i - TrRow * sb.Position] := i;
    46744669              x := (i - TrRow * sb.Position) * TrPitch;
    4675               NoMap.SetOutput(Panel);
    4676               NoMap.PaintUnit(xTroop + 2 + x, yTroop + 1,
     4670              NoMapPanel.SetOutput(Panel);
     4671              NoMapPanel.PaintUnit(xTroop + 2 + x, yTroop + 1,
    46774672                MyRO.EnemyUn[MyRO.nEnemyUn + i], 0);
    46784673            end;
     
    46814676      if not SmallScreen or supervising then
    46824677      begin // show terrain and improvements
    4683         PaintZoomedTile(Panel, xTerrain - xxt * 2, 110 - yyt * 3, TroopLoc);
    4684         if (UnFocus >= 0) and (MyUn[UnFocus].Job <> jNone) then
    4685         begin
     4678        with NoMapPanel do
     4679          PaintZoomedTile(Panel, xTerrain - xxt * 2, 110 - yyt * 3, TroopLoc);
     4680        if (UnFocus >= 0) and (MyUn[UnFocus].Job <> jNone) then begin
    46864681          JobFocus := MyUn[UnFocus].Job;
    46874682          Server(sGetJobProgress, me, MyUn[UnFocus].Loc, JobProgressData);
     
    47314726            (PanelHeight - 1), Left + width, Top + height - self.ClientHeight +
    47324727            PanelHeight, MainTexture.clBevelShade, MainTexture.clBevelLight)
    4733     end { if TroopLoc>=0 }
     4728    end; { if TroopLoc>=0 }
    47344729  end;
    47354730
     
    47614756            (PanelHeight - 1), Left + width, Top + height - self.ClientHeight +
    47624757            PanelHeight, MainTexture.clBevelShade, MainTexture.clBevelLight);
    4763         end
     4758        end;
    47644759  end;
    47654760  EOT.SetBack(Panel.Canvas, EOT.Left, EOT.Top - (ClientHeight - PanelHeight));
     
    48984893  Outside, Changed: boolean;
    48994894begin
    4900   dx := G.lx + 1 - (xw - Loc + G.lx * 1024 + 1) mod G.lx;
    4901   Outside := (dx >= (MapWidth + 1) div (xxt * 2) - 2) or (ywmax > 0) and
    4902     ((yw > 0) and (Loc div G.lx <= yw + 1) or (yw < ywmax) and
    4903     (Loc div G.lx >= yw + (MapHeight - 1) div yyt - 2));
     4895  with MainMap do begin
     4896    dx := G.lx + 1 - (xw - Loc + G.lx * 1024 + 1) mod G.lx;
     4897    Outside := (dx >= (MapWidth + 1) div (xxt * 2) - 2) or (ywmax > 0) and
     4898      ((yw > 0) and (Loc div G.lx <= yw + 1) or (yw < ywmax) and
     4899      (Loc div G.lx >= yw + (MapHeight - 1) div yyt - 2));
     4900  end;
    49044901  Changed := true;
    4905   if Outside then
    4906   begin
     4902  if Outside then begin
    49074903    Centre(Loc);
    49084904    PaintAllMaps;
     
    50775073procedure TMainScreen.Centre(Loc: integer);
    50785074begin
    5079   if FastScrolling and MapValid then
    5080     Update;
    5081   // necessary because ScrollDC for form canvas is called after
    5082   xw := (Loc mod G.lx - (MapWidth - xxt * 2 * ((Loc div G.lx) and 1))
    5083     div (xxt * 4) + G.lx) mod G.lx;
    5084   if ywmax <= 0 then
    5085     yw := ywcenter
    5086   else
    5087   begin
    5088     yw := (Loc div G.lx - MapHeight div (yyt * 2) + 1) and not 1;
    5089     if yw < 0 then
    5090       yw := 0
    5091     else if yw > ywmax then
    5092       yw := ywmax;
     5075  with MainMap do begin
     5076    if FastScrolling and MapValid then
     5077      Update;
     5078    // necessary because ScrollDC for form canvas is called after
     5079    xw := (Loc mod G.lx - (MapWidth - xxt * 2 * ((Loc div G.lx) and 1))
     5080      div (xxt * 4) + G.lx) mod G.lx;
     5081    if ywmax <= 0 then
     5082      yw := ywcenter
     5083    else begin
     5084      yw := (Loc div G.lx - MapHeight div (yyt * 2) + 1) and not 1;
     5085      if yw < 0 then
     5086        yw := 0
     5087      else if yw > ywmax then
     5088        yw := ywmax;
     5089    end;
    50935090  end;
    50945091end;
     
    51215118      PanelPaint;
    51225119      ShowNewContent(wmPersistent, Loc, ShowEvent);
    5123     end
     5120    end;
    51245121end;
    51255122
     
    51285125  qx, qy: integer;
    51295126begin
    5130   qx := (x * (yyt * 2) + y * (xxt * 2) + xxt * yyt * 2) div (xxt * yyt * 4) - 1;
    5131   qy := (y * (xxt * 2) - x * (yyt * 2) - xxt * yyt * 2 + 4000 * xxt * yyt)
    5132     div (xxt * yyt * 4) - 999;
    5133   result := (xw + (qx - qy + 2048) div 2 - 1024 + G.lx) mod G.lx + G.lx *
    5134     (yw + qx + qy);
     5127  with MainMap do begin
     5128    qx := (x * (yyt * 2) + y * (xxt * 2) + xxt * yyt * 2) div (xxt * yyt * 4) - 1;
     5129    qy := (y * (xxt * 2) - x * (yyt * 2) - xxt * yyt * 2 + 4000 * xxt * yyt)
     5130      div (xxt * yyt * 4) - 999;
     5131    result := (xw + (qx - qy + 2048) div 2 - 1024 + G.lx) mod G.lx + G.lx *
     5132      (yw + qx + qy);
     5133  end;
    51355134end;
    51365135
     
    52045203      BitBltCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
    52055204        MiniMap.Bitmap.Canvas, 0, 0);
    5206       if ywmax <= 0 then
    5207         Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
    5208           yMini + 2, xMini + 1 + G.lx + MapWidth div (2 * xxt),
    5209           yMini + 2 + G.ly - 1, MainTexture.clMark, MainTexture.clMark)
    5210       else
    5211         Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
    5212           yMini + 2 + yw, xMini + 2 + G.lx + MapWidth div (2 * xxt) - 1,
    5213           yMini + 2 + yw + MapHeight div yyt - 2, MainTexture.clMark,
    5214           MainTexture.clMark);
     5205      with MainMap do begin
     5206        if ywmax <= 0 then
     5207          Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
     5208            yMini + 2, xMini + 1 + G.lx + MapWidth div (2 * xxt),
     5209            yMini + 2 + G.ly - 1, MainTexture.clMark, MainTexture.clMark)
     5210        else
     5211          Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
     5212            yMini + 2 + yw, xMini + 2 + G.lx + MapWidth div (2 * xxt) - 1,
     5213            yMini + 2 + yw + MapHeight div yyt - 2, MainTexture.clMark,
     5214            MainTexture.clMark);
     5215      end;
    52155216      RectInvalidate(xMini + 2, TopBarHeight + MapHeight - overlap + yMini + 2,
    52165217        xMini + 2 + G.lx * 2, TopBarHeight + MapHeight - overlap + yMini
     
    59895990    xw1 := xw + G.lx;
    59905991    // ((xFromLoc-xw1)*2+yFromLoc and 1+1)*xxt+dx*xxt/2-MapWidth/2 -> min
    5991     while abs(((xFromLoc - xw1 + G.lx) * 2 + yFromLoc and 1 + 1) * xxt * 2 + dx
    5992       * xxt - MapWidth) < abs(((xFromLoc - xw1) * 2 + yFromLoc and 1 + 1) * xxt
    5993       * 2 + dx * xxt - MapWidth) do
    5994       dec(xw1, G.lx);
    5995 
    5996     xTo := (xToLoc - xw1) * (xxt * 2) + yToLoc and 1 * xxt + (xxt - xxu);
    5997     yTo := (yToLoc - yw) * yyt + (yyt - yyu_anchor);
    5998     xFrom := (xFromLoc - xw1) * (xxt * 2) + yFromLoc and 1 * xxt + (xxt - xxu);
    5999     yFrom := (yFromLoc - yw) * yyt + (yyt - yyu_anchor);
    6000     if xFrom < xTo then
    6001     begin
    6002       xMin := xFrom;
    6003       xRange := xTo - xFrom
    6004     end
    6005     else
    6006     begin
    6007       xMin := xTo;
    6008       xRange := xFrom - xTo
    6009     end;
    6010     if yFrom < yTo then
    6011     begin
    6012       yMin := yFrom;
    6013       yRange := yTo - yFrom
    6014     end
    6015     else
    6016     begin
    6017       yMin := yTo;
    6018       yRange := yFrom - yTo
    6019     end;
    6020     inc(xRange, xxt * 2);
    6021     inc(yRange, yyt * 3);
     5992    with MainMap do begin
     5993      while abs(((xFromLoc - xw1 + G.lx) * 2 + yFromLoc and 1 + 1) * xxt * 2 + dx
     5994        * xxt - MapWidth) < abs(((xFromLoc - xw1) * 2 + yFromLoc and 1 + 1) * xxt
     5995        * 2 + dx * xxt - MapWidth) do
     5996        dec(xw1, G.lx);
     5997
     5998      xTo := (xToLoc - xw1) * (xxt * 2) + yToLoc and 1 * xxt + (xxt - xxu);
     5999      yTo := (yToLoc - yw) * yyt + (yyt - yyu_anchor);
     6000      xFrom := (xFromLoc - xw1) * (xxt * 2) + yFromLoc and 1 * xxt + (xxt - xxu);
     6001      yFrom := (yFromLoc - yw) * yyt + (yyt - yyu_anchor);
     6002      if xFrom < xTo then begin
     6003        xMin := xFrom;
     6004        xRange := xTo - xFrom
     6005      end else begin
     6006        xMin := xTo;
     6007        xRange := xFrom - xTo
     6008      end;
     6009      if yFrom < yTo then begin
     6010        yMin := yFrom;
     6011        yRange := yTo - yFrom
     6012      end else begin
     6013        yMin := yTo;
     6014        yRange := yFrom - yTo
     6015      end;
     6016      inc(xRange, xxt * 2);
     6017      inc(yRange, yyt * 3);
     6018    end;
    60226019
    60236020    MainOffscreenPaint;
     
    61216118      begin
    61226119        assert(false);
    6123         Break
     6120        Break;
    61246121      end;
    61256122    until false;
     
    61476144          NextUnit(UnStartLoc, true)
    61486145        end;
    6149       end
    6150     end
    6151   end
     6146      end;
     6147    end;
     6148  end;
    61526149end;
    61536150
     
    61666163      if ssShift in Shift then
    61676164      begin
    6168         xMouse := (xwMini + (x - (xMini + 2) + MapWidth div (xxt * 2) + G.lx)
    6169           div 2) mod G.lx;
     6165        with MainMap do
     6166          xMouse := (xwMini + (x - (xMini + 2) + MapWidth div (xxt * 2) + G.lx)
     6167            div 2) mod G.lx;
    61706168        MouseLoc := xMouse + G.lx * (y - (yMini + 2));
    61716169        if MyMap[MouseLoc] and fTerrain <> fUNKNOWN then
     
    61746172          if (p1 = me) or (p1 >= 0) and (MyRO.Treaty[p1] >= trNone) then
    61756173            NatStatDlg.ShowNewContent(wmPersistent, p1);
    6176         end
     6174        end;
    61776175      end
    61786176      else
     
    62696267              CheckTerrainBtnVisible;
    62706268              PanelPaint;
    6271             end
     6269            end;
    62726270          end
    62736271          else if Server(sGetUnits, me, TroopLoc, TrCnt) >= rExecuted then
     
    62786276              UnitStatDlg.ShowNewContent_EnemyUnit(wmPersistent,
    62796277                MyRO.nEnemyUn + trix[i]); // unit info
    6280     end
    6281   end
     6278    end;
     6279  end;
    62826280end;
    62836281
     
    63716369procedure TMainScreen.SetDebugMap(p: integer);
    63726370begin
    6373   IsoEngine.pDebugMap := p;
    6374   IsoEngine.MapOptions := IsoEngine.MapOptions - [moLocCodes];
     6371  MainMap.pDebugMap := p;
     6372  MainMap.MapOptions := MainMap.MapOptions - [moLocCodes];
    63756373  mLocCodes.Checked := false;
    63766374  MapValid := false;
     
    72347232            m.ShortCut := ShortCut(48 + p1, [ssAlt]);
    72357233          m.RadioItem := true;
    7236           if m.Tag = IsoEngine.pDebugMap then
     7234          if m.Tag = MainMap.pDebugMap then
    72377235            m.Checked := true;
    72387236          mDebugMap.Add(m);
    72397237        end;
    72407238    end;
    7241     mSmallTiles.Checked := TileSize = tsSmall;
    7242     mNormalTiles.Checked := TileSize = tsMedium;
    7243     mBigTiles.Checked := TileSize = tsBig;
     7239    mSmallTiles.Checked := MainMap.TileSize = tsSmall;
     7240    mNormalTiles.Checked := MainMap.TileSize = tsMedium;
     7241    mBigTiles.Checked := MainMap.TileSize = tsBig;
    72447242  end
    72457243  else if Popup = StatPopup then
     
    74327430        FocusOnLoc(TroopLoc, flRepaintPanel)
    74337431      else
    7434         PanelPaint
     7432        PanelPaint;
    74357433    end
    74367434    else if StepFocus then
     
    74397437    begin
    74407438      SetTroopLoc(-1);
    7441       PanelPaint
     7439      PanelPaint;
    74427440    end;
    74437441  end;
     
    74557453begin
    74567454  if Tracking and (ssLeft in Shift) then
    7457   begin
     7455  with MainMap do begin
    74587456    if (x >= xMini + 2) and (y >= yMini + 2) and (x < xMini + 2 + 2 * G.lx) and
    74597457      (y < yMini + 2 + G.ly) then
     
    77037701  with Reg do try
    77047702    OpenKey(AppRegistryKey, False);
    7705     if ValueExists('TileSize') then TileSize := TTileSize(ReadInteger('TileSize'))
    7706       else TileSize := tsMedium;
    7707     xxt := TileSizes[TileSize].X;
    7708     yyt := TileSizes[TileSize].Y;
     7703    if ValueExists('TileSize') then MainMap.TileSize := TTileSize(ReadInteger('TileSize'))
     7704      else MainMap.TileSize := tsMedium;
     7705    NoMap.TileSize := MainMap.TileSize;
    77097706    if ValueExists('OptionChecked') then OptionChecked := TSaveOptions(ReadInteger('OptionChecked'))
    77107707      else OptionChecked := DefaultOptionChecked;
     
    79537950  i, CenterLoc: integer;
    79547951begin
    7955   CenterLoc := (xw + MapWidth div (xxt * 4)) mod G.lx +
    7956     (yw + MapHeight div (yyt * 2)) * G.lx;
    7957   IsoEngine.ApplyTileSize(TileSize);
     7952  CenterLoc := (xw + MapWidth div (MainMap.xxt * 4)) mod G.lx +
     7953    (yw + MapHeight div (MainMap.yyt * 2)) * G.lx;
     7954  MainMap.TileSize := TileSize;
     7955  NoMap.TileSize := TileSize;
    79587956  FormResize(nil);
    79597957  Centre(CenterLoc);
     
    79887986  try
    79897987    OpenKey(AppRegistryKey, true);
    7990     WriteInteger('TileSize', Integer(TileSize));
     7988    WriteInteger('TileSize', Integer(MainMap.TileSize));
    79917989    WriteInteger('OptionChecked', Integer(OptionChecked));
    79927990    WriteInteger('MapOptionChecked', Integer(MapOptionChecked));
  • trunk/LocalPlayer/UnitStat.pas

    r318 r330  
    77  Protocol, ClientTools, Term, ScreenTools, BaseWin,
    88  LCLIntf, LCLType, SysUtils, Classes, Graphics, Controls, Forms,
    9   ButtonB, ButtonC;
     9  ButtonB, ButtonC, IsoEngine;
    1010
    1111type
     
    2424    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    2525    procedure HelpBtnClick(Sender: TObject);
    26 
     26  private
     27    NoMap: TIsoMap;
    2728  public
    2829    procedure CheckAge;
     
    5152
    5253uses
    53   Tribes, IsoEngine, Help, Directories;
     54  Tribes, Help, Directories;
    5455
    5556{$R *.lfm}
     
    7374begin
    7475  inherited;
     76  NoMap := TIsoMap.Create;
    7577  AgePrepared := -2;
    7678  TitleHeight := Screen.Height;
     
    9193  FreeAndNil(Template);
    9294  FreeAndNil(Back);
     95  FreeAndNil(NoMap);
    9396end;
    9497
     
    521524    begin
    522525      if Kind in [dkOwnUnit, dkEnemyUnit, dkEnemyCityDefense] then
    523         with ui do
     526        with ui, NoMap do
    524527        begin
    525528          { Frame(offscreen.canvas,xView-1,yView-1,xView+64,yView+48,
  • trunk/Packages/CevoComponents/EOTButton.pas

    r323 r330  
    9191procedure TEOTButton.SetIndex(x: integer);
    9292begin
    93   if x <> FIndex then
    94   begin
     93  if x <> FIndex then begin
    9594    FIndex := x;
    9695    Invalidate;
     
    10099procedure TEOTButton.SetButtonIndexFast(x: integer);
    101100begin
    102   if Visible and (x <> FIndex) then
    103   begin
     101  if Visible and (x <> FIndex) then begin
    104102    FIndex := x;
    105103    try
    106       Paint
     104      Paint;
    107105    except
    108106    end;
Note: See TracChangeset for help on using the changeset viewer.