Changeset 349


Ignore:
Timestamp:
Apr 6, 2021, 8:11:02 PM (7 months ago)
Author:
chronos
Message:
  • Modified: Merged trunk branch version r348 into highdpi branch.
Location:
branches/highdpi
Files:
7 added
1 deleted
71 edited
50 moved

Legend:

Unmodified
Added
Removed
  • branches/highdpi/AI/StdAI/AI.pas

    r303 r349  
    11221122            begin // settlers could be added to this city
    11231123              Happy := BasicHappy;
    1124               for i := 0 to 27 do
     1124              for i := 0 to nWonder - 1 do
    11251125                if Built[i] > 0 then
    11261126                  Inc(Happy);
     
    25962596          if (iix >= 0) and (((Imp[iix].Kind in [ikNatLocal, ikNatGlobal]) and
    25972597            (RO.NatBuilt[iix] > 0)) or ((Imp[iix].Kind = ikWonder) and
    2598             (RO.Wonder[iix].CityID <> -1))) then
     2598            (RO.Wonder[iix].CityID <> WonderNotBuiltYet))) then
    25992599            CheckProd := True;
    26002600        end;
  • branches/highdpi/AI/StdAI/Barbarina.pas

    r303 r349  
    12421242      WonderAvailable := WonderAvailable and PrimeWonder; // alway prefer prime wonders
    12431243    Count := 0;
    1244     for iix := 0 to 27 do
     1244    for iix := 0 to nWonder - 1 do
    12451245    begin
    12461246      if (1 shl iix) and WonderAvailable <> 0 then
     
    12541254    end;
    12551255    Count := Random(Count);
    1256     for iix := 0 to 27 do
     1256    for iix := 0 to nWonder - 1 do
    12571257    begin
    12581258      if (1 shl iix) and WonderAvailable <> 0 then
     
    13261326  WonderAvailable := 0;
    13271327  WonderInWork := 0;
    1328   for iix := 0 to 27 do
     1328  for iix := 0 to nWonder - 1 do
    13291329    if (Imp[iix].Preq <> preNA) and ((Imp[iix].Preq = preNone) or
    1330       IsResearched(Imp[iix].Preq)) and (RO.Wonder[iix].CityID = -1) then
     1330      IsResearched(Imp[iix].Preq)) and (RO.Wonder[iix].CityID = WonderNotBuiltYet) then
    13311331      Inc(WonderAvailable, 1 shl iix);
    13321332  for cix := 0 to RO.nCity - 1 do
     
    13341334    begin
    13351335      iix := City_CurrentImprovementProject(cix);
    1336       if (iix >= 0) and (iix < 28) then
     1336      if (iix >= 0) and (iix < nWonder) then
    13371337        Inc(WonderInWork, 1 shl iix)
    13381338      else if iix = imPalace then
     
    14281428
    14291429          iix := City_CurrentImprovementProject(cix);
    1430           if (iix >= 0) and (iix < 28) or (iix = imPalace) or
     1430          if (iix >= 0) and (iix < nWonder) or (iix = imPalace) or
    14311431            (iix = imShipComp) or (iix = imShipPow) or (iix = imShipHab) then
    14321432            City_OptimizeTiles(cix, rwMaxProd)
     
    14471447          if cix = cixNewCapital then
    14481448            City_StartImprovement(cix, imPalace)
    1449           else if (iix >= 0) and (iix < 28) and ((1 shl iix) and
     1449          else if (iix >= 0) and (iix < nWonder) and ((1 shl iix) and
    14501450            WonderAvailable <> 0) then
    14511451          // complete wonder production first
     
    15001500              if ((RO.Government <> gDespotism) or (RO.nUn >= RO.nCity * 4)) and
    15011501                not IsResearched(adMassProduction) and (Built[imPalace] > 0) and
    1502                 (RO.Wonder[woZeus].CityID = -1) and City_Improvable(cix, woZeus) then
     1502                (RO.Wonder[woZeus].CityID = WonderNotBuiltYet) and City_Improvable(cix, woZeus) then
    15031503                City_StartImprovement(cix, woZeus)
    15041504              else if (City_CurrentImprovementProject(cix) >= 0) and
    1505                 (City_CurrentImprovementProject(cix) < 28) then
     1505                (City_CurrentImprovementProject(cix) < nWonder) then
    15061506              begin// wonder already built, try to switch to different one
    15071507                if (WonderAvailable and not WonderInWork > 0) and
     
    15531553              begin // low prio projects
    15541554                ImportantCity := WillProduceColonyShip or (Built[imPalace] > 0);
    1555                 for iix := 0 to 27 do
     1555                for iix := 0 to nWonder - 1 do
    15561556                  if Built[iix] > 0 then
    15571557                    ImportantCity := True;
     
    16051605            City_RebuildImprovement(cix, imTownHall)
    16061606          else if (RO.Government = gFundamentalism) and not WillProduceColonyShip then
    1607             for iix := 28 to nImp - 1 do
     1607            for iix := nWonder to nImp - 1 do
    16081608              if (Built[iix] > 0) and
    16091609                ((iix in [imTemple, imTheater, imCathedral, imColosseum,
  • branches/highdpi/AI/StdAI/Protocol.pas

    r303 r349  
    1111  nImp = 70; { number of improvements }
    1212  nPl = 15; { max number of players, don't change! }
     13  nWonder = 28; { max number of wonders }
    1314  nUmax = 4096; { max units/player, don't set above 4096 }
    1415  nCmax = 1024; { max cities/player, don't set above 4096 }
     
    12651266mcHospital = mcSupplyShip;
    12661267
     1268// Wonders CityID constants
     1269WonderNotBuiltYet = -1;
     1270WonderDestroyed = -2;
     1271
    12671272type
    12681273  TServerCall = function (Command, Player, Subject: Integer; var Data)
     
    12871292    Flags: Cardinal;
    12881293  end;
     1294  PUn = ^TUn;
    12891295
    12901296  { TCity }
     
    13101316    // array value =1 indicates built improvement
    13111317  end;
     1318  PCity = ^TCity;
    13121319
    13131320  TModel = packed record
     
    13481355    Flags: Word;
    13491356  end;
     1357  PUnitInfo = ^TUnitInfo;
    13501358
    13511359  TCityInfo = packed record
     
    13581366    Flags: Word;
    13591367  end;
     1368  PCityInfo = ^TCityInfo;
    13601369
    13611370  TModelInfo = packed record
     
    15871596
    15881597  TTileList = array [0 .. INFIN] of Cardinal;
     1598  PTileList = ^TTileList;
    15891599  TTileObservedLastList = array [0 .. INFIN] of SmallInt;
    15901600  TOwnerList = array [0 .. INFIN] of ShortInt;
     
    16411651    Tribute: array [0 .. nPl - 1] of Integer; // no longer in use
    16421652    TributePaid: array [0 .. nPl - 1] of Integer; // no longer in use
    1643     Wonder: array [0 .. 27] of TWonderInfo;
     1653    Wonder: array [0 .. nWonder - 1] of TWonderInfo;
    16441654    Ship: array [0 .. nPl - 1] of TShipInfo;
    1645     NatBuilt: array [28 .. (nImp + 3) div 4 * 4 - 1] of ShortInt;
     1655    NatBuilt: array [nWonder .. (nImp + 3) div 4 * 4 - 1] of ShortInt;
    16461656    nBattleHistory: Integer;
    16471657    BattleHistory: ^TBattleList; // complete list of all my battles in the whole game
     
    17681778procedure DelphiRandomize;
    17691779
     1780
    17701781implementation
    17711782
  • branches/highdpi/AI/StdAI/ToolAI.pas

    r303 r349  
    234234      Inc(Result, CityReport.FoodRep - CityReport.Eaten);
    235235  end;
    236   for i := 28 to nImp - 1 do
     236  for i := nWonder to nImp - 1 do
    237237    if MyCity[cix].Built[i] > 0 then
    238238      Dec(Result, Imp[i].Maint);
  • branches/highdpi/Back.pas

    r246 r349  
    7474    end;
    7575  end else begin
     76    if WindowState <> wsMaximized then begin
     77      WindowState := wsNormal;
     78      WindowState := wsFullScreen;
     79    end;
    7680    WindowState := wsNormal;
    7781    BoundsRect := Bounds(StartDlg.Left - 8, StartDlg.Top - 8,
  • branches/highdpi/CityProcessing.pas

    r210 r349  
    292292    begin { improvement project }
    293293      result := Imp[Project and cpIndex].Cost;
    294       if (Project and cpIndex < 28) and (GWonder[woColossus].EffectiveOwner = p)
     294      if (Project and cpIndex < nWonder) and (GWonder[woColossus].EffectiveOwner = p)
    295295      then
    296296        result := result * ColossusEffect div 100;
     
    370370          BaseHappiness := Size;
    371371      end;
    372       for i := 0 to 27 do
     372      for i := 0 to nWonder - 1 do
    373373        if Built[i] = 1 then
    374374        begin
     
    773773begin
    774774  with RW[p], City[cix] do
    775     for i := 28 to nImp - 1 do
     775    for i := nWonder to nImp - 1 do
    776776      if (Built[i] > 0) and (Project0 and (cpImp or cpIndex) <> (cpImp or i))
    777777      then // don't pay maintenance when just completed
     
    971971
    972972    // check if wonder already built
    973     if (Project and cpImp <> 0) and (Project and cpIndex < 28) and
    974       (GWonder[Project and cpIndex].CityID <> -1) then
     973    if (Project and cpImp <> 0) and (Project and cpIndex < nWonder) and
     974      (GWonder[Project and cpIndex].CityID <> WonderNotBuiltYet) then
    975975    begin
    976976      inc(Flags, chOldWonder);
     
    10501050        end;
    10511051
    1052         if NewImp < 28 then
     1052        if NewImp < nWonder then
    10531053        begin // wonder
    10541054          GWonder[NewImp].CityID := ID;
     
    10601060            woEiffel:
    10611061              begin // reactivate wonders
    1062                 for i := 0 to 27 do
     1062                for i := 0 to nWonder - 1 do
    10631063                  if Imp[i].Expiration >= 0 then
    10641064                    for cix2 := 0 to nCity - 1 do
     
    13031303                dxdy(Loc, Loc1, dx, dy);
    13041304                dec(SubCriterion[(dy + 3) shl 2 + (dx + 3) shr 1], 160);
    1305               end
    1306             end
    1307           end
    1308         end
     1305              end;
     1306            end;
     1307          end;
     1308        end;
    13091309      end;
    13101310
     
    14141414          Hierarchy[iH, iT].Trade := TileInfo.Trade;
    14151415          Hierarchy[iH, iT].SubValue := SubCriterion[V21];
    1416         end
     1416        end;
    14171417      end;
    14181418    if NeedRare <> 0 then
  • branches/highdpi/Database.pas

    r303 r349  
    4949  GTestFlags: Integer;
    5050  Mode: TGameMode;
    51   GWonder: array [0 .. 27] of TWonderInfo;
     51  GWonder: array [0 .. nWonder - 1] of TWonderInfo;
    5252  ServerVersion: array [0 .. nPl - 1] of integer;
    5353  ProcessClientData: array [0 .. nPl - 1] of boolean;
     
    452452    ResourceMask[p] := ResourceMask[p] or fModern;
    453453
    454   for i := 0 to 27 do { check whether wonders expired }
     454  for i := 0 to nWonder - 1 do { check whether wonders expired }
    455455    if (GWonder[i].EffectiveOwner <> GWonder[woEiffel].EffectiveOwner) and
    456456      (Imp[i].Expiration = ad) then
     
    31493149  i, j, uix1, cix1, nearest: integer;
    31503150begin
    3151   for i := 0 to 27 do
     3151  for i := 0 to nWonder - 1 do
    31523152    if RW[p].City[cix].Built[i] = 1 then
    31533153    begin
     
    31563156        FreeSlaves;
    31573157      if i = woEiffel then // deactivate expired wonders
    3158         for j := 0 to 27 do
     3158        for j := 0 to nWonder - 1 do
    31593159          if GWonder[j].EffectiveOwner = p then
    31603160            CheckExpiration(j);
    31613161    end;
    3162   for i := 28 to nImp - 1 do
     3162  for i := nWonder to nImp - 1 do
    31633163    if (Imp[i].Kind <> ikCommon) and (RW[p].City[cix].Built[i] > 0) then
    31643164    begin { destroy national projects }
     
    31913191begin
    31923192  StealCity(p, cix, SaveUnits);
    3193   with RW[p].City[cix] do
    3194   begin
    3195     for i := 0 to 27 do
     3193  with RW[p].City[cix] do begin
     3194    for i := 0 to nWonder - 1 do
    31963195      if Built[i] > 0 then
    3197         GWonder[i].CityID := -2; // wonder destroyed
     3196        GWonder[i].CityID := WonderDestroyed;
    31983197    V21_to_Loc(Loc, Radius);
    31993198    for V21 := 1 to 26 do
     
    32433242    Built[imTownHall] := 0;
    32443243    Built[imCourt] := 0;
    3245     for i := 28 to nImp - 1 do
     3244    for i := nWonder to nImp - 1 do
    32463245      if Imp[i].Kind <> ikCommon then
    32473246        Built[i] := 0; { destroy national projects }
    3248     for i := 0 to 27 do
     3247    for i := 0 to nWonder - 1 do
    32493248      if Built[i] = 1 then
    32503249      begin // new wonder owner!
     
    32523251        if i = woEiffel then // reactivate expired wonders
    32533252        begin
    3254           for j := 0 to 27 do
     3253          for j := 0 to nWonder - 1 do
    32553254            if Imp[j].Expiration >= 0 then
    32563255              for cix1 := 0 to (RW[pNew].nCity - 1) do
    32573256                if RW[pNew].City[cix1].Built[j] = 1 then
    3258                   GWonder[j].EffectiveOwner := pNew
     3257                  GWonder[j].EffectiveOwner := pNew;
    32593258        end
    32603259        else
  • branches/highdpi/Direct.pas

    r303 r349  
    88
    99  LCLIntf, LCLType, {$IFDEF Linux}LMessages, {$ENDIF}Messages, SysUtils, Classes,
    10   Graphics, Controls, Forms, DrawDlg;
     10  Graphics, Controls, Forms, DrawDlg, GameServer;
    1111
    1212const
     
    2323    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    2424  public
    25     procedure DlgNotify(ID: integer);
     25    procedure DlgNotify(ID: TNotify; Index: Integer = 0);
    2626  private
    2727    Info: string;
    28     State: integer;
    29     Gone, Quick: boolean;
     28    State: Integer;
     29    Gone: Boolean;
     30    Quick: Boolean;
    3031    procedure SetInfo(x: string);
    3132    procedure SetState(x: integer);
    32     procedure OnGo(var m: TMessage); message WM_GO;
    33     procedure OnChangeClient(var m: TMessage); message WM_CHANGECLIENT;
    34     procedure OnNextPlayer(var m: TMessage); message WM_NEXTPLAYER;
     33    procedure OnGo(var Msg: TMessage); message WM_GO;
     34    procedure OnChangeClient(var Msg: TMessage); message WM_CHANGECLIENT;
     35    procedure OnNextPlayer(var Msg: TMessage); message WM_NEXTPLAYER;
    3536    procedure OnAIException(var Msg: TMessage); message WM_AIEXCEPTION;
    3637  end;
     
    4243
    4344uses
    44   ScreenTools, Protocol, GameServer, Start, LocalPlayer, NoTerm, Back;
     45  ScreenTools, Protocol, Start, LocalPlayer, NoTerm, Back, Global;
    4546
    4647{$R *.lfm}
    4748
    48 procedure Notify(ID: integer);
    49 begin
    50   DirectDlg.DlgNotify(ID);
    51 end;
    52 
    53 procedure TDirectDlg.DlgNotify(ID: integer);
     49procedure Notify(ID: TNotify; Index: Integer = 0);
     50begin
     51  DirectDlg.DlgNotify(ID, Index);
     52end;
     53
     54procedure TDirectDlg.DlgNotify(ID: TNotify; Index: Integer = 0);
    5455var
    5556//  hMem: Cardinal;
     
    5859begin
    5960  case ID of
    60     ntInitLocalHuman:
    61       begin
    62         SetMainTextureByAge(-1);
    63         State := -1;
    64         Info := Phrases.Lookup('BUSY_MODLH');
    65         Show;
    66         Invalidate;
    67         Update;
    68       end;
    69     ntInitModule .. ntInitModule + maxBrain - 1:
     61    ntInitLocalHuman: begin
     62      SetMainTextureByAge(-1);
     63      State := -1;
     64      Info := Phrases.Lookup('BUSY_MODLH');
     65      Show;
     66      {$IFDEF LINUX}
     67      DpiApplication.ProcessMessages;
     68      {$ENDIF}
     69      Invalidate;
     70      Update;
     71    end;
     72    ntInitModule:
    7073      if visible then
    7174      begin
    72         s := Format(Phrases.Lookup('BUSY_MOD'),
    73           [Brains[ID - ntInitModule].Name]);
     75        s := Format(Phrases.Lookup('BUSY_MOD'), [Brains[Index].Name]);
    7476        while BiColorTextWidth(Canvas, s) + 64 > ClientWidth do
    7577          Delete(s, Length(s), 1);
     
    8284      if visible then
    8385        SetInfo(Phrases.Lookup('BUSY_INIT'));
    84     ntDeactivationMissing .. ntDeactivationMissing + nPl - 1:
    85       SimpleMessage(Format(Phrases.Lookup('MISSDEACT'),
    86         [ID - ntDeactivationMissing]));
    87     ntSetAIName .. ntSetAIName + nPl - 1:
    88       LocalPlayer.SetAIName(ID - ntSetAIName, NotifyMessage);
    89     ntException .. ntException + maxBrain - 1:
    90       PostMessage(Handle, WM_AIEXCEPTION, ID - ntException, 0);
    91     ntLoadBegin:
    92       begin
    93         Info := Phrases.Lookup('BUSY_LOAD');
    94         SetState(0);
    95       end;
    96     ntLoadState .. ntLoadState + 128:
    97       SetState(ID - ntLoadState);
    98     ntDLLError .. ntDLLError + 128:
    99       SimpleMessage(Format(Phrases.Lookup('DLLERROR'),
    100         [Brains[ID - ntDLLError].FileName]));
     86    ntDeactivationMissing:
     87      SimpleMessage(Format(Phrases.Lookup('MISSDEACT'), [Index]));
     88    ntSetAIName:
     89      LocalPlayer.SetAIName(Index, NotifyMessage);
     90    ntException:
     91      PostMessage(Handle, WM_AIEXCEPTION, Index, 0);
     92    ntLoadBegin: begin
     93      Info := Phrases.Lookup('BUSY_LOAD');
     94      SetState(0);
     95    end;
     96    ntLoadState: SetState(Index);
     97    ntDLLError:
     98      SimpleMessage(Format(Phrases.Lookup('DLLERROR'), [Brains[Index].FileName]));
    10199    ntAIError:
    102100      SimpleMessage(Format(Phrases.Lookup('AIERROR'), [NotifyMessage]));
    103     ntClientError .. ntClientError + 128:
     101    ntClientError:
    104102      SimpleMessage(Format(Phrases.Lookup('CLIENTERROR'),
    105         [Brains[ID - ntClientError].FileName]));
    106     ntEndInfo:
    107       begin
    108         Hide;
    109         background.Update;
    110       end;
    111     ntLoadError:
    112       begin
     103        [Brains[Index].FileName]));
     104    ntEndInfo: begin
     105      Hide;
     106      Background.Update;
     107    end;
     108    ntLoadError: begin
    113109(* TODO        if OpenClipboard(Handle) then
    114110        begin // copy file path to clipboard
     
    134130      end;
    135131    ntStartDone:
    136       if not Quick then
    137       begin
     132      if not Quick then begin
    138133        StartDlg.Hide;
    139         background.Update;
     134        Background.Update;
    140135      end;
    141136    ntStartGo, ntStartGoRefresh, ntStartGoRefreshMaps:
    142       if Quick then
    143         Close
    144       else
    145       begin
     137      if Quick then Close
     138      else begin
    146139        if ID = ntStartGoRefresh then
    147140          StartDlg.UpdateFormerGames
     
    150143        StartDlg.Show;
    151144      end;
    152     ntChangeClient:
    153       PostMessage(Handle, WM_CHANGECLIENT, 0, 0);
    154     ntNextPlayer:
    155       PostMessage(Handle, WM_NEXTPLAYER, 0, 0);
    156     ntDeinitModule .. ntDeinitModule + maxBrain - 1:
     145    ntChangeClient: PostMessage(Handle, WM_CHANGECLIENT, 0, 0);
     146    ntNextPlayer: PostMessage(Handle, WM_NEXTPLAYER, 0, 0);
     147    ntDeinitModule:
    157148      begin
    158149        Info := Format(Phrases2.Lookup('BUSY_DEINIT'),
    159           [Brains[ID - ntDeinitModule].Name]);
     150          [Brains[Index].Name]);
    160151        while BiColorTextWidth(Canvas, Info) + 64 > ClientWidth do
    161152          Delete(Info, Length(Info), 1);
     
    163154        State := -1;
    164155        Show;
     156        {$IFDEF LINUX}
     157        DpiApplication.ProcessMessages;
     158        {$ENDIF}
    165159        Invalidate;
    166160        Update;
    167161      end;
    168     ntBackOn:
    169       begin
    170         background.Show;
    171         background.Update;
    172         sleep(50); // prevent flickering
    173       end;
    174     ntBackOff:
    175       background.Close;
     162    ntBackOn: begin
     163      Background.Show;
     164      Background.Update;
     165      Sleep(50); // prevent flickering
     166    end;
     167    ntBackOff: Background.Close;
    176168  end;
    177169end;
     
    179171procedure TDirectDlg.FormCreate(Sender: TObject);
    180172begin
    181   Gone := false;
     173  Gone := False;
    182174  State := -1;
    183175  Info := '';
     
    208200end;
    209201
    210 procedure TDirectDlg.OnGo(var m: TMessage);
     202procedure TDirectDlg.OnGo(var Msg: TMessage);
    211203var
    212204  i: integer;
    213205  s: string;
     206  FileName: string;
    214207begin
    215208  Hide;
     
    218211    DpiApplication.MessageBox(PChar(Phrases.Lookup('NOAI')), 'C-evo', 0);
    219212    Close;
    220     exit;
     213    Exit;
    221214  end;
    222215  Quick := false;
     
    224217  begin
    225218    s := ParamStr(1);
    226     if (s[1] = '-') or (s[1] = '/') then
     219    if (s[1] = '-') {$IFDEF WINDOWS}or (s[1] = '/'){$ENDIF} then
    227220    begin // special mode
    228221      Delete(s, 1, 1);
     
    234227        Quick := true;
    235228        DirectHelp(cHelpOnly);
    236         Close
     229        Close;
    237230      end;
    238231    end
    239     else if (FileExists(ParamStr(1))) then
    240     begin
    241       Quick := true;
    242       if not LoadGame(ExtractFilePath(ParamStr(1)), ExtractFileName(ParamStr(1)
    243         ), -1, false) then
    244       begin
     232    else if (FileExists(ParamStr(1))) then begin
     233      FileName := ParamStr(1);
     234      if ExtractFileExt(FileName) = CevoExt then begin
     235        Quick := True;
     236        if not LoadGame(ExtractFilePath(ParamStr(1)), ExtractFileName(ParamStr(1)
     237        ), -1, false) then begin
     238          SimpleMessage(Phrases.Lookup('LOADERR'));
     239          Close;
     240        end;
     241      end else
     242      if ExtractFileExt(FileName) = CevoMapExt then begin
     243        Quick := True;
     244        EditMap(FileName, lxmax, lymax, 30);
     245      end else begin
    245246        SimpleMessage(Phrases.Lookup('LOADERR'));
    246247        Close;
     
    249250  end;
    250251  if not Quick then begin
    251     background.Show;
     252    Background.Show;
    252253    StartDlg.Show;
    253254  end;
    254255end;
    255256
    256 procedure TDirectDlg.OnChangeClient(var m: TMessage);
     257procedure TDirectDlg.OnChangeClient(var Msg: TMessage);
    257258begin
    258259  ChangeClient;
    259260end;
    260261
    261 procedure TDirectDlg.OnNextPlayer(var m: TMessage);
     262procedure TDirectDlg.OnNextPlayer(var Msg: TMessage);
    262263begin
    263264  NextPlayer;
     
    294295  Invalidate;
    295296  Update;
     297  {$IFDEF LINUX}
     298  DpiApplication.ProcessMessages;
     299  {$ENDIF}
    296300end;
    297301
    298302procedure TDirectDlg.SetState(x: integer);
    299303begin
    300   if (x < 0) <> (State < 0) then
    301   begin
     304  if (x < 0) <> (State < 0) then begin
    302305    State := x;
    303306    Invalidate;
    304     Update
     307    Update;
    305308  end
    306   else if x <> State then
    307   begin
     309  else if x <> State then begin
    308310    State := x;
    309311    PaintProgressBar(Canvas, 6, ClientWidth div 2 - 64, 40, State, 128 - State,
  • branches/highdpi/GameServer.pas

    r303 r349  
    1515  FirstBookCompatibleVersion = $010103;
    1616
    17   // notifications
    18   ntCreateWorld = 0;
    19   ntInitModule = $100;
    20   ntInitLocalHuman = $1FF;
    21   ntDLLError = $200;
    22   ntAIError = $2FF;
    23   ntClientError = $300;
    24   ntInitPlayers = $400;
    25   ntDeactivationMissing = $410;
    26   ntSetAIName = $420;
    27   ntException = $500;
    28   ntLoadBegin = $600;
    29   ntLoadState = $601;
    30   ntEndInfo = $6FC;
    31   ntBackOn = $6FD;
    32   ntBackOff = $6FE;
    33   ntLoadError = $6FF;
    34   ntStartDone = $700;
    35   ntStartGo = $701;
    36   ntStartGoRefresh = $702;
    37   ntStartGoRefreshMaps = $703;
    38   ntChangeClient = $800;
    39   ntNextPlayer = $810;
    40   ntDeinitModule = $900;
    41 
    4217  // module flags
    4318  fMultiple = $10000000;
     
    4520  fUsed = $40000000;
    4621
    47   // save map tile flags
    48   smOwned = $20;
    49   smUnit = $40;
    50   smCity = $80;
    51 
    5222  maxBrain = 255;
    5323
    5424type
    55   TNotifyFunction = procedure(ID: integer);
     25  // notifications
     26  TNotify = (
     27    ntCreateWorld,
     28    ntInitModule,
     29    ntInitLocalHuman,
     30    ntDLLError,
     31    ntAIError,
     32    ntClientError,
     33    ntInitPlayers,
     34    ntDeactivationMissing,
     35    ntSetAIName,
     36    ntException,
     37    ntLoadBegin,
     38    ntLoadState,
     39    ntEndInfo,
     40    ntBackOn,
     41    ntBackOff,
     42    ntLoadError,
     43    ntStartDone,
     44    ntStartGo,
     45    ntStartGoRefresh,
     46    ntStartGoRefreshMaps,
     47    ntChangeClient,
     48    ntNextPlayer,
     49    ntDeinitModule
     50  );
     51
     52  TNotifyFunction = procedure(ID: TNotify; Index: Integer = 0);
    5653
    5754  TBrainType = (btNoTerm, btSuperVirtual, btTerm, btRandom, btAI);
     
    370367    (CCPlayer < 0) then
    371368  begin
    372     Notify(ntDeactivationMissing + p);
     369    Notify(ntDeactivationMissing, p);
    373370    ForceClientDeactivation;
    374371  end
     
    518515    if Kind = btAI then
    519516    begin { get client function }
    520       Notify(ntInitModule + Brains.IndexOf(bix));
     517      Notify(ntInitModule, Brains.IndexOf(bix));
    521518      if Flags and fDotNet > 0 then
    522519        Client := DotNetClient
     
    527524        begin
    528525          Client := nil;
    529           Notify(ntDLLError + Brains.IndexOf(bix));
     526          Notify(ntDLLError, Brains.IndexOf(bix));
    530527        end
    531528        else
     
    533530          Client := GetProcAddress(hm, 'client');
    534531          if @Client = nil then
    535             Notify(ntClientError + Brains.IndexOf(bix));
    536         end
    537       end
     532            Notify(ntClientError, Brains.IndexOf(bix));
     533        end;
     534      end;
    538535    end;
    539536    if @Client <> nil then
     
    550547        DataSize := 0;
    551548      Flags := Flags or InitModuleData.Flags;
    552     end
    553   end
     549    end;
     550  end;
    554551end;
    555552
     
    586583  MapFile := nil;
    587584  try
    588     MapFile := TFileStream.Create(GetMapsDir + DirectorySeparator + FileName,
    589       fmOpenRead or fmShareExclusive);
     585    MapFile := TFileStream.Create(FileName, fmOpenRead or fmShareExclusive);
    590586    MapFile.Position := 0;
    591587    MapFile.read(s[1], 8); { file id }
     
    735731  if bix[0].Kind <> btNoTerm then
    736732    Notify(ntInitLocalHuman);
     733
    737734  BrainUsed := [];
    738735  for p := 0 to nPl - 1 do
     
    793790
    794791  GTurn := 0;
    795   for i := 0 to 27 do
     792  for i := 0 to nWonder - 1 do
    796793    with GWonder[i] do
    797794    begin
     
    960957        else
    961958          NotifyMessage := '';
    962         Notify(ntSetAIName + p1);
    963       end
     959        Notify(ntSetAIName, p1);
     960      end;
    964961  end;
    965962
     
    12831280    end;
    12841281    if not MovieMode then
    1285       Notify(ntLoadState + CL.Progress * 128 div 1000);
     1282      Notify(ntLoadState, CL.Progress * 128 div 1000);
    12861283  end;
    12871284
     
    32553252            begin
    32563253              if Brains[i].Kind = btAI then
    3257                 Notify(ntDeinitModule + i);
     3254                Notify(ntDeinitModule, i);
    32583255              CallClient(i, cBreakGame, nil^);
    32593256            end;
     
    42174214                else if built[NewProject and cpIndex] > 0 then
    42184215                  result := eInvalid
    4219                 else if (NewProject and cpIndex < 28) and
    4220                   (GWonder[NewProject and cpIndex].CityID <> -1) then
     4216                else if (NewProject and cpIndex < nWonder) and
     4217                  (GWonder[NewProject and cpIndex].CityID <> WonderNotBuiltYet) then
    42214218                  result := eViolation // wonder already exists
    42224219                else if (NewProject and cpIndex = imSpacePort) and
  • branches/highdpi/Global.pas

    r303 r349  
    55const
    66  CevoExt = '.cevo';
    7   CevoMapExt = '.cevo map';
     7  CevoMapExt = '.cevomap';
    88  CevoTribeExt = '.tribe.txt';
    9   CevoHomepage = 'https://app.zdechov.net/c-evo';
    10   CevoContact = 'https://app.zdechov.net/c-evo#Contact';
     9  CevoHomepageShort = 'app.zdechov.net/c-evo';
     10  CevoHomepage = 'https://' + CevoHomepageShort;
     11  CevoContactShort = 'app.zdechov.net/c-evo#Contact';
     12  CevoContact = 'https://' + CevoContactShort;
    1113  CevoContactBug = 'https://app.zdechov.net/c-evo/report/1';
    1214  AppRegistryKey = '\SOFTWARE\C-evo';
    13   AITemplateFileName = 'AI Template' + DirectorySeparator + 'AI development manual.html';
     15  AITemplateManual = 'AI development manual';
     16  AITemplateFileName = 'AI Template' + DirectorySeparator + AITemplateManual + '.html';
    1417
    1518
  • branches/highdpi/Install/deb/c-evo.desktop

    r55 r349  
    99Categories=GNOME;Application;Game;
    1010StartupNotify=true
     11MimeType=application/cevo;application/cevomap
  • branches/highdpi/Install/deb/debian/changelog

    r55 r349  
    1 c-evo (1.2.0-0) precise; urgency=low
     1c-evo (1.3.0-0) precise; urgency=low
    22
    3   * Original version 1.0.0 packaged with lazdebian
     3  * Original version 1.3.0 packaged with lazdebian
    44
    55 -- Chronos <robie@centrum.cz>  Sun, 17 Dec 2016 00:51:08 +0100
  • branches/highdpi/Install/deb/debian/control

    r210 r349  
    11Source: c-evo
    22Maintainer: Chronos <robie@centrum.cz>
    3 Section: devel
     3Section: games
    44Priority: optional
    5 Standards-Version: 1.0.0
     5Standards-Version: 1.3.0
    66Build-Depends: fpc, lazarus, lcl, lcl-utils, debhelper (>= 8)
    77
  • branches/highdpi/Install/deb/debian/rules

    r160 r349  
    2222        install -d -m 755 $(ROOT)/usr/share/applications
    2323        install -m 755 Install/deb/c-evo.desktop $(ROOT)/usr/share/applications
     24        install -d -m 755 $(ROOT)/usr/share/mime/packages
     25        install -m 755 Install/deb/c-evo.xml $(ROOT)/usr/share/mime/packages
    2426        install -d -m 755 $(ROOT)/usr/share/pixmaps
    2527        install -m 644 Graphics/c-evo_64x64.png $(ROOT)/usr/share/pixmaps/c-evo.png
     28        install -m 644 Graphics/c-evo_64x64.png $(ROOT)/usr/share/pixmaps/application-cevo.png
     29        install -m 644 Graphics/c-evo_64x64.png $(ROOT)/usr/share/pixmaps/application-cevomap.png
    2630        install -d -m 755 $(ROOT)/usr/share/c-evo/AI/StdAI
    2731        install -m 644 AI/StdAI/libstdai-$(DEB_HOST_ARCH).so $(ROOT)/usr/share/c-evo/AI/StdAI
  • branches/highdpi/Install/rpm/c-evo.spec

    r176 r349  
    11Name:           c-evo
    2 Version:        1.2.0
     2Version:        1.3.0
    33Release:        1%{?dist}
    44Summary:        Empire building game
     
    5151install -d -m 755 $RPM_BUILD_ROOT/usr/share/c-evo/Tribes
    5252install -D -m 644 Tribes/* $RPM_BUILD_ROOT/usr/share/c-evo/Tribes
     53install -d -m 755 $RPM_BUILD_ROOT/usr/share/c-evo/Maps
     54install -D -m 644 Maps/* $RPM_BUILD_ROOT/usr/share/c-evo/Maps
     55install -d -m 755 $RPM_BUILD_ROOT/usr/share/c-evo/Saved
     56install -D -m 644 Saved/* $RPM_BUILD_ROOT/usr/share/c-evo/Saved
     57#install -d -m 755 $RPM_BUILD_ROOT/usr/share/c-evo/AI\ Template
     58#install -D -m 644 AI\ Template/* $RPM_BUILD_ROOT/usr/share/c-evo/AI\ Template
    5359install -d -m 755 $RPM_BUILD_ROOT/usr/share/c-evo/Localization
    5460cp -R Localization $RPM_BUILD_ROOT/usr/share/c-evo
  • branches/highdpi/Install/win/Common.iss

    r246 r349  
    33
    44#define MyAppName "C-evo"
    5 #define MyAppVersion "1.2.0"
     5#define MyAppVersion "1.3.0"
    66#define MyAppPublisher "Chronosoft"
    77#define MyAppPublisherShort "Chronosoft"
     
    5555Root: HKCR; Subkey: "{#FileTypeName}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""
    5656
     57#define FileTypeName "C-evo map"
     58Root: HKCR; Subkey: ".cevomap"; ValueType: string; ValueName: ""; ValueData: "{#FileTypeName}"; Flags: uninsdeletevalue
     59Root: HKCR; Subkey: "{#FileTypeName}"; ValueType: string; ValueName: ""; ValueData: "{#FileTypeName}"; Flags: uninsdeletekey
     60Root: HKCR; Subkey: "{#FileTypeName}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
     61Root: HKCR; Subkey: "{#FileTypeName}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""
     62
    5763[Components]
    5864Name: "main"; Description: "Main Files"; Types: full compact custom; Flags: fixed
  • branches/highdpi/Integrated.lpi

    r303 r349  
    102102      </Item3>
    103103    </RequiredPackages>
    104     <Units Count="42">
     104    <Units Count="43">
    105105      <Unit0>
    106106        <Filename Value="Integrated.lpr"/>
     
    343343        <IsPartOfProject Value="True"/>
    344344      </Unit41>
     345      <Unit42>
     346        <Filename Value="UMiniMap.pas"/>
     347        <IsPartOfProject Value="True"/>
     348      </Unit42>
    345349    </Units>
    346350  </ProjectOptions>
  • branches/highdpi/Language.txt

    r210 r349  
    542542Patrols, Attacks and Captures Only
    543543Tile Size
     544Small
     545Medium
     546Big
    544547
    545548#ADVANCES
     
    945948#SETTINGS
    946949Full screen
     950Gamma
     951Restart is needed to apply changes
  • branches/highdpi/Language2.txt

    r20 r349  
    3535#ACTIONHEADER_AIDEV AI Development
    3636#ACTION_AIDEV Learn how to code your own AI for this game
    37 #ACTIONHEADER_WEB On the web: c-evo.org
     37#ACTIONHEADER_WEB On the web: %s
    3838
    3939'Message Text
  • branches/highdpi/LocalPlayer/Battle.pas

    r210 r349  
    66uses
    77  UDpiControls, ScreenTools, Protocol, ButtonBase, ButtonA, Types, LCLIntf, LCLType,
    8   SysUtils, Classes, Graphics, Controls, Forms, DrawDlg;
     8  SysUtils, Classes, Graphics, Controls, Forms, DrawDlg, IsoEngine;
    99
    1010type
     11
     12  { TBattleDlg }
     13
    1114  TBattleDlg = class(TDrawDlg)
    1215    OKBtn: TButtonA;
    1316    CancelBtn: TButtonA;
     17    procedure FormDestroy(Sender: TObject);
    1418    procedure FormPaint(Sender: TObject);
    1519    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
     
    2125    procedure OKBtnClick(Sender: TObject);
    2226    procedure CancelBtnClick(Sender: TObject);
     27    procedure PaintBattleOutcome(ca: TDpiCanvas; xm, ym, uix, ToLoc: Integer;
     28      Forecast: TBattleForecastEx);
     29  private
     30    IsoMap: TIsoMap;
    2331  public
    2432    uix, ToLoc: Integer;
     
    3038  BattleDlg: TBattleDlg;
    3139
    32 procedure PaintBattleOutcome(ca: TDpiCanvas; xm, ym, uix, ToLoc: Integer;
    33   Forecast: TBattleForecastEx);
    34 
    3540implementation
    3641
    3742uses
    38   Term, ClientTools, IsoEngine;
     43  Term, ClientTools;
    3944
    4045{$R *.lfm}
     
    4853  FirstStrikeColor = $A0A0A0;
    4954
    50 procedure PaintBattleOutcome(ca: TDpiCanvas; xm, ym, uix, ToLoc: Integer;
     55procedure TBattleDlg.PaintBattleOutcome(ca: TDpiCanvas; xm, ym, uix, ToLoc: Integer;
    5156  Forecast: TBattleForecastEx);
    5257var
     
    108113      FanaticColor);
    109114  DpiBitCanvas(ca, xm - 12, ym - 12, 24, 24,
    110     GrExt[HGrSystem].Mask.Canvas, 26, 146, SRCAND);
     115    HGrSystem.Mask.Canvas, 26, 146, SRCAND);
    111116  DpiBitCanvas(ca, xm - 12, ym - 12, 24, 24,
    112     GrExt[HGrSystem].Data.Canvas, 26, 146, SRCPAINT);
     117    HGrSystem.Data.Canvas, 26, 146, SRCPAINT);
    113118
    114119  LabelText := Format('%d', [Forecast.AStr]);
     
    133138  begin
    134139    DpiBitCanvas(ca, xm + 9 + LDDamage - 7, ym - 6, 14, 17,
    135       GrExt[HGrSystem].Mask.Canvas, 51, 153, SRCAND);
     140      HGrSystem.Mask.Canvas, 51, 153, SRCAND);
    136141    DpiBitCanvas(ca, xm + 8 + LDDamage - 7, ym - 7, 14, 17,
    137       GrExt[HGrSystem].Mask.Canvas, 51, 153, SRCAND);
     142      HGrSystem.Mask.Canvas, 51, 153, SRCAND);
    138143    DpiBitCanvas(ca, xm + 8 + LDDamage - 7, ym - 7, 14, 17,
    139       GrExt[HGrSystem].Data.Canvas, 51, 153, SRCPAINT);
     144      HGrSystem.Data.Canvas, 51, 153, SRCPAINT);
    140145  end;
    141146  LabelText := Format('%d', [DDamage]);
     
    153158  begin
    154159    DpiBitCanvas(ca, xm - 6, ym + 9 + LADamage - 7, 14, 17,
    155       GrExt[HGrSystem].Mask.Canvas, 51, 153, SRCAND);
     160      HGrSystem.Mask.Canvas, 51, 153, SRCAND);
    156161    DpiBitCanvas(ca, xm - 7, ym + 8 + LADamage - 7, 14, 17,
    157       GrExt[HGrSystem].Mask.Canvas, 51, 153, SRCAND);
     162      HGrSystem.Mask.Canvas, 51, 153, SRCAND);
    158163    DpiBitCanvas(ca, xm - 7, ym + 8 + LADamage - 7, 14, 17,
    159       GrExt[HGrSystem].Data.Canvas, 51, 153, SRCPAINT);
     164      HGrSystem.Data.Canvas, 51, 153, SRCPAINT);
    160165  end;
    161166  LabelText := Format('%d', [MyUn[uix].Health - Forecast.EndHealthAtt]);
     
    172177      (LADamage - LAAvoidedDamage - TextSize.cy) div 2, LabelText);
    173178
    174   NoMap.SetOutput(Buffer);
     179  IsoMap.SetOutput(Buffer);
    175180  DpiBitCanvas(Buffer.Canvas, 0, 0, 66, 48, ca, xm + 8 + 4,
    176181    ym - 8 - 12 - 48);
     
    184189    else Sprite(Buffer,HGrTerrain,0,16,66,32,1+7*(xxt*2+1),1+yyt+2*(2+TerrType-fForest)*(yyt*3+1));
    185190    end; }
    186   NoMap.PaintUnit(1, 0, UnitInfo, 0);
     191  IsoMap.PaintUnit(1, 0, UnitInfo, 0);
    187192  DpiBitCanvas(ca, xm + 8 + 4, ym - 8 - 12 - 48, 66, 48, Buffer.Canvas,
    188193    0, 0);
     
    192197  MakeUnitInfo(me, MyUn[uix], UnitInfo);
    193198  UnitInfo.Flags := UnitInfo.Flags and not unFortified;
    194   NoMap.PaintUnit(1, 0, UnitInfo, 0);
     199  IsoMap.PaintUnit(1, 0, UnitInfo, 0);
    195200  DpiBitCanvas(ca, xm - 8 - 4 - 66, ym + 8 + 12, 66, 48, Buffer.Canvas, 0, 0);
    196201end; { PaintBattleOutcome }
     
    198203procedure TBattleDlg.FormCreate(Sender: TObject);
    199204begin
     205  IsoMap := TIsoMap.Create;
    200206  OKBtn.Caption := Phrases.Lookup('BTN_YES');
    201207  CancelBtn.Caption := Phrases.Lookup('BTN_NO');
     
    276282end;
    277283
     284procedure TBattleDlg.FormDestroy(Sender: TObject);
     285begin
     286  FreeAndNil(IsoMap);
     287end;
     288
    278289procedure TBattleDlg.FormMouseDown(Sender: TObject; Button: TMouseButton;
    279290  Shift: TShiftState; X, Y: Integer);
  • branches/highdpi/LocalPlayer/CityScreen.pas

    r303 r349  
    55
    66uses
    7   UDpiControls, {$IFDEF LINUX}
    8   LMessages,
    9   {$ENDIF}
     7  UDpiControls, {$IFDEF LINUX}LMessages,{$ENDIF}
    108  Protocol, ClientTools, Term, ScreenTools, IsoEngine, BaseWin,
    119  LCLIntf, LCLType, Messages, SysUtils, Classes, Graphics, Controls, Forms, ExtCtrls,
     
    5351    procedure PageUpBtnClick(Sender: TObject);
    5452    procedure PageDownBtnClick(Sender: TObject);
    55 
     53  private
     54    c: TCity;
     55    Report: TCityReportNew;
     56    cOwner: Integer;
     57    cGov: Integer;
     58    emix: Integer; { enemy model index of produced unit }
     59    cix: Integer;
     60    cLoc: Integer;
     61    Mode: Integer;
     62    ZoomArea: Integer;
     63    Page: Integer;
     64    PageCount: Integer;
     65    BlinkTime: Integer;
     66    OpenSoundEvent: Integer;
     67    SizeClass: Integer;
     68    AgePrepared: Integer;
     69    Optimize_cixTileChange: Integer;
     70    Optimize_TilesBeforeChange: Integer;
     71    Happened: cardinal;
     72    imix: array [0 .. 15] of integer;
     73    CityAreaInfo: TCityAreaInfo;
     74    AreaMap: TIsoMap;
     75    CityMapTemplate: TDpiBitmap;
     76    SmallCityMapTemplate: TDpiBitmap;
     77    Back: TDpiBitmap;
     78    SmallCityMap: TDpiBitmap;
     79    ZoomCityMap: TDpiBitmap;
     80    Template: TDpiBitmap;
     81    IsPort: Boolean;
     82    ProdHint: Boolean;
     83    AllowChange: Boolean;
     84    procedure InitSmallCityMap;
     85    procedure InitZoomCityMap;
     86    procedure ChooseProject;
     87    procedure ChangeCity(d: integer);
     88    procedure ChangeResourceWeights(iResourceWeights: integer);
     89    procedure OnPlaySound(var Msg: TMessage); message WM_PLAYSOUND;
    5690  public
    5791    RestoreUnFocus: integer;
     
    6195    procedure Reset;
    6296    procedure CheckAge;
    63 
    64   private
    65     c: TCity;
    66     Report: TCityReportNew;
    67     cOwner, cGov, emix { enemy model index of produced unit } , cix, cLoc, Mode,
    68       ZoomArea, Page, PageCount, BlinkTime, OpenSoundEvent, SizeClass,
    69       AgePrepared: integer;
    70     Optimize_cixTileChange, Optimize_TilesBeforeChange: integer;
    71     Happened: cardinal;
    72     imix: array [0 .. 15] of integer;
    73     CityAreaInfo: TCityAreaInfo;
    74     AreaMap: TIsoMap;
    75     CityMapTemplate, SmallCityMapTemplate, Back, SmallCityMap, ZoomCityMap,
    76       Template: TDpiBitmap;
    77     IsPort, ProdHint, AllowChange: boolean;
    78     procedure InitSmallCityMap;
    79     procedure InitZoomCityMap;
    80     procedure ChooseProject;
    81     procedure ChangeCity(d: integer);
    82     procedure ChangeResourceWeights(iResourceWeights: integer);
    83     procedure OnPlaySound(var Msg: TMessage); message WM_PLAYSOUND;
    8497  end;
    8598
     
    87100  CityDlg: TCityDlg;
    88101
     102
    89103implementation
    90104
    91105uses
    92   Select, Messg, MessgEx, Help, Tribes, Directories, Math, UPixelPointer, Sound;
     106  Select, Messg, MessgEx, Help, Tribes, Directories, Math, Sound;
    93107
    94108{$R *.lfm}
     
    259273    AgePrepared := MainTextureAge;
    260274
    261     // TODO: FillRect should not be needed as BitBlt is with SRCCOPY
    262     Back.Canvas.FillRect(0, 0, ClientWidth, ClientHeight);
    263 
     275    UnshareBitmap(Back);
    264276    DpiBitCanvas(Back.Canvas, 0, 0, ClientWidth, ClientHeight,
    265277      MainTexture.Image.Canvas, 0, 0);
     
    280292    c := MyCity[cix];
    281293  case MyMap[cLoc] and fTerrain of
    282     fPrairie:
    283       cli1 := cliPrairie;
    284     fHills:
    285       cli1 := cliHills;
    286     fTundra:
    287       cli1 := cliTundra;
     294    fPrairie: cli1 := cliPrairie;
     295    fHills: cli1 := cliHills;
     296    fTundra: cli1 := cliTundra;
    288297  else
    289298    cli1 := cliPlains;
     
    316325    for i := 0 to 29 do
    317326    begin
    318       for iix := 28 to nImp - 1 do
     327      for iix := nWonder to nImp - 1 do
    319328        if (ImpPosition[iix] = i) and (c.Built[iix] > 0) then
    320329        begin
     
    327336    i := 30;
    328337    for iix := 0 to nImp do
    329       if (c.Built[iix] > 0) and ((iix < 28) or (ImpPosition[iix] < 0)) then
     338      if (c.Built[iix] > 0) and ((iix < nWonder) or (ImpPosition[iix] < 0)) then
    330339      begin
    331340        FillRect(Rect(5 + 16 * (i mod 3) + 48 * (i div 18),
     
    341350      if iix <> imTrGoods then
    342351      begin
    343         if (iix >= 28) and (ImpPosition[iix] >= 0) then
     352        if (iix >= nWonder) and (ImpPosition[iix] >= 0) then
    344353          i := ImpPosition[iix];
    345354        if i < 36 then
     
    358367procedure TCityDlg.InitZoomCityMap;
    359368begin
    360   // TODO: FillRect should not be needed as BitBlt is with SRCCOPY
    361   ZoomCityMap.Canvas.FillRect(0, 0, ZoomCityMap.Width, ZoomCityMap.Height);
    362 
     369  UnshareBitmap(ZoomCityMap);
    363370  DpiBitCanvas(ZoomCityMap.Canvas, 0, 0, wZoomMap, hZoomMap,
    364371    Back.Canvas, xZoomMap, yZoomMap);
     
    387394    if Kind = 3 then
    388395    begin
    389       Tex.clBevelLight := GrExt[HGrSystem].Data.Canvas.Pixels[104, 36];
     396      Tex.clBevelLight := HGrSystem.Data.Canvas.Pixels[104, 36];
    390397      Tex.clBevelShade := Tex.clBevelLight;
    391398    end;
     
    400407    rare: boolean;
    401408  begin
     409    with AreaMap do begin
    402410    if Server(sGetCityTileInfo, me, Loc, TileInfo) <> eOk then
    403411    begin
     
    435443      Sprite(offscreen, HGrSystem, x + xxt - 5 + d * (2 * i + 1 - Total),
    436444        y + yyt - 5, 10, 10, xGr, yGr);
     445    end;
    437446    end;
    438447  end;
     
    586595  end;
    587596
     597  with AreaMap do begin
    588598  rx := (192 + xxt * 2 - 1) div (xxt * 2);
    589599  ry := (96 + yyt * 2 - 1) div (yyt * 2);
     
    612622              Loc1, (dx = 0) and (dy = 0));
    613623        end;
     624  end;
    614625
    615626  if Report.Working > 1 then
     
    624635      xGr := 141;
    625636    DpiBitCanvas(offscreen.Canvas, xmArea - 192 + 5 + i * d, ymArea - 96 - 29,
    626       27, 30, GrExt[HGrSystem].Mask.Canvas, xGr, 171, SRCAND); { shadow }
     637      27, 30, HGrSystem.Mask.Canvas, xGr, 171, SRCAND); { shadow }
    627638    Sprite(offscreen, HGrSystem, xmArea - 192 + 4 + i * d, ymArea - 96 - 30, 27,
    628639      30, xGr, 171);
     
    636647    xGr := 1 + 112;
    637648    DpiBitCanvas(offscreen.Canvas, xmArea + 192 - 27 + 1 - i * d, 29 + 1, 27,
    638       30, GrExt[HGrSystem].Mask.Canvas, xGr, 171, SRCAND); { shadow }
     649      30, HGrSystem.Mask.Canvas, xGr, 171, SRCAND); { shadow }
    639650    Sprite(offscreen, HGrSystem, xmArea + 192 - 27 - i * d, 29, 27, 30,
    640651      xGr, 171);
     
    820831      Cnt := 0;
    821832      for iix := 0 to nImp - 1 do
    822         if ((iix < 28) or (ImpPosition[iix] < 0)) and (c.Built[iix] > 0) then
     833        if ((iix < nWonder) or (ImpPosition[iix] < 0)) and (c.Built[iix] > 0) then
    823834        begin
    824835          i := Cnt - Page * 6;
     
    831842    else
    832843    begin
    833       for iix := 28 to nImp - 1 do
     844      for iix := nWonder to nImp - 1 do
    834845      begin
    835846        i := ImpPosition[iix] - 6 * ZoomArea;
     
    923934            y := ((Cnt - 6 * Page) div 3) * 52 + yZoomMap + 20;
    924935            MakeUnitInfo(me, MyUn[i], UnitInfo);
    925             NoMap.SetOutput(offscreen);
    926             NoMap.PaintUnit(x, y, UnitInfo, MyUn[i].Status);
     936            AreaMap.SetOutput(offscreen);
     937            AreaMap.PaintUnit(x, y, UnitInfo, MyUn[i].Status);
    927938
    928939            for j := 0 to UnitReport.FoodSupport - 1 do
     
    10521063        (integer(MyRO.EnemyModel[emix].mix) <> c.Project and cpIndex)) do
    10531064        dec(emix);
    1054       if Tribe[cOwner].ModelPicture[c.Project and cpIndex].HGr = 0 then
     1065      if not Assigned(Tribe[cOwner].ModelPicture[c.Project and cpIndex].HGr) then
    10551066        InitEnemyModel(emix);
    10561067    end;
     
    13101321    else if (x >= xmArea - 192) and (x < xmArea + 192) and (y >= ymArea - 96)
    13111322      and (y < ymArea + 96) then
     1323    with AreaMap do
    13121324    begin
    13131325      qx := ((4000 * xxt * yyt) + (x - xmArea) * (yyt * 2) + (y - ymArea + yyt)
     
    13441356                not csResourceWeightsMask; // off
    13451357              c.Status := MyCity[cix].Status;
    1346               SmartUpdateContent
     1358              SmartUpdateContent;
    13471359            end;
    13481360            exit;
     
    17361748  end; }
    17371749
    1738 var
    1739   i, j, k: integer;
    1740 
    17411750procedure TCityDlg.PageUpBtnClick(Sender: TObject);
    17421751begin
     
    17441753  begin
    17451754    dec(Page);
    1746     SmartUpdateContent
     1755    SmartUpdateContent;
    17471756  end;
    17481757end;
     
    17531762  begin
    17541763    inc(Page);
    1755     SmartUpdateContent
     1764    SmartUpdateContent;
    17561765  end;
    17571766end;
     
    17751784end;
    17761785
     1786procedure SortImprovements;
     1787var
     1788  i, j, k: integer;
     1789begin
     1790  for i := 0 to nImp - 1 do
     1791    ImpSorted[i] := i;
     1792  for i := 0 to nImp - 2 do
     1793    for j := i + 1 to nImp - 1 do
     1794      if Prio(ImpSorted[i]) > Prio(ImpSorted[j]) then begin
     1795        k := ImpSorted[i];
     1796        ImpSorted[i] := ImpSorted[j];
     1797        ImpSorted[j] := k;
     1798      end;
     1799end;
     1800
    17771801initialization
    17781802
    1779 for i := 0 to nImp - 1 do
    1780   ImpSorted[i] := i;
    1781 for i := 0 to nImp - 2 do
    1782   for j := i + 1 to nImp - 1 do
    1783     if Prio(ImpSorted[i]) > Prio(ImpSorted[j]) then
    1784     begin
    1785       k := ImpSorted[i];
    1786       ImpSorted[i] := ImpSorted[j];
    1787       ImpSorted[j] := k;
    1788     end;
     1803SortImprovements;
    17891804
    17901805end.
  • branches/highdpi/LocalPlayer/CityType.pas

    r210 r349  
    158158
    159159  nPool := 0;
    160   for iix := 28 to nImp - 1 do
     160  for iix := nWonder to nImp - 1 do
    161161    if not(iix in listed) and (Imp[iix].Kind = ikCommon) and (iix <> imTrGoods)
    162162      and (Imp[iix].Preq <> preNA) and
  • branches/highdpi/LocalPlayer/ClientTools.pas

    r303 r349  
    1616  TEnhancementJobs = array [0 .. 11, 0 .. 7] of byte;
    1717  JobResultSet = set of 0 .. 39;
     18
     19  TMapOption = (
     20    // options switched by buttons
     21    moPolitical = 0, moCityNames = 1, moGreatWall = 4, moGrid = 5, moBareTerrain = 6,
     22    // other options
     23    moEditMode = 16, moLocCodes = 17
     24  );
     25  TMapOptions = set of TMapOption;
     26
     27  TSaveOption = (soAlEffectiveMovesOnly = 0, soEnMoves = 1, soEnAttacks = 2,
     28    soEnNoMoves = 3, soWaitTurn = 4, soEffectiveMovesOnly = 5, soEnFastMoves = 6,
     29    soSlowMoves = 7, soFastMoves = 8, soVeryFastMoves = 9, soNames = 10,
     30    soRepList = 11, soRepScreens = 12, soSoundOff = 13, soSoundOn = 14,
     31    soSoundOnAlt = 15, soScrollSlow = 16, soScrollFast = 17, soScrollOff = 18,
     32    soAlSlowMoves = 19, soAlFastMoves = 20, somAlNoMoves = 21, soTellAI = 30);
     33  TSaveOptions = set of TSaveOption;
    1834
    1935var
     
    5975procedure CityOptimizer_AfterRemoveUnit;
    6076procedure CityOptimizer_EndOfTurn;
     77function GetMyCityByLoc(Loc: Integer): PCity;
     78function GetEnemyCityByLoc(Loc: Integer): PCityInfo;
     79function GetMyUnitByLoc(Loc: Integer): PUn;
     80function GetEnemyUnitByLoc(Loc: Integer): PUnitInfo;
    6181
    6282
     
    241261      Inc(Result, CityReport.FoodSurplus);
    242262  end;
    243   for i := 28 to nImp - 1 do
     263  for i := nWonder to nImp - 1 do
    244264    if MyCity[cix].Built[i] > 0 then
    245265      Dec(Result, Imp[i].Maint);
     
    696716end;
    697717
     718function GetMyCityByLoc(Loc: Integer): PCity;
     719var
     720  I: Integer;
     721begin
     722  I := MyRO.nCity - 1;
     723  while (I >= 0) and (MyCity[I].Loc <> Loc) do Dec(I);
     724  if I >= 0 then Result := @MyCity[I]
     725    else Result := nil;
     726end;
     727
     728function GetEnemyCityByLoc(Loc: Integer): PCityInfo;
     729var
     730  I: Integer;
     731begin
     732  I := MyRO.nEnemyCity - 1;
     733  while (I >= 0) and (MyRo.EnemyCity[I].Loc <> Loc) do Dec(I);
     734  if I >= 0 then Result := @MyRo.EnemyCity[I]
     735    else Result := nil;
     736end;
     737
     738function GetMyUnitByLoc(Loc: Integer): PUn;
     739var
     740  I: Integer;
     741begin
     742  I := MyRO.nUn - 1;
     743  while (I >= 0) and (MyUn[I].Loc <> Loc) do Dec(I);
     744  if I >= 0 then Result := @MyUn[I]
     745    else Result := nil;
     746end;
     747
     748function GetEnemyUnitByLoc(Loc: Integer): PUnitInfo;
     749var
     750  I: Integer;
     751begin
     752  I := MyRO.nEnemyUn - 1;
     753  while (I >= 0) and (MyRO.EnemyUn[I].Loc <> Loc) do Dec(I);
     754  if I >= 0 then Result := @MyRO.EnemyUn[I]
     755    else Result := nil;
     756end;
     757
     758
    698759initialization
    699760
  • branches/highdpi/LocalPlayer/Diagram.pas

    r244 r349  
    355355      end;
    356356    Popup.Popup(Left + ToggleBtn.Left, Top + ToggleBtn.Top + ToggleBtn.Height);
    357   end
     357  end;
    358358end;
    359359
     
    370370  else if (Key = VK_F8) and (Kind = dkShip) then // my other key
    371371  else
    372     inherited
     372    inherited;
    373373end;
    374374
  • branches/highdpi/LocalPlayer/Draft.pas

    r303 r349  
    233233begin
    234234  inherited;
    235   // TODO: Explicitly clear background to black but in fact BitBlt SRCCOPY should do it
    236   Back.Canvas.FillRect(0, 0, Back.Width, Back.Height);
     235  UnshareBitmap(Back);
    237236
    238237  ClientHeight := Template.Height - Cut;
     
    275274          x := xDomain + d * DomainPitch;
    276275          if d = Domain then
    277             ImageOp_BCC(offscreen, Templates, x, yDomain, 142, 246 + 37 * d, 36,
     276            ImageOp_BCC(offscreen, Templates.Data, x, yDomain, 142, 246 + 37 * d, 36,
    278277              36, 0, $00C0FF)
    279278          else
    280             ImageOp_BCC(offscreen, Templates, x, yDomain, 142, 246 + 37 * d, 36,
     279            ImageOp_BCC(offscreen, Templates.Data, x, yDomain, 142, 246 + 37 * d, 36,
    281280              36, 0, $606060);
    282281        end;
     
    300299      for i := 0 to MaxWeight - 1 do
    301300        if i < Weight then
    302           ImageOp_BCC(offscreen, Templates, xWeight + 20 * i, yWeight, 123, 400,
    303             18, 20, 0, $949494)
     301          ImageOp_BCC(offscreen, Templates.Data, Point(xWeight + 20 * i, yWeight),
     302            WeightOn.BoundsRect, 0, $949494)
    304303        else
    305           ImageOp_BCC(offscreen, Templates, xWeight + 20 * i, yWeight, 105, 400,
    306             18, 20, 0, $949494);
     304          ImageOp_BCC(offscreen, Templates.Data, Point(xWeight + 20 * i, yWeight),
     305            WeightOff.BoundsRect, 0, $949494);
    307306    end;
    308307
     
    336335          // paint cost
    337336          LightGradient(offscreen.Canvas, xFeature + 34,
    338             yFeature + LinePitch * i, 50, GrExt[HGrSystem].Data.Canvas.Pixels
     337            yFeature + LinePitch * i, 50, HGrSystem.Data.Canvas.Pixels
    339338            [187, 137]);
    340339          if (Domain = dGround) and (code[i] = mcDefense) then
  • branches/highdpi/LocalPlayer/Enhance.pas

    r303 r349  
    77  UDpiControls, ScreenTools, BaseWin, Protocol, ClientTools, Term, LCLIntf, LCLType,
    88
    9   SysUtils, Classes, Graphics, Controls, Forms,
     9  SysUtils, Classes, Graphics, Controls, Forms, IsoEngine,
    1010  ButtonB, ButtonC, Menus;
    1111
     
    2828    Popup: TDpiPopupMenu;
    2929    procedure FormCreate(Sender: TObject);
     30    procedure FormDestroy(Sender: TObject);
    3031    procedure FormPaint(Sender: TObject);
    3132    procedure FormShow(Sender: TObject);
     
    3536    procedure JobClick(Sender: TObject);
    3637    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
     38  private
     39    NoMap: TIsoMap;
    3740  public
    3841    procedure ShowNewContent(NewMode: integer; TerrType: integer = -1);
     
    4548  EnhanceDlg: TEnhanceDlg;
    4649
     50
    4751implementation
    4852
    49 uses Help;
     53uses
     54  Help, UKeyBindings;
    5055
    5156{$R *.lfm}
     
    5762begin
    5863  inherited;
     64  NoMap := TIsoMap.Create;
    5965  CaptionRight := CloseBtn.Left;
    6066  CaptionLeft := ToggleBtn.Left + ToggleBtn.Width;
     
    8591end;
    8692
     93procedure TEnhanceDlg.FormDestroy(Sender: TObject);
     94begin
     95  FreeAndNil(NoMap);
     96end;
     97
    8798procedure TEnhanceDlg.FormPaint(Sender: TObject);
    8899var
     
    97108    if Controls[i] is TButtonC then
    98109      DpiBitCanvas(Canvas, Controls[i].Left + 2, Controls[i].Top - 11, 8, 8,
    99         GrExt[HGrSystem].Data.Canvas, 121 + Controls[i].Tag mod 7 * 9,
     110        HGrSystem.Data.Canvas, 121 + Controls[i].Tag mod 7 * 9,
    100111        1 + Controls[i].Tag div 7 * 9);
    101112end;
     
    129140  while (EndStage < 5) and (MyData.EnhancementJobs[Page, EndStage] <> jNone) do
    130141    inc(EndStage);
    131   x := InnerWidth div 2 - xxt - (xxt + 3) * EndStage;
     142  with NoMap do
     143    x := InnerWidth div 2 - xxt - (xxt + 3) * EndStage;
    132144
    133145  TerrType := Page;
     
    185197    end;
    186198
    187     if TerrType < fForest then
    188       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    189         1 + TerrType * (xxt * 2 + 1), 1 + yyt)
    190     else
    191     begin
    192       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    193         1 + 2 * (xxt * 2 + 1), 1 + yyt + 2 * (yyt * 3 + 1));
    194       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    195         1 + 7 * (xxt * 2 + 1), 1 + yyt + 2 * (2 + TerrType - fForest) *
    196         (yyt * 3 + 1));
    197     end;
    198     if TileImp and fTerImp = tiFarm then
    199       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    200         1 + (xxt * 2 + 1), 1 + yyt + 12 * (yyt * 3 + 1))
    201     else if TileImp and fTerImp = tiIrrigation then
    202       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2, 1,
    203         1 + yyt + 12 * (yyt * 3 + 1));
    204     if TileImp and fRR <> 0 then
    205     begin
    206       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    207         1 + 6 * (xxt * 2 + 1), 1 + yyt + 10 * (yyt * 3 + 1));
    208       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    209         1 + 2 * (xxt * 2 + 1), 1 + yyt + 10 * (yyt * 3 + 1));
    210     end
    211     else if TileImp and fRoad <> 0 then
    212     begin
    213       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    214         1 + 6 * (xxt * 2 + 1), 1 + yyt + 9 * (yyt * 3 + 1));
    215       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    216         1 + 2 * (xxt * 2 + 1), 1 + yyt + 9 * (yyt * 3 + 1));
    217     end;
    218     if TileImp and fTerImp = tiMine then
    219       Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
    220         1 + 2 * (xxt * 2 + 1), 1 + yyt + 12 * (yyt * 3 + 1));
    221     inc(x, xxt * 2 + 6)
     199    with NoMap do begin
     200      if TerrType < fForest then
     201        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     202          1 + TerrType * (xxt * 2 + 1), 1 + yyt)
     203      else
     204      begin
     205        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     206          1 + 2 * (xxt * 2 + 1), 1 + yyt + 2 * (yyt * 3 + 1));
     207        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     208          1 + 7 * (xxt * 2 + 1), 1 + yyt + 2 * (2 + TerrType - fForest) *
     209          (yyt * 3 + 1));
     210      end;
     211      if TileImp and fTerImp = tiFarm then
     212        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     213          1 + (xxt * 2 + 1), 1 + yyt + 12 * (yyt * 3 + 1))
     214      else if TileImp and fTerImp = tiIrrigation then
     215        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2, 1,
     216          1 + yyt + 12 * (yyt * 3 + 1));
     217      if TileImp and fRR <> 0 then
     218      begin
     219        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     220          1 + 6 * (xxt * 2 + 1), 1 + yyt + 10 * (yyt * 3 + 1));
     221        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     222          1 + 2 * (xxt * 2 + 1), 1 + yyt + 10 * (yyt * 3 + 1));
     223      end
     224      else if TileImp and fRoad <> 0 then
     225      begin
     226        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     227          1 + 6 * (xxt * 2 + 1), 1 + yyt + 9 * (yyt * 3 + 1));
     228        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     229          1 + 2 * (xxt * 2 + 1), 1 + yyt + 9 * (yyt * 3 + 1));
     230      end;
     231      if TileImp and fTerImp = tiMine then
     232        Sprite(offscreen, HGrTerrain, x, 64 - yyt, xxt * 2, yyt * 2,
     233          1 + 2 * (xxt * 2 + 1), 1 + yyt + 12 * (yyt * 3 + 1));
     234      inc(x, xxt * 2 + 6);
     235    end;
    222236  end;
    223237
     
    289303procedure TEnhanceDlg.CloseBtnClick(Sender: TObject);
    290304begin
    291   Close
     305  Close;
    292306end;
    293307
     
    304318begin
    305319  Page := TComponent(Sender).Tag;
    306   SmartUpdateContent
     320  SmartUpdateContent;
    307321end;
    308322
     
    324338          move(MyData.EnhancementJobs[Page, stage + 1],
    325339            MyData.EnhancementJobs[Page, stage], 4 - stage);
    326         MyData.EnhancementJobs[Page, 4] := jNone
     340        MyData.EnhancementJobs[Page, 4] := jNone;
    327341      end
    328342      else
     
    351365    begin
    352366      MyData.EnhancementJobs[Page, stage] := jRoad;
    353       inc(stage)
     367      inc(stage);
    354368    end;
    355369    if (NewJob = jFarm) and not(jIrr in Done) then
    356370    begin
    357371      MyData.EnhancementJobs[Page, stage] := jIrr;
    358       inc(stage)
    359     end;
    360     MyData.EnhancementJobs[Page, stage] := NewJob
    361   end;
    362   SmartUpdateContent
     372      inc(stage);
     373    end;
     374    MyData.EnhancementJobs[Page, stage] := NewJob;
     375  end;
     376  SmartUpdateContent;
    363377end;
    364378
    365379procedure TEnhanceDlg.FormKeyDown(Sender: TObject; var Key: Word;
    366380  Shift: TShiftState);
    367 begin
    368   if Key = VK_F1 then
     381var
     382  ShortCut: TShortCut;
     383begin
     384  ShortCut := KeyToShortCut(Key, Shift);
     385  if BHelp.Test(ShortCut) then
    369386    HelpDlg.ShowNewContent(FWindowMode or wmPersistent, hkText,
    370387      HelpDlg.TextIndex('MACRO'))
  • branches/highdpi/LocalPlayer/Help.pas

    r303 r349  
    77  UDpiControls, Protocol, ScreenTools, BaseWin, StringTables, Math, LCLIntf, LCLType,
    88  Messages, SysUtils, Classes, Graphics, Controls, Forms, ExtCtrls,
    9   ButtonB, PVSB, Types, fgl;
     9  ButtonB, PVSB, Types, fgl, IsoEngine;
    1010
    1111const
     
    102102    ExtPic, TerrIcon: TDpiBitmap;
    103103    ScrollBar: TPVScrollbar;
     104    NoMap: TIsoMap;
    104105    x0: array [-2..180] of Integer;
    105106    procedure PaintTerrIcon(x, y, xSrc, ySrc: Integer);
     
    241242
    242243  nSeeAlso = 14;
    243   SeeAlso: array [0 .. nSeeAlso - 1] of record Kind, no, SeeKind,
    244     SeeNo: integer end = ((Kind: hkImp; no: imWalls; SeeKind: hkFeature;
     244  SeeAlso: array [0 .. nSeeAlso - 1] of record
     245    Kind: Integer;
     246    no: Integer;
     247    SeeKind: Integer;
     248    SeeNo: Integer;
     249  end = ((Kind: hkImp; no: imWalls; SeeKind: hkFeature;
    245250    SeeNo: mcArtillery), (Kind: hkImp; no: imHydro; SeeKind: hkImp;
    246251    SeeNo: woHoover), (Kind: hkImp; no: imWalls; SeeKind: hkImp;
     
    269274begin
    270275  inherited;
     276  NoMap := TIsoMap.Create;
     277
    271278  HistItems := THistItems.Create;
    272279
     
    327334  // FreeAndNil(CaptionFont);
    328335  FreeAndNil(HistItems);
     336  FreeAndNil(NoMap);
    329337end;
    330338
     
    397405      ca.FrameRect(rect(x+1,i*24+1,x+24-1,i*24+24-1));
    398406      ca.Brush.Style:=bsClear; }
    399     DpiBitCanvas(ca, x, y - 4, 24, 24, GrExt[HGrSystem].Data.Canvas, 1,
     407    DpiBitCanvas(ca, x, y - 4, 24, 24, HGrSystem.Data.Canvas, 1,
    400408      146);
    401409    BiColorTextOut(ca, $FFFFFF, $7F007F, x + 10 - ca.Textwidth(s[1]) div 2,
     
    436444    if (Kind = hkMisc) and (no = miscMain) then
    437445      ca.Font.Assign(UniFont[ftNormal]);
    438   end
     446  end;
    439447end;
    440448
     
    460468  ySrc := (iix div 7 + 1) * ySizeBig;
    461469  PaintPtr := PixelPointer(OffScreen, ScaleToNative(x0), ScaleToNative(y0));
    462   CoalPtr := PixelPointer(Templates, ScaleToNative(xCoal), ScaleToNative(yCoal));
     470  CoalPtr := PixelPointer(Templates.Data, ScaleToNative(xCoal), ScaleToNative(yCoal));
    463471  for dy := -1 to 1 do
    464472    ImpPtr[dy] := PixelPointer(BigImp, ScaleToNative(xSrc), ScaleToNative(ySrc));
     
    504512procedure THelpDlg.PaintTerrIcon(x, y, xSrc, ySrc: integer);
    505513begin
    506   Frame(OffScreen.Canvas, x - 1, y - 1, x + xSizeBig, y + ySizeBig,
    507     $000000, $000000);
    508   if 2 * yyt < 40 then begin
    509     Sprite(OffScreen, HGrTerrain, x, y, 56, 2 * yyt, xSrc, ySrc);
    510     Sprite(OffScreen, HGrTerrain, x, y + 2 * yyt, 56, 40 - 2 * yyt,
     514  with NoMap do begin
     515    Frame(OffScreen.Canvas, x - 1, y - 1, x + xSizeBig, y + ySizeBig,
     516      $000000, $000000);
     517    if 2 * yyt < 40 then begin
     518      Sprite(OffScreen, HGrTerrain, x, y, 56, 2 * yyt, xSrc, ySrc);
     519      Sprite(OffScreen, HGrTerrain, x, y + 2 * yyt, 56, 40 - 2 * yyt,
     520        xSrc, ySrc);
     521    end else
     522      Sprite(OffScreen, HGrTerrain, x, y, 56, 40, xSrc, ySrc);
     523    Sprite(OffScreen, HGrTerrain, x, y, xxt, yyt, xSrc + xxt, ySrc + yyt);
     524    Sprite(OffScreen, HGrTerrain, x, y + yyt, xxt, 40 - yyt, xSrc + xxt, ySrc);
     525    Sprite(OffScreen, HGrTerrain, x + xxt, y, 56 - xxt, yyt, xSrc, ySrc + yyt);
     526    Sprite(OffScreen, HGrTerrain, x + xxt, y + yyt, 56 - xxt, 40 - yyt,
    511527      xSrc, ySrc);
    512   end else
    513     Sprite(OffScreen, HGrTerrain, x, y, 56, 40, xSrc, ySrc);
    514   Sprite(OffScreen, HGrTerrain, x, y, xxt, yyt, xSrc + xxt, ySrc + yyt);
    515   Sprite(OffScreen, HGrTerrain, x, y + yyt, xxt, 40 - yyt, xSrc + xxt, ySrc);
    516   Sprite(OffScreen, HGrTerrain, x + xxt, y, 56 - xxt, yyt, xSrc, ySrc + yyt);
    517   Sprite(OffScreen, HGrTerrain, x + xxt, y + yyt, 56 - xxt, 40 - yyt,
    518     xSrc, ySrc);
     528  end;
    519529end;
    520530
     
    571581                j and $FF]);
    572582              PaintLogo(OffScreen.Canvas, (InnerWidth - 122) div 2, i * 24 + 1,
    573                 GrExt[HGrSystem].Data.Canvas.Pixels[95, 1], $000000);
     583                HGrSystem.Data.Canvas.Pixels[95, 1], $000000);
    574584              Font.Assign(UniFont[ftSmall]);
    575585              BiColorTextOut(OffScreen.Canvas, $000000, $7F007F,
     
    604614              case HelpLineInfo.Picpix of
    605615                0:
    606                   FrameImage(OffScreen.Canvas, GrExt[HGrSystem2].Data,
     616                  FrameImage(OffScreen.Canvas, HGrSystem2.Data,
    607617                    12 + x0[i], -7 + i * 24, 56, 40, 137, 127);
    608618                1:
    609                   begin
     619                  with NoMap do begin
    610620                    PaintTerrIcon(12 + x0[i], -7 + i * 24,
    611621                      1 + 3 * (xxt * 2 + 1), 1 + yyt);
     
    620630                  end;
    621631                2:
    622                   begin
     632                  with NoMap do begin
    623633                    PaintTerrIcon(12 + x0[i], -7 + i * 24,
    624634                      1 + 7 * (xxt * 2 + 1), 1 + yyt + 4 * (yyt * 3 + 1));
     
    660670              j := AdvValue[HelpLineInfo.Picpix] div 1000;
    661671              DpiBitCanvas(OffScreen.Canvas, x0[i] + 4, 4 + i * 24, 14, 14,
    662                 GrExt[HGrSystem].Mask.Canvas, 127 + j * 15, 85, SRCAND);
     672                HGrSystem.Mask.Canvas, 127 + j * 15, 85, SRCAND);
    663673              Sprite(OffScreen, HGrSystem, x0[i] + 3, 3 + i * 24, 14, 14,
    664674                127 + j * 15, 85);
     
    705715            end;
    706716          pkTer, pkBigTer:
    707             begin
     717            with NoMap do begin
    708718              if HelpLineInfo.Format = pkBigTer then
    709719                y := i * 24 - 3 + yyt
     
    760770            end;
    761771          pkTerImp:
    762             begin
     772            with NoMap do begin
    763773              ofs := 8;
    764774              if HelpLineInfo.Picpix = 5 then
     
    767777                  xxt * 2 - 8, yyt * 2 - 4, 5 + 2 * (xxt * 2 + 1),
    768778                  3 + yyt + 2 * (yyt * 3 + 1));
    769                 srcno := 45
     779                srcno := 45;
    770780              end
    771781              else
     
    9901000  procedure AddTextual(s: string);
    9911001  var
    992     i, p, l, ofs, CurrentFormat, FollowFormat, Picpix, LinkCategory, LinkIndex,
    993       RightMargin: integer;
     1002    i: Integer;
     1003    p: Integer;
     1004    l: Integer;
     1005    ofs: Integer;
     1006    CurrentFormat: Integer;
     1007    FollowFormat: Integer;
     1008    Picpix: Integer;
     1009    LinkCategory: Integer;
     1010    LinkIndex: Integer;
     1011    RightMargin: Integer;
    9941012    Name: string;
     1013    Text: string;
    9951014  begin
    9961015    RightMargin := InnerWidth - 16 - DpiGetSystemMetrics(SM_CXVSCROLL);
     
    11391158            Break;
    11401159        until (p >= Length(s)) or (s[l + 1] = '\');
    1141         MainText.AddLine(Copy(s, 1, l), CurrentFormat, Picpix, LinkCategory,
     1160        Text := Copy(s, 1, l);
     1161        if LinkCategory and $3f = hkInternet then begin
     1162          if LinkIndex = 1 then Text := AITemplateManual
     1163          else if LinkIndex = 2 then Text := CevoHomepageShort
     1164          else if LinkIndex = 3 then Text := CevoContactShort;
     1165        end;
     1166        MainText.AddLine(Text, CurrentFormat, Picpix, LinkCategory,
    11421167          LinkIndex);
    11431168        if (l < Length(s)) and (s[l + 1] = '\') then
     
    14711496                hkMisc + hkCrossLink, miscGovList);
    14721497          NextSection('BUILDALLOW');
    1473           for i := 0 to 27 do
     1498          for i := 0 to nWonder - 1 do
    14741499            if Imp[i].Preq = no then
    14751500              AddImprovement(i);
    1476           for i := 28 to nImp - 1 do
     1501          for i := nWonder to nImp - 1 do
    14771502            if (Imp[i].Preq = no) and (Imp[i].Kind <> ikCommon) then
    14781503              AddImprovement(i);
    1479           for i := 28 to nImp - 1 do
     1504          for i := nWonder to nImp - 1 do
    14801505            if (Imp[i].Preq = no) and (Imp[i].Kind = ikCommon) then
    14811506              AddImprovement(i);
     
    15141539              end;
    15151540          NextSection('EXPIRATION');
    1516           for i := 0 to 27 do
     1541          for i := 0 to nWonder - 1 do
    15171542            if (Imp[i].Preq <> preNA) and (Imp[i].Expiration = no) then
    15181543              AddImprovement(i);
     
    15321557          List := THyperText.Create;
    15331558          List.OwnsObjects := True;
    1534           for i := 28 to nImp - 1 do
     1559          for i := nWonder to nImp - 1 do
    15351560            if (i <> imTrGoods) and (Imp[i].Preq <> preNA) and
    15361561              (Imp[i].Kind = ikCommon) then
     
    15451570          Caption := HelpText.Lookup('HELPTITLE_UNIQUELIST');
    15461571          // AddLine(HelpText.Lookup('HELPTITLE_UNIQUELIST'),pkSection);
    1547           for i := 28 to nImp - 1 do
     1572          for i := nWonder to nImp - 1 do
    15481573            if (Imp[i].Preq <> preNA) and
    15491574              ((Imp[i].Kind = ikNatLocal) or (Imp[i].Kind = ikNatGlobal)) then
     
    15531578            LineFeed;
    15541579            AddLine(HelpText.Lookup('HELPTITLE_SHIPPARTLIST'),pkSection);
    1555             for i:=28 to nImp-1 do
     1580            for i:= nWonder to nImp-1 do
    15561581            if (Imp[i].Preq<>preNA) and (Imp[i].Kind=ikShipPart) then
    15571582            AddLine(Phrases.Lookup('IMPROVEMENTS',i),pkSmallIcon,i,hkImp,i); }
     
    15611586          Caption := HelpText.Lookup('HELPTITLE_WONDERLIST');
    15621587          // AddLine(HelpText.Lookup('HELPTITLE_WONDERLIST'),pkSection);
    1563           for i := 0 to 27 do
     1588          for i := 0 to nWonder - 1 do
    15641589            if Imp[i].Preq <> preNA then
    15651590              AddLine(Phrases.Lookup('IMPROVEMENTS', i), pkSmallIcon, i,
     
    15871612            AddFeature(mcAcademy);
    15881613          end;
    1589           if (no < 28) and not Phrases2FallenBackToEnglish then
     1614          if (no < nWonder) and not Phrases2FallenBackToEnglish then
    15901615          begin
    15911616            LineFeed;
     
    16331658              [Phrases.Lookup('TERRAIN', 3 * 12 + i)]), pkTer, 3 * 12 + i);
    16341659          end;
    1635           if (no < 28) and (Imp[no].Expiration >= 0) then
     1660          if (no < nWonder) and (Imp[no].Expiration >= 0) then
    16361661          begin
    16371662            NextSection('EXPIRATION');
     
    16431668          end;
    16441669          NextSection('SEEALSO');
    1645           if (no < 28) and (Imp[no].Expiration >= 0) then
     1670          if (no < nWonder) and (Imp[no].Expiration >= 0) then
    16461671            AddImprovement(woEiffel);
    16471672          for i := 0 to nImpReplacement - 1 do
  • branches/highdpi/LocalPlayer/IsoEngine.pas

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

    r253 r349  
    11object MessgExDlg: TMessgExDlg
    22  Left = 463
     3  Height = 134
    34  Top = 164
     5  Width = 418
    46  BorderIcons = []
    57  BorderStyle = bsNone
     
    810  ClientWidth = 418
    911  Color = clBtnFace
    10   Font.Charset = DEFAULT_CHARSET
     12  DesignTimePPI = 144
    1113  Font.Color = clWindowText
    1214  Font.Height = -13
    1315  Font.Name = 'MS Sans Serif'
    14   Font.Style = []
    1516  FormStyle = fsStayOnTop
    1617  OnClose = FormClose
     
    1920  OnPaint = FormPaint
    2021  OnShow = FormShow
    21   PixelsPerInch = 96
     22  LCLVersion = '2.0.12.0'
    2223  Scaled = False
    2324  object Button1: TButtonA
    2425    Left = 43
     26    Height = 25
    2527    Top = 104
    2628    Width = 100
    27     Height = 25
    2829    Down = False
    2930    Permanent = False
    3031    OnClick = Button1Click
    31     Caption = ''
    3232  end
    3333  object Button2: TButtonA
    3434    Left = 159
     35    Height = 25
    3536    Top = 104
    3637    Width = 100
    37     Height = 25
    3838    Down = False
    3939    Permanent = False
    4040    OnClick = Button2Click
    41     Caption = ''
    4241  end
    4342  object Button3: TButtonA
    4443    Left = 275
     44    Height = 25
    4545    Top = 104
    4646    Width = 100
    47     Height = 25
    4847    Down = False
    4948    Permanent = False
    5049    OnClick = Button3Click
    51     Caption = ''
    5250  end
    5351  object RemoveBtn: TButtonB
    5452    Left = 384
     53    Height = 25
    5554    Top = 104
    5655    Width = 25
    57     Height = 25
    5856    Down = False
    5957    Permanent = False
     
    6361  object EInput: TDpiEdit
    6462    Left = 125
     63    Height = 26
    6564    Top = 64
    6665    Width = 168
    67     Height = 19
    68     TabStop = False
    6966    BorderStyle = bsNone
    7067    Color = clBlack
    71     Font.Charset = DEFAULT_CHARSET
    7268    Font.Color = 4176863
    7369    Font.Height = -15
     
    7571    Font.Style = [fsBold]
    7672    ParentFont = False
     73    TabStop = False
    7774    TabOrder = 0
    7875  end
  • branches/highdpi/LocalPlayer/MessgEx.pas

    r311 r349  
    149149      begin
    150150        Tribe[IconIndex].InitAge(GetAge(IconIndex));
    151         if Tribe[IconIndex].faceHGr >= 0 then
    152           TopSpace := 64
     151        if Assigned(Tribe[IconIndex].faceHGr) then
     152          TopSpace := 64;
    153153      end;
    154154    mikFullControl:
     
    233233  hScrewed = 27;
    234234var
    235   ix, iy, xDst, yDst, dx, dy, xIcon, yIcon, xb, yb, wb, hb: integer;
     235  ix, iy, xDst, yDst, dx, dy, xIcon, yIcon: integer;
     236  BookRect: TRect;
    236237  x1, xR, yR, share: single;
    237238  Screwed: array [0 .. wScrewed - 1, 0 .. hScrewed - 1, 0 .. 3] of single;
     
    282283    end;
    283284    BigImp.EndUpdate;
    284     xb := xBBook;
    285     yb := yBBook;
    286     wb := wBBook;
    287     hb := hBBook;
     285    BookRect := BigBook.BoundsRect;
    288286  end
    289287  else
    290288  begin
    291     xb := xSBook;
    292     yb := ySBook;
    293     wb := wSBook;
    294     hb := hSBook;
    295   end;
    296   x := x - wb div 2;
     289    BookRect := SmallBook.BoundsRect;
     290  end;
     291  x := x - BookRect.Width div 2;
    297292
    298293  // paint
    299   // TODO: Explicitly clear background to black but in fact BitBlt SRCCOPY should do it
    300   LogoBuffer.Canvas.FillRect(0, 0, LogoBuffer.Width, LogoBuffer.Height);
    301   DpiBitCanvas(LogoBuffer.Canvas, 0, 0, wb, hb, ca, x, y);
     294  UnshareBitmap(LogoBuffer);
     295  DpiBitCanvas(LogoBuffer.Canvas, 0, 0, BookRect.Width, BookRect.Height, ca, x, y);
    302296
    303297  if IconIndex >= 0 then
     
    310304            Trunc(Screwed[ix, iy, 0] / Screwed[ix, iy, 3]) shl 16;
    311305
    312   ImageOp_BCC(LogoBuffer, Templates, 0, 0, xb, yb, wb, hb, clCover, clPage);
    313 
    314   DpiBitCanvas(ca, x, y, wb, hb, LogoBuffer.Canvas, 0, 0);
     306  ImageOp_BCC(LogoBuffer, Templates.Data, Point(0, 0), BookRect, clCover, clPage);
     307
     308  DpiBitCanvas(ca, x, y, BookRect.Width, BookRect.Height, LogoBuffer.Canvas, 0, 0);
    315309end;
    316310
     
    336330      with MyRO.EnemyModel[emix], Tribe[Owner].ModelPicture[mix] do
    337331      begin
    338         DpiBitCanvas(Canvas, x, y, 64, 48, GrExt[HGr].Mask.Canvas,
     332        DpiBitCanvas(Canvas, x, y, 64, 48, HGr.Mask.Canvas,
    339333          pix mod 10 * 65 + 1, pix div 10 * 49 + 1, SRCAND);
    340         DpiBitCanvas(Canvas, x, y, 64, 48, GrExt[HGr].Data.Canvas,
     334        DpiBitCanvas(Canvas, x, y, 64, 48, HGr.Data.Canvas,
    341335          pix mod 10 * 65 + 1, pix div 10 * 49 + 1, SRCPAINT);
    342336      end;
     
    379373      begin
    380374        p1 := MyRO.Wonder[IconIndex].EffectiveOwner;
    381         // TODO: Explicitly clear background to black but in fact BitBlt SRCCOPY should do it
    382         Buffer.Canvas.FillRect(0, 0, 1, 1);
     375        UnshareBitmap(Buffer);
    383376        DpiBitCanvas(Buffer.Canvas, 0, 0, xSizeBig + 2 * GlowRange,
    384377          ySizeBig + 2 * GlowRange, Canvas,
     
    411404          ySizeBig, 0, 0);
    412405        DpiBitCanvas(Canvas, ClientWidth div 2 - 32, 20, 64, 44,
    413           GrExt[HGr].Mask.Canvas, pix mod 10 * 65 + 1,
     406          HGr.Mask.Canvas, pix mod 10 * 65 + 1,
    414407          pix div 10 * 49 + 1, SRCAND);
    415408        DpiBitCanvas(Canvas, ClientWidth div 2 - 32, 20, 64, 44,
    416           GrExt[HGr].Data.Canvas, pix mod 10 * 65 + 1,
     409          HGr.Data.Canvas, pix mod 10 * 65 + 1,
    417410          pix div 10 * 49 + 1, SRCPAINT);
    418411      end;
     
    421414        MainTexture.clCover);
    422415    mikTribe:
    423       if Tribe[IconIndex].faceHGr >= 0 then
     416      if Assigned(Tribe[IconIndex].faceHGr) then
    424417      begin
    425418        Frame(Canvas, ClientWidth div 2 - 32 - 1, 24 - 1,
    426419          ClientWidth div 2 + 32, 24 + 48, $000000, $000000);
    427420        DpiBitCanvas(Canvas, ClientWidth div 2 - 32, 24, 64, 48,
    428           GrExt[Tribe[IconIndex].faceHGr].Data.Canvas,
     421          Tribe[IconIndex].faceHGr.Data.Canvas,
    429422          1 + Tribe[IconIndex].facepix mod 10 * 65,
    430423          1 + Tribe[IconIndex].facepix div 10 * 49)
     
    441434        DpiBitCanvas(Buffer.Canvas, 0, 0, 140, 120, Canvas,
    442435          (ClientWidth - 140) div 2, 24);
    443         ImageOp_BCC(Buffer, Templates, 0, 0, 1, 279, 140, 120, 0, $FFFFFF);
     436        ImageOp_BCC(Buffer, Templates.Data, Point(0, 0), StarshipDeparted.BoundsRect, 0, $FFFFFF);
    444437        DpiBitCanvas(Canvas, (ClientWidth - 140) div 2, 24, 140, 120,
    445438          Buffer.Canvas, 0, 0);
  • branches/highdpi/LocalPlayer/NatStat.pas

    r303 r349  
    8282  ReportText := TStringList.Create;
    8383  InitButtons();
    84   ContactBtn.Template := Templates;
     84  ContactBtn.Template := Templates.Data;
    8585  HelpContext := 'DIPLOMACY';
    8686  ToggleBtn.Hint := Phrases.Lookup('BTN_SELECT');
     
    114114      (hMainTexture - ClientHeight) div 2);
    115115    ImageOp_B(Back, Template, 0, 0, 0, 0, ClientWidth, ClientHeight);
    116   end
     116  end;
    117117end;
    118118
     
    141141  ScrollDownBtn.Visible := (CurrentReport.TurnOfCivilReport >= 0) and
    142142    (ReportText.Count > ReportLines);
    143   if OptionChecked and (1 shl soTellAI) <> 0 then
     143  if soTellAI in OptionChecked then
    144144    TellAIBtn.ButtonIndex := 3
    145145  else
     
    279279    // show leader picture
    280280    Tribe[pView].InitAge(GetAge(pView));
    281     if Tribe[pView].faceHGr >= 0 then
     281    if Assigned(Tribe[pView].faceHGr) then
    282282    begin
    283283      Dump(offscreen, Tribe[pView].faceHGr, 18, yIcon - 4, 64, 48,
     
    390390    end;
    391391
    392     if OptionChecked and (1 shl soTellAI) <> 0 then
    393     begin
     392    if soTellAI in OptionChecked then begin
    394393      Server(sGetAIInfo, me, pView, ps);
    395394      LoweredTextOut(Canvas, -1, MainTexture, 42, 445, ps);
    396     end
    397     else
     395    end else
    398396      LoweredTextOut(Canvas, -2, MainTexture, 42, 445,
    399397        Phrases2.Lookup('MENU_TELLAI'));
     
    537535procedure TNatStatDlg.TellAIBtnClick(Sender: TObject);
    538536begin
    539   OptionChecked := OptionChecked xor (1 shl soTellAI);
    540   if OptionChecked and (1 shl soTellAI) <> 0 then
     537  if soTellAI in OptionChecked then OptionChecked := OptionChecked - [soTellAI]
     538    else OptionChecked := OptionChecked + [soTellAI];
     539  if soTellAI in OptionChecked then
    541540    TellAIBtn.ButtonIndex := 3
    542541  else
  • branches/highdpi/LocalPlayer/Nego.pas

    r210 r349  
    149149      with TButtonN(Components[cix]) do
    150150      begin
    151         Graphic := GrExt[HGrSystem].Data;
    152         Mask := GrExt[HGrSystem].Mask;
    153         BackGraphic := GrExt[HGrSystem2].Data;
     151        Graphic := HGrSystem.Data;
     152        Mask := HGrSystem.Mask;
     153        BackGraphic := HGrSystem2.Data;
    154154        case Tag shr 8 of
    155155          1:
     
    432432    Brush.Color := $000000;
    433433    Tribe[p].InitAge(GetAge(p));
    434     if Tribe[p].faceHGr >= 0 then
     434    if Assigned(Tribe[p].faceHGr) then
    435435      Dump(Offscreen, Tribe[p].faceHGr, X, Y, 64, 48,
    436436        1 + Tribe[p].facepix mod 10 * 65, 1 + Tribe[p].facepix div 10 * 49)
     
    681681procedure TNegoDlg.CloseBtnClick(Sender: TObject);
    682682begin
    683   Close
     683  Close;
    684684end;
    685685
     
    690690  begin
    691691    if OkBtn.Visible then
    692       OkBtnClick(nil)
     692      OkBtnClick(nil);
    693693  end
    694694  else
    695     inherited
     695    inherited;
    696696end;
    697697
  • branches/highdpi/LocalPlayer/PVSB.pas

    r210 r349  
    3232    procedure Init(Max, PageSize: Integer);
    3333    procedure SetPos(Pos: Integer);
    34     function Process(const m: TMessage): boolean;
     34    function Process(const Msg: TMessage): boolean;
    3535    function ProcessMouseWheel(Delta: Integer): Boolean;
    3636    procedure Show(Visible: boolean);
     
    6565end;
    6666
    67 function TPVScrollBar.Process(const m: TMessage): boolean;
     67function TPVScrollBar.Process(const Msg: TMessage): boolean;
    6868var
    6969  NewPos: integer;
     
    7373    else
    7474    begin
    75       if (m.wParam and $ffff) in [SB_THUMBPOSITION, SB_THUMBTRACK] then
     75      if (Msg.wParam and $ffff) in [SB_THUMBPOSITION, SB_THUMBTRACK] then
    7676      begin
    77         result := ((m.wParam shr 16) and $ffff) <> ScrollBar.Position;
    78         ScrollBar.Position := (m.wParam shr 16) and $ffff;
     77        result := ((Msg.wParam shr 16) and $ffff) <> ScrollBar.Position;
     78        ScrollBar.Position := (Msg.wParam shr 16) and $ffff;
    7979      end else begin
    80         case (m.wParam and $ffff) of
     80        case (Msg.wParam and $ffff) of
    8181          SB_LINEUP:
    8282            NewPos := ScrollBar.Position - 1;
     
    9595          NewPos := Max - ScrollBar.PageSize + 1;
    9696        result := NewPos <> ScrollBar.Position;
    97         if (NewPos <> ScrollBar.Position) or ((m.wParam and $ffff) = SB_ENDSCROLL) then
     97        if (NewPos <> ScrollBar.Position) or ((Msg.wParam and $ffff) = SB_ENDSCROLL) then
    9898        begin
    9999          ScrollBar.Position := NewPos;
  • branches/highdpi/LocalPlayer/Rates.pas

    r210 r349  
    123123      for i := 0 to current div 8 - 1 do
    124124        DpiBitCanvas(Offscreen.Canvas, x + max - 8 - i * 8, y, 8, 7,
    125           GrExt[HGrSystem].Data.Canvas, 104, 9 + 8 * 2);
     125          HGrSystem.Data.Canvas, 104, 9 + 8 * 2);
    126126      DpiBitCanvas(Offscreen.Canvas, x + max - current, y, current - 8 * (current div 8), 7,
    127         GrExt[HGrSystem].Data.Canvas, 104, 9 + 8 * 2);
     127        HGrSystem.Data.Canvas, 104, 9 + 8 * 2);
    128128      Brush.Color := $000000;
    129129      FillRect(Rect(x, y, x + max - current, y + 7));
  • branches/highdpi/LocalPlayer/Select.pas

    r303 r349  
    66uses
    77  UDpiControls, Protocol, ClientTools, Term, ScreenTools, IsoEngine, PVSB, BaseWin,
    8 
    98  LCLIntf, LCLType, Messages, SysUtils, Classes, Graphics, Controls, Forms,
    109  ExtCtrls, ButtonB, ButtonBase, Menus, Types;
     
    4645  private
    4746    Kind: TListKind;
    48     LineDistance, MaxLines, cixProject, pView, Sel, DispLines, Layer, nColumn,
    49       TechNameSpace, ScienceNation: integer;
     47    LineDistance: Integer;
     48    MaxLines: Integer;
     49    cixProject: Integer;
     50    pView: Integer;
     51    Sel: Integer;
     52    DispLines: Integer;
     53    Layer: Integer;
     54    nColumn: Integer;
     55    TechNameSpace: Integer;
     56    ScienceNation: Integer;
    5057    sb: TPVScrollbar;
    5158    Lines, FirstShrinkedLine: array [0 .. MaxLayer - 1] of integer;
    5259    code: array [0 .. MaxLayer - 1, 0 .. 4095] of integer;
    5360    Column: array [0 .. nPl - 1] of integer;
    54     Closable, MultiPage: boolean;
    55     ScienceNationDot: TDpiBitmap;
     61    Closable: Boolean;
     62    MultiPage: Boolean;
     63    ScienceNationDotBuffer: TDpiBitmap;
    5664    procedure ScrollBarUpdate(Sender: TObject);
    5765    procedure InitLines;
     
    8694  ModalSelectDlg: TModalSelectDlg;
    8795
     96
    8897implementation
    8998
     
    109118  Layer1Btn.Hint := Phrases.Lookup('BTN_WONDERS');
    110119  Layer2Btn.Hint := Phrases.Lookup('BTN_CLASSES');
    111   ScienceNationDot := TDpiBitmap.Create;
    112   ScienceNationDot.PixelFormat := pf24bit;
    113   ScienceNationDot.SetSize(17, 17);
    114   ScienceNationDot.Canvas.FillRect(0, 0, ScienceNationDot.Width, ScienceNationDot.Height);
     120  ScienceNationDotBuffer := TDpiBitmap.Create;
     121  ScienceNationDotBuffer.PixelFormat := pf24bit;
     122  ScienceNationDotBuffer.SetSize(17, 17);
     123  ScienceNationDotBuffer.Canvas.FillRect(0, 0, ScienceNationDotBuffer.Width, ScienceNationDotBuffer.Height);
    115124end;
    116125
     
    118127begin
    119128  FreeAndNil(sb);
    120   FreeAndNil(ScienceNationDot);
     129  FreeAndNil(ScienceNationDotBuffer);
    121130end;
    122131
     
    578587                j := AdvValue[lix] div 1000;
    579588                DpiBitCanvas(offscreen.Canvas, (8 + 16 - 4), y0 + 2, 14, 14,
    580                   GrExt[HGrSystem].Mask.Canvas, 127 + j * 15,
     589                  HGrSystem.Mask.Canvas, 127 + j * 15,
    581590                  85, SRCAND);
    582591                Sprite(offscreen, HGrSystem, (8 + 16 - 5), y0 + 1, 14, 14,
     
    816825        LoweredTextOut(Canvas, -1, MainTexture, xScreen + 10,
    817826          ClientHeight - 29, s);
    818         DpiBitCanvas(ScienceNationDot.Canvas, 0, 0, 17, 17, Canvas,
    819           xScreen - 10, ClientHeight - 27);
    820         ImageOp_BCC(ScienceNationDot, Templates, 0, 0, 114, 211, 17, 17,
    821           MainTexture.clBevelShade, Tribe[ScienceNation].Color);
    822         DpiBitCanvas(Canvas, xScreen - 10, ClientHeight - 27, 17, 17,
    823           ScienceNationDot.Canvas, 0, 0);
    824       end;
    825     end
     827        DpiBitCanvas(ScienceNationDotBuffer.Canvas, 0, 0, ScienceNationDot.Width,
     828          ScienceNationDot.Height, Canvas, xScreen - 10, ClientHeight - 27);
     829        ImageOp_BCC(ScienceNationDotBuffer, Templates.Data, Point(0, 0),
     830          ScienceNationDot.BoundsRect, MainTexture.clBevelShade, Tribe[ScienceNation].Color);
     831        DpiBitCanvas(Canvas, xScreen - 10, ClientHeight - 27, ScienceNationDot.Width,
     832          ScienceNationDot.Height, ScienceNationDotBuffer.Canvas, 0, 0);
     833      end;
     834    end;
    826835  end;
    827836end;
     
    854863    begin
    855864      CityDlg.FormShow(nil);
    856       CityDlg.Invalidate
     865      CityDlg.Invalidate;
    857866    end;
    858     result := true
     867    result := true;
    859868  end
    860869  else
    861     result := false
     870    result := false;
    862871end;
    863872
     
    880889    begin
    881890      UnitStatDlg.FormShow(nil);
    882       UnitStatDlg.Invalidate
     891      UnitStatDlg.Invalidate;
    883892    end;
    884     result := true
     893    result := true;
    885894  end
    886895  else
    887     result := false
     896    result := false;
    888897end;
    889898
     
    904913      result := lix;
    905914      Closable := true;
    906       Close
    907     end
     915      Close;
     916    end;
    908917  end
    909918  else if (ssLeft in Shift) and (ssShift in Shift) then
     
    948957        kShipPart, kEShipPart:
    949958          ;
    950       end
     959      end;
    951960  end
    952961  else if ssRight in Shift then
     
    960969          if RenameModel(lix) then
    961970            SmartUpdateContent;
    962       end
    963   end
     971      end;
     972  end;
    964973end;
    965974
     
    990999            swap := code[0, i];
    9911000            code[0, i] := code[0, j];
    992             code[0, j] := swap
     1001            code[0, j] := swap;
    9931002          end;
    9941003  end;
     
    10051014          swap := code[0, i];
    10061015          code[0, i] := code[0, j];
    1007           code[0, j] := swap
     1016          code[0, j] := swap;
    10081017        end;
    10091018  end;
     
    10461055      if (AdvPreq[i, 1] >= 0) then
    10471056        MarkPreqs(AdvPreq[i, 1]);
    1048     end
     1057    end;
    10491058  end;
    10501059
     
    10591068  begin
    10601069    Lines[i] := 0;
    1061     FirstShrinkedLine[i] := MaxInt
     1070    FirstShrinkedLine[i] := MaxInt;
    10621071  end;
    10631072  case Kind of
     
    10671076        code[0, 0] := cpImp + imTrGoods;
    10681077        Lines[0] := 1;
    1069         for i := 28 to nImp - 1 do
     1078        for i := nWonder to nImp - 1 do
    10701079          if Imp[i].Kind = ikCommon then
    10711080            TryAddImpLine(0, i + cpImp);
    1072         for i := 28 to nImp - 1 do
     1081        for i := nWonder to nImp - 1 do
    10731082          if not(Imp[i].Kind in [ikCommon, ikTrGoods]) and
    10741083            ((MyRO.NatBuilt[i] = 0) or (Imp[i].Kind = ikNatLocal)) then
     
    10821091
    10831092        // wonders
    1084         for i := 0 to 27 do
     1093        for i := 0 to nWonder - 1 do
    10851094          TryAddImpLine(1, i + cpImp);
    10861095
     
    11021111                    (MyMap[Loc1] and fCanal > 0)) then
    11031112                    ok := true;
    1104                 end
     1113                end;
    11051114          end
    11061115          else
     
    11111120            begin
    11121121              code[2, Lines[2]] := i;
    1113               inc(Lines[2])
     1122              inc(Lines[2]);
    11141123            end;
    11151124            if MyModel[i].Status and msAllowConscripts <> 0 then
    11161125            begin
    11171126              code[2, Lines[2]] := i + cpConscripts;
    1118               inc(Lines[2])
     1127              inc(Lines[2]);
    11191128            end;
    11201129          end;
     
    11521161        begin
    11531162          code[0, Lines[0]] := adMilitary;
    1154           inc(Lines[0])
     1163          inc(Lines[0]);
    11551164        end;
    11561165      end;
     
    12691278            begin
    12701279              code[0, Lines[0]] := i;
    1271               inc(Lines[0])
     1280              inc(Lines[0]);
    12721281            end;
    12731282        SortCities;
     
    12811290          begin
    12821291            code[0, Lines[0]] := i;
    1283             inc(Lines[0])
     1292            inc(Lines[0]);
    12841293          end;
    12851294        SortCities;
    1286         FirstShrinkedLine[0] := 0
     1295        FirstShrinkedLine[0] := 0;
    12871296      end;
    12881297    { kChooseECity:
     
    13041313        Lines[0] := MyRO.nModel;
    13051314        SortModels;
    1306         FirstShrinkedLine[0] := 0
     1315        FirstShrinkedLine[0] := 0;
    13071316      end;
    13081317    kChooseModel:
     
    13281337        begin
    13291338          code[0, Lines[0]] := mixAll;
    1330           inc(Lines[0]);
    1331         end;
    1332         FirstShrinkedLine[0] := 0
     1339          inc(Lines[0]);;
     1340        end;
     1341        FirstShrinkedLine[0] := 0;
    13331342      end;
    13341343    kChooseEModel:
     
    13481357          if ModelOk[emix] then
    13491358          begin
    1350             if Tribe[DipMem[me].pContact].ModelPicture
    1351               [MyRO.EnemyModel[emix].mix].HGr = 0 then
     1359            if not Assigned(Tribe[DipMem[me].pContact].ModelPicture
     1360              [MyRO.EnemyModel[emix].mix].HGr) then
    13521361              InitEnemyModel(emix);
    13531362            code[0, Lines[0]] := emix;
     
    13611370          inc(Lines[0]);
    13621371        end;
    1363         FirstShrinkedLine[0] := 0
     1372        FirstShrinkedLine[0] := 0;
    13641373      end;
    13651374    kEModels:
     
    13721381            (MyRO.EnemyModel[code[1, Lines[0]]].mix = i)) do
    13731382            dec(code[1, Lines[0]]);
    1374           if Tribe[pView].ModelPicture[i].HGr = 0 then
     1383          if not Assigned(Tribe[pView].ModelPicture[i].HGr) then
    13751384            InitEnemyModel(code[1, Lines[0]]);
    13761385          code[0, Lines[0]] := i;
     
    13801389        end;
    13811390        SortModels;
    1382         FirstShrinkedLine[0] := 0
     1391        FirstShrinkedLine[0] := 0;
    13831392      end;
    13841393    kAllEModels:
     
    13931402            PPicture := @Tribe[MyRO.EnemyModel[emix].Owner].ModelPicture
    13941403              [MyRO.EnemyModel[emix].mix];
    1395             if PPicture.HGr = 0 then
     1404            if not Assigned(PPicture.HGr) then
    13961405              InitEnemyModel(emix);
    13971406            ok := true;
     
    14081417                  code[1, j] := 1;
    14091418                  ok := false;
    1410                   Break
     1419                  Break;
    14111420                end;
    14121421              end;
     
    14171426              code[2, Lines[0]] := ModelSortValue(MyRO.EnemyModel[emix], true);
    14181427              inc(Lines[0]);
    1419             end
     1428            end;
    14201429          end;
    14211430        SortModels;
     
    14261435      begin
    14271436        code[0, Lines[0]] := i;
    1428         inc(Lines[0])
     1437        inc(Lines[0]);
    14291438      end;
    14301439    (* kDeliver:
     
    14711480        begin
    14721481          code[0, Lines[0]] := i;
    1473           inc(Lines[0])
     1482          inc(Lines[0]);
    14741483        end;
    14751484    kMission:
     
    14771486      begin
    14781487        code[0, Lines[0]] := i;
    1479         inc(Lines[0])
     1488        inc(Lines[0]);
    14801489      end;
    14811490  end;
     
    15881597          TechNameSpace := TechNameSpace + 640 - InnerWidth - 2 * SideFrame;
    15891598          InnerWidth := 640 - 2 * SideFrame
    1590         end
     1599        end;
    15911600      end;
    15921601    kAdvance, kFarAdvance:
     
    16971706  begin
    16981707    ToggleBtn.ButtonIndex := 13;
    1699     ToggleBtn.Hint := Phrases.Lookup('FARTECH')
     1708    ToggleBtn.Hint := Phrases.Lookup('FARTECH');
    17001709  end
    17011710  else if Kind = kCities then
    17021711  begin
    17031712    ToggleBtn.ButtonIndex := 15;
    1704     ToggleBtn.Hint := Phrases.Lookup('BTN_PAGE')
     1713    ToggleBtn.Hint := Phrases.Lookup('BTN_PAGE');
    17051714  end
    17061715  else
    17071716  begin
    17081717    ToggleBtn.ButtonIndex := 28;
    1709     ToggleBtn.Hint := Phrases.Lookup('BTN_SELECT')
     1718    ToggleBtn.Hint := Phrases.Lookup('BTN_SELECT');
    17101719  end;
    17111720
     
    17421751    ShowNewContent(NewMode, kModels)
    17431752  else
    1744     ShowNewContent(NewMode, kEModels)
     1753    ShowNewContent(NewMode, kEModels);
    17451754end;
    17461755
     
    17581767  sb.Init(Lines[Layer] - 1, DispLines);
    17591768  OffscreenPaint;
    1760   Invalidate
     1769  Invalidate;
    17611770end;
    17621771
     
    17701779  Sel := -2;
    17711780  sb.Init(Lines[Layer] - 1, DispLines);
    1772   SmartUpdateContent
     1781  SmartUpdateContent;
    17731782end;
    17741783
     
    17831792        result := adFar;
    17841793        Closable := true;
    1785         Close
     1794        Close;
    17861795      end;
    17871796    kCities, kCityEvents:
     
    18231832        Popup.Popup(Left + ToggleBtn.Left, Top + ToggleBtn.Top +
    18241833          ToggleBtn.Height);
    1825       end
    1826   end
     1834      end;
     1835  end;
    18271836end;
    18281837
     
    18371846  // prevent closing
    18381847  else
    1839     inherited
     1848    inherited;
    18401849end;
    18411850
     
    18431852begin
    18441853  if Visible and (Kind = kCities) then
    1845     SmartUpdateContent
     1854    SmartUpdateContent;
    18461855end;
    18471856
  • branches/highdpi/LocalPlayer/TechTree.pas

    r303 r349  
    131131  NewWidth: Integer;
    132132  NewHeight: Integer;
    133 const
    134   TransparentColor: Cardinal = $7F007F;
    135133begin
    136134  if Image = nil then begin
     
    156154            TextOut(xStart + X * xPitch + 2, yStart + Y * yPitch, s);
    157155            Pixels[xStart + X * xPitch + 10, yStart + Y * yPitch - 1]
    158               := TransparentColor;
     156              := TransparentColor2;
    159157          end
    160158        end;
     
    171169    end;
    172170
    173     Texturize(Image, Paper, TransparentColor);
     171    Texturize(Image, Paper, TransparentColor2);
    174172  end;
    175173
  • branches/highdpi/LocalPlayer/Term.lfm

    r246 r349  
    11object MainScreen: TMainScreen
    2   Left = 231
     2  Left = 169
    33  Height = 480
    4   Top = 190
     4  Top = 596
    55  Width = 800
    66  HorzScrollBar.Visible = False
     
    1212  Constraints.MinHeight = 480
    1313  Constraints.MinWidth = 800
     14  DesignTimePPI = 144
    1415  Font.Color = clWindowText
    1516  Font.Height = -13
     
    3031  OnShow = FormShow
    3132  Position = poDefault
    32   PixelsPerInch = 96
     33  LCLVersion = '2.0.12.0'
    3334  Scaled = False
    34   LCLVersion = '1.6.0.4'
    3535  WindowState = wsMaximized
    3636  object UnitBtn: TButtonB
     
    217217    Interval = 50
    218218    OnTimer = Timer1Timer
    219     left = 8
    220     top = 48
     219    Left = 8
     220    Top = 48
    221221  end
    222222  object GamePopup: TDpiPopupMenu
    223223    AutoPopup = False
    224     left = 40
    225     top = 48
     224    Left = 40
     225    Top = 48
    226226    object mHelp: TDpiMenuItem
    227227      Tag = 7
     
    446446        GroupIndex = 1
    447447        object mSmallTiles: TDpiMenuItem
    448           Caption = '40px'
     448          Tag = 97
    449449          RadioItem = True
    450450          OnClick = mSmallTilesClick
    451451        end
    452452        object mNormalTiles: TDpiMenuItem
    453           Caption = '60px'
     453          Tag = 98
    454454          RadioItem = True
    455455          OnClick = mNormalTilesClick
    456456        end
    457457        object mBigTiles: TDpiMenuItem
    458           Caption = '90px'
     458          Tag = 99
    459459          RadioItem = True
    460460          OnClick = mBigTilesClick
    461         end             
     461        end
    462462      end
    463463      object mSound: TDpiMenuItem
     
    587587  object UnitPopup: TDpiPopupMenu
    588588    AutoPopup = False
    589     left = 104
    590     top = 48
     589    Left = 104
     590    Top = 48
    591591    object mdisband: TDpiMenuItem
    592592      Tag = 72
     
    670670  object StatPopup: TDpiPopupMenu
    671671    AutoPopup = False
    672     left = 72
    673     top = 48
     672    Left = 72
     673    Top = 48
    674674    object mUnitStat: TDpiMenuItem
    675675      Tag = 9
     
    726726  end
    727727  object EditPopup: TDpiPopupMenu
    728     left = 168
    729     top = 48
     728    Left = 168
     729    Top = 48
    730730    object mCreateUnit: TDpiMenuItem
    731731      Tag = 47
     
    733733  end
    734734  object TerrainPopup: TDpiPopupMenu
    735     left = 136
    736     top = 48
     735    Left = 136
     736    Top = 48
    737737    object mtrans: TDpiMenuItem
    738738      Tag = 273
  • 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
    42