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

Legend:

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

    r303 r349  
    1313  Protocol, Tribes, PVSB, ClientTools, ScreenTools, BaseWin, Messg, ButtonBase,
    1414  LCLIntf, LCLType, SysUtils, Classes, Graphics, Controls, DrawDlg, Types,
    15   Forms, Menus, ExtCtrls, dateutils, Platform, ButtonB, ButtonC, EOTButton, Area;
     15  Forms, Menus, ExtCtrls, dateutils, Platform, ButtonB, ButtonC, EOTButton, Area,
     16  UGraphicSet, UMiniMap, IsoEngine;
    1617
    1718const
    1819  WM_EOT = WM_USER;
    1920
    20   pltsNormal = 0;
    21   pltsBlink = 1;
    22 
    2321type
     22  TPaintLocTempStyle = (pltsNormal, pltsBlink);
     23
     24  TSoundBlock = (sbStart, sbWonder, sbScience, sbContact, sbTurn);
     25  TSoundBlocks = set of TSoundBlock;
    2426
    2527  { TMainScreen }
     
    224226    procedure MovieSpeedBtnClick(Sender: TObject);
    225227  private
    226     xw, yw, xwd, ywd, xwMini, ywMini, xMidPanel, xRightPanel, xTroop, xTerrain,
    227       xMini, yMini, ywmax, ywcenter, TroopLoc, TrCnt, TrRow, TrPitch, MapWidth,
    228       MapOffset, MapHeight, BlinkTime, BrushLoc, EditLoc, xMouse,
    229       yMouse: integer;
     228    xw: Integer; // Base map x
     229    yw: Integer; // Base map y
     230    xwd: Integer;
     231    ywd: Integer;
     232    xwMini: Integer;
     233    ywMini: Integer;
     234    xMidPanel: Integer;
     235    xRightPanel: Integer;
     236    xTroop: Integer;
     237    xTerrain: Integer;
     238    xMini: Integer;
     239    yMini: Integer;
     240    ywmax: Integer;
     241    ywcenter: Integer;
     242    TroopLoc: Integer;
     243    TrCnt: Integer;
     244    TrRow: Integer;
     245    TrPitch: Integer;
     246    MapWidth: Integer;
     247    MapOffset: Integer;
     248    MapHeight: Integer;
     249    BlinkTime: Integer;
     250    BrushLoc: Integer;
     251    EditLoc: Integer;
     252    xMouse: Integer;
     253    yMouse: Integer;
    230254    BrushType: Cardinal;
    231     trix: array [0 .. 63] of integer;
     255    trix: array [0 .. 63] of Integer;
    232256    AILogo: array [0 .. nPl - 1] of TDpiBitmap;
    233     Mini, Panel, TopBar: TDpiBitmap;
     257    MiniMap: TMiniMap;
     258    Panel: TDpiBitmap;
     259    TopBar: TDpiBitmap;
    234260    sb: TPVScrollbar;
    235     Closable, RepaintOnResize, Tracking, TurnComplete, Edited, GoOnPhase,
    236       HaveStrategyAdvice, FirstMovieTurn: boolean;
     261    Closable: Boolean;
     262    RepaintOnResize: Boolean;
     263    Tracking: Boolean;
     264    TurnComplete: Boolean;
     265    Edited: Boolean;
     266    GoOnPhase: Boolean;
     267    HaveStrategyAdvice: Boolean;
     268    FirstMovieTurn: Boolean;
    237269    PrevWindowState: TWindowState;
    238270    CurrentWindowState: TWindowState;
     271    MainMap: TIsoMap;
     272    NoMap: TIsoMap;
     273    NoMapPanel: TIsoMap;
    239274    function ChooseUnusedTribe: integer;
    240275    procedure GetTribeList;
    241276    procedure InitModule;
     277    procedure DoneModule;
    242278    procedure InitTurn(NewPlayer: integer);
     279    procedure SaveMenuItemsState;
    243280    procedure ScrollBarUpdate(Sender: TObject);
    244281    procedure ArrangeMidPanel;
    245282    procedure MainOffscreenPaint;
    246     procedure MiniPaint;
     283    procedure MiniMapPaint;
    247284    procedure PaintAll;
    248285    procedure PaintAllMaps;
     
    251288    procedure NextUnit(NearLoc: integer; AutoTurn: boolean);
    252289    procedure Scroll(dx, dy: integer);
     290    procedure SetMapPos(Loc: integer; MapPos: TPoint);
    253291    procedure Centre(Loc: integer);
    254292    procedure SetTroopLoc(Loc: integer);
     
    256294    procedure PaintLoc(Loc: integer; Radius: integer = 0);
    257295    procedure PaintLoc_BeforeMove(FromLoc: integer);
    258     procedure PaintLocTemp(Loc: integer; Style: integer = pltsNormal);
     296    procedure PaintLocTemp(Loc: integer; Style: TPaintLocTempStyle = pltsNormal);
    259297    procedure PaintBufferToScreen(xMap, yMap, width, height: integer);
    260298    procedure PaintDestination;
     
    275313    procedure SetDebugMap(p: integer);
    276314    procedure SetViewpoint(p: integer);
    277     function LocationOfScreenPixel(x, y: integer): integer;
    278     procedure SetTileSize(x, y: integer);
     315    function LocationOfScreenPixel(x, y: integer): Integer;
     316    function GetCenterLoc: Integer;
     317    procedure SetTileSizeCenter(TileSize: TTileSize);
     318    procedure SetTileSize(TileSize: TTileSize; Loc: Integer; MapPos: TPoint);
    279319    procedure RectInvalidate(Left, Top, Rigth, Bottom: integer);
    280320    procedure ShowEnemyShipChange(ShowShipChange: TShowShipChange);
     
    284324    procedure OnScroll(var Msg: TMessage); message WM_VSCROLL;
    285325    procedure OnEOT(var Msg: TMessage); message WM_EOT;
    286     procedure SoundPreload(Check: integer);
     326    procedure SoundPreload(Check: TSoundBlocks);
    287327    procedure UpdateKeyShortcuts;
    288328    procedure SetFullScreen(Active: Boolean);
     329    procedure PaintZoomedTile(dst: TDpiBitmap; x, y, Loc: integer);
    289330  public
    290331    UsedOffscreenWidth, UsedOffscreenHeight: integer;
     
    311352    FileName: ShortString;
    312353  end;
     354
    313355  TCityNameInfo = record
    314356    ID: integer;
    315357    NewName: ShortString;
    316358  end;
     359
    317360  TModelNameInfo = record
    318361    mix: integer;
    319362    NewName: ShortString;
    320363  end;
    321   TPriceSet = Set of $00 .. $FF;
     364
     365  TPriceSet = set of $00 .. $FF;
    322366
    323367const
     
    388432  // lines of system icons in icons.bmp before improvements
    389433
    390   // save options apart from what's defined by SaveOption
    391   soTellAI = 30;
    392   soExtraMask = $40000000;
    393 
    394434  nCityEventPriority = 16;
    395435  CityEventPriority: array [0 .. nCityEventPriority - 1] of integer =
     
    404444    'CITY_WONDEREX', 'CITY_EMDELAY', 'CITY_FOUNDED', 'CITY_FOUNDED', '',
    405445    'CITY_INVALIDTYPE');
    406 
    407   // sound blocks for preload
    408   sbStart = $01;
    409   sbWonder = $02;
    410   sbScience = $04;
    411   sbContact = $08;
    412   sbTurn = $10;
    413   sbAll = $FF;
    414446
    415447type
     
    425457    EnhancementJobs: TEnhancementJobs;
    426458    ImpOrder: array [0 .. nCityType - 1] of TImpOrder;
    427     ToldWonders: array [0 .. 27] of TWonderInfo;
     459    ToldWonders: array [0 .. nWonder - 1] of TWonderInfo;
    428460    ToldTech: array [0 .. nAdv - 1] of ShortInt;
     461  end;
     462
     463  TDipMem = record
     464    pContact: Integer;
     465    SentCommand: Integer;
     466    FormerTreaty: Integer;
     467    SentOffer: TOffer;
     468    DeliveredPrices: TPriceSet;
     469    ReceivedPrices: TPriceSet;
     470  end;
     471
     472  TCurrentMoveInfo = record
     473    AfterMovePaintRadius: Integer;
     474    AfterAttackExpeller: Integer;
     475    DoShow: Boolean;
     476    IsAlly: Boolean;
    429477  end;
    430478
     
    433481  AdvIcon: array [0 .. nAdv - 1] of Integer;
    434482  { icons displayed with the technologies }
    435   xxt, yyt, // half of tile size x/y
    436483  GameMode: Integer;
    437484  ClientMode: Integer;
    438485  Age: Integer;
    439486  UnFocus: Integer;
    440   OptionChecked: Integer;
    441   MapOptionChecked: Integer;
     487  OptionChecked: TSaveOptions;
     488  MapOptionChecked: TMapOptions;
    442489  nLostArmy: Integer;
    443490  ScienceSum: Integer;
    444491  TaxSum: Integer;
    445   SoundPreloadDone: Integer;
     492  SoundPreloadDone: TSoundBlocks;
    446493  MarkCityLoc: Integer;
    447   HGrTerrain: Integer;
    448   HGrCities: Integer;
    449494  MovieSpeed: Integer;
    450495  CityRepMask: Cardinal;
     
    461506  TribeOriginal: array [0 .. nPl - 1] of Boolean;
    462507  LostArmy: array [0 .. nPl * nMmax - 1] of Integer;
    463   DipMem: array [0 .. nPl - 1] of record
    464     pContact: Integer;
    465     SentCommand: Integer;
    466     FormerTreaty: Integer;
    467     SentOffer: TOffer;
    468     DeliveredPrices: TPriceSet;
    469     ReceivedPrices: TPriceSet;
    470   end;
     508  DipMem: array [0 .. nPl - 1] of TDipMem;
    471509
    472510function CityEventName(i: integer): string;
     
    485523
    486524uses
    487   Directories, IsoEngine, CityScreen, Draft, MessgEx, Select, CityType, Help,
     525  Directories, CityScreen, Draft, MessgEx, Select, CityType, Help,
    488526  UnitStat, Log, Diagram, NatStat, Wonders, Enhance, Nego, UPixelPointer, Sound,
    489527  Battle, Rates, TechTree, Registry, Global, UKeyBindings;
     
    530568  flImmUpdate = $0002;
    531569
    532   nSaveOption = 22;
    533 
    534570var
    535   Jump: array [0 .. nPl - 1] of integer;
    536   pTurn, pLogo, UnStartLoc, ToldSlavery: integer;
    537   SmallScreen, GameOK, MapValid, skipped, idle: boolean;
    538 
    539   SaveOption: array [0..nSaveOption - 1] of integer;
    540   MiniColors: array [0..11, 0..1] of TColor;
    541   MainMap: TIsoMap;
    542   CurrentMoveInfo: record AfterMovePaintRadius, AfterAttackExpeller: integer;
    543   DoShow, IsAlly: boolean;
    544 end;
     571  Jump: array [0 .. nPl - 1] of Integer;
     572  pTurn: Integer;
     573  pLogo: Integer;
     574  UnStartLoc: Integer;
     575  ToldSlavery: Integer;
     576  SmallScreen: Boolean;
     577  GameOK: Boolean;
     578  MapValid: Boolean;
     579  Skipped: Boolean;
     580  Idle: Boolean;
     581
     582  SaveOption: array of Integer;
     583  CurrentMoveInfo: TCurrentMoveInfo;
    545584
    546585function CityEventName(i: integer): string;
     
    757796  for emix := 0 to MyRO.nEnemyModel - 1 do
    758797    with MyRO.EnemyModel[emix] do
    759       if Tribe[Owner].ModelPicture[mix].HGr = 0 then
     798      if not Assigned(Tribe[Owner].ModelPicture[mix].HGr) then
    760799        InitEnemyModel(emix);
    761800end;
     
    840879    while MyData.ToldModels < MyRO.nModel do
    841880    begin { new Unit class available }
    842       if (ModelPicture[MyData.ToldModels].HGr > 0) and
     881      if Assigned(ModelPicture[MyData.ToldModels].HGr) and
    843882        (MyModel[MyData.ToldModels].Kind <> mkSelfDeveloped) then
    844883      begin // save picture of DevModel
    845884        ModelPicture[MyData.ToldModels + 1] := ModelPicture[MyData.ToldModels];
    846885        ModelName[MyData.ToldModels + 1] := ModelName[MyData.ToldModels];
    847         ModelPicture[MyData.ToldModels].HGr := 0
    848       end;
    849       if ModelPicture[MyData.ToldModels].HGr = 0 then
     886        ModelPicture[MyData.ToldModels].HGr := nil;
     887      end;
     888      if not Assigned(ModelPicture[MyData.ToldModels].HGr) then
    850889        InitMyModel(MyData.ToldModels, true);
    851890      { only run if no researched model }
     
    878917          Server(cSetModelName + (Length(ModelNameInfo.NewName) + 1 + 4 + 3)
    879918            div 4, me, 0, ModelNameInfo);
    880         end
     919        end;
    881920      end;
    882921      if MyModel[MyData.ToldModels].Kind = mkSettler then
     
    890929end;
    891930
    892 procedure PaintZoomedTile(dst: TDpiBitmap; x, y, Loc: integer);
     931procedure TMainScreen.PaintZoomedTile(dst: TDpiBitmap; x, y, Loc: integer);
    893932
    894933  procedure TSprite(xDst, yDst, xSrc, ySrc: integer);
    895934  begin
    896     Sprite(dst, HGrTerrain, x + xDst, y + yDst, xxt * 2, yyt * 3,
    897       1 + xSrc * (xxt * 2 + 1), 1 + ySrc * (yyt * 3 + 1));
     935    with NoMapPanel do
     936      Sprite(dst, HGrTerrain, x + xDst, y + yDst, xxt * 2, yyt * 3,
     937        1 + xSrc * (xxt * 2 + 1), 1 + ySrc * (yyt * 3 + 1));
    898938  end;
    899939
    900940  procedure TSprite4(xSrc, ySrc: integer);
    901941  begin
    902     Sprite(dst, HGrTerrain, x + xxt, y + yyt + 2, xxt * 2, yyt * 2 - 2,
    903       1 + xSrc * (xxt * 2 + 1), 3 + yyt + ySrc * (yyt * 3 + 1));
    904     Sprite(dst, HGrTerrain, x + 4, y + 2 * yyt, xxt * 2 - 4, yyt * 2,
    905       5 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
    906     Sprite(dst, HGrTerrain, x + xxt * 2, y + 2 * yyt, xxt * 2 - 4, yyt * 2,
    907       1 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
    908     Sprite(dst, HGrTerrain, x + xxt, y + yyt * 3, xxt * 2, yyt * 2 - 2,
    909       1 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
     942    with NoMapPanel do begin
     943      Sprite(dst, HGrTerrain, x + xxt, y + yyt + 2, xxt * 2, yyt * 2 - 2,
     944        1 + xSrc * (xxt * 2 + 1), 3 + yyt + ySrc * (yyt * 3 + 1));
     945      Sprite(dst, HGrTerrain, x + 4, y + 2 * yyt, xxt * 2 - 4, yyt * 2,
     946        5 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
     947      Sprite(dst, HGrTerrain, x + xxt * 2, y + 2 * yyt, xxt * 2 - 4, yyt * 2,
     948        1 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
     949      Sprite(dst, HGrTerrain, x + xxt, y + yyt * 3, xxt * 2, yyt * 2 - 2,
     950        1 + xSrc * (xxt * 2 + 1), 1 + yyt + ySrc * (yyt * 3 + 1));
     951    end;
    910952  end;
    911953
     
    913955  cix, ySrc, Tile: integer;
    914956begin
    915   Tile := MyMap[Loc];
    916   if Tile and fCity <> 0 then
    917   begin
    918     if MyRO.Tech[adRailroad] >= tsApplicable then
    919       Tile := Tile or fRR
     957  with NoMapPanel do begin
     958    Tile := MyMap[Loc];
     959    if Tile and fCity <> 0 then
     960    begin
     961      if MyRO.Tech[adRailroad] >= tsApplicable then
     962        Tile := Tile or fRR
     963      else
     964        Tile := Tile or fRoad;
     965      if Tile and fOwned <> 0 then
     966      begin
     967        cix := MyRO.nCity - 1;
     968        while (cix >= 0) and (MyCity[cix].Loc <> Loc) do
     969          dec(cix);
     970        assert(cix >= 0);
     971        if MyCity[cix].Built[imSupermarket] > 0 then
     972          Tile := Tile or tiFarm
     973        else
     974          Tile := Tile or tiIrrigation;
     975      end
     976      else Tile := Tile or tiIrrigation;
     977    end;
     978
     979    if Tile and fTerrain >= fForest then
     980      TSprite4(2, 2)
    920981    else
    921       Tile := Tile or fRoad;
    922     if Tile and fOwned <> 0 then
    923     begin
    924       cix := MyRO.nCity - 1;
    925       while (cix >= 0) and (MyCity[cix].Loc <> Loc) do
    926         dec(cix);
    927       assert(cix >= 0);
    928       if MyCity[cix].Built[imSupermarket] > 0 then
    929         Tile := Tile or tiFarm
     982      TSprite4(Tile and fTerrain, 0);
     983    if Tile and fTerrain >= fForest then
     984    begin
     985      if (Tile and fTerrain = fForest) and IsJungle(Loc div G.lx) then
     986        ySrc := 18
    930987      else
    931         Tile := Tile or tiIrrigation;
    932     end
    933     else
    934       Tile := Tile or tiIrrigation;
    935   end;
    936 
    937   if Tile and fTerrain >= fForest then
    938     TSprite4(2, 2)
    939   else
    940     TSprite4(Tile and fTerrain, 0);
    941   if Tile and fTerrain >= fForest then
    942   begin
    943     if (Tile and fTerrain = fForest) and IsJungle(Loc div G.lx) then
    944       ySrc := 18
    945     else
    946       ySrc := 3 + 2 * (Tile and fTerrain - fForest);
    947     TSprite(xxt, 0, 6, ySrc);
    948     TSprite(0, yyt, 3, ySrc);
    949     TSprite((xxt * 2), yyt, 4, ySrc + 1);
    950     TSprite(xxt, (yyt * 2), 1, ySrc + 1);
    951   end;
    952 
    953   // irrigation
    954   case Tile and fTerImp of
    955     tiIrrigation:
    956       begin
     988        ySrc := 3 + 2 * (Tile and fTerrain - fForest);
     989      TSprite(xxt, 0, 6, ySrc);
     990      TSprite(0, yyt, 3, ySrc);
     991      TSprite((xxt * 2), yyt, 4, ySrc + 1);
     992      TSprite(xxt, (yyt * 2), 1, ySrc + 1);
     993    end;
     994
     995    // irrigation
     996    case Tile and fTerImp of
     997      tiIrrigation: begin
    957998        TSprite(xxt, 0, 0, 12);
    958999        TSprite(xxt * 2, yyt, 0, 12);
    9591000      end;
    960     tiFarm:
    961       begin
     1001      tiFarm: begin
    9621002        TSprite(xxt, 0, 1, 12);
    9631003        TSprite(xxt * 2, yyt, 1, 12);
    964       end
    965   end;
    966 
    967   // river/canal/road/railroad
    968   if Tile and fRiver <> 0 then
    969   begin
    970     TSprite(0, yyt, 2, 14);
    971     TSprite(xxt, (yyt * 2), 2, 14);
    972   end;
    973   if Tile and fCanal <> 0 then
    974   begin
    975     TSprite(xxt, 0, 7, 11);
    976     TSprite(xxt, 0, 3, 11);
    977     TSprite(xxt * 2, yyt, 7, 11);
    978     TSprite(xxt * 2, yyt, 3, 11);
    979   end;
    980   if Tile and fRR <> 0 then
    981   begin
    982     TSprite((xxt * 2), yyt, 1, 10);
    983     TSprite((xxt * 2), yyt, 5, 10);
    984     TSprite(xxt, (yyt * 2), 1, 10);
    985     TSprite(xxt, (yyt * 2), 5, 10);
    986   end
    987   else if Tile and fRoad <> 0 then
    988   begin
    989     TSprite((xxt * 2), yyt, 8, 9);
    990     TSprite((xxt * 2), yyt, 5, 9);
    991     TSprite(xxt, (yyt * 2), 1, 9);
    992     TSprite(xxt, (yyt * 2), 5, 9);
    993   end;
    994 
    995   if Tile and fPoll <> 0 then
    996     TSprite(xxt, (yyt * 2), 6, 12);
    997 
    998   // special
    999   if Tile and (fTerrain or fSpecial) = fGrass or fSpecial1 then
    1000     TSprite4(2, 1)
    1001   else if Tile and fSpecial <> 0 then
    1002     if Tile and fTerrain < fForest then
    1003       TSprite(0, yyt, Tile and fTerrain, Tile and fSpecial shr 5)
    1004     else if (Tile and fTerrain = fForest) and IsJungle(Loc div G.lx) then
    1005       TSprite(0, yyt, 8, 17 + Tile and fSpecial shr 5)
    1006     else
    1007       TSprite(0, yyt, 8, 2 + (Tile and fTerrain - fForest) * 2 + Tile and
    1008         fSpecial shr 5)
    1009   else if Tile and fDeadLands <> 0 then
    1010   begin
    1011     TSprite4(6, 2);
    1012     TSprite(xxt, yyt, 8, 12 + Tile shr 25 and 3);
    1013   end;
    1014 
    1015   // other improvements
    1016   case Tile and fTerImp of
    1017     tiMine:
    1018       TSprite(xxt, 0, 2, 12);
    1019     tiFort:
    1020       begin
     1004      end;
     1005    end;
     1006
     1007    // river/canal/road/railroad
     1008    if Tile and fRiver <> 0 then begin
     1009      TSprite(0, yyt, 2, 14);
     1010      TSprite(xxt, (yyt * 2), 2, 14);
     1011    end;
     1012    if Tile and fCanal <> 0 then begin
     1013      TSprite(xxt, 0, 7, 11);
     1014      TSprite(xxt, 0, 3, 11);
     1015      TSprite(xxt * 2, yyt, 7, 11);
     1016      TSprite(xxt * 2, yyt, 3, 11);
     1017    end;
     1018    if Tile and fRR <> 0 then begin
     1019      TSprite((xxt * 2), yyt, 1, 10);
     1020      TSprite((xxt * 2), yyt, 5, 10);
     1021      TSprite(xxt, (yyt * 2), 1, 10);
     1022      TSprite(xxt, (yyt * 2), 5, 10);
     1023    end
     1024    else if Tile and fRoad <> 0 then begin
     1025      TSprite((xxt * 2), yyt, 8, 9);
     1026      TSprite((xxt * 2), yyt, 5, 9);
     1027      TSprite(xxt, (yyt * 2), 1, 9);
     1028      TSprite(xxt, (yyt * 2), 5, 9);
     1029    end;
     1030
     1031    if Tile and fPoll <> 0 then
     1032      TSprite(xxt, (yyt * 2), 6, 12);
     1033
     1034    // special
     1035    if Tile and (fTerrain or fSpecial) = fGrass or fSpecial1 then 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 begin
     1045      TSprite4(6, 2);
     1046      TSprite(xxt, yyt, 8, 12 + Tile shr 25 and 3);
     1047    end;
     1048
     1049    // other improvements
     1050    case Tile and fTerImp of
     1051      tiMine: TSprite(xxt, 0, 2, 12);
     1052      tiFort: begin
    10211053        TSprite(xxt, 0, 7, 12);
    10221054        TSprite(xxt, 0, 3, 12);
    10231055      end;
    1024     tiBase:
    1025       TSprite(xxt, 0, 4, 12);
     1056     tiBase: TSprite(xxt, 0, 4, 12);
     1057    end;
    10261058  end;
    10271059end;
     
    10411073      begin
    10421074        result := false;
    1043         exit
     1075        exit;
    10441076      end;
    10451077      ChosenResearch := ModalSelectDlg.result;
     
    10481080        DraftDlg.ShowNewContent(wmModal);
    10491081        if DraftDlg.ModalResult <> mrOK then
    1050           Tribe[me].ModelPicture[MyRO.nModel].HGr := 0
     1082          Tribe[me].ModelPicture[MyRO.nModel].HGr := nil
    10511083      end;
    10521084    until (ChosenResearch <> adMilitary) or (DraftDlg.ModalResult = mrOK);
     
    12321264procedure TMainScreen.SetMapOptions;
    12331265begin
    1234   IsoEngine.Options := MapOptionChecked;
     1266  MiniMap.MapOptions := MapOptionChecked;
     1267  MapOptions := MapOptionChecked;
    12351268  if ClientMode = cEditMap then
    1236     IsoEngine.Options := IsoEngine.Options or (1 shl moEditMode);
     1269    MapOptions := MapOptions + [moEditMode];
    12371270  if mLocCodes.Checked then
    1238     IsoEngine.Options := IsoEngine.Options or (1 shl moLocCodes);
     1271    MapOptions := MapOptions + [moLocCodes];
    12391272end;
    12401273
     
    13211354end;
    13221355
    1323 procedure TMainScreen.SoundPreload(Check: integer);
     1356procedure TMainScreen.SoundPreload(Check: TSoundBlocks);
    13241357const
    13251358  nStartBlock = 27;
     
    13571390  mi: TModelInfo;
    13581391begin
    1359   if Check and sbStart and not SoundPreloadDone <> 0 then
    1360   begin
     1392  if (sbStart in Check) and not (sbStart in SoundPreloadDone) then begin
    13611393    for i := 0 to nStartBlock - 1 do
    13621394      PreparePlay(StartBlock[i]);
    1363     SoundPreloadDone := SoundPreloadDone or sbStart;
    1364   end;
    1365   if Check and sbWonder and not SoundPreloadDone <> 0 then
    1366   begin
     1395    SoundPreloadDone := SoundPreloadDone + [sbStart];
     1396  end;
     1397  if (sbWonder in Check) and not (sbWonder in SoundPreloadDone) then begin
    13671398    need := false;
    1368     for i := 0 to 27 do
    1369       if MyRO.Wonder[i].CityID <> -1 then
     1399    for i := 0 to nWonder - 1 do
     1400      if MyRO.Wonder[i].CityID <> WonderNotBuiltYet then
    13701401        need := true;
    1371     if need then
    1372     begin
     1402    if need then begin
    13731403      for i := 0 to nWonderBlock - 1 do
    13741404        PreparePlay(WonderBlock[i]);
    1375       SoundPreloadDone := SoundPreloadDone or sbWonder;
    1376     end;
    1377   end;
    1378   if (Check and sbScience and not SoundPreloadDone <> 0) and
    1379     (MyRO.Tech[adScience] >= tsApplicable) then
    1380   begin
     1405      SoundPreloadDone := SoundPreloadDone + [sbWonder];
     1406    end;
     1407  end;
     1408  if ((sbScience in Check) and not (sbScience in SoundPreloadDone)) and
     1409    (MyRO.Tech[adScience] >= tsApplicable) then begin
    13811410    for i := 0 to nScienceBlock - 1 do
    13821411      PreparePlay(ScienceBlock[i]);
    1383     SoundPreloadDone := SoundPreloadDone or sbScience;
    1384   end;
    1385   if (Check and sbContact and not SoundPreloadDone <> 0) and
    1386     (MyRO.nEnemyModel + MyRO.nEnemyCity > 0) then
    1387   begin
     1412    SoundPreloadDone := SoundPreloadDone + [sbScience];
     1413  end;
     1414  if ((sbContact in Check) and not (sbContact in SoundPreloadDone)) and
     1415    (MyRO.nEnemyModel + MyRO.nEnemyCity > 0) then begin
    13881416    for i := 0 to nContactBlock - 1 do
    13891417      PreparePlay(ContactBlock[i]);
    1390     SoundPreloadDone := SoundPreloadDone or sbContact;
    1391   end;
    1392   if Check and sbTurn <> 0 then
    1393   begin
     1418    SoundPreloadDone := SoundPreloadDone + [sbContact];
     1419  end;
     1420  if sbTurn in Check then begin
    13941421    if MyRO.Happened and phShipComplete <> 0 then
    13951422      PreparePlay('MSG_YOUWIN');
     
    14621489          $FF - Tribe[i].Color and $FF) * 2;
    14631490        if TestColorDistance < ColorDistance then
    1464           ColorDistance := TestColorDistance
     1491          ColorDistance := TestColorDistance;
    14651492      end;
    14661493    if ColorDistance > BestColorDistance then
    14671494    begin
    14681495      CountBest := 0;
    1469       BestColorDistance := ColorDistance
     1496      BestColorDistance := ColorDistance;
    14701497    end;
    14711498    if ColorDistance = BestColorDistance then
     
    14731500      inc(CountBest);
    14741501      if DelphiRandom(CountBest) = 0 then
    1475         result := j
     1502        result := j;
    14761503    end;
    14771504  end;
     
    15441571        begin
    15451572          MostCost := TestCost;
    1546           IconIndex := imShipComp + i
     1573          IconIndex := imShipComp + i;
    15471574        end;
    15481575      end;
     
    15561583procedure TMainScreen.InitModule;
    15571584var
    1558   x, y, i, j, Domain: integer;
     1585  i, j, Domain: integer;
    15591586begin
    15601587  { search icons for advances: }
     
    15801607              else
    15811608                AdvIcon[i] := 86 + Domain;
    1582       for j := 28 to nImp - 1 do
     1609      for j := nWonder to nImp - 1 do
    15831610        if Imp[j].Preq = i then
    15841611          AdvIcon[i] := j;
    1585       for j := 28 to nImp - 1 do
     1612      for j := nWonder to nImp - 1 do
    15861613        if (Imp[j].Preq = i) and (Imp[j].Kind <> ikCommon) then
    15871614          AdvIcon[i] := j;
     
    15891616        if i = JobPreq[j] then
    15901617          AdvIcon[i] := 84;
    1591       for j := 0 to 27 do
     1618      for j := 0 to nWonder - 1 do
    15921619        if Imp[j].Preq = i then
    15931620          AdvIcon[i] := j;
     
    16071634  TribeNames := tstringlist.Create;
    16081635
    1609   for x := 0 to 11 do
    1610     for y := 0 to 1 do
    1611       MiniColors[x, y] := GrExt[HGrSystem].Data.Canvas.Pixels[66 + x, 67 + y];
    16121636  IsoEngine.Init(InitEnemyModel);
    1613   if not IsoEngine.ApplyTileSize(xxt, yyt) and ((xxt <> 48) or (yyt <> 24) or (xxt <> 72))
    1614   then
    1615     ApplyTileSize(48, 24);
    16161637  // non-default tile size is missing a file, switch to default
    1617   MainMap := TIsoMap.Create;
    16181638  MainMap.SetOutput(offscreen);
    16191639
     
    16221642  SmallImp.PixelFormat := pf24bit;
    16231643  InitSmallImp;
    1624   SoundPreloadDone := 0;
     1644  SoundPreloadDone := [];
    16251645  StartRunning := false;
    16261646  StayOnTop_Ensured := false;
     
    16281648  sb := TPVScrollbar.Create(Self);
    16291649  sb.OnUpdate := ScrollBarUpdate;
     1650end;
     1651
     1652procedure TMainScreen.DoneModule;
     1653begin
     1654  FreeAndNil(SmallImp);
     1655  FreeAndNil(UnusedTribeFiles);
     1656  FreeAndNil(TribeNames);
     1657  // AdvisorDlg.DeInit;
    16301658end;
    16311659
     
    16441672    Icon: imRecycling), (Adv: adComputers; Icon: imResLab),
    16451673    (Adv: adSpaceFlight; Icon: woMIR));
     1674  sbAll = [sbStart, sbWonder, sbScience, sbContact, sbTurn];
    16461675var
    16471676  p1, i, ad, uix, cix, MoveOptions, MoveResult, Loc1,
     
    18121841    Loc1 := MyCity[0].Loc;
    18131842    if (ClientMode = cTurn) and (MyRO.Turn = 0) then
    1814     begin // move city out of center to not be covered by welcome screen
     1843    with MainMap do begin // move city out of center to not be covered by welcome screen
    18151844      dx := MapWidth div (xxt * 5);
    18161845      if dx > 5 then
     
    20202049    end;
    20212050
    2022     for i := 0 to 27 do
     2051    for i := 0 to nWonder - 1 do
    20232052    begin
    20242053      OwnWonder := false;
     
    20292058      if MyRO.Wonder[i].CityID <> MyData.ToldWonders[i].CityID then
    20302059      begin
    2031         if MyRO.Wonder[i].CityID = -2 then
     2060        if MyRO.Wonder[i].CityID = WonderDestroyed then
    20322061          with MessgExDlg do
    20332062          begin { tell about destroyed wonders }
     
    20812110      end
    20822111      else if (MyRO.Wonder[i].EffectiveOwner <> MyData.ToldWonders[i]
    2083         .EffectiveOwner) and (MyRO.Wonder[i].CityID > -2) then
     2112        .EffectiveOwner) and (MyRO.Wonder[i].CityID > WonderDestroyed) then
    20842113        if MyRO.Wonder[i].EffectiveOwner < 0 then
    20852114        begin
     
    21922221          if (MyRO.Turn > 0) and (Loc >= 0) and (Flags and chCaptured = 0) and
    21932222            (WondersOnly = (Flags and chProduction <> 0) and
    2194             (Project0 and cpImp <> 0) and (Project0 and cpIndex < 28)) then
     2223            (Project0 and cpImp <> 0) and (Project0 and cpIndex < nWonder)) then
    21952224          begin
    21962225            if WondersOnly then
     
    25092538      end;
    25102539
    2511     cReleaseModule:
    2512       begin
    2513         FreeAndNil(SmallImp);
    2514         FreeAndNil(UnusedTribeFiles);
    2515         FreeAndNil(TribeNames);
    2516         FreeAndNil(MainMap);
    2517         IsoEngine.Done;
    2518         // AdvisorDlg.DeInit;
    2519       end;
     2540    cReleaseModule: DoneModule;
    25202541
    25212542    cHelpOnly, cStartHelp, cStartCredits:
     
    25462567        ClientMode := -1;
    25472568        SetMapOptions;
    2548         IsoEngine.pDebugMap := -1;
     2569        MainMap.pDebugMap := -1;
    25492570        idle := false;
    25502571        FillChar(Jump, SizeOf(Jump), 0);
     
    25522573          Jump[0] := 999999;
    25532574        GameMode := Command;
    2554         for i := 0 to nGrExt - 1 do
    2555           FillChar(GrExt[i].pixUsed, GrExt[i].Data.height div 49 * 10, 0);
    2556         IsoEngine.Reset;
     2575        GrExt.ResetPixUsed;
     2576        MainMap.Reset;
     2577        NoMap.Reset;
    25572578        Tribes.Init;
    25582579        GetTribeList;
     
    25742595                  inc(ToldAlive, 1 shl i);
    25752596              PeaceEvaHappened := 0;
    2576               for i := 0 to 27 do
     2597              for i := 0 to nWonder - 1 do
    25772598                with ToldWonders[i] do
    25782599                begin
     
    25822603              FillChar(ToldTech, SizeOf(ToldTech), Byte(tsNA));
    25832604              if G.Difficulty[p1] > 0 then
    2584                 SoundPreload(sbStart);
     2605                SoundPreload([sbStart]);
    25852606            end;
    25862607
     
    26072628        CityDlg.Reset;
    26082629
    2609         Mini.SetSize(G.lx * 2, G.ly);
     2630        MiniMap.Size := Point(G.lx, G.ly);
    26102631        for i := 0 to nPl - 1 do
    26112632        begin
     
    27912812              ItsMeAgain(p1);
    27922813              for mix := 0 to MyRO.nModel - 1 do
    2793                 if Tribe[me].ModelPicture[mix].HGr = 0 then
     2814                if not Assigned(Tribe[me].ModelPicture[mix].HGr) then
    27942815                  InitMyModel(mix, true);
    27952816            end;
     
    28102831          MyData := G.RO[NewPlayer].Data;
    28112832          SetTroopLoc(-1);
    2812           MiniPaint;
     2833          MiniMapPaint;
    28132834          InitAllEnemyModels; // necessary for correct replay
    28142835          if not EndTurn(true) then
     
    28712892        ClientMode := cEditMap;
    28722893        SetMapOptions;
    2873         IsoEngine.pDebugMap := -1;
     2894        MainMap.pDebugMap := -1;
    28742895        ItsMeAgain(0);
    28752896        MyData := nil;
     
    30813102        begin
    30823103          CurrentMoveInfo.DoShow := false;
    3083           if not idle and (Tribe[Owner].ModelPicture[mix].HGr = 0) then
     3104          if not idle and (not Assigned(Tribe[Owner].ModelPicture[mix].HGr)) then
    30843105            InitEnemyModel(emix);
    30853106
     
    32763297          begin
    32773298            ToLoc := dLoc(FromLoc, dx, dy);
    3278             if Tribe[Owner].ModelPicture[mix].HGr = 0 then
     3299            if not Assigned(Tribe[Owner].ModelPicture[mix].HGr) then
    32793300              InitEnemyModel(emix);
    32803301
     
    33673388    cRefreshDebugMap:
    33683389      begin
    3369         if integer(Data) = IsoEngine.pDebugMap then
     3390        if integer(Data) = MainMap.pDebugMap then
    33703391        begin
    33713392          MapValid := false;
     
    34093430            if TribeOriginal[NewPlayer] then
    34103431              Tribe[NewPlayer].ModelName[mix] := NewName;
    3411       end
    3412   end
     3432      end;
     3433  end;
    34133434end;
    34143435
     
    34193440  i, j: integer;
    34203441begin
     3442  NoMap := TIsoMap.Create;
     3443  MainMap := TIsoMap.Create;
     3444  NoMapPanel := TIsoMap.Create;
     3445
    34213446  KeyBindings.LoadFromRegistry(HKEY_CURRENT_USER, AppRegistryKey + '\KeyBindings');
    34223447  UpdateKeyShortcuts;
     
    34253450  BaseWin.CreateOffscreen(Offscreen);
    34263451
    3427    // define which menu settings to save
     3452  // define which menu settings to save
     3453  SetLength(SaveOption, 22);
    34283454  SaveOption[0] := mAlEffectiveMovesOnly.Tag;
    34293455  SaveOption[1] := mEnMoves.Tag;
     
    34573483  for i := 0 to ComponentCount - 1 do
    34583484    if Components[i].Tag and $FF <> 0 then
    3459       if Components[i] is TDpiMenuItem then
    3460       begin
     3485      if Components[i] is TDpiMenuItem then begin
    34613486        TDpiMenuItem(Components[i]).Caption := Phrases.Lookup('CONTROLS',
    34623487          -1 + Components[i].Tag and $FF);
    3463         for j := 0 to nSaveOption - 1 do
     3488        for j := 0 to Length(SaveOption) - 1 do
    34643489          if Components[i].Tag and $FF = SaveOption[j] then
    3465             TDpiMenuItem(Components[i]).Checked := ((1 shl j) and OptionChecked) <> 0;
    3466       end
    3467       else if Components[i] is TButtonBase then
    3468       begin
     3490            TDpiMenuItem(Components[i]).Checked := TSaveOption(j) in OptionChecked;
     3491      end else
     3492      if Components[i] is TButtonBase then begin
    34693493        TButtonBase(Components[i]).Hint := Phrases.Lookup('CONTROLS',
    34703494          -1 + Components[i].Tag and $FF);
     
    34723496          (TButtonC(Components[i]).ButtonIndex <> 1) then
    34733497          TButtonC(Components[i]).ButtonIndex :=
    3474             MapOptionChecked shr (Components[i].Tag shr 8) and 1 + 2
     3498            Integer(MapOptionChecked) shr (Components[i].Tag shr 8) and 1 + 2
    34753499      end;
    34763500
     
    34923516  end;
    34933517
    3494   Mini := TDpiBitmap.Create;
    3495   Mini.PixelFormat := pf24bit;
     3518  MiniMap := TMiniMap.Create;
    34963519  Panel := TDpiBitmap.Create;
    34973520  Panel.PixelFormat := pf24bit;
     
    35043527  Buffer := TDpiBitmap.Create;
    35053528  Buffer.PixelFormat := pf24bit;
    3506   if 2 * lxmax > 3 * xSizeBig then
    3507     Buffer.width := 2 * lxmax
    3508   else
    3509     Buffer.width := 3 * xSizeBig;
    3510   if lymax > 3 * ySizeBig then
    3511     Buffer.height := lymax
    3512   else
    3513     Buffer.height := 3 * ySizeBig;
     3529  if 2 * lxmax > 3 * xSizeBig then Buffer.width := 2 * lxmax
     3530    else Buffer.width := 3 * xSizeBig;
     3531  if lymax > 3 * ySizeBig then Buffer.height := lymax
     3532    else Buffer.height := 3 * ySizeBig;
    35143533  Buffer.Canvas.Font.Assign(UniFont[ftSmall]);
    35153534  for i := 0 to nPl - 1 do
     
    35173536  Canvas.Font.Assign(UniFont[ftSmall]);
    35183537  InitButtons;
    3519   EOT.Template := Templates;
     3538  EOT.Template := Templates.Data;
    35203539end;
    35213540
     
    35283547  FreeAndNil(sb);
    35293548  FreeAndNil(TopBar);
    3530   FreeAndNil(Mini);
     3549  FreeAndNil(MiniMap);
    35313550  FreeAndNil(Buffer);
    35323551  FreeAndNil(Panel);
     
    35353554      FreeAndNil(AILogo[I]);
    35363555  FreeAndNil(Offscreen);
     3556  FreeAndNil(MainMap);
     3557  FreeAndNil(NoMap);
     3558  FreeAndNil(NoMapPanel);
    35373559end;
    35383560
    35393561procedure TMainScreen.FormMouseWheel(Sender: TObject; Shift: TShiftState;
    35403562  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    3541 begin
    3542   if sb.ProcessMouseWheel(WheelDelta) then begin
    3543     PanelPaint;
    3544     Update;
     3563var
     3564  MouseLoc: Integer;
     3565begin
     3566  if (MousePos.Y > ClientHeight - MidPanelHeight) and
     3567    (MousePos.Y < ClientHeight) then begin
     3568    if sb.ProcessMouseWheel(WheelDelta) then begin
     3569      PanelPaint;
     3570      Update;
     3571    end;
     3572  end else begin
     3573    if (WheelDelta > 0) and (MainMap.TileSize < High(TTileSize)) then begin
     3574      MouseLoc := LocationOfScreenPixel(MousePos.X, MousePos.Y);
     3575      SetTileSize(Succ(MainMap.TileSize), MouseLoc, Point(MousePos.X, MousePos.Y));
     3576    end
     3577    else if (WheelDelta < 0) and (MainMap.TileSize > Low(TTileSize)) then begin
     3578      MouseLoc := LocationOfScreenPixel(MousePos.X, MousePos.Y);
     3579      SetTileSize(Pred(MainMap.TileSize), MouseLoc, Point(MousePos.X, MousePos.Y));
     3580    end;
    35453581  end;
    35463582end;
     
    35513587begin
    35523588  SmallScreen := ClientWidth < 1024;
    3553   MaxMapWidth := (G.lx * 2 - 3) * xxt;
    3554   // avoide the same tile being visible left and right
    3555   if ClientWidth <= MaxMapWidth then
    3556   begin
    3557     MapWidth := ClientWidth;
    3558     MapOffset := 0;
    3559   end
    3560   else
    3561   begin
    3562     MapWidth := MaxMapWidth;
    3563     MapOffset := (ClientWidth - MapWidth) div 2;
    3564   end;
    3565   MapHeight := ClientHeight - TopBarHeight - PanelHeight + overlap;
    3566   Panel.SetSize(ClientWidth, PanelHeight);
    3567   TopBar.SetSize(ClientWidth, TopBarHeight);
    3568   MiniFrame := (lxmax_xxx - G.ly) div 2;
    3569   xMidPanel := (G.lx + MiniFrame) * 2 + 1;
    3570   xRightPanel := ClientWidth - LeftPanelWidth - 10;
    3571   if ClientMode = cEditMap then
    3572     TrPitch := 2 * xxt
    3573   else
    3574     TrPitch := 66;
    3575   xMini := MiniFrame - 5;
    3576   yMini := (PanelHeight - 26 - lxmax_xxx) div 2 + MiniFrame;
    3577   ywmax := (G.ly - MapHeight div yyt + 1) and not 1;
    3578   ywcenter := -((MapHeight - yyt * (G.ly - 1)) div (4 * yyt)) * 2;
     3589  with MainMap do begin
     3590    MaxMapWidth := (G.lx * 2 - 3) * xxt;
     3591    // avoide the same tile being visible left and right
     3592    if ClientWidth <= MaxMapWidth then begin
     3593      MapWidth := ClientWidth;
     3594      MapOffset := 0;
     3595    end else begin
     3596      MapWidth := MaxMapWidth;
     3597      MapOffset := (ClientWidth - MapWidth) div 2;
     3598    end;
     3599    MapHeight := ClientHeight - TopBarHeight - PanelHeight + overlap;
     3600    Panel.SetSize(ClientWidth, PanelHeight);
     3601    TopBar.SetSize(ClientWidth, TopBarHeight);
     3602    MiniFrame := (lxmax_xxx - G.ly) div 2;
     3603    xMidPanel := (G.lx + MiniFrame) * 2 + 1;
     3604    xRightPanel := ClientWidth - LeftPanelWidth - 10;
     3605    if ClientMode = cEditMap then
     3606      TrPitch := 2 * xxt
     3607    else
     3608      TrPitch := 66;
     3609    xMini := MiniFrame - 5;
     3610    yMini := (PanelHeight - 26 - lxmax_xxx) div 2 + MiniFrame;
     3611    ywmax := (G.ly - MapHeight div yyt + 1) and not 1;
     3612    ywcenter := -((MapHeight - yyt * (G.ly - 1)) div (4 * yyt)) * 2;
     3613  end;
    35793614  // only for ywmax<=0
    35803615  if ywmax <= 0 then
     
    36783713    xTroop := xMidPanel + 15
    36793714  else
    3680   begin
     3715  with MainMap do begin
    36813716    if supervising then
    36823717      xTerrain := xMidPanel + 2 * xxt + 14
     
    39473982  xs, ys, xl, yl: integer;
    39483983begin
    3949   xl := nx * xxt + xxt;
    3950   yl := ny * yyt + yyt * 2;
    3951   xs := (x0 - xw) * (xxt * 2) + y0 and 1 * xxt - G.lx * (xxt * 2);
    3952   // |xs+xl/2-MapWidth/2| -> min
    3953   while abs(2 * (xs + G.lx * (xxt * 2)) + xl - MapWidth) <
    3954     abs(2 * xs + xl - MapWidth) do
    3955     inc(xs, G.lx * (xxt * 2));
    3956   ys := (y0 - yw) * yyt - yyt;
    3957   if xs + xl > MapWidth then
    3958     xl := MapWidth - xs;
    3959   if ys + yl > MapHeight then
    3960     yl := MapHeight - ys;
    3961   if (xl <= 0) or (yl <= 0) then
    3962     exit;
    3963   if Options and prPaint <> 0 then
    3964   begin
    3965     if Options and prAutoBounds <> 0 then
    3966       MainMap.SetPaintBounds(xs, ys, xs + xl, ys + yl);
    3967     MainMap.Paint(xs, ys, x0 + G.lx * y0, nx, ny, -1, -1);
    3968   end;
    3969   if Options and prInvalidate <> 0 then
    3970     RectInvalidate(MapOffset + xs, TopBarHeight + ys, MapOffset + xs + xl,
    3971       TopBarHeight + ys + yl)
     3984  with MainMap do begin
     3985    xl := nx * xxt + xxt;
     3986    yl := ny * yyt + yyt * 2;
     3987    xs := (x0 - xw) * (xxt * 2) + y0 and 1 * xxt - G.lx * (xxt * 2);
     3988    // |xs+xl/2-MapWidth/2| -> min
     3989    while abs(2 * (xs + G.lx * (xxt * 2)) + xl - MapWidth) <
     3990      abs(2 * xs + xl - MapWidth) do
     3991        inc(xs, G.lx * (xxt * 2));
     3992    ys := (y0 - yw) * yyt - yyt;
     3993    if xs + xl > MapWidth then
     3994      xl := MapWidth - xs;
     3995    if ys + yl > MapHeight then
     3996      yl := MapHeight - ys;
     3997    if (xl <= 0) or (yl <= 0) then
     3998      exit;
     3999    if Options and prPaint <> 0 then begin
     4000      if Options and prAutoBounds <> 0 then
     4001        MainMap.SetPaintBounds(xs, ys, xs + xl, ys + yl);
     4002      MainMap.Paint(xs, ys, x0 + G.lx * y0, nx, ny, -1, -1);
     4003    end;
     4004    if Options and prInvalidate <> 0 then
     4005      RectInvalidate(MapOffset + xs, TopBarHeight + ys, MapOffset + xs + xl,
     4006        TopBarHeight + ys + yl)
     4007  end;
    39724008end;
    39734009
     
    39764012  yLoc, x0: integer;
    39774013begin
    3978   if MapValid then
    3979   begin
     4014  if MapValid then begin
    39804015    yLoc := (Loc + G.lx * 1024) div G.lx - 1024;
    39814016    x0 := (Loc + (yLoc and 1 - 2 * Radius + G.lx * 1024) div 2) mod G.lx;
     
    39844019      prPaint or prAutoBounds or prInvalidate);
    39854020    Update;
    3986   end
    3987 end;
    3988 
    3989 procedure TMainScreen.PaintLocTemp(Loc: integer; Style: integer);
     4021  end;
     4022end;
     4023
     4024procedure TMainScreen.PaintLocTemp(Loc: integer; Style: TPaintLocTempStyle);
    39904025var
    39914026  y0, x0, xMap, yMap: integer;
    39924027begin
    3993   if not MapValid then
    3994     exit;
    3995   Buffer.Canvas.Font.Assign(UniFont[ftSmall]);
    3996   y0 := Loc div G.lx;
    3997   x0 := Loc mod G.lx;
    3998   xMap := (x0 - xw) * (xxt * 2) + y0 and 1 * xxt - G.lx * (xxt * 2);
    3999   // |xMap+xxt-MapWidth/2| -> min
    4000   while abs(2 * (xMap + G.lx * (xxt * 2)) + 2 * xxt - MapWidth) <
    4001     abs(2 * xMap + 2 * xxt - MapWidth) do
    4002     inc(xMap, G.lx * (xxt * 2));
    4003   yMap := (y0 - yw) * yyt - yyt;
    4004   NoMap.SetOutput(Buffer);
    4005   NoMap.SetPaintBounds(0, 0, 2 * xxt, 3 * yyt);
    4006   NoMap.Paint(0, 0, Loc, 1, 1, -1, -1, Style = pltsBlink);
    4007   PaintBufferToScreen(xMap, yMap, 2 * xxt, 3 * yyt);
     4028  with NoMap do begin
     4029    if not MapValid then
     4030      exit;
     4031    Buffer.Canvas.Font.Assign(UniFont[ftSmall]);
     4032    y0 := Loc div G.lx;
     4033    x0 := Loc mod G.lx;
     4034    xMap := (x0 - xw) * (xxt * 2) + y0 and 1 * xxt - G.lx * (xxt * 2);
     4035    // |xMap+xxt-MapWidth/2| -> min
     4036    while abs(2 * (xMap + G.lx * (xxt * 2)) + 2 * xxt - MapWidth) <
     4037      abs(2 * xMap + 2 * xxt - MapWidth) do
     4038      inc(xMap, G.lx * (xxt * 2));
     4039    yMap := (y0 - yw) * yyt - yyt;
     4040    NoMap.SetOutput(Buffer);
     4041    NoMap.SetPaintBounds(0, 0, 2 * xxt, 3 * yyt);
     4042    NoMap.Paint(0, 0, Loc, 1, 1, -1, -1, Style = pltsBlink);
     4043    PaintBufferToScreen(xMap, yMap, 2 * xxt, 3 * yyt);
     4044  end;
    40084045end;
    40094046
     
    40334070    else
    40344071      DpiBitCanvas(Canvas, xMap + MapOffset, TopBarHeight, width,
    4035         height + yMap, Buffer.Canvas, 0, -yMap)
     4072        height + yMap, Buffer.Canvas, 0, -yMap);
    40364073  end
    40374074  else
     
    40434080      DpiBitCanvas(Canvas, xMap + MapOffset, TopBarHeight + yMap, width,
    40444081        height, Buffer.Canvas, 0, 0);
    4045   end
     4082  end;
    40464083end;
    40474084
     
    40714108end;
    40724109
    4073 procedure TMainScreen.MiniPaint;
    4074 var
    4075   uix, cix, x, y, Loc, i, hw, xm, cm, cmPolOcean, cmPolNone: integer;
    4076   PrevMiniPixel: TPixelPointer;
    4077   MiniPixel: TPixelPointer;
    4078   TerrainTile: Cardinal;
    4079 begin
    4080   cmPolOcean := GrExt[HGrSystem].Data.Canvas.Pixels[101, 67];
    4081   cmPolNone := GrExt[HGrSystem].Data.Canvas.Pixels[102, 67];
    4082   hw := MapWidth div (xxt * 2);
    4083   with Mini.Canvas do
    4084   begin
    4085     Brush.Color := $000000;
    4086     FillRect(Rect(0, 0, Mini.width, Mini.height));
    4087   end;
    4088   Mini.BeginUpdate;
    4089   MiniPixel := PixelPointer(Mini);
    4090   PrevMiniPixel := PixelPointer(Mini);
    4091   for y := 0 to ScaleToNative(G.ly) - 1 do
    4092   begin
    4093     for x := 0 to ScaleToNative(G.lx) - 1 do
    4094       if MyMap[ScaleFromNative(x) + G.lx * ScaleFromNative(y)] and fTerrain <> fUNKNOWN then
    4095       begin
    4096         Loc := ScaleFromNative(x) + G.lx * ScaleFromNative(y);
    4097         for i := 0 to 1 do
    4098         begin
    4099           xm := ((x - ScaleToNative(xwMini)) * 2 + i + y and 1 - ScaleToNative(hw) +
    4100             ScaleToNative(G.lx) * 5) mod (ScaleToNative(G.lx) * 2);
    4101           MiniPixel.SetXY(xm, y);
    4102           TerrainTile := MyMap[Loc] and fTerrain;
    4103           if TerrainTile > 11 then TerrainTile := 0;
    4104           cm := MiniColors[TerrainTile, i];
    4105           if ClientMode = cEditMap then
    4106           begin
    4107             if MyMap[Loc] and (fPrefStartPos or fStartPos) <> 0 then
    4108               cm := $FFFFFF;
    4109           end
    4110           else if MyMap[Loc] and fCity <> 0 then
    4111           begin
    4112             cix := MyRO.nCity - 1;
    4113             while (cix >= 0) and (MyCity[cix].Loc <> Loc) do
    4114               dec(cix);
    4115             if cix >= 0 then
    4116               cm := Tribe[me].Color
    4117             else
    4118             begin
    4119               cix := MyRO.nEnemyCity - 1;
    4120               while (cix >= 0) and (MyRO.EnemyCity[cix].Loc <> Loc) do
    4121                 dec(cix);
    4122               if cix >= 0 then
    4123                 cm := Tribe[MyRO.EnemyCity[cix].Owner].Color
    4124             end;
    4125             cm := $808080 or cm shr 1; { increase brightness }
    4126             if y > 0 then begin
    4127               // 2x2 city dot covers two lines
    4128               PrevMiniPixel.SetXY(xm, y - 1);
    4129               PrevMiniPixel.Pixel^.B := cm shr 16;
    4130               PrevMiniPixel.Pixel^.G := cm shr 8 and $FF;
    4131               PrevMiniPixel.Pixel^.R := cm and $FF;
    4132             end
    4133           end
    4134           else if (i = 0) and (MyMap[Loc] and fUnit <> 0) then
    4135           begin
    4136             uix := MyRO.nUn - 1;
    4137             while (uix >= 0) and (MyUn[uix].Loc <> Loc) do
    4138               dec(uix);
    4139             if uix >= 0 then
    4140               cm := Tribe[me].Color
    4141             else
    4142             begin
    4143               uix := MyRO.nEnemyUn - 1;
    4144               while (uix >= 0) and (MyRO.EnemyUn[uix].Loc <> Loc) do
    4145                 dec(uix);
    4146               if uix >= 0 then
    4147                 cm := Tribe[MyRO.EnemyUn[uix].Owner].Color
    4148             end;
    4149             cm := $808080 or cm shr 1; { increase brightness }
    4150           end
    4151           else if MapOptionChecked and (1 shl moPolitical) <> 0 then
    4152           begin
    4153             if MyMap[Loc] and fTerrain < fGrass then
    4154               cm := cmPolOcean
    4155             else if MyRO.Territory[Loc] < 0 then
    4156               cm := cmPolNone
    4157             else
    4158               cm := Tribe[MyRO.Territory[Loc]].Color;
    4159           end;
    4160           MiniPixel.Pixel^.B := cm shr 16;
    4161           MiniPixel.Pixel^.G := cm shr 8 and $FF;
    4162           MiniPixel.Pixel^.R := cm and $FF;
    4163         end;
    4164       end;
    4165   end;
    4166   Mini.EndUpdate;
    4167 end;
     4110{$IFDEF LINUX}
     4111// Can't do scrolling of DC under Linux, then fallback into BitBlt.
     4112function DpiScrollDC(Canvas: TDpiCanvas; dx: longint; dy: longint; const lprcScroll:TRect; const lprcClip:TRect; hrgnUpdate:HRGN; lprcUpdate: PRect):Boolean;
     4113begin
     4114  Result := DpiBitCanvas(Canvas, lprcScroll.Left + dx, lprcScroll.Top + dy, lprcScroll.Right - lprcScroll.Left, lprcScroll.Bottom - lprcScroll.Top,
     4115    Canvas, lprcScroll.Left, lprcScroll.Top);
     4116end;
     4117{$ENDIF}
    41684118
    41694119procedure TMainScreen.MainOffscreenPaint;
     
    41804130      Brush.Style := bsClear;
    41814131      OffscreenUser := self;
    4182       exit
     4132      exit;
    41834133    end;
    41844134
     
    41954145  end;
    41964146
    4197   if xw - xwd > G.lx div 2 then
    4198     xwd := xwd + G.lx
    4199   else if xwd - xw > G.lx div 2 then
    4200     xwd := xwd - G.lx;
    4201   if not MapValid or (xw - xwd > MapWidth div (xxt * 2)) or
    4202     (xwd - xw > MapWidth div (xxt * 2)) or (yw - ywd > MapHeight div yyt) or
    4203     (ywd - yw > MapHeight div yyt) then
    4204   begin
    4205     offscreen.Canvas.Font.Assign(UniFont[ftSmall]);
    4206     ProcessRect(xw, yw, MapWidth div xxt, MapHeight div yyt,
    4207       prPaint or prInvalidate)
    4208   end
    4209   else
    4210   begin
    4211     if (xwd = xw) and (ywd = yw) then
    4212       exit; { map window not moved }
    4213     offscreen.Canvas.Font.Assign(UniFont[ftSmall]);
    4214     rec := Rect(0, 0, MapWidth, MapHeight);
    4215     DpiScrollDC(offscreen.Canvas, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt,
    4216       rec, rec, 0, nil);
    4217     for DoInvalidate := false to FastScrolling do
    4218     begin
    4219       if DoInvalidate then
    4220       begin
    4221         rec.Bottom := MapHeight - overlap;
    4222         DpiScrollDC(Canvas, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt, rec,
    4223           rec, 0, nil);
    4224         ProcessOptions := prInvalidate;
    4225       end
    4226       else
    4227         ProcessOptions := prPaint or prAutoBounds;
    4228       if yw < ywd then
    4229       begin
    4230         ProcessRect(xw, yw, MapWidth div xxt, ywd - yw - 1, ProcessOptions);
    4231         if xw < xwd then
    4232           ProcessRect(xw, ywd, (xwd - xw) * 2 - 1, MapHeight div yyt - ywd + yw,
     4147  with MainMap do begin
     4148    if xw - xwd > G.lx div 2 then
     4149      xwd := xwd + G.lx
     4150    else if xwd - xw > G.lx div 2 then
     4151      xwd := xwd - G.lx;
     4152    if not MapValid or (xw - xwd > MapWidth div (xxt * 2)) or
     4153      (xwd - xw > MapWidth div (xxt * 2)) or (yw - ywd > MapHeight div yyt) or
     4154      (ywd - yw > MapHeight div yyt) then
     4155    begin
     4156      offscreen.Canvas.Font.Assign(UniFont[ftSmall]);
     4157      ProcessRect(xw, yw, MapWidth div xxt, MapHeight div yyt,
     4158        prPaint or prInvalidate);
     4159    end else begin
     4160      if (xwd = xw) and (ywd = yw) then
     4161        exit; { map window not moved }
     4162      offscreen.Canvas.Font.Assign(UniFont[ftSmall]);
     4163      rec := Rect(0, 0, MapWidth, MapHeight);
     4164{$IFDEF WINDOWS}
     4165      DpiScrollDC(offscreen.Canvas.Handle, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt,
     4166        rec, rec, 0, nil);
     4167{$ENDIF}
     4168{$IFDEF LINUX}
     4169      DpiScrollDC(offscreen.Canvas, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt,
     4170        rec, rec, 0, nil);
     4171{$ENDIF}
     4172      for DoInvalidate := false to FastScrolling do begin
     4173        if DoInvalidate then begin
     4174          rec.Bottom := MapHeight - overlap;
     4175{$IFDEF WINDOWS}
     4176          DpiScrollDC(Canvas.Handle, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt, rec,
     4177            rec, 0, nil);
     4178{$ENDIF}
     4179{$IFDEF LINUX}
     4180          DpiScrollDC(Canvas, (xwd - xw) * (xxt * 2), (ywd - yw) * yyt,
     4181            rec, rec, 0, nil);
     4182{$ENDIF}
     4183          ProcessOptions := prInvalidate;
     4184        end
     4185        else ProcessOptions := prPaint or prAutoBounds;
     4186        if yw < ywd then begin
     4187          ProcessRect(xw, yw, MapWidth div xxt, ywd - yw - 1, ProcessOptions);
     4188          if xw < xwd then
     4189            ProcessRect(xw, ywd, (xwd - xw) * 2 - 1, MapHeight div yyt - ywd + yw,
     4190              ProcessOptions)
     4191          else if xw > xwd then
     4192            ProcessRect((xwd + MapWidth div (xxt * 2)) mod G.lx, ywd,
     4193              (xw - xwd) * 2 + 1, MapHeight div yyt - ywd + yw, ProcessOptions)
     4194        end
     4195        else if yw > ywd then begin
     4196          if DoInvalidate then
     4197            RectInvalidate(MapOffset, TopBarHeight + MapHeight - overlap -
     4198              (yw - ywd) * yyt, MapOffset + MapWidth, TopBarHeight + MapHeight
     4199              - overlap)
     4200          else
     4201            ProcessRect(xw, (ywd + MapHeight div (yyt * 2) * 2), MapWidth div xxt,
     4202              yw - ywd + 1, ProcessOptions);
     4203          if xw < xwd then
     4204            ProcessRect(xw, yw, (xwd - xw) * 2 - 1, MapHeight div yyt - yw + ywd -
     4205              2, ProcessOptions)
     4206          else if xw > xwd then
     4207            ProcessRect((xwd + MapWidth div (xxt * 2)) mod G.lx, yw,
     4208              (xw - xwd) * 2 + 1, MapHeight div yyt - yw + ywd - 2,
     4209              ProcessOptions);
     4210        end
     4211        else if xw < xwd then
     4212          ProcessRect(xw, yw, (xwd - xw) * 2 - 1, MapHeight div yyt,
    42334213            ProcessOptions)
    42344214        else if xw > xwd then
    4235           ProcessRect((xwd + MapWidth div (xxt * 2)) mod G.lx, ywd,
    4236             (xw - xwd) * 2 + 1, MapHeight div yyt - ywd + yw, ProcessOptions)
    4237       end
    4238       else if yw > ywd then
    4239       begin
    4240         if DoInvalidate then
    4241           RectInvalidate(MapOffset, TopBarHeight + MapHeight - overlap -
    4242             (yw - ywd) * yyt, MapOffset + MapWidth, TopBarHeight + MapHeight
    4243             - overlap)
    4244         else
    4245           ProcessRect(xw, (ywd + MapHeight div (yyt * 2) * 2), MapWidth div xxt,
    4246             yw - ywd + 1, ProcessOptions);
    4247         if xw < xwd then
    4248           ProcessRect(xw, yw, (xwd - xw) * 2 - 1, MapHeight div yyt - yw + ywd -
    4249             2, ProcessOptions)
    4250         else if xw > xwd then
    42514215          ProcessRect((xwd + MapWidth div (xxt * 2)) mod G.lx, yw,
    4252             (xw - xwd) * 2 + 1, MapHeight div yyt - yw + ywd - 2,
    4253             ProcessOptions)
    4254       end
    4255       else if xw < xwd then
    4256         ProcessRect(xw, yw, (xwd - xw) * 2 - 1, MapHeight div yyt,
    4257           ProcessOptions)
    4258       else if xw > xwd then
    4259         ProcessRect((xwd + MapWidth div (xxt * 2)) mod G.lx, yw,
    4260           (xw - xwd) * 2 + 1, MapHeight div yyt, ProcessOptions);
    4261     end;
    4262     if not FastScrolling then
    4263       RectInvalidate(MapOffset, TopBarHeight, MapOffset + MapWidth,
    4264         TopBarHeight + MapHeight - overlap);
    4265     RectInvalidate(xMidPanel, TopBarHeight + MapHeight - overlap, xRightPanel,
    4266       TopBarHeight + MapHeight)
     4216            (xw - xwd) * 2 + 1, MapHeight div yyt, ProcessOptions);
     4217      end;
     4218      if not FastScrolling then
     4219        RectInvalidate(MapOffset, TopBarHeight, MapOffset + MapWidth,
     4220          TopBarHeight + MapHeight - overlap);
     4221      RectInvalidate(xMidPanel, TopBarHeight + MapHeight - overlap, xRightPanel,
     4222        TopBarHeight + MapHeight);
     4223    end;
    42674224  end;
    42684225  // if (xwd<>xw) or (ywd<>yw) then
     
    42734230end;
    42744231
     4232procedure TMainScreen.MiniMapPaint;
     4233begin
     4234  with MainMap do
     4235    MiniMap.Paint(MyMap, MapWidth, ClientMode, xxt, xwMini);
     4236end;
     4237
    42754238procedure TMainScreen.PaintAll;
    42764239begin
     
    42784241  xwMini := xw;
    42794242  ywMini := yw;
    4280   MiniPaint;
     4243  MiniMapPaint;
    42814244  PanelPaint;
    42824245end;
     
    42874250  xwMini := xw;
    42884251  ywMini := yw;
    4289   MiniPaint;
     4252  MiniMapPaint;
    42904253  CopyMiniToPanel;
    42914254  RectInvalidate(xMini + 2, TopBarHeight + MapHeight - overlap + yMini + 2,
     
    42964259procedure TMainScreen.CopyMiniToPanel;
    42974260begin
    4298   DpiBitCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
    4299     Mini.Canvas, 0, 0);
    4300   if MarkCityLoc >= 0 then
    4301     Sprite(Panel, HGrSystem, xMini - 2 + (4 * G.lx + 2 * (MarkCityLoc mod G.lx)
    4302       + (G.lx - MapWidth div (xxt * 2)) - 2 * xwd) mod (2 * G.lx) +
    4303       MarkCityLoc div G.lx and 1, yMini - 3 + MarkCityLoc div G.lx, 10,
    4304       10, 77, 47)
    4305   else if ywmax <= 0 then
    4306     Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (xxt * 2), yMini + 2,
    4307       xMini + 1 + G.lx + MapWidth div (xxt * 2), yMini + 2 + G.ly - 1,
    4308       MainTexture.clMark, MainTexture.clMark)
    4309   else
    4310     Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (xxt * 2),
    4311       yMini + 2 + yw, xMini + 1 + G.lx + MapWidth div (xxt * 2),
    4312       yMini + yw + MapHeight div yyt, MainTexture.clMark, MainTexture.clMark);
     4261  with MainMap do begin
     4262    DpiBitCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
     4263      MiniMap.Bitmap.Canvas, 0, 0);
     4264    if MarkCityLoc >= 0 then
     4265      Sprite(Panel, HGrSystem, xMini - 2 + (4 * G.lx + 2 * (MarkCityLoc mod G.lx)
     4266        + (G.lx - MapWidth div (xxt * 2)) - 2 * xwd) mod (2 * G.lx) +
     4267        MarkCityLoc div G.lx and 1, yMini - 3 + MarkCityLoc div G.lx, CityMark2.Width,
     4268        CityMark2.Height, CityMark2.Left, CityMark2.Top)
     4269    else if ywmax <= 0 then
     4270      Frame(Panel.Canvas,
     4271        xMini + 2 + G.lx - MapWidth div (xxt * 2), yMini + 2,
     4272        xMini + 1 + G.lx + MapWidth div (xxt * 2), yMini + 2 + G.ly - 1,
     4273        MainTexture.clMark, MainTexture.clMark)
     4274    else
     4275      Frame(Panel.Canvas,
     4276        xMini + 2 + G.lx - MapWidth div (xxt * 2), yMini + 2 + yw,
     4277        xMini + 1 + G.lx + MapWidth div (xxt * 2), yMini + yw + MapHeight div yyt,
     4278        MainTexture.clMark, MainTexture.clMark);
     4279  end;
    43134280end;
    43144281
     
    43364303  Prio: boolean;
    43374304begin
     4305  if not Assigned(MyRO) then Exit;
    43384306  with Panel.Canvas do
    43394307  begin
     
    43864354          $FFFFFF, $B0B0B0);
    43874355        DpiBitCanvas(Panel.Canvas, ClientWidth - xPalace, yPalace, xSizeBig,
    4388           ySizeBig, GrExt[HGrSystem2].Data.Canvas, 70, 123);
     4356          ySizeBig, HGrSystem2.Data.Canvas, 70, 123);
    43894357      end
    43904358      else if MyRO.NatBuilt[imPalace] > 0 then
     
    44974465              end;
    44984466          end;
    4499           if xSrcBase >= 0 then
     4467          with MainMap do begin
     4468            if xSrcBase >= 0 then
     4469              Sprite(Panel, HGrTerrain, xTroop + 2 + x, yTroop + 9 - yyt, xxt * 2,
     4470                yyt * 3, 1 + xSrcBase * (xxt * 2 + 1),
     4471                1 + ySrcBase * (yyt * 3 + 1));
    45004472            Sprite(Panel, HGrTerrain, xTroop + 2 + x, yTroop + 9 - yyt, xxt * 2,
    4501               yyt * 3, 1 + xSrcBase * (xxt * 2 + 1),
    4502               1 + ySrcBase * (yyt * 3 + 1));
    4503           Sprite(Panel, HGrTerrain, xTroop + 2 + x, yTroop + 9 - yyt, xxt * 2,
    4504             yyt * 3, 1 + xSrc * (xxt * 2 + 1), 1 + ySrc * (yyt * 3 + 1));
    4505           if BrushTypes[i] = BrushType then
    4506           begin
    4507             ScreenTools.Frame(Panel.Canvas, xTroop + 2 + x,
    4508               yTroop + 7 - yyt div 2, xTroop + 2 * xxt + x,
    4509               yTroop + 2 * yyt + 11, $000000, $000000);
    4510             ScreenTools.Frame(Panel.Canvas, xTroop + 1 + x,
    4511               yTroop + 6 - yyt div 2, xTroop + 2 * xxt - 1 + x,
    4512               yTroop + 2 * yyt + 10, MainTexture.clMark, MainTexture.clMark);
    4513           end
     4473              yyt * 3, 1 + xSrc * (xxt * 2 + 1), 1 + ySrc * (yyt * 3 + 1));
     4474            if BrushTypes[i] = BrushType then begin
     4475              ScreenTools.Frame(Panel.Canvas, xTroop + 2 + x,
     4476                yTroop + 7 - yyt div 2, xTroop + 2 * xxt + x,
     4477                yTroop + 2 * yyt + 11, $000000, $000000);
     4478              ScreenTools.Frame(Panel.Canvas, xTroop + 1 + x,
     4479                yTroop + 6 - yyt div 2, xTroop + 2 * xxt - 1 + x,
     4480                yTroop + 2 * yyt + 10, MainTexture.clMark, MainTexture.clMark);
     4481            end;
     4482          end;
    45144483        end;
    45154484        inc(Count)
     
    45714540      Brush.Style := bsClear;
    45724541      if UnFocus >= 0 then
    4573         with MyUn[UnFocus], MyModel[mix] do
     4542        with MyUn[UnFocus] do
     4543        with MyModel[mix] do
    45744544        begin { display info about selected unit }
    45754545          if Job = jCity then
     
    46004570            BiColorTextWidth(Panel.Canvas, s) div 2, PanelHeight - 23, s);
    46014571
    4602           FrameImage(Panel.Canvas, GrExt[HGrSystem].Data,
     4572          FrameImage(Panel.Canvas, HGrSystem.Data,
    46034573            xMidPanel + 7 + xUnitText, yTroop + 15, 12, 14,
    46044574            121 + Exp div ExpCost * 13, 28);
     
    46764646                          xTroop + 63 + x, yTroop + 46, 8, MainTexture.clMark);
    46774647                      end;
    4678                       NoMap.SetOutput(Panel);
    4679                       NoMap.PaintUnit(xTroop + 2 + x, yTroop + 1, UnitInfo,
     4648                      NoMapPanel.SetOutput(Panel);
     4649                      NoMapPanel.PaintUnit(xTroop + 2 + x, yTroop + 1, UnitInfo,
    46804650                        unx.Status);
    46814651                      if (ClientMode < scContact) and
     
    46944664                          xTroop + x + 34 - BiColorTextWidth(Panel.Canvas, s)
    46954665                          div 2, yTroop - 16, s);
    4696                       end
     4666                      end;
    46974667                    end;
    46984668                    inc(Count)
     
    47004670                end; // for uix:=0 to MyRO.nUn-1
    47014671            assert(Count = TrCnt);
    4702           end
     4672          end;
    47034673        end
    47044674        else
     
    47124682              trix[i - TrRow * sb.Position] := i;
    47134683              x := (i - TrRow * sb.Position) * TrPitch;
    4714               NoMap.SetOutput(Panel);
    4715               NoMap.PaintUnit(xTroop + 2 + x, yTroop + 1,
     4684              NoMapPanel.SetOutput(Panel);
     4685              NoMapPanel.PaintUnit(xTroop + 2 + x, yTroop + 1,
    47164686                MyRO.EnemyUn[MyRO.nEnemyUn + i], 0);
    47174687            end;
     
    47204690      if not SmallScreen or supervising then
    47214691      begin // show terrain and improvements
    4722         PaintZoomedTile(Panel, xTerrain - xxt * 2, 110 - yyt * 3, TroopLoc);
    4723         if (UnFocus >= 0) and (MyUn[UnFocus].Job <> jNone) then
    4724         begin
     4692        with NoMapPanel do
     4693          PaintZoomedTile(Panel, xTerrain - xxt * 2, 110 - yyt * 3, TroopLoc);
     4694        if (UnFocus >= 0) and (MyUn[UnFocus].Job <> jNone) then begin
    47254695          JobFocus := MyUn[UnFocus].Job;
    47264696          Server(sGetJobProgress, me, MyUn[UnFocus].Loc, JobProgressData);
     
    47704740            (PanelHeight - 1), Left + width, Top + height - self.ClientHeight +
    47714741            PanelHeight, MainTexture.clBevelShade, MainTexture.clBevelLight)
    4772     end { if TroopLoc>=0 }
     4742    end; { if TroopLoc>=0 }
    47734743  end;
    47744744
     
    48004770            (PanelHeight - 1), Left + width, Top + height - self.ClientHeight +
    48014771            PanelHeight, MainTexture.clBevelShade, MainTexture.clBevelLight);
    4802         end
     4772        end;
    48034773  end;
    48044774  EOT.SetBack(Panel.Canvas, EOT.Left, EOT.Top - (ClientHeight - PanelHeight));
     
    48284798  end;
    48294799  if GameMode <> cMovie then
    4830     ImageOp_BCC(TopBar, Templates, 2, 1, 145, 38, 36, 36, $BFBF20, $4040DF);
     4800    ImageOp_BCC(TopBar, Templates.Data, Point(2, 1), MenuLogo.BoundsRect, $BFBF20, $4040DF);
    48314801  if MyRO.nCity > 0 then
    48324802  begin
     
    48444814
    48454815    // treasury section
    4846     ImageOp_BCC(TopBar, Templates, xTreasurySection + 8, 1, 145, 1, 36, 36,
     4816    ImageOp_BCC(TopBar, Templates.Data, Point(xTreasurySection + 8, 1), TreasuryIcon.BoundsRect,
    48474817      $40A040, $4030C0);
    48484818    s := IntToStr(TrueMoney);
     
    48514821    if MyRO.Government <> gAnarchy then
    48524822    begin
    4853       ImageOp_BCC(TopBar, Templates, xTreasurySection + 48, 22, 124, 1, 14, 14,
     4823      ImageOp_BCC(TopBar, Templates.Data, Point(xTreasurySection + 48, 22), ChangeIcon.BoundsRect,
    48544824        $0000C0, $0080C0);
    48554825      if TaxSum >= 0 then
     
    48624832
    48634833    // research section
    4864     ImageOp_BCC(TopBar, Templates, xResearchSection + 8, 1, 145, 75, 36, 36,
     4834    ImageOp_BCC(TopBar, Templates.Data, Point(xResearchSection + 8, 1), ResearchIcon.BoundsRect,
    48654835      $FF0000, $00FFE0);
    48664836    if MyData.FarTech <> adNexus then
     
    49134883    if (MyData.FarTech <> adNexus) and (ScienceSum > 0) then
    49144884    begin
    4915       ImageOp_BCC(TopBar, Templates, xResearchSection + 48 + CostFactor + 11,
    4916         22, 124, 1, 14, 14, $0000C0, $0080C0);
     4885      ImageOp_BCC(TopBar, Templates.Data, Point(xResearchSection + 48 + CostFactor + 11,
     4886        22), ChangeIcon.BoundsRect, $0000C0, $0080C0);
    49174887      s := Format(Phrases.Lookup('TECHGAIN'), [ScienceSum]);
    49184888      LoweredTextOut(TopBar.Canvas, -1, MainTexture, xResearchSection + 48 +
    49194889        CostFactor + 26, 18, s);
    4920     end
     4890    end;
    49214891  end;
    49224892  if ClientMode <> cEditMap then
     
    49304900  end;
    49314901  RectInvalidate(0, 0, ClientWidth, TopBarHeight);
    4932 end; { PanelPaint }
     4902end;
    49334903
    49344904procedure TMainScreen.FocusOnLoc(Loc: integer; Options: integer = 0);
     
    49374907  Outside, Changed: boolean;
    49384908begin
    4939   dx := G.lx + 1 - (xw - Loc + G.lx * 1024 + 1) mod G.lx;
    4940   Outside := (dx >= (MapWidth + 1) div (xxt * 2) - 2) or (ywmax > 0) and
    4941     ((yw > 0) and (Loc div G.lx <= yw + 1) or (yw < ywmax) and
    4942     (Loc div G.lx >= yw + (MapHeight - 1) div yyt - 2));
     4909  with MainMap do begin
     4910    dx := G.lx + 1 - (xw - Loc + G.lx * 1024 + 1) mod G.lx;
     4911    Outside := (dx >= (MapWidth + 1) div (xxt * 2) - 2) or (ywmax > 0) and
     4912      ((yw > 0) and (Loc div G.lx <= yw + 1) or (yw < ywmax) and
     4913      (Loc div G.lx >= yw + (MapHeight - 1) div yyt - 2));
     4914  end;
    49434915  Changed := true;
    4944   if Outside then
    4945   begin
     4916  if Outside then begin
    49464917    Centre(Loc);
    4947     PaintAllMaps
     4918    PaintAllMaps;
    49484919  end
    49494920  else if not MapValid then
     
    49804951        begin
    49814952          NewFocus := uix;
    4982           Break
     4953          Break;
    49834954        end
    49844955        else
     
    49884959          begin
    49894960            NewFocus := uix;
    4990             Dist := TestDist
    4991           end
    4992         end
     4961            Dist := TestDist;
     4962          end;
     4963        end;
    49934964    end;
    49944965    if GotoOnly then
     
    50204991    PanelPaint;
    50214992  end;
    5022 end; { NextUnit }
     4993end;
    50234994
    50244995procedure TMainScreen.Scroll(dx, dy: integer);
     
    50365007  xwMini := xw;
    50375008  ywMini := yw;
    5038   MiniPaint;
     5009  MiniMapPaint;
    50395010  CopyMiniToPanel;
    50405011  RectInvalidate(xMini + 2, TopBarHeight + MapHeight - overlap + yMini + 2,
     
    50465017procedure TMainScreen.Timer1Timer(Sender: TObject);
    50475018var
    5048   dx, dy, speed: integer;
     5019  dx, dy, ScrollSpeed: integer;
    50495020begin
    50505021  if idle and (me >= 0) and (GameMode <> cMovie) then
     
    50605031          PaintLocTemp(MyUn[UnFocus].Loc)
    50615032        else if TurnComplete and not supervising then
    5062           EOT.SetButtonIndexFast(eotBlinkOn)
    5063       end
     5033          EOT.SetButtonIndexFast(eotBlinkOn);
     5034      end;
    50645035    end
    50655036    else
     
    50675038      if DpiApplication.Active and not mScrollOff.Checked then
    50685039      begin
    5069         if mScrollFast.Checked then
    5070           speed := 2
    5071         else
    5072           speed := 1;
     5040        if mScrollFast.Checked then ScrollSpeed := 2
     5041          else ScrollSpeed := 1;
    50735042        dx := 0;
    50745043        dy := 0;
    50755044        if DpiMouse.CursorPos.y < DpiScreen.height - PanelHeight then
    50765045          if DpiMouse.CursorPos.x = 0 then
    5077             dx := -speed // scroll left
    5078           else if DpiMouse.CursorPos.x >= DpiScreen.width - 1 then
    5079             dx := speed; // scroll right
     5046            dx := -ScrollSpeed // scroll left
     5047          else if DpiMouse.CursorPos.x = DpiScreen.width - 1 then
     5048            dx := ScrollSpeed; // scroll right
    50805049        if DpiMouse.CursorPos.y = 0 then
    5081           dy := -speed // scroll up
    5082         else if (DpiMouse.CursorPos.y >= DpiScreen.height - 1) and
     5050          dy := -ScrollSpeed // scroll up
     5051        else if (DpiMouse.CursorPos.y = DpiScreen.height - 1) and
    50835052          (DpiMouse.CursorPos.x >= TerrainBtn.Left + TerrainBtn.width) and
    50845053          (DpiMouse.CursorPos.x < xRightPanel + 10 - 8) then
    5085           dy := speed; // scroll down
     5054          dy := ScrollSpeed; // scroll down
    50865055        if (dx <> 0) or (dy <> 0) then
    50875056        begin
     
    50905059            DpiScreen.ActiveForm.OnDeactivate(nil);
    50915060          Scroll(dx, dy);
    5092         end
     5061        end;
    50935062      end;
    50945063
     
    51045073          // if MoveHintToLoc>=0 then
    51055074          // ShowMoveHint(MoveHintToLoc, true);
    5106         end
     5075        end;
    51075076      end
    51085077      else if TurnComplete and not supervising then
     
    51115080          EOT.SetButtonIndexFast(eotBlinkOff)
    51125081        else if BlinkTime = BlinkOffTime then
    5113           EOT.SetButtonIndexFast(eotBlinkOn)
    5114       end
    5115     end
     5082          EOT.SetButtonIndexFast(eotBlinkOn);
     5083      end;
     5084    end;
     5085end;
     5086
     5087procedure TMainScreen.SetMapPos(Loc: integer; MapPos: TPoint);
     5088begin
     5089  with MainMap do begin
     5090    if FastScrolling and MapValid then
     5091      Update;
     5092    // necessary because ScrollDC for form canvas is called after
     5093    xw := (Loc mod G.lx) - (MapPos.X - ((xxt * 2) * ((Loc div G.lx) and 1)) div 2)
     5094      div (xxt * 2);
     5095    xw := (xw + G.lx) mod G.lx;
     5096    if ywmax <= 0 then yw := ywcenter
     5097    else begin
     5098      yw := (Loc div G.lx - (MapPos.Y * 2) div (yyt * 2) + 1) and not 1;
     5099      if yw < 0 then yw := 0
     5100        else if yw > ywmax then yw := ywmax;
     5101    end;
     5102  end;
    51165103end;
    51175104
    51185105procedure TMainScreen.Centre(Loc: integer);
    51195106begin
    5120   if FastScrolling and MapValid then
    5121     Update;
    5122   // necessary because ScrollDC for form canvas is called after
    5123   xw := (Loc mod G.lx - (MapWidth - xxt * 2 * ((Loc div G.lx) and 1))
    5124     div (xxt * 4) + G.lx) mod G.lx;
    5125   if ywmax <= 0 then
    5126     yw := ywcenter
    5127   else
    5128   begin
    5129     yw := (Loc div G.lx - MapHeight div (yyt * 2) + 1) and not 1;
    5130     if yw < 0 then
    5131       yw := 0
    5132     else if yw > ywmax then
    5133       yw := ywmax;
    5134   end
     5107  SetMapPos(Loc, Point(MapWidth div 2, MapHeight div 2));
    51355108end;
    51365109
     
    51625135      PanelPaint;
    51635136      ShowNewContent(wmPersistent, Loc, ShowEvent);
    5164     end
    5165 end;
    5166 
    5167 function TMainScreen.LocationOfScreenPixel(x, y: integer): integer;
     5137    end;
     5138end;
     5139
     5140function TMainScreen.LocationOfScreenPixel(x, y: integer): Integer;
    51685141var
    51695142  qx, qy: integer;
    51705143begin
    5171   qx := (x * (yyt * 2) + y * (xxt * 2) + xxt * yyt * 2) div (xxt * yyt * 4) - 1;
    5172   qy := (y * (xxt * 2) - x * (yyt * 2) - xxt * yyt * 2 + 4000 * xxt * yyt)
    5173     div (xxt * yyt * 4) - 999;
    5174   result := (xw + (qx - qy + 2048) div 2 - 1024 + G.lx) mod G.lx + G.lx *
    5175     (yw + qx + qy);
     5144  with MainMap do begin
     5145    qx := (x * (yyt * 2) + y * (xxt * 2) + xxt * yyt * 2) div (xxt * yyt * 4) - 1;
     5146    qy := (y * (xxt * 2) - x * (yyt * 2) - xxt * yyt * 2 + 4000 * xxt * yyt)
     5147      div (xxt * yyt * 4) - 999;
     5148    Result := (xw + (qx - qy + 2048) div 2 - 1024 + G.lx) mod G.lx + G.lx *
     5149      (yw + qx + qy);
     5150  end;
     5151end;
     5152
     5153function TMainScreen.GetCenterLoc: Integer;
     5154begin
     5155  Result := (xw + MapWidth div (MainMap.xxt * 4)) mod G.lx +
     5156    (yw + MapHeight div (MainMap.yyt * 2)) * G.lx;
    51765157end;
    51775158
     
    52425223      BrushLoc := MouseLoc;
    52435224      PaintLoc(MouseLoc, 2);
    5244       MiniPaint;
     5225      MiniMapPaint;
    52455226      DpiBitCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
    5246         Mini.Canvas, 0, 0);
    5247       if ywmax <= 0 then
    5248         Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
    5249           yMini + 2, xMini + 1 + G.lx + MapWidth div (2 * xxt),
    5250           yMini + 2 + G.ly - 1, MainTexture.clMark, MainTexture.clMark)
    5251       else
    5252         Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
    5253           yMini + 2 + yw, xMini + 2 + G.lx + MapWidth div (2 * xxt) - 1,
    5254           yMini + 2 + yw + MapHeight div yyt - 2, MainTexture.clMark,
    5255           MainTexture.clMark);
     5227        MiniMap.Bitmap.Canvas, 0, 0);
     5228      with MainMap do begin
     5229        if ywmax <= 0 then
     5230          Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
     5231            yMini + 2, xMini + 1 + G.lx + MapWidth div (2 * xxt),
     5232            yMini + 2 + G.ly - 1, MainTexture.clMark, MainTexture.clMark)
     5233        else
     5234          Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
     5235            yMini + 2 + yw, xMini + 2 + G.lx + MapWidth div (2 * xxt) - 1,
     5236            yMini + 2 + yw + MapHeight div yyt - 2, MainTexture.clMark,
     5237            MainTexture.clMark);
     5238      end;
    52565239      RectInvalidate(xMini + 2, TopBarHeight + MapHeight - overlap + yMini + 2,
    52575240        xMini + 2 + G.lx * 2, TopBarHeight + MapHeight - overlap + yMini
    5258         + 2 + G.ly)
     5241        + 2 + G.ly);
    52595242    end
    52605243    else if MyMap[MouseLoc] and fCity <> 0 then { city clicked }
     
    52695252        UnitStatDlg.ShowNewContent_EnemyCity(wmPersistent, MouseLoc);
    52705253        DoCenter := false;
    5271       end
     5254      end;
    52725255    end
    52735256    else if MyMap[MouseLoc] and fUnit <> 0 then { unit clicked }
     
    52915274            end;
    52925275            if i = 0 then
    5293               uix := UnFocus
     5276              uix := UnFocus;
    52945277          end
    52955278          else
     
    53175300    begin
    53185301      Centre(MouseLoc);
    5319       PaintAllMaps
    5320     end
     5302      PaintAllMaps;
     5303    end;
    53215304  end
    53225305  else if (ClientMode <> cEditMap) and (Button = mbRight) and
     
    53385321              MyRO.EnemyModel[emix].mix, MouseLoc) >= rExecuted) then
    53395322            begin
    5340               if Tribe[p1].ModelPicture[MyRO.EnemyModel[emix].mix].HGr = 0 then
     5323              if not Assigned(Tribe[p1].ModelPicture[MyRO.EnemyModel[emix].mix].HGr) then
    53415324                InitEnemyModel(emix);
    53425325              m2 := TDpiMenuItem.Create(m);
     
    53685351          Status := Status and ($FFFF - usStay - usRecover - usGoto - usEnhance)
    53695352            or usWaiting;
    5370           MoveUnit(dx, dy, muAutoNext) { simple move }
     5353          MoveUnit(dx, dy, muAutoNext); { simple move }
    53715354        end
    53725355        else if GetMoveAdvice(UnFocus, MouseLoc, MoveAdviceData) >= rExecuted
     
    53935376              if BattleDlg.ModalResult <> mrOK then
    53945377                exit;
    5395             end
     5378            end;
    53965379          end;
    53975380          DestinationMarkON := false;
     
    54005383            usWaiting;
    54015384          MoveToLoc(MouseLoc, false); { goto }
    5402         end
    5403       end
     5385        end;
     5386      end;
    54045387  end
    54055388  else if (Button = mbMiddle) and (UnFocus >= 0) and
     
    54145397      MoveToLoc(MouseLoc, true); { goto }
    54155398    if (UnFocus = uix) and (MyUn[uix].Loc = MouseLoc) then
    5416       MenuClick(mEnhance)
     5399      MenuClick(mEnhance);
    54175400  end
    54185401  else if (Button = mbLeft) and (ssShift in Shift) and
     
    54495432      BattleDlg.IsSuicideQuery := false;
    54505433      BattleDlg.Show;
    5451     end
    5452   end
     5434    end;
     5435  end;
    54535436end;
    54545437
     
    58915874    if CityCaptured and (MyMap[ToLoc] and fCity = 0) then
    58925875    begin // city destroyed
    5893       for i := 0 to 27 do { tell about destroyed wonders }
    5894         if (MyRO.Wonder[i].CityID = -2) and (MyData.ToldWonders[i].CityID <> -2)
     5876      for i := 0 to nWonder - 1 do { tell about destroyed wonders }
     5877        if (MyRO.Wonder[i].CityID = WonderDestroyed) and (MyData.ToldWonders[i].CityID <> WonderDestroyed)
    58955878        then
    58965879          with MessgExDlg do
     
    59135896    begin // city captured
    59145897      ListDlg.AddCity;
    5915       for i := 0 to 27 do { tell about capture of wonders }
     5898      for i := 0 to nWonder - 1 do { tell about capture of wonders }
    59165899        if MyRO.City[MyRO.nCity - 1].Built[i] > 0 then
    59175900          with MessgExDlg do
     
    60306013    xw1 := xw + G.lx;
    60316014    // ((xFromLoc-xw1)*2+yFromLoc and 1+1)*xxt+dx*xxt/2-MapWidth/2 -> min
    6032     while abs(((xFromLoc - xw1 + G.lx) * 2 + yFromLoc and 1 + 1) * xxt * 2 + dx
    6033       * xxt - MapWidth) < abs(((xFromLoc - xw1) * 2 + yFromLoc and 1 + 1) * xxt
    6034       * 2 + dx * xxt - MapWidth) do
    6035       dec(xw1, G.lx);
    6036 
    6037     xTo := (xToLoc - xw1) * (xxt * 2) + yToLoc and 1 * xxt + (xxt - xxu);
    6038     yTo := (yToLoc - yw) * yyt + (yyt - yyu_anchor);
    6039     xFrom := (xFromLoc - xw1) * (xxt * 2) + yFromLoc and 1 * xxt + (xxt - xxu);
    6040     yFrom := (yFromLoc - yw) * yyt + (yyt - yyu_anchor);
    6041     if xFrom < xTo then
    6042     begin
    6043       xMin := xFrom;
    6044       xRange := xTo - xFrom
    6045     end
    6046     else
    6047     begin
    6048       xMin := xTo;
    6049       xRange := xFrom - xTo
    6050     end;
    6051     if yFrom < yTo then
    6052     begin
    6053       yMin := yFrom;
    6054       yRange := yTo - yFrom
    6055     end
    6056     else
    6057     begin
    6058       yMin := yTo;
    6059       yRange := yFrom - yTo
    6060     end;
    6061     inc(xRange, xxt * 2);
    6062     inc(yRange, yyt * 3);
     6015    with MainMap do begin
     6016      while abs(((xFromLoc - xw1 + G.lx) * 2 + yFromLoc and 1 + 1) * xxt * 2 + dx
     6017        * xxt - MapWidth) < abs(((xFromLoc - xw1) * 2 + yFromLoc and 1 + 1) * xxt
     6018        * 2 + dx * xxt - MapWidth) do
     6019        dec(xw1, G.lx);
     6020
     6021      xTo := (xToLoc - xw1) * (xxt * 2) + yToLoc and 1 * xxt + (xxt - xxu);
     6022      yTo := (yToLoc - yw) * yyt + (yyt - yyu_anchor);
     6023      xFrom := (xFromLoc - xw1) * (xxt * 2) + yFromLoc and 1 * xxt + (xxt - xxu);
     6024      yFrom := (yFromLoc - yw) * yyt + (yyt - yyu_anchor);
     6025      if xFrom < xTo then begin
     6026        xMin := xFrom;
     6027        xRange := xTo - xFrom
     6028      end else begin
     6029        xMin := xTo;
     6030        xRange := xFrom - xTo
     6031      end;
     6032      if yFrom < yTo then begin
     6033        yMin := yFrom;
     6034        yRange := yTo - yFrom
     6035      end else begin
     6036        yMin := yTo;
     6037        yRange := yFrom - yTo
     6038      end;
     6039      inc(xRange, xxt * 2);
     6040      inc(yRange, yyt * 3);
     6041    end;
    60636042
    60646043    MainOffscreenPaint;
     
    61626141      begin
    61636142        assert(false);
    6164         Break
     6143        Break;
    61656144      end;
    61666145    until false;
     
    61886167          NextUnit(UnStartLoc, true)
    61896168        end;
    6190       end
    6191     end
    6192   end
     6169      end;
     6170    end;
     6171  end;
    61936172end;
    61946173
     
    62076186      if ssShift in Shift then
    62086187      begin
    6209         xMouse := (xwMini + (x - (xMini + 2) + MapWidth div (xxt * 2) + G.lx)
    6210           div 2) mod G.lx;
     6188        with MainMap do
     6189          xMouse := (xwMini + (x - (xMini + 2) + MapWidth div (xxt * 2) + G.lx)
     6190            div 2) mod G.lx;
    62116191        MouseLoc := xMouse + G.lx * (y - (yMini + 2));
    62126192        if MyMap[MouseLoc] and fTerrain <> fUNKNOWN then
     
    62156195          if (p1 = me) or (p1 >= 0) and (MyRO.Treaty[p1] >= trNone) then
    62166196            NatStatDlg.ShowNewContent(wmPersistent, p1);
    6217         end
     6197        end;
    62186198      end
    62196199      else
     
    63106290              CheckTerrainBtnVisible;
    63116291              PanelPaint;
    6312             end
     6292            end;
    63136293          end
    63146294          else if Server(sGetUnits, me, TroopLoc, TrCnt) >= rExecuted then
     
    63196299              UnitStatDlg.ShowNewContent_EnemyUnit(wmPersistent,
    63206300                MyRO.nEnemyUn + trix[i]); // unit info
    6321     end
    6322   end
     6301    end;
     6302  end;
    63236303end;
    63246304
     
    64126392procedure TMainScreen.SetDebugMap(p: integer);
    64136393begin
    6414   IsoEngine.pDebugMap := p;
    6415   IsoEngine.Options := IsoEngine.Options and not(1 shl moLocCodes);
     6394  MainMap.pDebugMap := p;
     6395  MapOptions := MapOptions - [moLocCodes];
    64166396  mLocCodes.Checked := false;
    64176397  MapValid := false;
     
    64216401procedure TMainScreen.SetViewpoint(p: integer);
    64226402var
    6423   i: integer;
     6403  i: Integer;
    64246404begin
    64256405  if supervising and (G.RO[0].Turn > 0) and
     
    64326412    SumCities(TaxSum, ScienceSum);
    64336413    for i := 0 to MyRO.nModel - 1 do
    6434       if Tribe[me].ModelPicture[i].HGr = 0 then
    6435         InitMyModel(i, true);
     6414      if not Assigned(Tribe[me].ModelPicture[i].HGr) then
     6415        InitMyModel(i, True);
    64366416
    64376417    SetTroopLoc(-1);
    64386418    PanelPaint;
    6439     MapValid := false;
     6419    MapValid := False;
    64406420    PaintAllMaps;
    64416421  end;
     
    72227202      // check if city types already usefull:
    72237203      if MyRO.nCity > 0 then
    7224         for i := 28 to nImp - 1 do
     7204        for i := nWonder to nImp - 1 do
    72257205          if (i <> imTrGoods) and (Imp[i].Kind = ikCommon) and
    72267206            (Imp[i].Preq <> preNA) and
     
    72757255            m.ShortCut := ShortCut(48 + p1, [ssAlt]);
    72767256          m.RadioItem := true;
    7277           if m.Tag = IsoEngine.pDebugMap then
     7257          if m.Tag = MainMap.pDebugMap then
    72787258            m.Checked := true;
    72797259          mDebugMap.Add(m);
    72807260        end;
    72817261    end;
    7282     mSmallTiles.Checked := xxt = 33;
    7283     mNormalTiles.Checked := xxt = 48;
    7284     mBigTiles.Checked := xxt = 72;
     7262    mSmallTiles.Checked := MainMap.TileSize = tsSmall;
     7263    mNormalTiles.Checked := MainMap.TileSize = tsMedium;
     7264    mBigTiles.Checked := MainMap.TileSize = tsBig;
    72857265  end
    72867266  else if Popup = StatPopup then
     
    73017281    mEUnitStat.Enabled := MyRO.nEnemyModel > 0;
    73027282    { mWonders.Enabled:= false;
    7303       for i:=0 to 27 do if MyRO.Wonder[i].CityID<>-1 then
     7283      for i:=0 to nWonder - 1 do if MyRO.Wonder[i].CityID <> WonderNotBuiltYet then
    73047284      mWonders.Enabled:=true; }
    73057285    mDiagram.Enabled := MyRO.Turn >= 2;
     
    74737453        FocusOnLoc(TroopLoc, flRepaintPanel)
    74747454      else
    7475         PanelPaint
     7455        PanelPaint;
    74767456    end
    74777457    else if StepFocus then
     
    74807460    begin
    74817461      SetTroopLoc(-1);
    7482       PanelPaint
     7462      PanelPaint;
    74837463    end;
    74847464  end;
     
    74967476begin
    74977477  if Tracking and (ssLeft in Shift) then
    7498   begin
     7478  with MainMap do begin
    74997479    if (x >= xMini + 2) and (y >= yMini + 2) and (x < xMini + 2 + 2 * G.lx) and
    75007480      (y < yMini + 2 + G.ly) then
     
    75147494          yw := ywmax;
    75157495      end;
    7516       DpiBitCanvas(Buffer.Canvas, 0, 0, G.lx * 2, G.ly, Mini.Canvas, 0, 0);
     7496      DpiBitCanvas(Buffer.Canvas, 0, 0, G.lx * 2, G.ly, MiniMap.Bitmap.Canvas, 0, 0);
    75177497      if ywmax <= 0 then
    75187498        Frame(Buffer.Canvas, x - xMini - 2 - MapWidth div (xxt * 2), 0,
     
    75447524    xwMini := xw;
    75457525    ywMini := yw;
    7546     MiniPaint;
     7526    MiniMapPaint;
    75477527    PanelPaint;
    75487528  end;
     
    77377717var
    77387718  Reg: TRegistry;
    7739   DefaultOptionChecked: Integer;
    7740 begin
    7741   DefaultOptionChecked := 1 shl 1 + 1 shl 7 + 1 shl 10 + 1 shl 12 + 1 shl 14 +
    7742     1 shl 18 + 1 shl 19;
     7719  DefaultOptionChecked: TSaveOptions;
     7720begin
     7721  DefaultOptionChecked := [soEnMoves, soSlowMoves, soNames, soRepScreens,
     7722    soSoundOn, soScrollOff, soAlSlowMoves];
    77437723  Reg := TRegistry.Create;
    77447724  with Reg do try
    77457725    OpenKey(AppRegistryKey, False);
    7746     if ValueExists('TileWidth') then xxt := ReadInteger('TileWidth') div 2
    7747       else xxt := 48;
    7748     if ValueExists('TileHeight') then yyt := ReadInteger('TileHeight') div 2
    7749       else yyt := 24;
    7750     if ValueExists('OptionChecked') then OptionChecked := ReadInteger('OptionChecked')
     7726    if ValueExists('TileSize') then MainMap.TileSize := TTileSize(ReadInteger('TileSize'))
     7727      else MainMap.TileSize := tsMedium;
     7728    NoMap.TileSize := MainMap.TileSize;
     7729    if ValueExists('OptionChecked') then OptionChecked := TSaveOptions(ReadInteger('OptionChecked'))
    77517730      else OptionChecked := DefaultOptionChecked;
    7752     if ValueExists('MapOptionChecked') then MapOptionChecked := ReadInteger('MapOptionChecked')
    7753       else MapOptionChecked := 1 shl moCityNames;
     7731    if ValueExists('MapOptionChecked') then MapOptionChecked := TMapOptions(ReadInteger('MapOptionChecked'))
     7732      else MapOptionChecked := [moCityNames];
    77547733    if ValueExists('CityReport') then CityRepMask := Cardinal(ReadInteger('CityReport'))
    77557734      else CityRepMask := Cardinal(not chPopIncrease and not chNoGrowthWarning and
    77567735          not chCaptured);
    7757     if OptionChecked and (7 shl 16) = 0 then
    7758       OptionChecked := OptionChecked or (1 shl 16);
     7736    if (not (soScrollFast in OptionChecked)) and (not (soScrollSlow in OptionChecked)) and
     7737      (not (soScrollOff in OptionChecked)) then
     7738      OptionChecked := OptionChecked + [soScrollSlow];
    77597739      // old regver with no scrolling
    77607740  finally
     
    77627742  end;
    77637743
    7764   if 1 shl 13 and OptionChecked <> 0 then
     7744  if soSoundOff in OptionChecked then
    77657745    SoundMode := smOff
    7766   else if 1 shl 15 and OptionChecked <> 0 then
     7746  else if soSoundOnAlt in OptionChecked then
    77677747    SoundMode := smOnAlt
    77687748  else
     
    78257805      end
    78267806      else if Flag = tfAllTechs then
    7827         TellNewModels
     7807        TellNewModels;
    78287808    end;
    78297809  end;
     
    78347814  with TButtonC(Sender) do
    78357815  begin
    7836     MapOptionChecked := MapOptionChecked xor (1 shl (Tag shr 8));
     7816    MapOptionChecked := TMapOptions(Integer(MapOptionChecked) xor (1 shl (Tag shr 8)));
    78377817    SetMapOptions;
    7838     ButtonIndex := MapOptionChecked shr (Tag shr 8) and 1 + 2
     7818    ButtonIndex := Integer(MapOptionChecked) shr (Tag shr 8) and 1 + 2;
    78397819  end;
    78407820  if Sender = MapBtn0 then
    78417821  begin
    7842     MiniPaint;
    7843     PanelPaint
     7822    MiniMapPaint;
     7823    PanelPaint;
    78447824  end // update mini map only
    78457825  else
     
    78547834  if TButtonBase(Sender).Down then
    78557835  begin
    7856     MapOptionChecked := MapOptionChecked or (1 shl moGreatWall);
     7836    MapOptionChecked := MapOptionChecked + [moGreatWall];
    78577837    TButtonBase(Sender).Hint := '';
    78587838  end
    78597839  else
    78607840  begin
    7861     MapOptionChecked := MapOptionChecked and not(1 shl moGreatWall);
     7841    MapOptionChecked := MapOptionChecked - [moGreatWall];
    78627842    TButtonBase(Sender).Hint := Phrases.Lookup('CONTROLS',
    78637843      -1 + TButtonBase(Sender).Tag and $FF);
     
    78727852  if TButtonBase(Sender).Down then
    78737853  begin
    7874     MapOptionChecked := MapOptionChecked or (1 shl moBareTerrain);
     7854    MapOptionChecked := MapOptionChecked + [moBareTerrain];
    78757855    TButtonBase(Sender).Hint := '';
    78767856  end
    78777857  else
    78787858  begin
    7879     MapOptionChecked := MapOptionChecked and not(1 shl moBareTerrain);
     7859    MapOptionChecked := MapOptionChecked - [moBareTerrain];
    78807860    TButtonBase(Sender).Hint := Phrases.Lookup('CONTROLS',
    78817861      -1 + TButtonBase(Sender).Tag and $FF);
     
    79767956procedure TMainScreen.mSmallTilesClick(Sender: TObject);
    79777957begin
    7978   SetTileSize(33, 16);
     7958  SetTileSizeCenter(tsSmall);
    79797959end;
    79807960
    79817961procedure TMainScreen.mNormalTilesClick(Sender: TObject);
    79827962begin
    7983   SetTileSize(48, 24);
     7963  SetTileSizeCenter(tsMedium);
    79847964end;
    79857965
    79867966procedure TMainScreen.mBigTilesClick(Sender: TObject);
    79877967begin
    7988   SetTileSize(72, 36);
    7989 end;
    7990 
    7991 procedure TMainScreen.SetTileSize(x, y: integer);
     7968  SetTileSizeCenter(tsBig);
     7969end;
     7970
     7971procedure TMainScreen.SetTileSizeCenter(TileSize: TTileSize);
     7972begin
     7973  SetTileSize(TileSize, GetCenterLoc, Point(MapWidth div 2, MapHeight div 2));
     7974end;
     7975
     7976procedure TMainScreen.SetTileSize(TileSize: TTileSize; Loc: Integer; MapPos: TPoint);
    79927977var
    7993   i, CenterLoc: integer;
    7994 begin
    7995   CenterLoc := (xw + MapWidth div (xxt * 4)) mod G.lx +
    7996     (yw + MapHeight div (yyt * 2)) * G.lx;
    7997   IsoEngine.ApplyTileSize(x, y);
     7978  i: integer;
     7979begin
     7980  MainMap.TileSize := TileSize;
     7981  NoMap.TileSize := TileSize;
    79987982  FormResize(nil);
    7999   Centre(CenterLoc);
     7983  SetMapPos(Loc, MapPos);
    80007984  PaintAllMaps;
    80017985  for i := 0 to DpiScreen.FormCount - 1 do
     
    80047988end;
    80057989
     7990procedure TMainScreen.SaveMenuItemsState;
     7991var
     7992  i, j: integer;
     7993begin
     7994  if soTellAI in OptionChecked then OptionChecked := [soTellAI]
     7995    else OptionChecked := [];
     7996  for i := 0 to ComponentCount - 1 do
     7997    if Components[i] is TDpiMenuItem then
     7998      for j := 0 to Length(SaveOption) - 1 do
     7999        if TDpiMenuItem(Components[i]).Checked and
     8000          (TDpiMenuItem(Components[i]).Tag = SaveOption[j]) then
     8001          OptionChecked := OptionChecked + [TSaveOption(j)];
     8002end;
     8003
    80068004procedure TMainScreen.SaveSettings;
    80078005var
    8008   i, j: integer;
    80098006  Reg: TRegistry;
    80108007begin
    8011   OptionChecked := OptionChecked and soExtraMask;
    8012   for i := 0 to ComponentCount - 1 do
    8013     if Components[i] is TDpiMenuItem then
    8014       for j := 0 to nSaveOption - 1 do
    8015         if TDpiMenuItem(Components[i]).Checked and
    8016           (TDpiMenuItem(Components[i]).Tag = SaveOption[j]) then
    8017           inc(OptionChecked, 1 shl j);
     8008  SaveMenuItemsState;
    80188009
    80198010  Reg := TRegistry.Create;
     
    80218012  try
    80228013    OpenKey(AppRegistryKey, true);
    8023     WriteInteger('TileWidth', xxt * 2);
    8024     WriteInteger('TileHeight', yyt * 2);
    8025     WriteInteger('OptionChecked', OptionChecked);
    8026     WriteInteger('MapOptionChecked', MapOptionChecked);
     8014    WriteInteger('TileSize', Integer(MainMap.TileSize));
     8015    WriteInteger('OptionChecked', Integer(OptionChecked));
     8016    WriteInteger('MapOptionChecked', Integer(MapOptionChecked));
    80278017    WriteInteger('CityReport', integer(CityRepMask));
    80288018  finally
Note: See TracChangeset for help on using the changeset viewer.