Changeset 349 for branches


Ignore:
Timestamp:
Apr 6, 2021, 8:11:02 PM (4 years 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
    42754238procedure TMainScreen.PaintAll;
    42764239begin
     
    42784241  xwMini := xw;
    42794242  ywMini := yw;
    4280   MiniPaint;
     4243  MiniMapPaint;
    42814244  PanelPaint;
    42824245end;
     
    42874250  xwMini := xw;
    42884251  ywMini := yw;
    4289   MiniPaint;
     4252  MiniMapPaint;
    42904253  CopyMiniToPanel;
    42914254  RectInvalidate(xMini + 2, TopBarHeight + MapHeight - overlap + yMini + 2,
     
    42964259procedure TMainScreen.CopyMiniToPanel;
    42974260begin
    4298   DpiBitCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
    4299     Mini.Canvas, 0, 0);
    4300   if MarkCityLoc >= 0 then
    4301     Sprite(Panel, HGrSystem, xMini - 2 + (4 * G.lx + 2 * (MarkCityLoc mod G.lx)
    4302       + (G.lx - MapWidth div (xxt * 2)) - 2 * xwd) mod (2 * G.lx) +
    4303       MarkCityLoc div G.lx and 1, yMini - 3 + MarkCityLoc div G.lx, 10,
    4304       10, 77, 47)
    4305   else if ywmax <= 0 then
    4306     Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (xxt * 2), yMini + 2,
    4307       xMini + 1 + G.lx + MapWidth div (xxt * 2), yMini + 2 + G.ly - 1,
    4308       MainTexture.clMark, MainTexture.clMark)
    4309   else
    4310     Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (xxt * 2),
    4311       yMini + 2 + yw, xMini + 1 + G.lx + MapWidth div (xxt * 2),
    4312       yMini + yw + MapHeight div yyt, MainTexture.clMark, MainTexture.clMark);
     4261  with MainMap do begin
     4262    DpiBitCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
     4263      MiniMap.Bitmap.Canvas, 0, 0);
     4264    if MarkCityLoc >= 0 then
     4265      Sprite(Panel, HGrSystem, xMini - 2 + (4 * G.lx + 2 * (MarkCityLoc mod G.lx)
     4266        + (G.lx - MapWidth div (xxt * 2)) - 2 * xwd) mod (2 * G.lx) +
     4267        MarkCityLoc div G.lx and 1, yMini - 3 + MarkCityLoc div G.lx, CityMark2.Width,
     4268        CityMark2.Height, CityMark2.Left, CityMark2.Top)
     4269    else if ywmax <= 0 then
     4270      Frame(Panel.Canvas,
     4271        xMini + 2 + G.lx - MapWidth div (xxt * 2), yMini + 2,
     4272        xMini + 1 + G.lx + MapWidth div (xxt * 2), yMini + 2 + G.ly - 1,
     4273        MainTexture.clMark, MainTexture.clMark)
     4274    else
     4275      Frame(Panel.Canvas,
     4276        xMini + 2 + G.lx - MapWidth div (xxt * 2), yMini + 2 + yw,
     4277        xMini + 1 + G.lx + MapWidth div (xxt * 2), yMini + yw + MapHeight div yyt,
     4278        MainTexture.clMark, MainTexture.clMark);
     4279  end;
    43134280end;
    43144281
     
    43364303  Prio: boolean;
    43374304begin
     4305  if not Assigned(MyRO) then Exit;
    43384306  with Panel.Canvas do
    43394307  begin
     
    43864354          $FFFFFF, $B0B0B0);
    43874355        DpiBitCanvas(Panel.Canvas, ClientWidth - xPalace, yPalace, xSizeBig,
    4388           ySizeBig, GrExt[HGrSystem2].Data.Canvas, 70, 123);
     4356          ySizeBig, HGrSystem2.Data.Canvas, 70, 123);
    43894357      end
    43904358      else if MyRO.NatBuilt[imPalace] > 0 then
     
    44974465              end;
    44984466          end;
    4499           if xSrcBase >= 0 then
     4467          with MainMap do begin
     4468            if xSrcBase >= 0 then
     4469              Sprite(Panel, HGrTerrain, xTroop + 2 + x, yTroop + 9 - yyt, xxt * 2,
     4470                yyt * 3, 1 + xSrcBase * (xxt * 2 + 1),
     4471                1 + ySrcBase * (yyt * 3 + 1));
    45004472            Sprite(Panel, HGrTerrain, xTroop + 2 + x, yTroop + 9 - yyt, xxt * 2,
    4501               yyt * 3, 1 + xSrcBase * (xxt * 2 + 1),
    4502               1 + ySrcBase * (yyt * 3 + 1));
    4503           Sprite(Panel, HGrTerrain, xTroop + 2 + x, yTroop + 9 - yyt, xxt * 2,
    4504             yyt * 3, 1 + xSrc * (xxt * 2 + 1), 1 + ySrc * (yyt * 3 + 1));
    4505           if BrushTypes[i] = BrushType then
    4506           begin
    4507             ScreenTools.Frame(Panel.Canvas, xTroop + 2 + x,
    4508               yTroop + 7 - yyt div 2, xTroop + 2 * xxt + x,
    4509               yTroop + 2 * yyt + 11, $000000, $000000);
    4510             ScreenTools.Frame(Panel.Canvas, xTroop + 1 + x,
    4511               yTroop + 6 - yyt div 2, xTroop + 2 * xxt - 1 + x,
    4512               yTroop + 2 * yyt + 10, MainTexture.clMark, MainTexture.clMark);
    4513           end
     4473              yyt * 3, 1 + xSrc * (xxt * 2 + 1), 1 + ySrc * (yyt * 3 + 1));
     4474            if BrushTypes[i] = BrushType then begin
     4475              ScreenTools.Frame(Panel.Canvas, xTroop + 2 + x,
     4476                yTroop + 7 - yyt div 2, xTroop + 2 * xxt + x,
     4477                yTroop + 2 * yyt + 11, $000000, $000000);
     4478              ScreenTools.Frame(Panel.Canvas, xTroop + 1 + x,
     4479                yTroop + 6 - yyt div 2, xTroop + 2 * xxt - 1 + x,
     4480                yTroop + 2 * yyt + 10, MainTexture.clMark, MainTexture.clMark);
     4481            end;
     4482          end;
    45144483        end;
    45154484        inc(Count)
     
    45714540      Brush.Style := bsClear;
    45724541      if UnFocus >= 0 then
    4573         with MyUn[UnFocus], MyModel[mix] do
     4542        with MyUn[UnFocus] do
     4543        with MyModel[mix] do
    45744544        begin { display info about selected unit }
    45754545          if Job = jCity then
     
    46004570            BiColorTextWidth(Panel.Canvas, s) div 2, PanelHeight - 23, s);
    46014571
    4602           FrameImage(Panel.Canvas, GrExt[HGrSystem].Data,
     4572          FrameImage(Panel.Canvas, HGrSystem.Data,
    46034573            xMidPanel + 7 + xUnitText, yTroop + 15, 12, 14,
    46044574            121 + Exp div ExpCost * 13, 28);
     
    46764646                          xTroop + 63 + x, yTroop + 46, 8, MainTexture.clMark);
    46774647                      end;
    4678                       NoMap.SetOutput(Panel);
    4679                       NoMap.PaintUnit(xTroop + 2 + x, yTroop + 1, UnitInfo,
     4648                      NoMapPanel.SetOutput(Panel);
     4649                      NoMapPanel.PaintUnit(xTroop + 2 + x, yTroop + 1, UnitInfo,
    46804650                        unx.Status);
    46814651                      if (ClientMode < scContact) and
     
    46944664                          xTroop + x + 34 - BiColorTextWidth(Panel.Canvas, s)
    46954665                          div 2, yTroop - 16, s);
    4696                       end
     4666                      end;
    46974667                    end;
    46984668                    inc(Count)
     
    47004670                end; // for uix:=0 to MyRO.nUn-1
    47014671            assert(Count = TrCnt);
    4702           end
     4672          end;
    47034673        end
    47044674        else
     
    47124682              trix[i - TrRow * sb.Position] := i;
    47134683              x := (i - TrRow * sb.Position) * TrPitch;
    4714               NoMap.SetOutput(Panel);
    4715               NoMap.PaintUnit(xTroop + 2 + x, yTroop + 1,
     4684              NoMapPanel.SetOutput(Panel);
     4685              NoMapPanel.PaintUnit(xTroop + 2 + x, yTroop + 1,
    47164686                MyRO.EnemyUn[MyRO.nEnemyUn + i], 0);
    47174687            end;
     
    47204690      if not SmallScreen or supervising then
    47214691      begin // show terrain and improvements
    4722         PaintZoomedTile(Panel, xTerrain - xxt * 2, 110 - yyt * 3, TroopLoc);
    4723         if (UnFocus >= 0) and (MyUn[UnFocus].Job <> jNone) then
    4724         begin
     4692        with NoMapPanel do
     4693          PaintZoomedTile(Panel, xTerrain - xxt * 2, 110 - yyt * 3, TroopLoc);
     4694        if (UnFocus >= 0) and (MyUn[UnFocus].Job <> jNone) then begin
    47254695          JobFocus := MyUn[UnFocus].Job;
    47264696          Server(sGetJobProgress, me, MyUn[UnFocus].Loc, JobProgressData);
     
    47704740            (PanelHeight - 1), Left + width, Top + height - self.ClientHeight +
    47714741            PanelHeight, MainTexture.clBevelShade, MainTexture.clBevelLight)
    4772     end { if TroopLoc>=0 }
     4742    end; { if TroopLoc>=0 }
    47734743  end;
    47744744
     
    48004770            (PanelHeight - 1), Left + width, Top + height - self.ClientHeight +
    48014771            PanelHeight, MainTexture.clBevelShade, MainTexture.clBevelLight);
    4802         end
     4772        end;
    48034773  end;
    48044774  EOT.SetBack(Panel.Canvas, EOT.Left, EOT.Top - (ClientHeight - PanelHeight));
     
    48284798  end;
    48294799  if GameMode <> cMovie then
    4830     ImageOp_BCC(TopBar, Templates, 2, 1, 145, 38, 36, 36, $BFBF20, $4040DF);
     4800    ImageOp_BCC(TopBar, Templates.Data, Point(2, 1), MenuLogo.BoundsRect, $BFBF20, $4040DF);
    48314801  if MyRO.nCity > 0 then
    48324802  begin
     
    48444814
    48454815    // treasury section
    4846     ImageOp_BCC(TopBar, Templates, xTreasurySection + 8, 1, 145, 1, 36, 36,
     4816    ImageOp_BCC(TopBar, Templates.Data, Point(xTreasurySection + 8, 1), TreasuryIcon.BoundsRect,
    48474817      $40A040, $4030C0);
    48484818    s := IntToStr(TrueMoney);
     
    48514821    if MyRO.Government <> gAnarchy then
    48524822    begin
    4853       ImageOp_BCC(TopBar, Templates, xTreasurySection + 48, 22, 124, 1, 14, 14,
     4823      ImageOp_BCC(TopBar, Templates.Data, Point(xTreasurySection + 48, 22), ChangeIcon.BoundsRect,
    48544824        $0000C0, $0080C0);
    48554825      if TaxSum >= 0 then
     
    48624832
    48634833    // research section
    4864     ImageOp_BCC(TopBar, Templates, xResearchSection + 8, 1, 145, 75, 36, 36,
     4834    ImageOp_BCC(TopBar, Templates.Data, Point(xResearchSection + 8, 1), ResearchIcon.BoundsRect,
    48654835      $FF0000, $00FFE0);
    48664836    if MyData.FarTech <> adNexus then
     
    49134883    if (MyData.FarTech <> adNexus) and (ScienceSum > 0) then
    49144884    begin
    4915       ImageOp_BCC(TopBar, Templates, xResearchSection + 48 + CostFactor + 11,
    4916         22, 124, 1, 14, 14, $0000C0, $0080C0);
     4885      ImageOp_BCC(TopBar, Templates.Data, Point(xResearchSection + 48 + CostFactor + 11,
     4886        22), ChangeIcon.BoundsRect, $0000C0, $0080C0);
    49174887      s := Format(Phrases.Lookup('TECHGAIN'), [ScienceSum]);
    49184888      LoweredTextOut(TopBar.Canvas, -1, MainTexture, xResearchSection + 48 +
    49194889        CostFactor + 26, 18, s);
    4920     end
     4890    end;
    49214891  end;
    49224892  if ClientMode <> cEditMap then
     
    49304900  end;
    49314901  RectInvalidate(0, 0, ClientWidth, TopBarHeight);
    4932 end; { PanelPaint }
     4902end;
    49334903
    49344904procedure TMainScreen.FocusOnLoc(Loc: integer; Options: integer = 0);
     
    49374907  Outside, Changed: boolean;
    49384908begin
    4939   dx := G.lx + 1 - (xw - Loc + G.lx * 1024 + 1) mod G.lx;
    4940   Outside := (dx >= (MapWidth + 1) div (xxt * 2) - 2) or (ywmax > 0) and
    4941     ((yw > 0) and (Loc div G.lx <= yw + 1) or (yw < ywmax) and
    4942     (Loc div G.lx >= yw + (MapHeight - 1) div yyt - 2));
     4909  with MainMap do begin
     4910    dx := G.lx + 1 - (xw - Loc + G.lx * 1024 + 1) mod G.lx;
     4911    Outside := (dx >= (MapWidth + 1) div (xxt * 2) - 2) or (ywmax > 0) and
     4912      ((yw > 0) and (Loc div G.lx <= yw + 1) or (yw < ywmax) and
     4913      (Loc div G.lx >= yw + (MapHeight - 1) div yyt - 2));
     4914  end;
    49434915  Changed := true;
    4944   if Outside then
    4945   begin
     4916  if Outside then begin
    49464917    Centre(Loc);
    4947     PaintAllMaps
     4918    PaintAllMaps;
    49484919  end
    49494920  else if not MapValid then
     
    49804951        begin
    49814952          NewFocus := uix;
    4982           Break
     4953          Break;
    49834954        end
    49844955        else
     
    49884959          begin
    49894960            NewFocus := uix;
    4990             Dist := TestDist
    4991           end
    4992         end
     4961            Dist := TestDist;
     4962          end;
     4963        end;
    49934964    end;
    49944965    if GotoOnly then
     
    50204991    PanelPaint;
    50214992  end;
    5022 end; { NextUnit }
     4993end;
    50234994
    50244995procedure TMainScreen.Scroll(dx, dy: integer);
     
    50365007  xwMini := xw;
    50375008  ywMini := yw;
    5038   MiniPaint;
     5009  MiniMapPaint;
    50395010  CopyMiniToPanel;
    50405011  RectInvalidate(xMini + 2, TopBarHeight + MapHeight - overlap + yMini + 2,
     
    50465017procedure TMainScreen.Timer1Timer(Sender: TObject);
    50475018var
    5048   dx, dy, speed: integer;
     5019  dx, dy, ScrollSpeed: integer;
    50495020begin
    50505021  if idle and (me >= 0) and (GameMode <> cMovie) then
     
    50605031          PaintLocTemp(MyUn[UnFocus].Loc)
    50615032        else if TurnComplete and not supervising then
    5062           EOT.SetButtonIndexFast(eotBlinkOn)
    5063       end
     5033          EOT.SetButtonIndexFast(eotBlinkOn);
     5034      end;
    50645035    end
    50655036    else
     
    50675038      if DpiApplication.Active and not mScrollOff.Checked then
    50685039      begin
    5069         if mScrollFast.Checked then
    5070           speed := 2
    5071         else
    5072           speed := 1;
     5040        if mScrollFast.Checked then ScrollSpeed := 2
     5041          else ScrollSpeed := 1;
    50735042        dx := 0;
    50745043        dy := 0;
    50755044        if DpiMouse.CursorPos.y < DpiScreen.height - PanelHeight then
    50765045          if DpiMouse.CursorPos.x = 0 then
    5077             dx := -speed // scroll left
    5078           else if DpiMouse.CursorPos.x >= DpiScreen.width - 1 then
    5079             dx := speed; // scroll right
     5046            dx := -ScrollSpeed // scroll left
     5047          else if DpiMouse.CursorPos.x = DpiScreen.width - 1 then
     5048            dx := ScrollSpeed; // scroll right
    50805049        if DpiMouse.CursorPos.y = 0 then
    5081           dy := -speed // scroll up
    5082         else if (DpiMouse.CursorPos.y >= DpiScreen.height - 1) and
     5050          dy := -ScrollSpeed // scroll up
     5051        else if (DpiMouse.CursorPos.y = DpiScreen.height - 1) and
    50835052          (DpiMouse.CursorPos.x >= TerrainBtn.Left + TerrainBtn.width) and
    50845053          (DpiMouse.CursorPos.x < xRightPanel + 10 - 8) then
    5085           dy := speed; // scroll down
     5054          dy := ScrollSpeed; // scroll down
    50865055        if (dx <> 0) or (dy <> 0) then
    50875056        begin
     
    50905059            DpiScreen.ActiveForm.OnDeactivate(nil);
    50915060          Scroll(dx, dy);
    5092         end
     5061        end;
    50935062      end;
    50945063
     
    51045073          // if MoveHintToLoc>=0 then
    51055074          // ShowMoveHint(MoveHintToLoc, true);
    5106         end
     5075        end;
    51075076      end
    51085077      else if TurnComplete and not supervising then
     
    51115080          EOT.SetButtonIndexFast(eotBlinkOff)
    51125081        else if BlinkTime = BlinkOffTime then
    5113           EOT.SetButtonIndexFast(eotBlinkOn)
    5114       end
    5115     end
     5082          EOT.SetButtonIndexFast(eotBlinkOn);
     5083      end;
     5084    end;
     5085end;
     5086
     5087procedure TMainScreen.SetMapPos(Loc: integer; MapPos: TPoint);
     5088begin
     5089  with MainMap do begin
     5090    if FastScrolling and MapValid then
     5091      Update;
     5092    // necessary because ScrollDC for form canvas is called after
     5093    xw := (Loc mod G.lx) - (MapPos.X - ((xxt * 2) * ((Loc div G.lx) and 1)) div 2)
     5094      div (xxt * 2);
     5095    xw := (xw + G.lx) mod G.lx;
     5096    if ywmax <= 0 then yw := ywcenter
     5097    else begin
     5098      yw := (Loc div G.lx - (MapPos.Y * 2) div (yyt * 2) + 1) and not 1;
     5099      if yw < 0 then yw := 0
     5100        else if yw > ywmax then yw := ywmax;
     5101    end;
     5102  end;
    51165103end;
    51175104
    51185105procedure TMainScreen.Centre(Loc: integer);
    51195106begin
    5120   if FastScrolling and MapValid then
    5121     Update;
    5122   // necessary because ScrollDC for form canvas is called after
    5123   xw := (Loc mod G.lx - (MapWidth - xxt * 2 * ((Loc div G.lx) and 1))
    5124     div (xxt * 4) + G.lx) mod G.lx;
    5125   if ywmax <= 0 then
    5126     yw := ywcenter
    5127   else
    5128   begin
    5129     yw := (Loc div G.lx - MapHeight div (yyt * 2) + 1) and not 1;
    5130     if yw < 0 then
    5131       yw := 0
    5132     else if yw > ywmax then
    5133       yw := ywmax;
    5134   end
     5107  SetMapPos(Loc, Point(MapWidth div 2, MapHeight div 2));
    51355108end;
    51365109
     
    51625135      PanelPaint;
    51635136      ShowNewContent(wmPersistent, Loc, ShowEvent);
    5164     end
    5165 end;
    5166 
    5167 function TMainScreen.LocationOfScreenPixel(x, y: integer): integer;
     5137    end;
     5138end;
     5139
     5140function TMainScreen.LocationOfScreenPixel(x, y: integer): Integer;
    51685141var
    51695142  qx, qy: integer;
    51705143begin
    5171   qx := (x * (yyt * 2) + y * (xxt * 2) + xxt * yyt * 2) div (xxt * yyt * 4) - 1;
    5172   qy := (y * (xxt * 2) - x * (yyt * 2) - xxt * yyt * 2 + 4000 * xxt * yyt)
    5173     div (xxt * yyt * 4) - 999;
    5174   result := (xw + (qx - qy + 2048) div 2 - 1024 + G.lx) mod G.lx + G.lx *
    5175     (yw + qx + qy);
     5144  with MainMap do begin
     5145    qx := (x * (yyt * 2) + y * (xxt * 2) + xxt * yyt * 2) div (xxt * yyt * 4) - 1;
     5146    qy := (y * (xxt * 2) - x * (yyt * 2) - xxt * yyt * 2 + 4000 * xxt * yyt)
     5147      div (xxt * yyt * 4) - 999;
     5148    Result := (xw + (qx - qy + 2048) div 2 - 1024 + G.lx) mod G.lx + G.lx *
     5149      (yw + qx + qy);
     5150  end;
     5151end;
     5152
     5153function TMainScreen.GetCenterLoc: Integer;
     5154begin
     5155  Result := (xw + MapWidth div (MainMap.xxt * 4)) mod G.lx +
     5156    (yw + MapHeight div (MainMap.yyt * 2)) * G.lx;
    51765157end;
    51775158
     
    52425223      BrushLoc := MouseLoc;
    52435224      PaintLoc(MouseLoc, 2);
    5244       MiniPaint;
     5225      MiniMapPaint;
    52455226      DpiBitCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
    5246         Mini.Canvas, 0, 0);
    5247       if ywmax <= 0 then
    5248         Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
    5249           yMini + 2, xMini + 1 + G.lx + MapWidth div (2 * xxt),
    5250           yMini + 2 + G.ly - 1, MainTexture.clMark, MainTexture.clMark)
    5251       else
    5252         Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
    5253           yMini + 2 + yw, xMini + 2 + G.lx + MapWidth div (2 * xxt) - 1,
    5254           yMini + 2 + yw + MapHeight div yyt - 2, MainTexture.clMark,
    5255           MainTexture.clMark);
     5227        MiniMap.Bitmap.Canvas, 0, 0);
     5228      with MainMap do begin
     5229        if ywmax <= 0 then
     5230          Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
     5231            yMini + 2, xMini + 1 + G.lx + MapWidth div (2 * xxt),
     5232            yMini + 2 + G.ly - 1, MainTexture.clMark, MainTexture.clMark)
     5233        else
     5234          Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
     5235            yMini + 2 + yw, xMini + 2 + G.lx + MapWidth div (2 * xxt) - 1,
     5236            yMini + 2 + yw + MapHeight div yyt - 2, MainTexture.clMark,
     5237            MainTexture.clMark);
     5238      end;
    52565239      RectInvalidate(xMini + 2, TopBarHeight + MapHeight - overlap + yMini + 2,
    52575240        xMini + 2 + G.lx * 2, TopBarHeight + MapHeight - overlap + yMini
    5258         + 2 + G.ly)
     5241        + 2 + G.ly);
    52595242    end
    52605243    else if MyMap[MouseLoc] and fCity <> 0 then { city clicked }
     
    52695252        UnitStatDlg.ShowNewContent_EnemyCity(wmPersistent, MouseLoc);
    52705253        DoCenter := false;
    5271       end
     5254      end;
    52725255    end
    52735256    else if MyMap[MouseLoc] and fUnit <> 0 then { unit clicked }
     
    52915274            end;
    52925275            if i = 0 then
    5293               uix := UnFocus
     5276              uix := UnFocus;
    52945277          end
    52955278          else
     
    53175300    begin
    53185301      Centre(MouseLoc);
    5319       PaintAllMaps
    5320     end
     5302      PaintAllMaps;
     5303    end;
    53215304  end
    53225305  else if (ClientMode <> cEditMap) and (Button = mbRight) and
     
    53385321              MyRO.EnemyModel[emix].mix, MouseLoc) >= rExecuted) then
    53395322            begin
    5340               if Tribe[p1].ModelPicture[MyRO.EnemyModel[emix].mix].HGr = 0 then
     5323              if not Assigned(Tribe[p1].ModelPicture[MyRO.EnemyModel[emix].mix].HGr) then
    53415324                InitEnemyModel(emix);
    53425325              m2 := TDpiMenuItem.Create(m);
     
    53685351          Status := Status and ($FFFF - usStay - usRecover - usGoto - usEnhance)
    53695352            or usWaiting;
    5370           MoveUnit(dx, dy, muAutoNext) { simple move }
     5353          MoveUnit(dx, dy, muAutoNext); { simple move }
    53715354        end
    53725355        else if GetMoveAdvice(UnFocus, MouseLoc, MoveAdviceData) >= rExecuted
     
    53935376              if BattleDlg.ModalResult <> mrOK then
    53945377                exit;
    5395             end
     5378            end;
    53965379          end;
    53975380          DestinationMarkON := false;
     
    54005383            usWaiting;
    54015384          MoveToLoc(MouseLoc, false); { goto }
    5402         end
    5403       end
     5385        end;
     5386      end;
    54045387  end
    54055388  else if (Button = mbMiddle) and (UnFocus >= 0) and
     
    54145397      MoveToLoc(MouseLoc, true); { goto }
    54155398    if (UnFocus = uix) and (MyUn[uix].Loc = MouseLoc) then
    5416       MenuClick(mEnhance)
     5399      MenuClick(mEnhance);
    54175400  end
    54185401  else if (Button = mbLeft) and (ssShift in Shift) and
     
    54495432      BattleDlg.IsSuicideQuery := false;
    54505433      BattleDlg.Show;
    5451     end
    5452   end
     5434    end;
     5435  end;
    54535436end;
    54545437
     
    58915874    if CityCaptured and (MyMap[ToLoc] and fCity = 0) then
    58925875    begin // city destroyed
    5893       for i := 0 to 27 do { tell about destroyed wonders }
    5894         if (MyRO.Wonder[i].CityID = -2) and (MyData.ToldWonders[i].CityID <> -2)
     5876      for i := 0 to nWonder - 1 do { tell about destroyed wonders }
     5877        if (MyRO.Wonder[i].CityID = WonderDestroyed) and (MyData.ToldWonders[i].CityID <> WonderDestroyed)
    58955878        then
    58965879          with MessgExDlg do
     
    59135896    begin // city captured
    59145897      ListDlg.AddCity;
    5915       for i := 0 to 27 do { tell about capture of wonders }
     5898      for i := 0 to nWonder - 1 do { tell about capture of wonders }
    59165899        if MyRO.City[MyRO.nCity - 1].Built[i] > 0 then
    59175900          with MessgExDlg do
     
    60306013    xw1 := xw + G.lx;
    60316014    // ((xFromLoc-xw1)*2+yFromLoc and 1+1)*xxt+dx*xxt/2-MapWidth/2 -> min
    6032     while abs(((xFromLoc - xw1 + G.lx) * 2 + yFromLoc and 1 + 1) * xxt * 2 + dx
    6033       * xxt - MapWidth) < abs(((xFromLoc - xw1) * 2 + yFromLoc and 1 + 1) * xxt
    6034       * 2 + dx * xxt - MapWidth) do
    6035       dec(xw1, G.lx);
    6036 
    6037     xTo := (xToLoc - xw1) * (xxt * 2) + yToLoc and 1 * xxt + (xxt - xxu);
    6038     yTo := (yToLoc - yw) * yyt + (yyt - yyu_anchor);
    6039     xFrom := (xFromLoc - xw1) * (xxt * 2) + yFromLoc and 1 * xxt + (xxt - xxu);
    6040     yFrom := (yFromLoc - yw) * yyt + (yyt - yyu_anchor);
    6041     if xFrom < xTo then
    6042     begin
    6043       xMin := xFrom;
    6044       xRange := xTo - xFrom
    6045     end
    6046     else
    6047     begin
    6048       xMin := xTo;
    6049       xRange := xFrom - xTo
    6050     end;
    6051     if yFrom < yTo then
    6052     begin
    6053       yMin := yFrom;
    6054       yRange := yTo - yFrom
    6055     end
    6056     else
    6057     begin
    6058       yMin := yTo;
    6059       yRange := yFrom - yTo
    6060     end;
    6061     inc(xRange, xxt * 2);
    6062     inc(yRange, yyt * 3);
     6015    with MainMap do begin
     6016      while abs(((xFromLoc - xw1 + G.lx) * 2 + yFromLoc and 1 + 1) * xxt * 2 + dx
     6017        * xxt - MapWidth) < abs(((xFromLoc - xw1) * 2 + yFromLoc and 1 + 1) * xxt
     6018        * 2 + dx * xxt - MapWidth) do
     6019        dec(xw1, G.lx);
     6020
     6021      xTo := (xToLoc - xw1) * (xxt * 2) + yToLoc and 1 * xxt + (xxt - xxu);
     6022      yTo := (yToLoc - yw) * yyt + (yyt - yyu_anchor);
     6023      xFrom := (xFromLoc - xw1) * (xxt * 2) + yFromLoc and 1 * xxt + (xxt - xxu);
     6024      yFrom := (yFromLoc - yw) * yyt + (yyt - yyu_anchor);
     6025      if xFrom < xTo then begin
     6026        xMin := xFrom;
     6027        xRange := xTo - xFrom
     6028      end else begin
     6029        xMin := xTo;
     6030        xRange := xFrom - xTo
     6031      end;
     6032      if yFrom < yTo then begin
     6033        yMin := yFrom;
     6034        yRange := yTo - yFrom
     6035      end else begin
     6036        yMin := yTo;
     6037        yRange := yFrom - yTo
     6038      end;
     6039      inc(xRange, xxt * 2);
     6040      inc(yRange, yyt * 3);
     6041    end;
    60636042
    60646043    MainOffscreenPaint;
     
    61626141      begin
    61636142        assert(false);
    6164         Break
     6143        Break;
    61656144      end;
    61666145    until false;
     
    61886167          NextUnit(UnStartLoc, true)
    61896168        end;
    6190       end
    6191     end
    6192   end
     6169      end;
     6170    end;
     6171  end;
    61936172end;
    61946173
     
    62076186      if ssShift in Shift then
    62086187      begin
    6209         xMouse := (xwMini + (x - (xMini + 2) + MapWidth div (xxt * 2) + G.lx)
    6210           div 2) mod G.lx;
     6188        with MainMap do
     6189          xMouse := (xwMini + (x - (xMini + 2) + MapWidth div (xxt * 2) + G.lx)
     6190            div 2) mod G.lx;
    62116191        MouseLoc := xMouse + G.lx * (y - (yMini + 2));
    62126192        if MyMap[MouseLoc] and fTerrain <> fUNKNOWN then
     
    62156195          if (p1 = me) or (p1 >= 0) and (MyRO.Treaty[p1] >= trNone) then
    62166196            NatStatDlg.ShowNewContent(wmPersistent, p1);
    6217         end
     6197        end;
    62186198      end
    62196199      else
     
    63106290              CheckTerrainBtnVisible;
    63116291              PanelPaint;
    6312             end
     6292            end;
    63136293          end
    63146294          else if Server(sGetUnits, me, TroopLoc, TrCnt) >= rExecuted then
     
    63196299              UnitStatDlg.ShowNewContent_EnemyUnit(wmPersistent,
    63206300                MyRO.nEnemyUn + trix[i]); // unit info
    6321     end
    6322   end
     6301    end;
     6302  end;
    63236303end;
    63246304
     
    64126392procedure TMainScreen.SetDebugMap(p: integer);
    64136393begin
    6414   IsoEngine.pDebugMap := p;
    6415   IsoEngine.Options := IsoEngine.Options and not(1 shl moLocCodes);
     6394  MainMap.pDebugMap := p;
     6395  MapOptions := MapOptions - [moLocCodes];
    64166396  mLocCodes.Checked := false;
    64176397  MapValid := false;
     
    64216401procedure TMainScreen.SetViewpoint(p: integer);
    64226402var
    6423   i: integer;
     6403  i: Integer;
    64246404begin
    64256405  if supervising and (G.RO[0].Turn > 0) and
     
    64326412    SumCities(TaxSum, ScienceSum);
    64336413    for i := 0 to MyRO.nModel - 1 do
    6434       if Tribe[me].ModelPicture[i].HGr = 0 then
    6435         InitMyModel(i, true);
     6414      if not Assigned(Tribe[me].ModelPicture[i].HGr) then
     6415        InitMyModel(i, True);
    64366416
    64376417    SetTroopLoc(-1);
    64386418    PanelPaint;
    6439     MapValid := false;
     6419    MapValid := False;
    64406420    PaintAllMaps;
    64416421  end;
     
    72227202      // check if city types already usefull:
    72237203      if MyRO.nCity > 0 then
    7224         for i := 28 to nImp - 1 do
     7204        for i := nWonder to nImp - 1 do
    72257205          if (i <> imTrGoods) and (Imp[i].Kind = ikCommon) and
    72267206            (Imp[i].Preq <> preNA) and
     
    72757255            m.ShortCut := ShortCut(48 + p1, [ssAlt]);
    72767256          m.RadioItem := true;
    7277           if m.Tag = IsoEngine.pDebugMap then
     7257          if m.Tag = MainMap.pDebugMap then
    72787258            m.Checked := true;
    72797259          mDebugMap.Add(m);
    72807260        end;
    72817261    end;
    7282     mSmallTiles.Checked := xxt = 33;
    7283     mNormalTiles.Checked := xxt = 48;
    7284     mBigTiles.Checked := xxt = 72;
     7262    mSmallTiles.Checked := MainMap.TileSize = tsSmall;
     7263    mNormalTiles.Checked := MainMap.TileSize = tsMedium;
     7264    mBigTiles.Checked := MainMap.TileSize = tsBig;
    72857265  end
    72867266  else if Popup = StatPopup then
     
    73017281    mEUnitStat.Enabled := MyRO.nEnemyModel > 0;
    73027282    { mWonders.Enabled:= false;
    7303       for i:=0 to 27 do if MyRO.Wonder[i].CityID<>-1 then
     7283      for i:=0 to nWonder - 1 do if MyRO.Wonder[i].CityID <> WonderNotBuiltYet then
    73047284      mWonders.Enabled:=true; }
    73057285    mDiagram.Enabled := MyRO.Turn >= 2;
     
    74737453        FocusOnLoc(TroopLoc, flRepaintPanel)
    74747454      else
    7475         PanelPaint
     7455        PanelPaint;
    74767456    end
    74777457    else if StepFocus then
     
    74807460    begin
    74817461      SetTroopLoc(-1);
    7482       PanelPaint
     7462      PanelPaint;
    74837463    end;
    74847464  end;
     
    74967476begin
    74977477  if Tracking and (ssLeft in Shift) then
    7498   begin
     7478  with MainMap do begin
    74997479    if (x >= xMini + 2) and (y >= yMini + 2) and (x < xMini + 2 + 2 * G.lx) and
    75007480      (y < yMini + 2 + G.ly) then
     
    75147494          yw := ywmax;
    75157495      end;
    7516       DpiBitCanvas(Buffer.Canvas, 0, 0, G.lx * 2, G.ly, Mini.Canvas, 0, 0);
     7496      DpiBitCanvas(Buffer.Canvas, 0, 0, G.lx * 2, G.ly, MiniMap.Bitmap.Canvas, 0, 0);
    75177497      if ywmax <= 0 then
    75187498        Frame(Buffer.Canvas, x - xMini - 2 - MapWidth div (xxt * 2), 0,
     
    75447524    xwMini := xw;
    75457525    ywMini := yw;
    7546     MiniPaint;
     7526    MiniMapPaint;
    75477527    PanelPaint;
    75487528  end;
     
    77377717var
    77387718  Reg: TRegistry;
    7739   DefaultOptionChecked: Integer;
    7740 begin
    7741   DefaultOptionChecked := 1 shl 1 + 1 shl 7 + 1 shl 10 + 1 shl 12 + 1 shl 14 +
    7742     1 shl 18 + 1 shl 19;
     7719  DefaultOptionChecked: TSaveOptions;
     7720begin
     7721  DefaultOptionChecked := [soEnMoves, soSlowMoves, soNames, soRepScreens,
     7722    soSoundOn, soScrollOff, soAlSlowMoves];
    77437723  Reg := TRegistry.Create;
    77447724  with Reg do try
    77457725    OpenKey(AppRegistryKey, False);
    7746     if ValueExists('TileWidth') then xxt := ReadInteger('TileWidth') div 2
    7747       else xxt := 48;
    7748     if ValueExists('TileHeight') then yyt := ReadInteger('TileHeight') div 2
    7749       else yyt := 24;
    7750     if ValueExists('OptionChecked') then OptionChecked := ReadInteger('OptionChecked')
     7726    if ValueExists('TileSize') then MainMap.TileSize := TTileSize(ReadInteger('TileSize'))
     7727      else MainMap.TileSize := tsMedium;
     7728    NoMap.TileSize := MainMap.TileSize;
     7729    if ValueExists('OptionChecked') then OptionChecked := TSaveOptions(ReadInteger('OptionChecked'))
    77517730      else OptionChecked := DefaultOptionChecked;
    7752     if ValueExists('MapOptionChecked') then MapOptionChecked := ReadInteger('MapOptionChecked')
    7753       else MapOptionChecked := 1 shl moCityNames;
     7731    if ValueExists('MapOptionChecked') then MapOptionChecked := TMapOptions(ReadInteger('MapOptionChecked'))
     7732      else MapOptionChecked := [moCityNames];
    77547733    if ValueExists('CityReport') then CityRepMask := Cardinal(ReadInteger('CityReport'))
    77557734      else CityRepMask := Cardinal(not chPopIncrease and not chNoGrowthWarning and
    77567735          not chCaptured);
    7757     if OptionChecked and (7 shl 16) = 0 then
    7758       OptionChecked := OptionChecked or (1 shl 16);
     7736    if (not (soScrollFast in OptionChecked)) and (not (soScrollSlow in OptionChecked)) and
     7737      (not (soScrollOff in OptionChecked)) then
     7738      OptionChecked := OptionChecked + [soScrollSlow];
    77597739      // old regver with no scrolling
    77607740  finally
     
    77627742  end;
    77637743
    7764   if 1 shl 13 and OptionChecked <> 0 then
     7744  if soSoundOff in OptionChecked then
    77657745    SoundMode := smOff
    7766   else if 1 shl 15 and OptionChecked <> 0 then
     7746  else if soSoundOnAlt in OptionChecked then
    77677747    SoundMode := smOnAlt
    77687748  else
     
    78257805      end
    78267806      else if Flag = tfAllTechs then
    7827         TellNewModels
     7807        TellNewModels;
    78287808    end;
    78297809  end;
     
    78347814  with TButtonC(Sender) do
    78357815  begin
    7836     MapOptionChecked := MapOptionChecked xor (1 shl (Tag shr 8));
     7816    MapOptionChecked := TMapOptions(Integer(MapOptionChecked) xor (1 shl (Tag shr 8)));
    78377817    SetMapOptions;
    7838     ButtonIndex := MapOptionChecked shr (Tag shr 8) and 1 + 2
     7818    ButtonIndex := Integer(MapOptionChecked) shr (Tag shr 8) and 1 + 2;
    78397819  end;
    78407820  if Sender = MapBtn0 then
    78417821  begin
    7842     MiniPaint;
    7843     PanelPaint
     7822    MiniMapPaint;
     7823    PanelPaint;
    78447824  end // update mini map only
    78457825  else
     
    78547834  if TButtonBase(Sender).Down then
    78557835  begin
    7856     MapOptionChecked := MapOptionChecked or (1 shl moGreatWall);
     7836    MapOptionChecked := MapOptionChecked + [moGreatWall];
    78577837    TButtonBase(Sender).Hint := '';
    78587838  end
    78597839  else
    78607840  begin
    7861     MapOptionChecked := MapOptionChecked and not(1 shl moGreatWall);
     7841    MapOptionChecked := MapOptionChecked - [moGreatWall];
    78627842    TButtonBase(Sender).Hint := Phrases.Lookup('CONTROLS',
    78637843      -1 + TButtonBase(Sender).Tag and $FF);
     
    78727852  if TButtonBase(Sender).Down then
    78737853  begin
    7874     MapOptionChecked := MapOptionChecked or (1 shl moBareTerrain);
     7854    MapOptionChecked := MapOptionChecked + [moBareTerrain];
    78757855    TButtonBase(Sender).Hint := '';
    78767856  end
    78777857  else
    78787858  begin
    7879     MapOptionChecked := MapOptionChecked and not(1 shl moBareTerrain);
     7859    MapOptionChecked := MapOptionChecked - [moBareTerrain];
    78807860    TButtonBase(Sender).Hint := Phrases.Lookup('CONTROLS',
    78817861      -1 + TButtonBase(Sender).Tag and $FF);
     
    79767956procedure TMainScreen.mSmallTilesClick(Sender: TObject);
    79777957begin
    7978   SetTileSize(33, 16);
     7958  SetTileSizeCenter(tsSmall);
    79797959end;
    79807960
    79817961procedure TMainScreen.mNormalTilesClick(Sender: TObject);
    79827962begin
    7983   SetTileSize(48, 24);
     7963  SetTileSizeCenter(tsMedium);
    79847964end;
    79857965
    79867966procedure TMainScreen.mBigTilesClick(Sender: TObject);
    79877967begin
    7988   SetTileSize(72, 36);
    7989 end;
    7990 
    7991 procedure TMainScreen.SetTileSize(x, y: integer);
     7968  SetTileSizeCenter(tsBig);
     7969end;
     7970
     7971procedure TMainScreen.SetTileSizeCenter(TileSize: TTileSize);
     7972begin
     7973  SetTileSize(TileSize, GetCenterLoc, Point(MapWidth div 2, MapHeight div 2));
     7974end;
     7975
     7976procedure TMainScreen.SetTileSize(TileSize: TTileSize; Loc: Integer; MapPos: TPoint);
    79927977var
    7993   i, CenterLoc: integer;
    7994 begin
    7995   CenterLoc := (xw + MapWidth div (xxt * 4)) mod G.lx +
    7996     (yw + MapHeight div (yyt * 2)) * G.lx;
    7997   IsoEngine.ApplyTileSize(x, y);
     7978  i: integer;
     7979begin
     7980  MainMap.TileSize := TileSize;
     7981  NoMap.TileSize := TileSize;
    79987982  FormResize(nil);
    7999   Centre(CenterLoc);
     7983  SetMapPos(Loc, MapPos);
    80007984  PaintAllMaps;
    80017985  for i := 0 to DpiScreen.FormCount - 1 do
     
    80047988end;
    80057989
     7990procedure TMainScreen.SaveMenuItemsState;
     7991var
     7992  i, j: integer;
     7993begin
     7994  if soTellAI in OptionChecked then OptionChecked := [soTellAI]
     7995    else OptionChecked := [];
     7996  for i := 0 to ComponentCount - 1 do
     7997    if Components[i] is TDpiMenuItem then
     7998      for j := 0 to Length(SaveOption) - 1 do
     7999        if TDpiMenuItem(Components[i]).Checked and
     8000          (TDpiMenuItem(Components[i]).Tag = SaveOption[j]) then
     8001          OptionChecked := OptionChecked + [TSaveOption(j)];
     8002end;
     8003
    80068004procedure TMainScreen.SaveSettings;
    80078005var
    8008   i, j: integer;
    80098006  Reg: TRegistry;
    80108007begin
    8011   OptionChecked := OptionChecked and soExtraMask;
    8012   for i := 0 to ComponentCount - 1 do
    8013     if Components[i] is TDpiMenuItem then
    8014       for j := 0 to nSaveOption - 1 do
    8015         if TDpiMenuItem(Components[i]).Checked and
    8016           (TDpiMenuItem(Components[i]).Tag = SaveOption[j]) then
    8017           inc(OptionChecked, 1 shl j);
     8008  SaveMenuItemsState;
    80188009
    80198010  Reg := TRegistry.Create;
     
    80218012  try
    80228013    OpenKey(AppRegistryKey, true);
    8023     WriteInteger('TileWidth', xxt * 2);
    8024     WriteInteger('TileHeight', yyt * 2);
    8025     WriteInteger('OptionChecked', OptionChecked);
    8026     WriteInteger('MapOptionChecked', MapOptionChecked);
     8014    WriteInteger('TileSize', Integer(MainMap.TileSize));
     8015    WriteInteger('OptionChecked', Integer(OptionChecked));
     8016    WriteInteger('MapOptionChecked', Integer(MapOptionChecked));
    80278017    WriteInteger('CityReport', integer(CityRepMask));
    80288018  finally
  • branches/highdpi/LocalPlayer/Tribes.pas

    r303 r349  
    55
    66uses
    7   Protocol, ScreenTools, LazFileUtils, Classes, Graphics, SysUtils, Global;
     7  Protocol, ScreenTools, LazFileUtils, Classes, Graphics, SysUtils, Global,
     8  UGraphicSet;
    89
    910type
     
    1415
    1516  TModelPicture = record
    16     HGr: Integer;
     17    HGr: TGraphicSet;
    1718    pix: Integer;
    1819    xShield: Integer;
     
    2930
    3031  TTribe = class
    31     symHGr: Integer;
     32    symHGr: TGraphicSet;
    3233    sympix: Integer;
    33     faceHGr: Integer;
     34    faceHGr: TGraphicSet;
    3435    facepix: Integer;
    35     cHGr: Integer;
     36    cHGr: TGraphicSet;
    3637    cpix: Integer;
    3738    // symbol and city graphics
     
    6263var
    6364  Tribe: array [0 .. nPl - 1] of TTribe;
    64   HGrStdUnits: Integer;
     65  HGrStdUnits: TGraphicSet;
    6566
    6667procedure Init;
     
    7071procedure FindStdModelPicture(Code: Integer; var pix: Integer; var Name: string);
    7172function GetTribeInfo(FileName: string; var Name: string; var Color: TColor): Boolean;
    72 procedure FindPosition(HGr, x, y, xmax, ymax: Integer; Mark: TColor;
     73procedure FindPosition(HGr: TGraphicSet; x, y, xmax, ymax: Integer; Mark: TColor;
    7374  var xp, yp: Integer);
    7475
     
    8283  TChosenModelPictureInfo = record
    8384    Hash: Integer;
    84     HGr: Integer;
     85    HGr: TGraphicSet;
    8586    pix: Integer;
    8687    ModelName: ShortString;
     
    328329end;
    329330
    330 procedure FindPosition(HGr, x, y, xmax, ymax: Integer; Mark: TColor;
     331procedure FindPosition(HGr: TGraphicSet; x, y, xmax, ymax: Integer; Mark: TColor;
    331332  var xp, yp: Integer);
    332333begin
    333334  xp := 0;
    334   while (xp < xmax) and (GrExt[HGr].Data.Canvas.Pixels[x + 1 + xp, y] <> Mark) do
     335  while (xp < xmax) and (HGr.Data.Canvas.Pixels[x + 1 + xp, y] <> Mark) do
    335336    Inc(xp);
    336337  yp := 0;
    337   while (yp < ymax) and (GrExt[HGr].Data.Canvas.Pixels[x, y + 1 + yp] <> Mark) do
     338  while (yp < ymax) and (HGr.Data.Canvas.Pixels[x, y + 1 + yp] <> Mark) do
    338339    Inc(yp);
    339340end;
     
    447448      end
    448449      else
    449         cHGr := -1;
     450        cHGr := nil;
    450451
    451452{$IFNDEF SCR}
     
    454455      Item := Get;
    455456      if Item = '' then
    456         faceHGr := -1
     457        faceHGr := nil
    457458      else
    458459      begin
    459460        faceHGr := LoadGraphicSet(Item + '.png');
    460461        facepix := GetNum;
    461         if GrExt[faceHGr].Data.Canvas.Pixels[facepix mod 10 * 65,
     462        if faceHGr.Data.Canvas.Pixels[facepix mod 10 * 65,
    462463          facepix div 10 * 49 + 48] = $00FFFF then
    463464        begin // generate shield picture
    464           GrExt[faceHGr].Data.Canvas.Pixels[facepix mod 10 * 65,
     465          faceHGr.Data.Canvas.Pixels[facepix mod 10 * 65,
    465466            facepix div 10 * 49 + 48] := $000000;
    466467          Gray := $B8B8B8;
    467           ImageOp_BCC(GrExt[faceHGr].Data, Templates,
     468          ImageOp_BCC(faceHGr.Data, Templates.Data,
    468469            facepix mod 10 * 65 + 1, facepix div 10 * 49 + 1, 1, 25, 64, 48,
    469470            Gray, Color);
     
    500501        HGr := LoadGraphicSet(GrName);
    501502        pix := Info.pix;
    502         Inc(GrExt[HGr].pixUsed[pix]);
     503        Inc(HGr.pixUsed[pix]);
    503504      end;
    504505      ModelName[mix] := '';
     
    558559  Code, Turn: Integer; ForceNew: Boolean): Boolean;
    559560var
    560   i, Cnt, HGr, Used, LeastUsed: Integer;
     561  i: Integer;
     562  Cnt: Integer;
     563  HGr: TGraphicSet;
     564  Used: Integer;
     565  LeastUsed: Integer;
    561566  TestPic: TModelPictureInfo;
    562567  ok: Boolean;
     
    567572    if Code = GetNum then
    568573    begin
    569       if ForceNew or (HGr < 0) then
     574      if ForceNew or (not Assigned(HGr)) then
    570575        Used := 0
    571576      else
    572577      begin
    573         Used := 4 * GrExt[HGr].pixUsed[TestPic.pix];
     578        Used := 4 * HGr.pixUsed[TestPic.pix];
    574579        if HGr = HGrStdUnits then
    575580          Inc(Used, 2); // prefer units not from StdUnits
     
    596601      if PictureList[i].Hash = Picture.Hash then
    597602      begin
    598         Picture.GrName := GrExt[PictureList[i].HGr].Name;
     603        Picture.GrName := PictureList[i].HGr.Name;
    599604        Picture.pix := PictureList[i].pix;
    600605        Result := False;
     
    623628      ok := True;
    624629      TestPic.GrName := Copy(Input, 8, 255) + '.png';
    625       HGr := nGrExt - 1;
    626       while (HGr >= 0) and (GrExt[HGr].Name <> TestPic.GrName) do
    627         Dec(HGr);
     630      HGr := GrExt.SearchByName(TestPic.GrName);
    628631    end
    629632    else if (Input <> '') and (Input[1] = '#') then
  • branches/highdpi/LocalPlayer/UnitStat.pas

    r303 r349  
    77  UDpiControls, Protocol, ClientTools, Term, ScreenTools, BaseWin,
    88  LCLIntf, LCLType, SysUtils, Classes, Graphics, Controls, Forms,
    9   ButtonB, ButtonC;
     9  ButtonB, ButtonC, IsoEngine;
    1010
    1111type
     
    2424    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    2525    procedure HelpBtnClick(Sender: TObject);
    26 
     26  private
     27    NoMap: TIsoMap;
    2728  public
    2829    procedure CheckAge;
     
    5152
    5253uses
    53   Tribes, IsoEngine, Help, Directories;
     54  Tribes, Help, Directories;
    5455
    5556{$R *.lfm}
     
    7374begin
    7475  inherited;
     76  NoMap := TIsoMap.Create;
    7577  AgePrepared := -2;
    7678  TitleHeight := DpiScreen.Height;
     
    9193  FreeAndNil(Template);
    9294  FreeAndNil(Back);
     95  FreeAndNil(NoMap);
    9396end;
    9497
     
    136139      begin
    137140        mox := @MyRO.EnemyModel[emix];
    138         if Tribe[owner].ModelPicture[mix].HGr = 0 then
     141        if not Assigned(Tribe[owner].ModelPicture[mix].HGr) then
    139142          InitEnemyModel(emix);
    140143      end
     
    521524    begin
    522525      if Kind in [dkOwnUnit, dkEnemyUnit, dkEnemyCityDefense] then
    523         with ui do
     526        with ui, NoMap do
    524527        begin
    525528          { Frame(offscreen.canvas,xView-1,yView-1,xView+64,yView+48,
     
    529532          with offscreen.Canvas do
    530533          begin
    531             Brush.Color := GrExt[HGrSystem].Data.Canvas.Pixels[98, 67];
     534            Brush.Color := HGrSystem.Data.Canvas.Pixels[98, 67];
    532535            offscreen.Canvas.FillRect(Rect(xView, yView, xView + 64,
    533536              yView + 16));
     
    574577            Sprite(offscreen, HGrStdUnits, xView, yView, xxu * 2, yyu * 2,
    575578              1 + 6 * (xxu * 2 + 1), 1);
    576           FrameImage(offscreen.Canvas, GrExt[HGrSystem].Data, xView - 20,
     579          FrameImage(offscreen.Canvas, HGrSystem.Data, xView - 20,
    577580            yView + 5, 12, 14, 121 + Exp div ExpCost * 13, 28);
    578581          if Health < 100 then
  • branches/highdpi/LocalPlayer/Wonders.pas

    r246 r349  
    100100  ax: Integer;
    101101  R: Integer;
    102   I: Integer;
    103102  C: Integer;
    104103  Ch: Integer;
     
    223222  PaintBackgroundShape;
    224223
    225   for I := 0 to 20 do
    226     if Imp[I].Preq <> preNA then
    227     begin
     224  // Draw all bitmaps first
     225  HaveWonder := False;
     226  for I := 0 to 20 do begin
     227    if Imp[I].Preq <> preNA then begin
    228228      case MyRO.Wonder[I].CityID of
    229         - 1: // not built yet
    230           begin
    231             Fill(Offscreen.Canvas, Center.X - xSizeBig div 2 + RingPosition[I].X - 3,
    232               Center.Y - ySizeBig div 2 + RingPosition[I].Y - 3, xSizeBig + 6,
    233               ySizeBig + 6, (wMaintexture - ClientWidth) div 2,
    234               (hMaintexture - ClientHeight) div 2);
    235             DarkIcon(I);
    236           end;
    237         -2: // destroyed
    238           begin
    239             Glow(I, $000000);
    240           end;
    241       else
    242         begin
    243           if MyRO.Wonder[I].EffectiveOwner >= 0 then
    244             Glow(I, Tribe[MyRO.Wonder[I].EffectiveOwner].Color)
    245           else
    246             Glow(I, $000000);
    247         end;
    248       end;
    249     end;
    250 
    251   HaveWonder := False;
    252   for I := 0 to 20 do
    253     if Imp[I].Preq <> preNA then
    254     begin
    255       case MyRO.Wonder[I].CityID of
    256         -1: // not built yet
    257           begin
    258             Fill(Offscreen.Canvas, Center.X - xSizeBig div 2 + RingPosition[I].X - 3,
    259               Center.Y - ySizeBig div 2 + RingPosition[I].Y - 3, xSizeBig + 6,
    260               ySizeBig + 6, (wMaintexture - ClientWidth) div 2,
    261               (hMaintexture - ClientHeight) div 2);
    262             DarkIcon(I);
    263           end;
    264         -2: // destroyed
    265           begin
    266             HaveWonder := True;
    267             DpiBitCanvas(Offscreen.Canvas,
    268               Center.X - xSizeBig div 2 + RingPosition[I].X,
    269               Center.Y - ySizeBig div 2 + RingPosition[I].Y, xSizeBig,
    270               ySizeBig, BigImp.Canvas, 0, (SystemIconLines + 3) *
    271               ySizeBig);
    272           end;
    273       else
    274         begin
     229        WonderNotBuiltYet: begin
     230          Fill(Offscreen.Canvas, Center.X - xSizeBig div 2 + RingPosition[I].X - 3,
     231            Center.Y - ySizeBig div 2 + RingPosition[I].Y - 3, xSizeBig + 6,
     232            ySizeBig + 6, (wMaintexture - ClientWidth) div 2,
     233            (hMaintexture - ClientHeight) div 2);
     234        end;
     235        WonderDestroyed: begin
     236          HaveWonder := True;
     237          DpiBitCanvas(Offscreen.Canvas,
     238            Center.X - xSizeBig div 2 + RingPosition[I].X,
     239            Center.Y - ySizeBig div 2 + RingPosition[I].Y, xSizeBig,
     240            ySizeBig, BigImp.Canvas, 0, (SystemIconLines + 3) *
     241            ySizeBig);
     242        end;
     243        else begin
    275244          HaveWonder := True;
    276245          DpiBitCanvas(Offscreen.Canvas,
     
    282251      end;
    283252    end;
     253  end;
     254
     255  // Do direct pixel postprocessing separately to avoid bitmap copying in memory
     256  Offscreen.Canvas.FillRect(0, 0, 0, 0);
     257  Offscreen.BeginUpdate;
     258  for I := 0 to 20 do begin
     259    if Imp[I].Preq <> preNA then begin
     260      case MyRO.Wonder[I].CityID of
     261        WonderNotBuiltYet: DarkIcon(I);
     262        WonderDestroyed: Glow(I, $000000);
     263        else begin
     264          if MyRO.Wonder[I].EffectiveOwner >= 0 then
     265            Glow(I, Tribe[MyRO.Wonder[I].EffectiveOwner].Color)
     266          else Glow(I, $000000);
     267        end;
     268      end;
     269    end;
     270  end;
     271  Offscreen.EndUpdate;
    284272
    285273  if not HaveWonder then
     
    323311    if Selection >= 0 then
    324312    begin
    325       if MyRO.Wonder[Selection].CityID = -1 then
     313      if MyRO.Wonder[Selection].CityID = WonderNotBuiltYet then
    326314      begin // not built yet
    327315        { S:=Phrases.Lookup('IMPROVEMENTS',Selection);
     
    338326      begin
    339327        S := Phrases.Lookup('IMPROVEMENTS', Selection);
    340         if MyRO.Wonder[Selection].CityID <> -2 then
     328        if MyRO.Wonder[Selection].CityID <> WonderDestroyed then
    341329          S := Format(Phrases.Lookup('WONDEROF'),
    342330            [S, CityName(MyRO.Wonder[Selection].CityID)]);
     
    344332          (ClientWidth - BiColorTextWidth(Canvas, S)) div 2,
    345333          ClientHeight - 3 - 36 - 10, S);
    346         if MyRO.Wonder[Selection].CityID = -2 then
     334        if MyRO.Wonder[Selection].CityID = WonderDestroyed then
    347335          S := Phrases.Lookup('DESTROYED')
    348336        else if MyRO.Wonder[Selection].EffectiveOwner < 0 then
  • branches/highdpi/Localization/cs/Language.txt

    r210 r349  
    542542Pouze hlídkování, útoky a obsazení
    543543Velikost políčka
     544Malá
     545Střední
     546Velká
    544547
    545548#ADVANCES
     
    945948#SETTINGS
    946949Celá obrazovka
     950Gamma
     951Pro projevení změn je potřeba restart
  • branches/highdpi/Localization/cs/Language2.txt

    r64 r349  
    3535#ACTIONHEADER_AIDEV Vývoj AI
    3636#ACTION_AIDEV Jak naprogramovat vlastní AI pro tuto hru
    37 #ACTIONHEADER_WEB Na webu: c-evo.org
     37#ACTIONHEADER_WEB Na webu: %s
    3838
    3939'Message Text
  • branches/highdpi/Localization/de/Language.txt

    r210 r349  
    551551Nur Angriffe und Eroberungen
    552552Tile Size
     553Small
     554Medium
     555Big
    553556
    554557#ADVANCES
     
    963966#SETTINGS
    964967Full screen
     968Gamma
     969Restart is needed to apply changes
  • branches/highdpi/Localization/it/Language.txt

    r210 r349  
    532532Solo pattuglie, attacchi e conquiste
    533533Dimensione casella
     534Small
     535Medium
     536Big
    534537
    535538#ADVANCES
     
    935938#SETTINGS
    936939Full screen
     940Gamma
     941Restart is needed to apply changes
  • branches/highdpi/Localization/it/Language2.txt

    r77 r349  
    3535#ACTIONHEADER_AIDEV Sviluppo I.A.
    3636#ACTION_AIDEV Impara a programmare la tua I.A. per questo gioco
    37 #ACTIONHEADER_WEB Sul web: c-evo.org
     37#ACTIONHEADER_WEB Sul web: %s
    3838
    3939'Message Text
  • branches/highdpi/Localization/ru/Language.txt

    r210 r349  
    558558Только военные действия
    559559Размер секции
     560Small
     561Medium
     562Big
    560563
    561564#ADVANCES
     
    970973#SETTINGS
    971974Full screen
     975Gamma
     976Restart is needed to apply changes
  • branches/highdpi/Localization/zh-Hans/language.txt

    r210 r349  
    550550Ö»ÏÔʾѲÂß¡¢¹¥»÷¼°Õ¼ÁìÐж¯
    551551µØ¿é³ß´ç
     552Small
     553Medium
     554Big
    552555
    553556#ADVANCES
     
    962965#SETTINGS
    963966Full screen
     967Gamma
     968Restart is needed to apply changes
  • branches/highdpi/Localization/zh-Hant/language.txt

    r210 r349  
    550550¥uÅã¥Ü¨µÅÞ¡B§ðÀ»¤Î¥e»â¦æ°Ê
    551551¦a¶ô¤Ø¤o
     552Small
     553Medium
     554Big
    552555
    553556#ADVANCES
     
    962965#SETTINGS
    963966Full screen
     967Gamma
     968Restart is needed to apply changes
  • branches/highdpi/Packages/CevoComponents/BaseWin.pas

    r269 r349  
    8787end;
    8888
    89 
    9089constructor TBufferedDrawDlg.Create(AOwner: TComponent);
    9190begin
     
    112111procedure TBufferedDrawDlg.FormClose(Sender: TObject; var Action: TCloseAction);
    113112begin
    114   if FWindowMode = wmPersistent then
    115   begin
     113  if FWindowMode = wmPersistent then begin
    116114    UserLeft := Left;
    117     UserTop := Top
     115    UserTop := Top;
    118116  end;
    119117  if OffscreenUser = self then
     
    131129  Shift: TShiftState);
    132130begin
    133   if Key = VK_ESCAPE then
    134   begin
     131  if Key = VK_ESCAPE then begin
    135132    if fsModal in FormState then
    136       ModalResult := mrCancel
    137   end
    138   else if Key = VK_RETURN then
    139   begin
     133      ModalResult := mrCancel;
     134  end else
     135  if Key = VK_RETURN then begin
    140136    if fsModal in FormState then
    141       ModalResult := mrOK
    142   end
    143   else if Key = VK_F1 then begin
     137      ModalResult := mrOK;
     138  end else
     139  if Key = VK_F1 then begin
    144140    if Assigned(ShowNewContentProc) then
    145141      ShowNewContentProc(FWindowMode or wmPersistent, HelpContext);
    146   end else if FWindowMode = wmPersistent then begin
     142  end else
     143  if FWindowMode = wmPersistent then begin
    147144    if Assigned(MainFormKeyDown) then
    148145      MainFormKeyDown(Sender, Key, Shift);
     
    153150begin
    154151  if FWindowMode = wmSubmodal then
    155     Close
     152    Close;
    156153end;
    157154
     
    316313    else
    317314      MainTexture := MainTexture;
    318     MainTexture := MainTexture
     315    MainTexture := MainTexture;
    319316  end;
    320317  Canvas.Font.Assign(UniFont[ftCaption]);
     
    330327  begin
    331328    FrameTop := 0;
    332     FrameBottom := ClientHeight
     329    FrameBottom := ClientHeight;
    333330  end
    334331  else
     
    338335      FrameBottom := ClientHeight - (WideFrame - NarrowFrame)
    339336    else
    340       FrameBottom := ClientHeight
     337      FrameBottom := ClientHeight;
    341338  end;
    342339  Fill(Canvas, 3, InnerBottom + 1, ClientWidth - 6, ClientHeight - InnerBottom -
     
    386383        MoveTo(ClientWidth - 3 - ModalFrameIndent, 3);
    387384        LineTo(ClientWidth - 3 - ModalFrameIndent, TitleHeight);
    388       end
     385      end;
    389386  end
    390387  else
     
    441438        LineTo(ClientWidth - CaptionLeft - 2, FrameBottom - 2);
    442439      end;
    443     end
     440    end;
    444441  end;
    445442  RisedTextOut(Canvas, Cut - 1, 7, Caption);
     
    496493begin
    497494  if Offscreen <> nil then
    498     Exit;
     495    exit;
    499496  Offscreen := TDpiBitmap.Create;
    500497  Offscreen.PixelFormat := pf24bit;
  • branches/highdpi/Packages/CevoComponents/ButtonA.pas

    r303 r349  
    44
    55uses
    6   UDpiControls, ButtonBase, Classes, Graphics, LCLIntf, LCLType, ScreenTools;
     6  UDpiControls, ButtonBase, Classes, Graphics, LCLIntf, LCLType, ScreenTools, Types;
    77
    88type
     
    4141
    4242procedure TButtonA.Paint;
     43var
     44  TextSize: TSize;
    4345begin
    4446  with Canvas do
    45     if FGraphic <> nil then
    46     begin
     47    if FGraphic <> nil then begin
    4748      DpiBitCanvas(Canvas, 0, 0, 100, 25, Graphic.Canvas, 195,
    4849        243 + 26 * Byte(Down));
    4950      Canvas.Brush.Style := bsClear;
    50       Textout(50 - (TextWidth(FCaption) + 1) div 2, 12 - textheight(FCaption)
    51         div 2, FCaption);
    52     end
    53     else
    54     begin
     51      TextSize := TextExtent(FCaption);
     52      TextOut(50 - (TextSize.Width + 1) div 2,
     53        12 - TextSize.Height div 2, FCaption);
     54    end else begin
    5555      Brush.Color := $0000FF;
    5656      FrameRect(Rect(0, 0, 100, 25))
  • branches/highdpi/Packages/CevoComponents/CevoComponents.lpk

    r303 r349  
    3737    <Description Value="C-evo components"/>
    3838    <Version Major="1" Minor="2"/>
    39     <Files Count="15">
     39    <Files Count="17">
    4040      <Item1>
    4141        <Filename Value="Area.pas"/>
     
    106106        <UnitName Value="AsyncProcess2"/>
    107107      </Item15>
     108      <Item16>
     109        <Filename Value="UGraphicSet.pas"/>
     110        <UnitName Value="UGraphicSet"/>
     111      </Item16>
     112      <Item17>
     113        <Filename Value="UXMLUtils.pas"/>
     114        <UnitName Value="UXMLUtils"/>
     115      </Item17>
    108116    </Files>
    109117    <RequiredPkgs Count="3">
  • branches/highdpi/Packages/CevoComponents/CevoComponents.pas

    r303 r349  
    1010uses
    1111  Area, ButtonA, ButtonB, ButtonC, ButtonN, EOTButton, ButtonBase, DrawDlg,
    12   Sound, BaseWin, UPixelPointer, AsyncProcess2, LazarusPackageIntf;
     12  Sound, BaseWin, UPixelPointer, AsyncProcess2, UGraphicSet, UXMLUtils,
     13  LazarusPackageIntf;
    1314
    1415implementation
  • branches/highdpi/Packages/CevoComponents/DrawDlg.pas

    r303 r349  
    8686procedure TDrawDlg.OnEraseBkgnd(var Msg: TMessage);
    8787begin
     88  // Full area should be covered by Paint method
    8889end;
    8990
     
    202203    if Components[cix] is TButtonBase then
    203204    begin
    204       TButtonBase(Components[cix]).Graphic := GrExt[HGrSystem].Data;
     205      TButtonBase(Components[cix]).Graphic := HGrSystem.Data;
    205206      // if ButtonDownSound <> '*' then
    206207      // DownSound := GetSoundsDir + DirectorySeparator + ButtonDownSound + '.wav';
     
    210211        TButtonA(Components[cix]).Font := UniFont[ftButton];
    211212      if Components[cix] is TButtonB then
    212         TButtonB(Components[cix]).Mask := GrExt[HGrSystem].Mask;
     213        TButtonB(Components[cix]).Mask := HGrSystem.Mask;
    213214    end;
    214215end;
  • branches/highdpi/Packages/CevoComponents/EOTButton.pas

    r210 r349  
    7474begin
    7575  with Canvas do
    76     if FGraphic <> nil then
    77     begin
    78       // TODO: For some reason BitBlt is not working with gray background here
    79       //DpiBitCanvas(Buffer.Canvas, 0, 0, 48, 48, Back.Canvas, 0, 0);
    80       Buffer.Canvas.Draw(0, 0, Back);
     76    if FGraphic <> nil then begin
     77      UnshareBitmap(Buffer);
     78      DpiBitCanvas(Buffer.Canvas, 0, 0, 48, 48, Back.Canvas, 0, 0);
    8179      ImageOp_CBC(Buffer, Template, 0, 0, 133, 149 + 48 * Byte(FDown), 48, 48,
    8280        $000000, $FFFFFF);
     
    8583          $000000, $FFFFFF);
    8684      DpiBitCanvas(Canvas, 0, 0, 48, 48, Buffer.Canvas, 0, 0);
    87     end
    88     else
    89     begin
     85    end else begin
    9086      Brush.Color := $0000FF;
    9187      FrameRect(Rect(0, 0, 48, 48))
     
    9591procedure TEOTButton.SetIndex(x: integer);
    9692begin
    97   if x <> FIndex then
    98   begin
     93  if x <> FIndex then begin
    9994    FIndex := x;
    10095    Invalidate;
     
    10499procedure TEOTButton.SetButtonIndexFast(x: integer);
    105100begin
    106   if Visible and (x <> FIndex) then
    107   begin
     101  if Visible and (x <> FIndex) then begin
    108102    FIndex := x;
    109103    try
    110       Paint
     104      Paint;
    111105    except
    112106    end;
  • branches/highdpi/Packages/CevoComponents/ScreenTools.pas

    r303 r349  
    88  {$ENDIF}
    99  StringTables, LCLIntf, LCLType, SysUtils, Classes, Graphics, Controls, Math,
    10   Forms, Menus, GraphType;
     10  Forms, Menus, GraphType, fgl, UGraphicSet, LazFileUtils;
    1111
    1212type
     
    2525  TLoadGraphicFileOptions = set of TLoadGraphicFileOption;
    2626
     27  TFontType = (ftNormal, ftSmall, ftTiny, ftCaption, ftButton);
    2728
    2829{$IFDEF WINDOWS}
     
    3839function HexStringToColor(S: string): integer;
    3940function LoadGraphicFile(Bmp: TDpiBitmap; FileName: string; Options: TLoadGraphicFileOptions = []): boolean;
    40 function LoadGraphicSet(const Name: string): integer;
    41 procedure Dump(dst: TDpiBitmap; HGr, xDst, yDst, Width, Height, xGr, yGr: integer);
    42 procedure Sprite(Canvas: TDpiCanvas; HGr, xDst, yDst, Width, Height, xGr, yGr: integer);
     41function LoadGraphicSet(const Name: string): TGraphicSet;
     42function LoadGraphicSet2(const Name: string): TGraphicSet;
     43procedure Dump(dst: TDpiBitmap; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
     44procedure BitmapReplaceColor(Dst: TDpiBitmap; X, Y, Width, Height: Integer; OldColor, NewColor: TColor);
     45procedure Sprite(Canvas: TDpiCanvas; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
    4346  overload;
    44 procedure Sprite(dst: TDpiBitmap; HGr, xDst, yDst, Width, Height, xGr, yGr: integer);
     47procedure Sprite(dst: TDpiBitmap; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
    4548  overload;
    4649procedure MakeBlue(Dst: TDpiBitmap; X, Y, Width, Height: Integer);
    4750procedure MakeRed(Dst: TDpiBitmap; X, Y, Width, Height: Integer);
    4851procedure ImageOp_B(dst, Src: TDpiBitmap; xDst, yDst, xSrc, ySrc, Width, Height: Integer);
    49 procedure ImageOp_BCC(dst, Src: TDpiBitmap;
    50   xDst, yDst, xSrc, ySrc, Width, Height, Color1, Color2: Integer);
     52procedure ImageOp_BCC(Dst, Src: TDpiBitmap;
     53  xDst, yDst, xSrc, ySrc, Width, Height, Color1, Color2: Integer); overload;
     54procedure ImageOp_BCC(Dst, Src: TDpiBitmap;
     55  DstPos: TPoint; SrcRect: TRect; Color1, Color2: Integer); overload;
    5156procedure ImageOp_CBC(Dst, Src: TDpiBitmap; xDst, yDst, xSrc, ySrc, Width, Height,
    5257  Color0, Color2: Integer);
     
    8893procedure VLightGradient(ca: TDpiCanvas; x, y, Height, Color: integer);
    8994procedure VDarkGradient(ca: TDpiCanvas; x, y, Height, Kind: integer);
     95procedure UnderlinedTitleValue(Canvas: TDpiCanvas; Title, Value: string; X, Y, Width: Integer);
    9096procedure NumberBar(dst: TDpiBitmap; x, y: integer; Cap: string; val: integer;
    9197  const T: TTexture);
     
    97103  Kind, x, y, size, pos, Growth, max: integer; IndicateComplete: boolean;
    98104  const T: TTexture);
    99 procedure PaintLogo(ca: TDpiCanvas; x, y, clLight, clShade: integer);
     105procedure PaintLogo(Canvas: TDpiCanvas; X, Y, LightColor, ShadeColor: integer);
    100106function SetMainTextureByAge(Age: integer): boolean;
    101107procedure LoadPhrases;
    102108procedure Texturize(Dest, Texture: TDpiBitmap; TransparentColor: Cardinal);
    103109procedure DarkenImage(Bitmap: TDpiBitmap; Change: Integer);
     110procedure UnshareBitmap(Bitmap: TDpiBitmap);
    104111
    105112const
    106   nGrExtmax = 64;
     113  TransparentColor1 = $FF00FF;
     114  TransparentColor2 = $7F007F;
     115
    107116  wMainTexture = 640;
    108117  hMainTexture = 480;
    109118
    110   // template positions in Template.bmp
    111   xLogo = 1;
    112   yLogo = 1;
    113   wLogo = 122;
    114   hLogo = 23; // logo
    115   xBBook = 1;
    116   yBBook = 74;
    117   wBBook = 143;
    118   hBBook = 73; // big book
    119   xSBook = 72;
    120   ySBook = 37;
    121   wSBook = 72;
    122   hSBook = 36; // small book
     119  // template positions in Templates.png
    123120  xNation = 1;
    124121  yNation = 25;
     
    133130
    134131  EmptySpaceColor = $101010;
    135 
    136   // template positions in System2.bmp
    137   xOrna = 156;
    138   yOrna = 1;
    139   wOrna = 27;
    140   hOrna = 26; // ornament
    141132
    142133  // color matrix
     
    167158  cliWater = 4;
    168159
    169 type
    170   TGrExtDescr = record { don't use dynamic strings here! }
    171     Name: string[31];
    172     Data: TDpiBitmap;
    173     Mask: TDpiBitmap;
    174     pixUsed: array [Byte] of Byte;
    175   end;
    176 
    177   TGrExtDescrSize = record { for size calculation only - must be the same as
    178       TGrExtDescr, but without pixUsed }
    179     Name: string[31];
    180     Data: TDpiBitmap;
    181     Mask: TDpiBitmap;
    182   end;
    183 
    184   TFontType = (ftNormal, ftSmall, ftTiny, ftCaption, ftButton);
    185 
    186160var
    187161  Phrases: TStringTable;
    188162  Phrases2: TStringTable;
    189   nGrExt: Integer;
    190   GrExt: array [0 .. nGrExtmax - 1] of ^TGrExtDescr;
    191   HGrSystem: Integer;
    192   HGrSystem2: Integer;
     163  GrExt: TGraphicSets;
     164  HGrSystem: TGraphicSet;
     165  HGrSystem2: TGraphicSet;
    193166  ClickFrameColor: Integer;
    194167  MainTextureAge: Integer;
    195168  MainTexture: TTexture;
    196   Templates: TDpiBitmap;
     169  Templates: TGraphicSet;
    197170  Colors: TDpiBitmap;
    198171  Paper: TDpiBitmap;
     
    203176  InitOrnamentDone: Boolean;
    204177  Phrases2FallenBackToEnglish: Boolean;
     178
     179  // Graphic set items
     180  CityMark1: TGraphicSetItem;
     181  CityMark2: TGraphicSetItem;
     182  Ornament: TGraphicSetItem;
     183  Logo: TGraphicSetItem;
     184  BigBook: TGraphicSetItem;
     185  SmallBook: TGraphicSetItem;
     186  MenuLogo: TGraphicSetItem;
     187  LinkArrows: TGraphicSetItem;
     188  ScienceNationDot: TGraphicSetItem;
     189  ResearchIcon: TGraphicSetItem;
     190  ChangeIcon: TGraphicSetItem;
     191  TreasuryIcon: TGraphicSetItem;
     192  StarshipDeparted: TGraphicSetItem;
     193  WeightOn: TGraphicSetItem;
     194  WeightOff: TGraphicSetItem;
    205195
    206196  UniFont: array [TFontType] of TDpiFont;
     
    489479end;
    490480
    491 function LoadGraphicSet(const Name: string): Integer;
    492 var
    493   I, x, y, xmax, OriginalColor: Integer;
     481function LoadGraphicSet(const Name: string): TGraphicSet;
     482var
     483  x: Integer;
     484  y: Integer;
     485  OriginalColor: Integer;
    494486  FileName: string;
    495   Source: TDpiBitmap;
    496   DataPixel, MaskPixel: TPixelPointer;
    497 begin
    498   I := 0;
    499   while (I < nGrExt) and (GrExt[i].Name <> Name) do
    500     Inc(I);
    501   Result := I;
    502   if I = nGrExt then begin
    503     Source := TDpiBitmap.Create;
    504     Source.PixelFormat := pf24bit;
     487  DataPixel: TPixelPointer;
     488  MaskPixel: TPixelPointer;
     489begin
     490  Result := GrExt.SearchByName(Name);
     491  if not Assigned(Result) then begin
     492    Result := GrExt.AddNew(Name);
    505493    FileName := GetGraphicsDir + DirectorySeparator + Name;
    506     if not LoadGraphicFile(Source, FileName) then begin
    507       Result := -1;
     494    // Do not apply gamma during file load as it would affect also transparency colors
     495    if not LoadGraphicFile(Result.Data, FileName, [gfNoGamma]) then begin
     496      Result := nil;
    508497      Exit;
    509498    end;
    510499
    511     GetMem(GrExt[nGrExt], SizeOf(TGrExtDescrSize) + Source.Height div 49 * 10);
    512     GrExt[nGrExt].Name := Name;
    513 
    514     xmax := Source.Width - 1; // allows 4-byte access even for last pixel
    515     // Why there was that limit?
    516     //if xmax > 970 then
    517     //  xmax := 970;
    518 
    519     GrExt[nGrExt].Data := Source;
    520     GrExt[nGrExt].Data.PixelFormat := pf24bit;
    521     GrExt[nGrExt].Mask := TDpiBitmap.Create;
    522     GrExt[nGrExt].Mask.PixelFormat := pf24bit;
    523     GrExt[nGrExt].Mask.SetSize(Source.Width, Source.Height);
    524 
    525     GrExt[nGrExt].Data.BeginUpdate;
    526     GrExt[nGrExt].Mask.BeginUpdate;
    527     DataPixel := PixelPointer(GrExt[nGrExt].Data);
    528     MaskPixel := PixelPointer(GrExt[nGrExt].Mask);
    529     for y := 0 to ScaleToNative(Source.Height) - 1 do begin
    530       for x := 0 to ScaleToNative(xmax) - 1 do begin
     500    FileName := ExtractFileNameWithoutExt(FileName) + GraphicSetFileExt;
     501    if FileExists(FileName) then
     502      Result.LoadFromFile(FileName);
     503
     504    Result.ResetPixUsed;
     505
     506    Result.Mask.SetSize(Result.Data.Width, Result.Data.Height);
     507
     508    Result.Data.BeginUpdate;
     509    Result.Mask.BeginUpdate;
     510    DataPixel := PixelPointer(Result.Data);
     511    MaskPixel := PixelPointer(Result.Mask);
     512    for y := 0 to ScaleToNative(Result.Data.Height) - 1 do begin
     513      for x := 0 to ScaleToNative(Result.Data.Width) - 1 do begin
    531514        OriginalColor := DataPixel.Pixel^.ARGB and $FFFFFF;
    532         if (OriginalColor = $FF00FF) or (OriginalColor = $7F007F) then
    533         begin // transparent
    534           MaskPixel.Pixel^.ARGB := $FFFFFF;
    535           DataPixel.Pixel^.ARGB := DataPixel.Pixel^.ARGB and $FF000000;
    536         end
    537         else begin
    538           MaskPixel.Pixel^.ARGB := $000000; // non-transparent
    539           if Gamma <> 100 then
    540             DataPixel.Pixel^ := ApplyGammaToPixel(DataPixel.Pixel^);
     515        if (OriginalColor = TransparentColor1) or (OriginalColor = TransparentColor2) then begin
     516          MaskPixel.Pixel^.R := $FF;
     517          MaskPixel.Pixel^.G := $FF;
     518          MaskPixel.Pixel^.B := $FF;
     519          DataPixel.Pixel^.R := 0;
     520          DataPixel.Pixel^.G := 0;
     521          DataPixel.Pixel^.B := 0;
     522        end else begin
     523          MaskPixel.Pixel^.R := $00;
     524          MaskPixel.Pixel^.G := $00;
     525          MaskPixel.Pixel^.B := $00;
    541526        end;
    542527        DataPixel.NextPixel;
     
    546531      MaskPixel.NextLine;
    547532    end;
    548     GrExt[nGrExt].Data.EndUpdate;
    549     GrExt[nGrExt].Mask.EndUpdate;
    550 
    551     FillChar(GrExt[nGrExt].pixUsed, GrExt[nGrExt].Data.Height div 49 * 10, 0);
    552     Inc(nGrExt);
    553   end;
    554 end;
    555 
    556 procedure Dump(dst: TDpiBitmap; HGr, xDst, yDst, Width, Height, xGr, yGr: integer);
     533    Result.Data.EndUpdate;
     534    Result.Mask.EndUpdate;
     535
     536    if Gamma <> 100 then
     537      ApplyGammaToBitmap(Result.Data);
     538  end;
     539end;
     540
     541function LoadGraphicSet2(const Name: string): TGraphicSet;
     542var
     543  FileName: string;
     544begin
     545  Result := GrExt.SearchByName(Name);
     546  if not Assigned(Result) then begin
     547    Result := GrExt.AddNew(Name);
     548    FileName := GetGraphicsDir + DirectorySeparator + Name;
     549    if not LoadGraphicFile(Result.Data, FileName, [gfNoGamma]) then begin
     550      Result := nil;
     551      Exit;
     552    end;
     553
     554    FileName := ExtractFileNameWithoutExt(FileName) + GraphicSetFileExt;
     555    if FileExists(FileName) then
     556      Result.LoadFromFile(FileName);
     557
     558    Result.ResetPixUsed;
     559  end;
     560end;
     561
     562procedure Dump(dst: TDpiBitmap; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
    557563begin
    558564  DpiBitCanvas(dst.Canvas, xDst, yDst, Width, Height,
    559     GrExt[HGr].Data.Canvas, xGr, yGr);
     565    HGr.Data.Canvas, xGr, yGr);
     566end;
     567
     568procedure BitmapReplaceColor(Dst: TDpiBitmap; X, Y, Width, Height: Integer; OldColor, NewColor: TColor);
     569var
     570  XX, YY: Integer;
     571  PixelPtr: TPixelPointer;
     572begin
     573  Dst.BeginUpdate;
     574  PixelPtr := PixelPointer(Dst, ScaleToNative(X), ScaleToNative(Y));
     575  for YY := 0 to ScaleToNative(Height) - 1 do begin
     576    for XX := 0 to ScaleToNative(Width) - 1 do begin
     577      if PixelPtr.Pixel^.RGB = SwapRedBlue(OldColor) then begin
     578        PixelPtr.Pixel^.RGB := SwapRedBlue(NewColor);
     579      end;
     580      PixelPtr.NextPixel;
     581    end;
     582    PixelPtr.NextLine;
     583  end;
     584  Dst.EndUpdate;
    560585end;
    561586
     
    734759end;
    735760
     761procedure ImageOp_BCC(Dst, Src: TDpiBitmap; DstPos: TPoint; SrcRect: TRect;
     762  Color1, Color2: Integer);
     763begin
     764  ImageOp_BCC(Dst, Src, DstPos.X, DstPos.Y, SrcRect.Left, SrcRect.Top,
     765    SrcRect.Width, SrcRect.Height, Color1, Color2);
     766end;
     767
    736768procedure ImageOp_CBC(Dst, Src: TDpiBitmap; xDst, yDst, xSrc, ySrc, Width, Height,
    737769  Color0, Color2: Integer);
     
    820852end;
    821853
    822 procedure Sprite(Canvas: TDpiCanvas; HGr, xDst, yDst, Width, Height, xGr, yGr: integer);
     854procedure Sprite(Canvas: TDpiCanvas; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
    823855begin
    824856  DpiBitCanvas(Canvas, xDst, yDst, Width, Height,
    825     GrExt[HGr].Mask.Canvas, xGr, yGr, SRCAND);
     857    HGr.Mask.Canvas, xGr, yGr, SRCAND);
    826858  DpiBitCanvas(Canvas, xDst, yDst, Width, Height,
    827     GrExt[HGr].Data.Canvas, xGr, yGr, SRCPAINT);
    828 end;
    829 
    830 procedure Sprite(dst: TDpiBitmap; HGr, xDst, yDst, Width, Height, xGr, yGr: integer);
     859    HGr.Data.Canvas, xGr, yGr, SRCPAINT);
     860end;
     861
     862procedure Sprite(dst: TDpiBitmap; HGr: TGraphicSet; xDst, yDst, Width, Height, xGr, yGr: integer);
    831863begin
    832864  DpiBitCanvas(dst.Canvas, xDst, yDst, Width, Height,
    833     GrExt[HGr].Mask.Canvas, xGr, yGr, SRCAND);
     865    HGr.Mask.Canvas, xGr, yGr, SRCAND);
    834866  DpiBitCanvas(dst.Canvas, xDst, yDst, Width, Height,
    835     GrExt[HGr].Data.Canvas, xGr, yGr, SRCPAINT);
     867    HGr.Data.Canvas, xGr, yGr, SRCPAINT);
    836868end;
    837869
     
    10111043  Shade := ColorToColor32(MainTexture.clBevelShade and $FCFCFC shr 2 * 3 +
    10121044    MainTexture.clBevelLight and $FCFCFC shr 2);
    1013   GrExt[HGrSystem2].Data.BeginUpdate;
    1014   PixelPtr := PixelPointer(GrExt[HGrSystem2].Data, ScaleToNative(xOrna), ScaleToNative(yOrna));
     1045  HGrSystem2.Data.BeginUpdate;
     1046  PixelPtr := PixelPointer(HGrSystem2.Data, ScaleToNative(Ornament.Left), ScaleToNative(Ornament.Top));
    10151047  if PixelPtr.BytesPerPixel = 3 then begin
    1016     for Y := 0 to ScaleToNative(hOrna) - 1 do begin
    1017       for X := 0 to ScaleToNative(wOrna) - 1 do begin
    1018         P := Color32ToColor(PixelPtr.Pixel^.GetRGB);
    1019         if P = $0000FF then PixelPtr.Pixel^.SetRGB(Light)
    1020         else if P = $FF0000 then PixelPtr.Pixel^.SetRGB(Shade);
     1048    for Y := 0 to ScaleToNative(Ornament.Height) - 1 do begin
     1049      for X := 0 to ScaleToNative(Ornament.Width) - 1 do begin
     1050        P := Color32ToColor(PixelPtr.Pixel^.RGB);
     1051        if P = $0000FF then PixelPtr.Pixel^.RGB := Light
     1052        else if P = $FF0000 then PixelPtr.Pixel^.RGB := Shade;
    10211053        PixelPtr.NextPixel;
    10221054      end;
     
    10241056    end;
    10251057  end else begin
    1026     for Y := 0 to ScaleToNative(hOrna) - 1 do begin
    1027       for X := 0 to ScaleToNative(wOrna) - 1 do begin
     1058    for Y := 0 to ScaleToNative(Ornament.Height) - 1 do begin
     1059      for X := 0 to ScaleToNative(Ornament.Width) - 1 do begin
    10281060        P := Color32ToColor(PixelPtr.Pixel^.ARGB);
    10291061        if P = $0000FF then PixelPtr.Pixel^.ARGB := Light
     
    10351067  end;
    10361068  InitOrnamentDone := True;
    1037   GrExt[HGrSystem2].Data.EndUpdate;
     1069  HGrSystem2.Data.EndUpdate;
    10381070end;
    10391071
    10401072procedure InitCityMark(const T: TTexture);
    10411073var
    1042   x, y, intensity: Integer;
    1043 begin
    1044   for x := 0 to 9 do
    1045     for y := 0 to 9 do
    1046       if GrExt[HGrSystem].Mask.Canvas.Pixels[66 + x, 47 + y] = 0 then
     1074  x: Integer;
     1075  y: Integer;
     1076  Intensity: Integer;
     1077begin
     1078  for x := 0 to CityMark1.Width - 1 do begin
     1079    for y := 0 to CityMark1.Height - 1 do begin
     1080      if HGrSystem.Mask.Canvas.Pixels[CityMark1.Left + x, CityMark1.Top + y] = 0 then
    10471081      begin
    1048         intensity := GrExt[HGrSystem].Data.Canvas.Pixels[66 +
    1049           x, 47 + y] and $FF;
    1050         GrExt[HGrSystem].Data.Canvas.Pixels[77 + x, 47 + y] :=
    1051           T.clMark and $FF * intensity div $FF + T.clMark shr 8 and
    1052           $FF * intensity div $FF shl 8 + T.clMark shr 16 and
    1053           $FF * intensity div $FF shl 16;
     1082        Intensity := HGrSystem.Data.Canvas.Pixels[CityMark1.Left +
     1083          x, CityMark1.Top + y] and $FF;
     1084        HGrSystem.Data.Canvas.Pixels[CityMark2.Left + x, CityMark2.Top + y] :=
     1085          T.clMark and $FF * Intensity div $FF + T.clMark shr 8 and
     1086          $FF * Intensity div $FF shl 8 + T.clMark shr 16 and
     1087          $FF * Intensity div $FF shl 16;
    10541088      end;
    1055   DpiBitCanvas(GrExt[HGrSystem].Mask.Canvas, 77, 47, 10, 10,
    1056     GrExt[HGrSystem].Mask.Canvas, 66, 47);
     1089    end;
     1090  end;
     1091  DpiBitCanvas(HGrSystem.Mask.Canvas, CityMark2.Left, CityMark2.Top, CityMark1.Width, CityMark1.Width,
     1092    HGrSystem.Mask.Canvas, CityMark1.Left, CityMark1.Top);
    10571093end;
    10581094
     
    11531189procedure Corner(ca: TDpiCanvas; x, y, Kind: Integer; const T: TTexture);
    11541190begin
    1155   { DpiBitCanvas(ca,x,y,8,8,GrExt[T.HGr].Mask.Canvas,
     1191  { DpiBitCanvas(ca,x,y,8,8,T.HGr.Mask.Canvas,
    11561192    T.xGr+29+Kind*9,T.yGr+89,SRCAND);
    1157     DpiBitCanvas(ca,x,y,8,8,GrExt[T.HGr].Data.Canvas,
     1193    DpiBitCanvas(ca,x,y,8,8,T.HGr.Data.Canvas,
    11581194    T.xGr+29+Kind*9,T.yGr+89,SRCPAINT); }
    11591195end;
     
    11631199  procedure PaintIcon(x, y, Kind: Integer);
    11641200  begin
    1165     DpiBitCanvas(ca, x, y + 6, 10, 10, GrExt[HGrSystem].Mask.Canvas,
     1201    DpiBitCanvas(ca, x, y + 6, 10, 10, HGrSystem.Mask.Canvas,
    11661202      66 + Kind mod 11 * 11, 115 + Kind div 11 * 11, SRCAND);
    1167     DpiBitCanvas(ca, x, y + 6, 10, 10, GrExt[HGrSystem].Data.Canvas,
     1203    DpiBitCanvas(ca, x, y + 6, 10, 10, HGrSystem.Data.Canvas,
    11681204      66 + Kind mod 11 * 11, 115 + Kind div 11 * 11, SRCPAINT);
    11691205  end;
     
    11731209  sp: string;
    11741210  shadow: Boolean;
     1211  Text: string;
    11751212begin
    11761213  Inc(x);
     
    11961233          else
    11971234          begin
    1198             Textout(xp, y, copy(sp, 1, p - 1));
    1199             Inc(xp, ca.TextWidth(copy(sp, 1, p - 1)));
     1235            Text := Copy(sp, 1, p - 1);
     1236            Textout(xp, y, Text);
     1237            Inc(xp, ca.TextWidth(Text));
    12001238            if not shadow then
    12011239              case sp[p + 1] of
     
    13051343    (16, 12, 8, 4, 0, -4, -8, -12 - 24, -16 + 16, -20, -24, -28, -32, -36, -40, -44);
    13061344begin
    1307   Gradient(ca, x, y, 0, 1, Width, 0, GrExt[HGrSystem].Data.Canvas.Pixels
     1345  Gradient(ca, x, y, 0, 1, Width, 0, HGrSystem.Data.Canvas.Pixels
    13081346    [187, 137 + Kind], Brightness);
    13091347end;
     
    13231361begin
    13241362  Gradient(ca, x, y, 1, 0, 0, Height,
    1325     GrExt[HGrSystem].Data.Canvas.Pixels[187, 137 + Kind], Brightness);
     1363    HGrSystem.Data.Canvas.Pixels[187, 137 + Kind], Brightness);
     1364end;
     1365
     1366procedure UnderlinedTitleValue(Canvas: TDpiCanvas; Title, Value: string; X, Y, Width: Integer);
     1367begin
     1368  DLine(Canvas, X, X + Width, Y + 19, MainTexture.clBevelLight, MainTexture.clBevelShade);
     1369  RisedTextOut(Canvas, X, Y, Title);
     1370  RisedTextOut(Canvas, X + Width - BiColorTextWidth(Canvas, Value), Y, Value);
    13261371end;
    13271372
     
    13851430      begin
    13861431        DpiBitCanvas(dst.Canvas, xIcon + 4 + i * (14 * ld div sd), yIcon + 2 + 1, 14,
    1387           14, GrExt[HGrSystem].Mask.Canvas, 67 + Kind mod 8 * 15,
     1432          14, HGrSystem.Mask.Canvas, 67 + Kind mod 8 * 15,
    13881433          70 + Kind div 8 * 15, SRCAND);
    13891434        Sprite(dst, HGrSystem, xIcon + 3 + i * (14 * ld div sd), yIcon + 2,
     
    13941439        DpiBitCanvas(dst.Canvas, xIcon + 4 + (val mod 10) *
    13951440          (14 * ld div sd) + i * (14 * ld div sd), yIcon + 3, 14, 14,
    1396           GrExt[HGrSystem].Mask.Canvas, 67 + 7 mod 8 * 15,
     1441          HGrSystem.Mask.Canvas, 67 + 7 mod 8 * 15,
    13971442          70 + 7 div 8 * 15, SRCAND);
    13981443        Sprite(dst, HGrSystem, xIcon + 3 + (val mod 10) *
     
    14181463      begin
    14191464        DpiBitCanvas(dst.Canvas, xIcon + 4 + i * (14 * ld div sd), yIcon + 3, 14, 14,
    1420           GrExt[HGrSystem].Mask.Canvas, 67 + Kind mod 8 * 15,
     1465          HGrSystem.Mask.Canvas, 67 + Kind mod 8 * 15,
    14211466          70 + Kind div 8 * 15, SRCAND);
    14221467        Sprite(dst, HGrSystem, xIcon + 3 + i * (14 * ld div sd), yIcon + 2,
     
    14271472        DpiBitCanvas(dst.Canvas, xIcon + 4 + (val div 10) *
    14281473          (14 * ld div sd) + i * (10 * ld div sd), yIcon + 7, 10, 10,
    1429           GrExt[HGrSystem].Mask.Canvas, 66 + Kind mod 11 * 11,
     1474          HGrSystem.Mask.Canvas, 66 + Kind mod 11 * 11,
    14301475          115 + Kind div 11 * 11, SRCAND);
    14311476        Sprite(dst, HGrSystem, xIcon + 3 + (val div 10) *
     
    14631508    for i := 0 to pos div 8 - 1 do
    14641509      DpiBitCanvas(ca, x + i * 8, y, 8, 7,
    1465         GrExt[HGrSystem].Data.Canvas, 104, 9 + 8 * Kind);
     1510        HGrSystem.Data.Canvas, 104, 9 + 8 * Kind);
    14661511    DpiBitCanvas(ca, x + 8 * (pos div 8), y, pos - 8 * (pos div 8), 7,
    1467       GrExt[HGrSystem].Data.Canvas, 104, 9 + 8 * Kind);
     1512      HGrSystem.Data.Canvas, 104, 9 + 8 * Kind);
    14681513    if Growth > 0 then
    14691514    begin
    14701515      for i := 0 to Growth div 8 - 1 do
    14711516        DpiBitCanvas(ca, x + pos + i * 8, y, 8, 7,
    1472           GrExt[HGrSystem].Data.Canvas, 112, 9 + 8 * Kind);
     1517          HGrSystem.Data.Canvas, 112, 9 + 8 * Kind);
    14731518      DpiBitCanvas(ca, x + pos + 8 * (Growth div 8), y,
    1474         Growth - 8 * (Growth div 8), 7, GrExt[HGrSystem].Data.Canvas,
     1519        Growth - 8 * (Growth div 8), 7, HGrSystem.Data.Canvas,
    14751520        112, 9 + 8 * Kind);
    14761521    end
     
    14791524      for i := 0 to -Growth div 8 - 1 do
    14801525        DpiBitCanvas(ca, x + pos + i * 8, y, 8, 7,
    1481           GrExt[HGrSystem].Data.Canvas, 104, 1);
     1526          HGrSystem.Data.Canvas, 104, 1);
    14821527      DpiBitCanvas(ca, x + pos + 8 * (-Growth div 8), y, -Growth -
    14831528        8 * (-Growth div 8), 7,
    1484         GrExt[HGrSystem].Data.Canvas, 104, 1);
     1529        HGrSystem.Data.Canvas, 104, 1);
    14851530    end;
    14861531    Brush.Color := $000000;
     
    15051550end;
    15061551
    1507 procedure PaintLogo(ca: TDpiCanvas; x, y, clLight, clShade: Integer);
    1508 begin
    1509   // TODO: Explicitly clear background to black but in fact BitBlt SRCCOPY should do it
    1510   LogoBuffer.Canvas.FillRect(0, 0, LogoBuffer.Width, LogoBuffer.Height);
    1511   DpiBitCanvas(LogoBuffer.Canvas, 0, 0, wLogo, hLogo, ca, x, y);
    1512   ImageOp_BCC(LogoBuffer, Templates, 0, 0, 1, 1, wLogo, hLogo,
    1513     clLight, clShade);
    1514   DpiBitCanvas(ca, x, y, wLogo, hLogo, LogoBuffer.Canvas, 0, 0);
     1552procedure PaintLogo(Canvas: TDpiCanvas; X, Y, LightColor, ShadeColor: Integer);
     1553begin
     1554  UnshareBitmap(LogoBuffer);
     1555  DpiBitCanvas(LogoBuffer.Canvas, 0, 0, Logo.Width, Logo.Height, Canvas, X, Y);
     1556  ImageOp_BCC(LogoBuffer, Templates.Data, Point(0, 0), Logo.BoundsRect,
     1557    LightColor, ShadeColor);
     1558  DpiBitCanvas(Canvas, X, Y, Logo.Width, Logo.Height, LogoBuffer.Canvas, 0, 0);
    15151559end;
    15161560
     
    16111655end;
    16121656
    1613 function ScaleToNative(Value: Integer): Integer;
    1614 begin
    1615   Result := Value;
    1616 end;
    1617 
    1618 function ScaleFromNative(Value: Integer): Integer;
    1619 begin
    1620   Result := Value;
     1657procedure UnshareBitmap(Bitmap: TDpiBitmap);
     1658begin
     1659  // FillRect cause image data to be freed so subsequent BitBlt can access valid image data
     1660  Bitmap.Canvas.FillRect(0, 0, 0, 0);
    16211661end;
    16221662
     
    16951735  LoadPhrases;
    16961736  LoadFonts;
    1697   LoadGraphicFile(Templates, GetGraphicsDir + DirectorySeparator +
    1698     'Templates.png', [gfNoGamma]);
     1737  Templates := LoadGraphicSet2('Templates.png');
     1738  with Templates do begin
     1739    Logo := GetItem('Logo');
     1740    BigBook := GetItem('BigBook');
     1741    SmallBook := GetItem('SmallBook');
     1742    MenuLogo := GetItem('MenuLogo');
     1743    LinkArrows := GetItem('LinkArrows');
     1744    ScienceNationDot := GetItem('ScienceNationDot');
     1745    ResearchIcon := GetItem('Research');
     1746    ChangeIcon := GetItem('Change');
     1747    TreasuryIcon := GetItem('Treasury');
     1748    StarshipDeparted := GetItem('StarshipDeparted');
     1749    WeightOn := GetItem('WeightOn');
     1750    WeightOff := GetItem('WeightOff');
     1751  end;
     1752
    16991753  LoadGraphicFile(Colors, GetGraphicsDir + DirectorySeparator + 'Colors.png');
    17001754  LoadGraphicFile(Paper, GetGraphicsDir + DirectorySeparator + 'Paper.jpg');
     
    17141768  {$ENDIF}
    17151769
    1716   LogoBuffer := TDpiBitmap.Create;
    1717   LogoBuffer.PixelFormat := pf24bit;
    1718   LogoBuffer.SetSize(wBBook, hBBook);
    1719 
    17201770  for Section := Low(TFontType) to High(TFontType) do
    17211771    UniFont[Section] := TDpiFont.Create;
    17221772
    1723   nGrExt := 0;
     1773  GrExt := TGraphicSets.Create;
     1774
    17241775  HGrSystem := LoadGraphicSet('System.png');
     1776  CityMark1 := HGrSystem.GetItem('CityMark1');
     1777  CityMark2 := HGrSystem.GetItem('CityMark2');
     1778
    17251779  HGrSystem2 := LoadGraphicSet('System2.png');
    1726   Templates := TDpiBitmap.Create;
    1727   Templates.PixelFormat := pf24bit;
     1780  Ornament := HGrSystem2.GetItem('Ornament');
     1781
    17281782  Colors := TDpiBitmap.Create;
    17291783  Colors.PixelFormat := pf24bit;
     
    17341788  MainTexture.Image := TDpiBitmap.Create;
    17351789  MainTextureAge := -2;
    1736   ClickFrameColor := GrExt[HGrSystem].Data.Canvas.Pixels[187, 175];
     1790  ClickFrameColor := HGrSystem.Data.Canvas.Pixels[187, 175];
    17371791  InitOrnamentDone := False;
    17381792  GenerateNames := True;
    17391793
    17401794  LoadAssets;
     1795
     1796  LogoBuffer := TDpiBitmap.Create;
     1797  LogoBuffer.PixelFormat := pf24bit;
     1798  LogoBuffer.SetSize(BigBook.Width, BigBook.Height);
    17411799end;
    17421800
    17431801procedure UnitDone;
    1744 var
    1745   I: integer;
    17461802begin
    17471803  RestoreResolution;
    1748   for I := 0 to nGrExt - 1 do begin
    1749     FreeAndNil(GrExt[I].Data);
    1750     FreeAndNil(GrExt[I].Mask);
    1751     FreeMem(GrExt[I]);
    1752   end;
    1753 
     1804  FreeAndNil(GrExt);
    17541805  ReleaseFonts;
    1755 
    17561806  FreeAndNil(Phrases);
    17571807  FreeAndNil(Phrases2);
     
    17591809  FreeAndNil(BigImp);
    17601810  FreeAndNil(Paper);
    1761   FreeAndNil(Templates);
    17621811  FreeAndNil(Colors);
    17631812  FreeAndNil(MainTexture.Image);
  • branches/highdpi/Packages/CevoComponents/Sound.lfm

    r210 r349  
    88  Caption = 'SoundPlayer'
    99  Color = clBtnFace
    10   DesignTimePPI = 125
     10  DesignTimePPI = 144
    1111  Font.Color = clWindowText
    1212  Font.Height = -11
    1313  Font.Name = 'MS Sans Serif'
    14   LCLVersion = '1.8.0.6'
     14  LCLVersion = '2.0.12.0'
    1515  Scaled = False
    1616end
  • branches/highdpi/Packages/CevoComponents/Sound.pas

    r303 r349  
    1111type
    1212  TPlayStyle = (psAsync, psSync);
     13  TSoundMode = (smOff, smOn, smOnAlt);
    1314
    1415  { TSoundPlayer }
     
    1819    {$IFDEF WINDOWS}
    1920    PrevWndProc: WNDPROC;
    20     procedure OnMCI(var m: TMessage); message MM_MCINOTIFY;
     21    procedure OnMCI(var Msg: TMessage); message MM_MCINOTIFY;
    2122  public
    2223    constructor Create(AOwner: TComponent); override;
     
    5051procedure PreparePlay(Item: string; Index: Integer = -1);
    5152
    52 const
    53   // sound modes
    54   smOff = 0;
    55   smOn = 1;
    56   smOnAlt = 2;
    57 
    5853var
    5954  Sounds: TStringTable;
    60   SoundMode: Integer;
     55  SoundMode: TSoundMode;
    6156  SoundPlayer: TSoundPlayer;
    6257  SoundList: TFPGObjectList<TSound>;
     
    260255end;
    261256
    262 procedure TSoundPlayer.OnMCI(var m: TMessage);
    263 begin
    264   if (m.wParam = MCI_NOTIFY_SUCCESSFUL) and (PlayingSound <> nil) then
     257procedure TSoundPlayer.OnMCI(var Msg: TMessage);
     258begin
     259  if (Msg.wParam = MCI_NOTIFY_SUCCESSFUL) and (PlayingSound <> nil) then
    265260  begin
    266261    PlayingSound.Reset;
  • branches/highdpi/Packages/CevoComponents/UPixelPointer.pas

    r251 r349  
    1313
    1414  TPixel32 = packed record
    15     procedure SetRGB(Color: TColor32);
    16     function GetRGB: TColor32;
     15  private
     16    function GetRGB: Cardinal;
     17    procedure SetRGB(AValue: Cardinal);
     18  public
     19    property RGB: Cardinal read GetRGB write SetRGB;
    1720    case Integer of
    1821      0: (B, G, R, A: Byte);
     
    4245
    4346  function PixelPointer(Bitmap: TDpiRasterImage; BaseX: Integer = 0; BaseY: Integer = 0): TPixelPointer; inline;
     47  function SwapRedBlue(Color: TColor32): TColor32;
    4448  function Color32ToColor(Color: TColor32): TColor;
    4549  function ColorToColor32(Color: TColor): TColor32;
    46 
    4750
    4851implementation
     
    5053{ TPixel32 }
    5154
    52 procedure TPixel32.SetRGB(Color: TColor32);
     55function TPixel32.GetRGB: Cardinal;
    5356begin
    54   B := Color and $ff;
    55   G := (Color shr 8) and $ff;
    56   R := (Color shr 16) and $ff;
     57  Result := ARGB and $ffffff;
    5758end;
    5859
    59 function TPixel32.GetRGB: TColor32;
     60procedure TPixel32.SetRGB(AValue: Cardinal);
    6061begin
    61   Result := ARGB and $ffffff;
     62  R := (AValue shr 16) and $ff;
     63  G := (AValue shr 8) and $ff;
     64  B := (AValue shr 0) and $ff;
    6265end;
    6366
     
    107110end;
    108111
     112function SwapRedBlue(Color: TColor32): TColor32;
     113begin
     114  Result := (Color and $ff00ff00) or ((Color and $ff) shl 16) or ((Color shr 16) and $ff);
     115end;
     116
    109117function Color32ToColor(Color: TColor32): TColor;
    110118begin
  • branches/highdpi/Packages/DpiControls/UDpiControls.pas

    r308 r349  
    445445    procedure ScreenChanged; override;
    446446    function ControlCount: Integer;
     447    procedure SetFocus; virtual;
    447448    constructor Create(TheOwner: TComponent); override;
    448449    destructor Destroy; override;
     
    562563    property ModalResult: TModalResult read GetModalResult write SetModalResult;
    563564    function ShowModal: Integer; virtual;
     565    procedure SetFocus; override;
    564566    procedure Close;
    565567    function CloseQuery: boolean; virtual;
     
    29602962end;
    29612963
     2964procedure TDpiWinControl.SetFocus;
     2965begin
     2966  GetNativeWinControl.SetFocus;
     2967end;
     2968
    29622969constructor TDpiWinControl.Create(TheOwner: TComponent);
    29632970begin
     
    38503857begin
    38513858  Result := GetNativeForm.ShowModal;
     3859end;
     3860
     3861procedure TDpiForm.SetFocus;
     3862begin
     3863  GetNativeForm.SetFocus;
    38523864end;
    38533865
  • branches/highdpi/Protocol.pas

    r210 r349  
    1111  nImp = 70; { number of improvements }
    1212  nPl = 15; { max number of players, don't change! }
     13  nWonder = 28; { 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
     
    16611671
    16621672  TNewGameData = record
    1663     lx: Integer;
    1664     ly: Integer;
     1673    lx: Integer; // Map width
     1674    ly: Integer; // Map height
    16651675    LandMass: Integer;
    16661676    MaxTurn: Integer;
     
    17681778procedure DelphiRandomize;
    17691779
     1780
    17701781implementation
    17711782
  • branches/highdpi/Settings.lfm

    r303 r349  
    1414  OnPaint = FormPaint
    1515  OnShow = FormShow
    16   LCLVersion = '2.0.2.0'
    1716  Position = poScreenCenter
    18   PixelsPerInch = 96
     17  LCLVersion = '2.0.12.0'
    1918  Scaled = False
    2019  object List: TDpiListBox
    2120    Tag = 15360
    2221    Left = 24
    23     Height = 336
     22    Height = 304
    2423    Top = 16
    2524    Width = 424
     
    6867    ButtonIndex = 0
    6968  end
     69  object Up2Btn: TButtonC
     70    Tag = 6912
     71    Left = 432
     72    Height = 12
     73    Top = 328
     74    Width = 12
     75    Down = False
     76    Permanent = False
     77    OnClick = Up2BtnClick
     78    ButtonIndex = 1
     79  end
     80  object Down2Btn: TButtonC
     81    Tag = 6912
     82    Left = 432
     83    Height = 12
     84    Top = 340
     85    Width = 12
     86    Down = False
     87    Permanent = False
     88    OnClick = Down2BtnClick
     89    ButtonIndex = 0
     90  end
    7091end
  • branches/highdpi/Settings.pas

    r303 r349  
    2828  TSettingsDlg = class(TDrawDlg)
    2929    ButtonFullscreen: TButtonC;
     30    Down2Btn: TButtonC;
    3031    List: TDpiListBox;
    3132    OKBtn: TButtonA;
    3233    CancelBtn: TButtonA;
     34    Up2Btn: TButtonC;
    3335    procedure ButtonFullscreenClick(Sender: TObject);
    3436    procedure CancelBtnClick(Sender: TObject);
     37    procedure Down2BtnClick(Sender: TObject);
    3538    procedure FormCreate(Sender: TObject);
    3639    procedure FormDestroy(Sender: TObject);
     
    3841    procedure FormShow(Sender: TObject);
    3942    procedure OKBtnClick(Sender: TObject);
     43    procedure Up2BtnClick(Sender: TObject);
    4044  private
    41     { private declarations }
     45    LocalGamma: Integer;
    4246  public
    4347    Languages: TLanguages;
     
    103107  OKBtn.Caption := Phrases.Lookup('BTN_OK');
    104108  CancelBtn.Caption := Phrases.Lookup('BTN_CANCEL');
    105   OkBtn.Graphic := GrExt[HGrSystem].Data;
    106   CancelBtn.Graphic := GrExt[HGrSystem].Data;
    107 
    108   ButtonFullscreen.Graphic := GrExt[HGrSystem].Data;
     109  InitButtons;
    109110end;
    110111
     
    112113begin
    113114  ModalResult := mrCancel;
     115end;
     116
     117procedure TSettingsDlg.Down2BtnClick(Sender: TObject);
     118begin
     119  if LocalGamma > 50 then
     120  begin
     121    Dec(LocalGamma);
     122    Invalidate;
     123  end;
    114124end;
    115125
     
    142152    MainTexture.clBevelLight);
    143153
    144   s := Phrases.Lookup('SETTINGS', 0);
     154  S := Phrases.Lookup('SETTINGS', 0);
    145155  LoweredTextOut(Canvas, -2, MainTexture, ButtonFullscreen.Left + 32,
    146     ButtonFullscreen.Top - 4, s);
     156    ButtonFullscreen.Top - 4, S);
     157
     158  // Gamma
     159  UnderlinedTitleValue(Canvas, Phrases.Lookup('SETTINGS', 1), IntToStr(LocalGamma) + '%',
     160    Up2Btn.Left - 150 - 4, Up2Btn.Top + 2, 150);
    147161end;
    148162
     
    158172  SaveData;
    159173  ModalResult := mrOk;
     174end;
     175
     176procedure TSettingsDlg.Up2BtnClick(Sender: TObject);
     177begin
     178  if LocalGamma < 150 then begin
     179    Inc(LocalGamma);
     180    Invalidate;
     181  end;
    160182end;
    161183
     
    167189  if FullScreen then ButtonFullscreen.ButtonIndex := 3
    168190    else ButtonFullscreen.ButtonIndex := 2;
     191  LocalGamma := Gamma;
    169192end;
    170193
    171194procedure TSettingsDlg.SaveData;
    172 begin
     195var
     196  NeedRestart: Boolean;
     197begin
     198  NeedRestart := Gamma <> LocalGamma;
    173199  LocaleCode := Languages[List.ItemIndex].ShortName;
    174200  FullScreen := (ButtonFullscreen.ButtonIndex and 1) = 1;
     201  Gamma := LocalGamma;
     202  if NeedRestart then SimpleMessage(Phrases.Lookup('SETTINGS', 2));
    175203end;
    176204
  • branches/highdpi/Start.lfm

    r246 r349  
    2525  OnPaint = FormPaint
    2626  OnShow = FormShow
    27   LCLVersion = '2.0.2.0'
    28   PixelsPerInch = 96
     27  LCLVersion = '2.0.12.0'
    2928  Scaled = False
    3029  object StartBtn: TButtonA
     
    197196    ItemHeight = 0
    198197    OnClick = ListClick
     198    OnKeyDown = FormKeyDown
    199199    ParentFont = False
    200200    ScrollWidth = 266
     
    205205  end
    206206  object PopupMenu1: TDpiPopupMenu
    207     left = 8
    208     top = 8
     207    Left = 8
     208    Top = 8
    209209  end
    210210end
  • branches/highdpi/Start.pas

    r308 r349  
    55
    66uses
    7   UDpiControls, GameServer, Messg, ButtonBase, ButtonA, ButtonC, ButtonB, Area,
     7  UDpiControls, GameServer, Messg, ButtonBase, ButtonA, ButtonC, ButtonB, Area, Types,
    88  LCLIntf, LCLType, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls,
    9   Menus, Registry, DrawDlg, fgl, Protocol;
     9  Menus, Registry,  DrawDlg, fgl, Protocol, UMiniMap;
    1010
    1111type
     
    3434  TMainAction = (maConfig, maManual, maCredits, maAIDev, maWeb, maNone);
    3535  TMainActionSet = set of TMainAction;
    36 
    37   TMapArray = array[0 .. lxmax * lymax - 1] of Byte;
    38 
    39   TMiniMode = (mmNone, mmPicture, mmMultiPlayer);
    40 
    41   { TMiniMap }
    42 
    43   TMiniMap = class
    44   const
    45     MaxWidthMapLogo = 96;
    46     MaxHeightMapLogo = 96;
    47   var
    48     Bitmap: TDpiBitmap; { game world sample preview }
    49     Size: TPoint;
    50     Colors: array [0 .. 11, 0 .. 1] of TColor;
    51     Mode: TMiniMode;
    52     procedure LoadFromLogFile(FileName: string; var LastTurn: Integer);
    53     procedure LoadFromMapFile(FileName: string; var nMapLandTiles, nMapStartPositions: Integer);
    54     procedure PaintRandom(Brightness, StartLandMass, WorldSize: Integer);
    55     procedure PaintFile(SaveMap: TMapArray);
    56     constructor Create;
    57     destructor Destroy; override;
    58   end;
    5936
    6037  { TStartDlg }
     
    166143
    167144uses
    168   Global, Directories, Direct, ScreenTools, Inp, Back, Settings, UPixelPointer;
     145  Global, Directories, Direct, ScreenTools, Inp, Back, Settings, UKeyBindings;
    169146
    170147{$R *.lfm}
     
    226203  EnemyAutoDiff: array [1 .. 5] of integer = (4, 3, 2, 1, 1);
    227204
    228 { TMiniMap }
    229 
    230 constructor TMiniMap.Create;
    231 var
    232   X, Y: Integer;
    233 begin
    234   Bitmap := TDpiBitmap.Create;
    235 
    236   for X := 0 to 11 do
    237     for Y := 0 to 1 do
    238       Colors[x, y] := GrExt[HGrSystem].Data.Canvas.Pixels[66 + x, 67 + y];
    239 end;
    240 
    241 destructor TMiniMap.Destroy;
    242 begin
    243   FreeAndNil(Bitmap);
    244   inherited;
    245 end;
    246 
    247 procedure TMiniMap.LoadFromLogFile(FileName: string; var LastTurn: Integer);
    248 var
    249   SaveMap: TMapArray;
    250   y: Integer;
    251   Dummy: Integer;
    252   FileLandMass: integer;
    253   LogFile: file;
    254   s: string[255];
    255   MapRow: array [0 .. lxmax - 1] of Cardinal;
    256 begin
    257   AssignFile(LogFile, FileName);
    258   try
    259     Reset(LogFile, 4);
    260     BlockRead(LogFile, s[1], 2); { file id }
    261     BlockRead(LogFile, Dummy, 1); { format id }
    262     if Dummy >= $000E01 then
    263       BlockRead(LogFile, Dummy, 1); { item stored since 0.14.1 }
    264     BlockRead(LogFile, Size.X, 1);
    265     BlockRead(LogFile, Size.Y, 1);
    266     BlockRead(LogFile, FileLandMass, 1);
    267     if FileLandMass = 0 then
    268       for y := 0 to Size.Y - 1 do
    269         BlockRead(LogFile, MapRow, Size.X);
    270     BlockRead(LogFile, Dummy, 1);
    271     BlockRead(LogFile, Dummy, 1);
    272     BlockRead(LogFile, LastTurn, 1);
    273     BlockRead(LogFile, SaveMap, 1);
    274     if SaveMap[0] = $80 then
    275       Mode := mmMultiPlayer
    276     else
    277       Mode := mmPicture;
    278     if Mode = mmPicture then
    279       BlockRead(LogFile, SaveMap[4], (Size.X * Size.Y - 1) div 4);
    280     CloseFile(LogFile);
    281   except
    282     CloseFile(LogFile);
    283     LastTurn := 0;
    284     Size := WorldSizes[DefaultWorldSize];
    285     Mode := mmNone;
    286   end;
    287   PaintFile(SaveMap);
    288 end;
    289 
    290 procedure TMiniMap.LoadFromMapFile(FileName: string; var nMapLandTiles, nMapStartPositions: Integer);
    291 var
    292   x, y, lxFile, lyFile: integer;
    293   MapFile: file;
    294   s: string[255];
    295   MapRow: array [0 .. lxmax - 1] of Cardinal;
    296   ImageFileName: string;
    297 begin
    298   ImageFileName := Copy(FileName, 1, Length(FileName) - Length(CevoMapExt)) + '.png';
    299   Mode := mmPicture;
    300   if LoadGraphicFile(Bitmap, ImageFileName, [gfNoError]) then
    301   begin
    302     if Bitmap.width div 2 > MaxWidthMapLogo then
    303       Bitmap.width := MaxWidthMapLogo * 2;
    304     if Bitmap.height > MaxHeightMapLogo then
    305       Bitmap.height := MaxHeightMapLogo;
    306     Size.X := Bitmap.width div 2;
    307     Size.Y := Bitmap.height;
    308   end
    309   else
    310   begin
    311     Mode := mmNone;
    312     Size.X := MaxWidthMapLogo;
    313     Size.Y := MaxHeightMapLogo;
    314   end;
    315 
    316   AssignFile(MapFile, FileName);
    317   try
    318     Reset(MapFile, 4);
    319     BlockRead(MapFile, s[1], 2); { file id }
    320     BlockRead(MapFile, x, 1); { format id }
    321     BlockRead(MapFile, x, 1); // MaxTurn
    322     BlockRead(MapFile, lxFile, 1);
    323     BlockRead(MapFile, lyFile, 1);
    324     nMapLandTiles := 0;
    325     nMapStartPositions := 0;
    326     for y := 0 to lyFile - 1 do begin
    327       BlockRead(MapFile, MapRow, lxFile);
    328       for x := 0 to lxFile - 1 do
    329       begin
    330         if (MapRow[x] and fTerrain) in [fGrass, fPrairie, fTundra, fSwamp,
    331           fForest, fHills] then
    332           inc(nMapLandTiles);
    333         if MapRow[x] and (fPrefStartPos or fStartPos) <> 0 then
    334           inc(nMapStartPositions);
    335       end
    336     end;
    337     if nMapStartPositions > nPl then
    338       nMapStartPositions := nPl;
    339     CloseFile(MapFile);
    340   except
    341     CloseFile(MapFile);
    342   end;
    343 end;
    344 
    345 procedure TMiniMap.PaintRandom(Brightness, StartLandMass, WorldSize: Integer);
    346 var
    347   i, x, y, xm, cm: Integer;
    348   MiniPixel: TPixelPointer;
    349   Map: ^TTileList;
    350 begin
    351   Map := PreviewMap(StartLandMass);
    352   Size := WorldSizes[WorldSize];
    353 
    354   Bitmap.PixelFormat := pf24bit;
    355   Bitmap.SetSize(Size.X * 2, Size.Y);
    356   Bitmap.BeginUpdate;
    357   MiniPixel := PixelPointer(Bitmap);
    358   for y := 0 to ScaleToNative(Size.Y) - 1 do begin
    359     for x := 0 to ScaleToNative(Size.X) - 1 do begin
    360       for i := 0 to 1 do begin
    361         xm := (x * 2 + i + y and 1) mod (ScaleToNative(Size.X) * 2);
    362         MiniPixel.SetX(xm);
    363         cm := Colors
    364           [Map[ScaleFromNative(x) * lxmax div Size.X + lxmax *
    365           ((ScaleFromNative(y) * (lymax - 1) + Size.Y div 2) div (Size.Y - 1))] and
    366           fTerrain, i];
    367         MiniPixel.Pixel^.B := ((cm shr 16) and $FF) * Brightness div 3;
    368         MiniPixel.Pixel^.G := ((cm shr 8) and $FF) * Brightness div 3;
    369         MiniPixel.Pixel^.R := ((cm shr 0) and $FF) * Brightness div 3;
    370       end;
    371     end;
    372     MiniPixel.NextLine;
    373   end;
    374   Bitmap.EndUpdate;
    375 end;
    376 
    377 procedure TMiniMap.PaintFile(SaveMap: TMapArray);
    378 var
    379   i, x, y, xm, cm, Tile, OwnColor, EnemyColor: integer;
    380   MiniPixel: TPixelPointer;
    381   PrevMiniPixel: TPixelPointer;
    382   TerrainTile: Cardinal;
    383 begin
    384   OwnColor := GrExt[HGrSystem].Data.Canvas.Pixels[95, 67];
    385   EnemyColor := GrExt[HGrSystem].Data.Canvas.Pixels[96, 67];
    386   Bitmap.PixelFormat := pf24bit;
    387   Bitmap.SetSize(Size.X * 2, Size.Y);
    388   if Mode = mmPicture then begin
    389     Bitmap.BeginUpdate;
    390     MiniPixel := PixelPointer(Bitmap);
    391     PrevMiniPixel := PixelPointer(Bitmap, 0, -1);
    392     for y := 0 to ScaleToNative(Size.Y) - 1 do begin
    393       for x := 0 to ScaleToNative(Size.X) - 1 do begin
    394         for i := 0 to 1 do begin
    395           xm := (x * 2 + i + y and 1) mod (ScaleToNative(Size.X) * 2);
    396           MiniPixel.SetX(xm);
    397           Tile := SaveMap[ScaleFromNative(x) + Size.X * ScaleFromNative(y)];
    398           if Tile and fTerrain = fUNKNOWN then
    399             cm := $000000
    400           else if Tile and smCity <> 0 then
    401           begin
    402             if Tile and smOwned <> 0 then
    403               cm := OwnColor
    404             else
    405               cm := EnemyColor;
    406             if y > 0 then begin
    407               // 2x2 city dot covers two lines
    408               PrevMiniPixel.SetX(xm);
    409               PrevMiniPixel.Pixel^.B := cm shr 16;
    410               PrevMiniPixel.Pixel^.G:= cm shr 8 and $FF;
    411               PrevMiniPixel.Pixel^.R := cm and $FF;
    412             end;
    413           end
    414           else if (i = 0) and (Tile and smUnit <> 0) then
    415             if Tile and smOwned <> 0 then
    416               cm := OwnColor
    417             else cm := EnemyColor
    418           else begin
    419             TerrainTile := Tile and fTerrain;
    420             if TerrainTile > 11 then TerrainTile := 0;
    421             cm := Colors[TerrainTile, i];
    422           end;
    423           MiniPixel.Pixel^.B := (cm shr 16) and $ff;
    424           MiniPixel.Pixel^.G := (cm shr 8) and $ff;
    425           MiniPixel.Pixel^.R := (cm shr 0) and $ff;
    426         end;
    427       end;
    428       MiniPixel.NextLine;
    429       PrevMiniPixel.NextLine;
    430     end;
    431     Bitmap.EndUpdate;
    432   end;
    433 end;
    434 
    435205{ TStartDlg }
    436206
     
    483253  with PlayerSlots[i] do begin
    484254    DiffUpBtn := TButtonC.Create(self);
    485     DiffUpBtn.Graphic := GrExt[HGrSystem].Data;
     255    DiffUpBtn.Graphic := HGrSystem.Data;
    486256    DiffUpBtn.left := xBrain[i] - 18;
    487257    DiffUpBtn.top := yBrain[i] + 39;
     
    490260    DiffUpBtn.OnClick := DiffBtnClick;
    491261    DiffDownBtn := TButtonC.Create(self);
    492     DiffDownBtn.Graphic := GrExt[HGrSystem].Data;
     262    DiffDownBtn.Graphic := HGrSystem.Data;
    493263    DiffDownBtn.left := xBrain[i] - 18;
    494264    DiffDownBtn.top := yBrain[i] + 51;
     
    500270  with PlayerSlots[i] do begin
    501271    MultiBtn := TButtonC.Create(self);
    502     MultiBtn.Graphic := GrExt[HGrSystem].Data;
     272    MultiBtn.Graphic := HGrSystem.Data;
    503273    MultiBtn.left := xBrain[i] - 18;
    504274    MultiBtn.top := yBrain[i];
     
    515285    CustomizeBtn.ButtonIndex := 2;
    516286
    517   BitBltBitmap(BrainNoTerm.Picture, 0, 0, 64, 64, GrExt[HGrSystem2].Data, 1, 111);
    518   BitBltBitmap(BrainSuperVirtual.Picture, 0, 0, 64, 64, GrExt[HGrSystem2].Data, 66, 111);
    519   BitBltBitmap(BrainTerm.Picture, 0, 0, 64, 64, GrExt[HGrSystem2].Data, 131, 111);
    520   BitBltBitmap(BrainRandom.Picture, 0, 0, 64, 64, GrExt[HGrSystem2].Data, 131, 46);
     287  BitBltBitmap(BrainNoTerm.Picture, 0, 0, 64, 64, HGrSystem2.Data, 1, 111);
     288  BitBltBitmap(BrainSuperVirtual.Picture, 0, 0, 64, 64, HGrSystem2.Data, 66, 111);
     289  BitBltBitmap(BrainTerm.Picture, 0, 0, 64, 64, HGrSystem2.Data, 131, 111);
     290  BitBltBitmap(BrainRandom.Picture, 0, 0, 64, 64, HGrSystem2.Data, 131, 46);
    521291  LoadAiBrainsPictures;
    522292
     
    675445  AIBrains: TBrains;
    676446  I: Integer;
     447  TextSize: TSize;
    677448begin
    678449  AIBrains := TBrains.Create(False);
     
    688459        Font.Style := [];
    689460        Font.Color := $5FDBFF;
    690         Textout(32 - TextWidth(FileName) div 2,
    691           32 - TextHeight(FileName) div 2, FileName);
     461        TextSize := TextExtent(FileName);
     462        Textout(32 - TextSize.Width div 2,
     463          32 - TextSize.Height div 2, FileName);
    692464      end;
    693465    end;
     
    731503    $000000, xAction, y + 21, Phrases2.Lookup(TextItem));
    732504
    733   // TODO: Explicitly clear background to black but in fact BitBlt SRCCOPY should do it
    734   LogoBuffer.Canvas.FillRect(0, 0, LogoBuffer.Width, LogoBuffer.Height);
     505  UnshareBitmap(LogoBuffer);
    735506  DpiBitCanvas(LogoBuffer.Canvas, 0, 0, 50, 50, Canvas,
    736507    xActionIcon - 2, y - 2);
     
    829600      TabOffset + (Integer(Tab) + 1) * TabSize + 2, TabHeight, MainTexture.clBevelShade,
    830601      MainTexture.clBevelShade); // Tab shadow
    831   // TODO: Explicitly clear background to black but in fact BitBlt SRCCOPY should do it
    832   LogoBuffer.Canvas.FillRect(0, 0, LogoBuffer.Width, LogoBuffer.Height);
    833   DpiBitCanvas(LogoBuffer.Canvas, 0, 0, 36, 36, Canvas, 6,
     602
     603  // Paint menu logo
     604  UnshareBitmap(LogoBuffer);
     605  DpiBitCanvas(LogoBuffer.Canvas, 0, 0, MenuLogo.Width, MenuLogo.Height, Canvas, 6,
    834606    3 + 2 * integer(Tab <> tbMain));
    835607
    836   ImageOp_BCC(LogoBuffer, Templates, 0, 0, 145, 38, 36, 27, $BFBF20, $4040DF);
    837   // logo part 1
    838   ImageOp_BCC(LogoBuffer, Templates, 10, 27, 155, 38 + 27, 26, 9, $BFBF20,
    839     $4040DF); // logo part 2
    840   DpiBitCanvas(Canvas, 6, 3 + 2 * integer(Tab <> tbMain), 36, 36,
     608  ImageOp_BCC(LogoBuffer, Templates.Data, 0, 0, MenuLogo.Left, MenuLogo.Top,
     609    MenuLogo.Width, MenuLogo.Height - 9, $BFBF20, $4040DF); // logo part 1
     610  ImageOp_BCC(LogoBuffer, Templates.Data, 10, 27, MenuLogo.Left + 10,
     611    MenuLogo.Top + 27, MenuLogo.Width - 10, 9, $BFBF20, $4040DF); // logo part 2
     612  DpiBitCanvas(Canvas, 6, 3 + 2 * integer(Tab <> tbMain), MenuLogo.Width, MenuLogo.Height,
    841613    LogoBuffer.Canvas, 0, 0);
    842614
     
    853625          h := ClientHeight - ActionBottomBorder -
    854626            (yAction + Integer(SelectedAction) * ActionPitch - 8);
    855         // TODO: Explicitly clear background to black but in fact BitBlt SRCCOPY should do it
    856         LogoBuffer.Canvas.FillRect(0, 0, LogoBuffer.Width, LogoBuffer.Height);
     627
     628        UnshareBitmap(LogoBuffer);
    857629        DpiBitCanvas(LogoBuffer.Canvas, 0, 0, w, h, Canvas,
    858630          ActionSideBorder + i * wBuffer, yAction + Integer(SelectedAction) * ActionPitch
     
    877649              // Canvas.Font.Style:=Canvas.Font.Style+[fsUnderline];
    878650              RisedTextOut(Canvas, xActionIcon + 99, y,
    879                 Phrases2.Lookup('ACTIONHEADER_WEB'));
     651                Format(Phrases2.Lookup('ACTIONHEADER_WEB'), [CevoHomepageShort]));
    880652              Canvas.Font.Assign(UniFont[ftNormal]);
    881               // TODO: Explicitly clear background to black but in fact BitBlt SRCCOPY should do it
    882               LogoBuffer.Canvas.FillRect(0, 0, LogoBuffer.Width, LogoBuffer.Height);
    883               DpiBitCanvas(LogoBuffer.Canvas, 0, 0, 91, 25, Canvas,
     653
     654              UnshareBitmap(LogoBuffer);
     655              DpiBitCanvas(LogoBuffer.Canvas, 0, 0, LinkArrows.Width, LinkArrows.Height, Canvas,
    884656                xActionIcon, y + 2);
    885               ImageOp_BCC(LogoBuffer, Templates, 0, 0, 1, 400, 91, 25, 0,
     657              ImageOp_BCC(LogoBuffer, Templates.Data, Point(0, 0), LinkArrows.BoundsRect, 0,
    886658                Colors.Canvas.Pixels[clkAge0 - 1, cliDimmedText]);
    887               DpiBitCanvas(Canvas, xActionIcon, y + 2, 91, 25,
     659              DpiBitCanvas(Canvas, xActionIcon, y + 2, LinkArrows.Width, LinkArrows.Height,
    888660                LogoBuffer.Canvas, 0, 0);
    889661            end;
     
    894666  else if Page in [pgStartRandom, pgStartMap] then
    895667  begin
    896     DLine(Canvas, 344, 514, y0Mini + 61 + 19, MainTexture.clBevelLight,
    897       MainTexture.clBevelShade);
    898     RisedTextOut(Canvas, 344, y0Mini + 61, Phrases.Lookup('STARTCONTROLS', 10));
    899     s := TurnToString(MaxTurn);
    900     RisedTextOut(Canvas, 514 - BiColorTextWidth(Canvas, s), y0Mini + 61, s);
     668    UnderlinedTitleValue(Canvas, Phrases.Lookup('STARTCONTROLS', 10),
     669      TurnToString(MaxTurn), 344, y0Mini + 61, 170);
     670
    901671    s := Phrases.Lookup('STARTCONTROLS', 7);
    902672    w := Canvas.TextWidth(s);
     
    910680        if (i < 13) or (i > 17) then
    911681        begin
    912           DpiBitCanvas(Canvas, 9 + i * 27, yLogo - 2, wOrna, hOrna,
    913             GrExt[HGrSystem2].Mask.Canvas, xOrna, yOrna, SRCAND);
    914           DpiBitCanvas(Canvas, 9 + i * 27, yLogo - 2, wOrna, hOrna,
    915             GrExt[HGrSystem2].Data.Canvas, xOrna, yOrna, SRCPAINT);
     682          DpiBitCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
     683            HGrSystem2.Mask.Canvas, Ornament.Left, Ornament.Top, SRCAND);
     684          DpiBitCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
     685            HGrSystem2.Data.Canvas, Ornament.Left, Ornament.Top, SRCPAINT);
    916686        end;
    917687      PaintLogo(Canvas, 69 + 11 * 27, yLogo, MainTexture.clBevelLight,
     
    930700          begin
    931701            DpiBitCanvas(Canvas, xBrain[i] - 18, yBrain[i] + 19, 12, 14,
    932               GrExt[HGrSystem].Data.Canvas, 134 + (Difficulty[i] - 1) *
     702              HGrSystem.Data.Canvas, 134 + (Difficulty[i] - 1) *
    933703              13, 28);
    934704            Frame(Canvas, xBrain[i] - 19, yBrain[i] + 18, xBrain[i] - 18 + 12,
     
    950720                MainTexture.clBevelShade, MainTexture.clBevelLight);
    951721              DpiBitCanvas(Canvas, xBrain[i] - 31, yBrain[i], 13, 12,
    952                 GrExt[HGrSystem].Data.Canvas, 88, 47);
     722                HGrSystem.Data.Canvas, 88, 47);
    953723            end;
    954724          end;
     
    974744        s := IntToStr(nMapStartPositions - 1);
    975745      RisedTextOut(Canvas, 198 - BiColorTextWidth(Canvas, s), yMain + 140, s);
     746
    976747      DLine(Canvas, 24, xDefault - 6, yMain + 164 + 19,
    977748        MainTexture.clBevelLight, MainTexture.clBevelShade);
     
    986757      DLine(Canvas, 56, 272, y0Mini + 61 + 19, MainTexture.clBevelLight,
    987758        MainTexture.clBevelShade);
     759
    988760      RisedTextOut(Canvas, 56, y0Mini + 61,
    989761        Phrases.Lookup('STARTCONTROLS', 14));
     
    994766        if (i < 2) or (i > 6) then
    995767        begin
    996           DpiBitCanvas(Canvas, 9 + i * 27, yLogo - 2, wOrna, hOrna,
    997             GrExt[HGrSystem2].Mask.Canvas, xOrna, yOrna, SRCAND);
    998           DpiBitCanvas(Canvas, 9 + i * 27, yLogo - 2, wOrna, hOrna,
    999             GrExt[HGrSystem2].Data.Canvas, xOrna, yOrna, SRCPAINT);
     768          DpiBitCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
     769            HGrSystem2.Mask.Canvas, Ornament.Left, Ornament.Top, SRCAND);
     770          DpiBitCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
     771            HGrSystem2.Data.Canvas, Ornament.Left, Ornament.Top, SRCPAINT);
    1000772        end;
    1001773      PaintLogo(Canvas, 69, yLogo, MainTexture.clBevelLight,
     
    1024796  else if Page = pgEditRandom then
    1025797  begin
    1026     DLine(Canvas, 344, 514, y0Mini - 77 + 19, MainTexture.clBevelLight,
    1027       MainTexture.clBevelShade);
    1028     RisedTextOut(Canvas, 344, y0Mini - 77, Phrases.Lookup('STARTCONTROLS', 5));
    1029     s := IntToStr((WorldSizes[WorldSize].X * WorldSizes[WorldSize].Y * 20 +
    1030       DefaultWorldTiles div 2) div DefaultWorldTiles * 5) + '%';
    1031     RisedTextOut(Canvas, 514 - BiColorTextWidth(Canvas, s), y0Mini - 77, s);
    1032     DLine(Canvas, 344, 514, y0Mini + 61 + 19, MainTexture.clBevelLight,
    1033       MainTexture.clBevelShade);
    1034     RisedTextOut(Canvas, 344, y0Mini + 61, Phrases.Lookup('STARTCONTROLS', 6));
    1035     s := IntToStr(StartLandMass) + '%';
    1036     RisedTextOut(Canvas, 514 - BiColorTextWidth(Canvas, s), y0Mini + 61, s);
     798    UnderlinedTitleValue(Canvas, Phrases.Lookup('STARTCONTROLS', 5),
     799      IntToStr((WorldSizes[WorldSize].X * WorldSizes[WorldSize].Y * 20 +
     800      DefaultWorldTiles div 2) div DefaultWorldTiles * 5) + '%',
     801      344, y0Mini - 77, 170);
     802    UnderlinedTitleValue(Canvas, Phrases.Lookup('STARTCONTROLS', 6),
     803      IntToStr(StartLandMass) + '%', 344, y0Mini + 61, 170);
    1037804  end
    1038805  else if Page = pgEditMap then
     
    1098865      s := Phrases.Lookup('MPMAP')
    1099866    else if Page = pgStartMap then
    1100       s := Copy(MapFileName, 1, Length(MapFileName) - 9)
     867      s := Copy(MapFileName, 1, Length(MapFileName) - Length(CevoMapExt))
    1101868    else if Page = pgEditMap then
    1102869      s := List.Items[List.ItemIndex]
     
    12411008      end;
    12421009    pgEditMap:
    1243       EditMap(MapFileName, lxmax, lymax, StartLandMass);
     1010      EditMap(GetMapsDir + DirectorySeparator + MapFileName, lxmax, lymax, StartLandMass);
    12441011    pgEditRandom: // new map
    12451012      begin
     
    12561023        end;
    12571024        MapFileName := Format(Phrases.Lookup('MAP'), [MapCount]) + CevoMapExt;
    1258         EditMap(MapFileName, WorldSizes[WorldSize].X, WorldSizes[WorldSize].Y, StartLandMass);
     1025        EditMap(GetMapsDir + DirectorySeparator + MapFileName,
     1026          WorldSizes[WorldSize].X, WorldSizes[WorldSize].Y, StartLandMass);
    12591027      end;
    12601028  end;
     
    12661034    pgStartRandom: begin
    12671035      MiniMap.Mode := mmPicture;
    1268       MiniMap.PaintRandom(3, StartLandMass, WorldSize);
     1036      MiniMap.PaintRandom(3, StartLandMass, WorldSizes[WorldSize]);
    12691037    end;
    12701038    pgNoLoad: begin
     
    12741042    pgLoad: begin
    12751043        MiniMap.LoadFromLogFile(GetSavedDir + DirectorySeparator +
    1276           List.Items[List.ItemIndex] + CevoExt, LastTurn);
     1044          List.Items[List.ItemIndex] + CevoExt, LastTurn, WorldSizes[DefaultWorldSize]);
    12771045        // BookDate:=DateToStr(FileDateToDateTime(FileAge(FileName)));
    12781046        if not TurnValid then  begin
     
    12861054      MapFileName := '';
    12871055      MiniMap.Mode := mmPicture;
    1288       MiniMap.PaintRandom(4, StartLandMass, WorldSize);
     1056      MiniMap.PaintRandom(4, StartLandMass, WorldSizes[WorldSize]);
    12891057    end;
    12901058    pgStartMap, pgEditMap:
     
    12921060        if Page = pgEditMap then
    12931061          MapFileName := List.Items[List.ItemIndex] + CevoMapExt;
    1294         MiniMap.LoadFromMapFile(GetMapsDir + DirectorySeparator + MapFileName, nMapLandTiles, nMapStartPositions);
     1062        MiniMap.LoadFromMapFile(GetMapsDir + DirectorySeparator + MapFileName,
     1063          nMapLandTiles, nMapStartPositions);
    12951064        if Page = pgEditMap then
    12961065          SmartInvalidate(x0Mini - 112, y0Mini + 61, x0Mini + 112, y0Mini + 91);
     
    14671236  if FindFirst(GetMapsDir + DirectorySeparator + '*' + CevoMapExt, $21, f) = 0 then
    14681237    repeat
    1469       Maps.Add(Copy(f.Name, 1, Length(f.Name) - 9));
     1238      Maps.Add(Copy(f.Name, 1, Length(f.Name) - Length(CevoMapExt)));
    14701239    until FindNext(f) <> 0;
    14711240  FindClose(F);
    14721241  Maps.Sort;
    14731242  Maps.Insert(0, Phrases.Lookup('RANMAP'));
    1474   ListIndex[tbMain] := Maps.IndexOf(Copy(MapFileName, 1, Length(MapFileName) - 9));
     1243  ListIndex[tbMain] := Maps.IndexOf(Copy(MapFileName, 1, Length(MapFileName) - Length(CevoMapExt)));
    14751244  if ListIndex[tbMain] < 0 then
    14761245    ListIndex[tbMain] := 0;
     
    19731742procedure TStartDlg.FormKeyDown(Sender: TObject; var Key: Word;
    19741743  Shift: TShiftState);
    1975 begin
    1976   if KeyToShortCut(Key, Shift) = VK_F1 then
     1744var
     1745  ShortCut: TShortCut;
     1746begin
     1747  ShortCut := KeyToShortCut(Key, Shift);
     1748  if BFullScreen.Test(ShortCut) then begin
     1749    FullScreen := not FullScreen;
     1750    UpdateInterface;
     1751    Background.UpdateInterface;
     1752    SetFocus;
     1753  end else
     1754  if BHelp.Test(ShortCut) then
    19771755    DirectHelp(cStartHelp);
    19781756end;
  • branches/highdpi/readme.txt

    r303 r349  
    1 C-evo 1.3.0 Horizons
    2 ========================
     1C-evo: New Horizons
     2===================
    33
    44* Developed with: Lazarus 2.0.12 (https://www.lazarus-ide.org/)
     
    66* Supported architectures: 32-bit and 64-bit x86
    77
    8 = Code changes to original source =
     8= Main code changes to original source =
    99
    1010* Converted from Delphi to Lazarus
     
    1313* Game text files .txt converted to UTF-8
    1414* Binary .dfm files converted to text .lfm
    15 * Removed external Configurator application written in C#. Use ingame config interface.
    16 * Available localizations included in installed game
     15* Removed external Configurator application written in C#. Use in-game config interface.
     16* Available localizations included in the installed game
    1717* Used latest Delphi StdAI. Newer is implemented in C#.
    1818* Added installer scripts for Windows and Ubuntu/Debian Linux.
    1919* Design time components converted to Lazarus package (cevocomponenets.lpk)
     20* User configurable key bindings
    2021
    2122= Development =
Note: See TracChangeset for help on using the changeset viewer.