Ignore:
Timestamp:
May 9, 2020, 4:02:07 PM (4 years ago)
Author:
chronos
Message:
  • Modified: Improved HighDPI branch. Imported new changes from trunk branch.
File:
1 edited

Legend:

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

    r193 r210  
    55
    66uses
    7 {$IFDEF Windows}
     7  UDpiControls, {$IFDEF Windows}
    88  Windows,
    99{$ENDIF}
     
    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,
    16   UDpiControls;
     15  Forms, Menus, ExtCtrls, dateutils, Platform, ButtonB, ButtonC, EOTButton, Area;
    1716
    1817const
     
    2726
    2827  TMainScreen = class(TDrawDlg)
     28    mBigTiles: TMenuItem;
    2929    Timer1: TTimer;
    3030    GamePopup: TPopupMenu;
     
    219219    procedure mSmallTilesClick(Sender: TObject);
    220220    procedure mNormalTilesClick(Sender: TObject);
     221    procedure mBigTilesClick(Sender: TObject);
    221222    procedure GrWallBtnDownChanged(Sender: TObject);
    222223    procedure BareBtnDownChanged(Sender: TObject);
     
    234235    Closable, RepaintOnResize, Tracking, TurnComplete, Edited, GoOnPhase,
    235236      HaveStrategyAdvice, FirstMovieTurn: boolean;
     237    function ChooseUnusedTribe: integer;
     238    procedure GetTribeList;
     239    procedure InitModule;
     240    procedure InitTurn(NewPlayer: integer);
    236241    procedure ScrollBarUpdate(Sender: TObject);
    237242    procedure ArrangeMidPanel;
     
    271276    procedure SetTileSize(x, y: integer);
    272277    procedure RectInvalidate(Left, Top, Rigth, Bottom: integer);
     278    procedure ShowEnemyShipChange(ShowShipChange: TShowShipChange);
    273279    procedure SmartRectInvalidate(Left, Top, Rigth, Bottom: integer);
     280    procedure LoadSettings;
    274281    procedure SaveSettings;
    275282    procedure OnScroll(var m: TMessage); message WM_VSCROLL;
    276283    procedure OnEOT(var Msg: TMessage); message WM_EOT;
     284    procedure SoundPreload(Check: integer);
    277285  public
    278286    UsedOffscreenWidth, UsedOffscreenHeight: integer;
     
    391399    'CITY_WONDEREX', 'CITY_EMDELAY', 'CITY_FOUNDED', 'CITY_FOUNDED', '',
    392400    'CITY_INVALIDTYPE');
     401
     402  // sound blocks for preload
     403  sbStart = $01;
     404  sbWonder = $02;
     405  sbScience = $04;
     406  sbContact = $08;
     407  sbTurn = $10;
     408  sbAll = $FF;
    393409
    394410type
     
    460476procedure HelpOnTerrain(Loc, NewMode: integer);
    461477
     478
    462479implementation
    463480
    464481uses
    465482  Directories, IsoEngine, CityScreen, Draft, MessgEx, Select, CityType, Help,
    466   UnitStat, Log, Diagram, NatStat, Wonders, Enhance, Nego,
    467   Battle, Rates, TechTree, Registry;
     483  UnitStat, Log, Diagram, NatStat, Wonders, Enhance, Nego, UPixelPointer, Sound,
     484  Battle, Rates, TechTree, Registry, Global;
    468485
    469486{$R *.lfm}
     
    560577        if ydivider > ySizeSmall then
    561578          ydivider := ySizeSmall;
    562         PixelPtr.Init(BigImp, 0, cut + iy * ySizeBig + y);
     579        PixelPtr := PixelPointer(BigImp, 0, cut + iy * ySizeBig + y);
    563580        for x := 0 to xSizeBig - 1 do
    564581        begin
     
    593610  SmallImp.BeginUpdate;
    594611  for y := 0 to ny - 1 do begin
    595     PixelPtr.Init(SmallImp, 0, y);
     612    PixelPtr := PixelPointer(SmallImp, 0, y);
    596613    for x := 0 to nx - 1 do
    597614      for ch := 0 to 2 do begin
     
    12921309end;
    12931310
    1294 procedure TMainScreen.Client(Command, NewPlayer: integer; var Data);
    1295 
    1296   procedure GetTribeList;
    1297   var
    1298     SearchRec: TSearchRec;
    1299     Color: TColor;
    1300     Name: string;
    1301     ok: boolean;
    1302   begin
    1303     UnusedTribeFiles.Clear;
    1304     ok := FindFirst(LocalizedFilePath('Tribes') + DirectorySeparator + '*.tribe.txt',
     1311procedure TMainScreen.SoundPreload(Check: integer);
     1312const
     1313  nStartBlock = 27;
     1314  StartBlock: array [0 .. nStartBlock - 1] of string = ('INVALID', 'TURNEND',
     1315    'DISBAND', 'CHEAT', 'MSG_DEFAULT', 'WARNING_DISORDER', 'WARNING_FAMINE',
     1316    'WARNING_LOWSUPPORT', 'WARNING_LOWFUNDS', 'MOVE_MOUNTAIN', 'MOVE_LOAD',
     1317    'MOVE_UNLOAD', 'MOVE_DIE', 'NOMOVE_TIME', 'NOMOVE_DOMAIN',
     1318    'NOMOVE_DEFAULT', 'CITY_SELLIMP', 'CITY_REBUILDIMP', 'CITY_BUYPROJECT',
     1319    'CITY_UTILIZE', 'NEWMODEL_0', 'NEWADVANCE_0', 'AGE_0', 'REVOLUTION',
     1320    'NEWGOV', 'CITY_INVALIDTYPE', 'MSG_GAMEOVER');
     1321
     1322  nWonderBlock = 6;
     1323  WonderBlock: array [0 .. nWonderBlock - 1] of string = ('WONDER_BUILT',
     1324    'WONDER_CAPTURED', 'WONDER_EXPIRED', 'WONDER_DESTROYED', 'MSG_COLDWAR',
     1325    'NEWADVANCE_GRLIB');
     1326
     1327  nScienceBlock = 17;
     1328  ScienceBlock: array [0 .. nScienceBlock - 1] of string = ('MOVE_PARACHUTE',
     1329    'MOVE_PLANESTART', 'MOVE_PLANELANDING', 'MOVE_COVERT', 'NEWMODEL_1',
     1330    'NEWMODEL_2', 'NEWMODEL_3', 'NEWADVANCE_1', 'NEWADVANCE_2',
     1331    'NEWADVANCE_3', 'AGE_1', 'AGE_2', 'AGE_3', 'SHIP_BUILT', 'SHIP_TRADED',
     1332    'SHIP_CAPTURED', 'SHIP_DESTROYED');
     1333
     1334  nContactBlock = 20;
     1335  ContactBlock: array [0 .. nContactBlock - 1] of string = ('NEWTREATY',
     1336    'CANCELTREATY', 'ACCEPTOFFER', 'MSG_WITHDRAW', 'MSG_BANKRUPT',
     1337    'CONTACT_0', 'CONTACT_1', 'CONTACT_2', 'CONTACT_3', 'CONTACT_4',
     1338    'CONTACT_5', 'CONTACT_5', 'CONTACT_6', 'NEGO_REJECTED', 'MOVE_CAPTURE',
     1339    'MOVE_EXPEL', 'NOMOVE_TREATY', 'NOMOVE_ZOC', 'NOMOVE_SUBMARINE',
     1340    'NOMOVE_STEALTH');
     1341
     1342var
     1343  i, cix, mix: integer;
     1344  need: boolean;
     1345  mi: TModelInfo;
     1346begin
     1347  if Check and sbStart and not SoundPreloadDone <> 0 then
     1348  begin
     1349    for i := 0 to nStartBlock - 1 do
     1350      PreparePlay(StartBlock[i]);
     1351    SoundPreloadDone := SoundPreloadDone or sbStart;
     1352  end;
     1353  if Check and sbWonder and not SoundPreloadDone <> 0 then
     1354  begin
     1355    need := false;
     1356    for i := 0 to 27 do
     1357      if MyRO.Wonder[i].CityID <> -1 then
     1358        need := true;
     1359    if need then
     1360    begin
     1361      for i := 0 to nWonderBlock - 1 do
     1362        PreparePlay(WonderBlock[i]);
     1363      SoundPreloadDone := SoundPreloadDone or sbWonder;
     1364    end;
     1365  end;
     1366  if (Check and sbScience and not SoundPreloadDone <> 0) and
     1367    (MyRO.Tech[adScience] >= tsApplicable) then
     1368  begin
     1369    for i := 0 to nScienceBlock - 1 do
     1370      PreparePlay(ScienceBlock[i]);
     1371    SoundPreloadDone := SoundPreloadDone or sbScience;
     1372  end;
     1373  if (Check and sbContact and not SoundPreloadDone <> 0) and
     1374    (MyRO.nEnemyModel + MyRO.nEnemyCity > 0) then
     1375  begin
     1376    for i := 0 to nContactBlock - 1 do
     1377      PreparePlay(ContactBlock[i]);
     1378    SoundPreloadDone := SoundPreloadDone or sbContact;
     1379  end;
     1380  if Check and sbTurn <> 0 then
     1381  begin
     1382    if MyRO.Happened and phShipComplete <> 0 then
     1383      PreparePlay('MSG_YOUWIN');
     1384    if MyData.ToldAlive <> MyRO.Alive then
     1385      PreparePlay('MSG_EXTINCT');
     1386    for cix := 0 to MyRO.nCity - 1 do
     1387      with MyCity[cix] do
     1388        if (Loc >= 0) and (Flags and CityRepMask <> 0) then
     1389          for i := 0 to 12 do
     1390            if 1 shl i and Flags and CityRepMask <> 0 then
     1391              PreparePlay(CityEventSoundItem[i]);
     1392    for mix := 0 to MyRO.nModel - 1 do
     1393      with MyModel[mix] do
     1394        if Attack > 0 then
     1395        begin
     1396          MakeModelInfo(me, mix, MyModel[mix], mi);
     1397          PreparePlay(AttackSound(ModelCode(mi)));
     1398        end;
     1399  end;
     1400end;
     1401
     1402procedure TMainScreen.GetTribeList;
     1403var
     1404  SearchRec: TSearchRec;
     1405  Color: TColor;
     1406  Name: string;
     1407  ok: boolean;
     1408begin
     1409  UnusedTribeFiles.Clear;
     1410  ok := FindFirst(LocalizedFilePath('Tribes') + DirectorySeparator + '*.tribe.txt',
     1411    faArchive + faReadOnly, SearchRec) = 0;
     1412  if not ok then
     1413  begin
     1414    FindClose(SearchRec);
     1415    ok := FindFirst(LocalizedFilePath('Tribes' + DirectorySeparator + '*.tribe.txt'),
    13051416      faArchive + faReadOnly, SearchRec) = 0;
    1306     if not ok then
    1307     begin
    1308       FindClose(SearchRec);
    1309       ok := FindFirst(LocalizedFilePath('Tribes' + DirectorySeparator + '*.tribe.txt'),
    1310         faArchive + faReadOnly, SearchRec) = 0;
     1417  end;
     1418  if ok then
     1419    repeat
     1420      SearchRec.Name := Copy(SearchRec.Name, 1, Length(SearchRec.Name) - 10);
     1421      if GetTribeInfo(SearchRec.Name, Name, Color) then
     1422        UnusedTribeFiles.AddObject(SearchRec.Name, TObject(Color));
     1423    until FindNext(SearchRec) <> 0;
     1424  FindClose(SearchRec);
     1425end;
     1426
     1427function TMainScreen.ChooseUnusedTribe: integer;
     1428var
     1429  i, j, ColorDistance, BestColorDistance, TestColorDistance,
     1430    CountBest: integer;
     1431begin
     1432  assert(UnusedTribeFiles.Count > 0);
     1433  result := -1;
     1434  BestColorDistance := -1;
     1435  for j := 0 to UnusedTribeFiles.Count - 1 do
     1436  begin
     1437    ColorDistance := 250; // consider differences more than this infinite
     1438    for i := 0 to nPl - 1 do
     1439      if Tribe[i] <> nil then
     1440      begin
     1441        TestColorDistance := abs(integer(UnusedTribeFiles.Objects[j])
     1442          shr 16 and $FF - Tribe[i].Color shr 16 and $FF) +
     1443          abs(integer(UnusedTribeFiles.Objects[j]) shr 8 and
     1444          $FF - Tribe[i].Color shr 8 and $FF) * 3 +
     1445          abs(integer(UnusedTribeFiles.Objects[j]) and
     1446          $FF - Tribe[i].Color and $FF) * 2;
     1447        if TestColorDistance < ColorDistance then
     1448          ColorDistance := TestColorDistance
     1449      end;
     1450    if ColorDistance > BestColorDistance then
     1451    begin
     1452      CountBest := 0;
     1453      BestColorDistance := ColorDistance
    13111454    end;
    1312     if ok then
    1313       repeat
    1314         SearchRec.Name := Copy(SearchRec.Name, 1, Length(SearchRec.Name) - 10);
    1315         if GetTribeInfo(SearchRec.Name, Name, Color) then
    1316           UnusedTribeFiles.AddObject(SearchRec.Name, TObject(Color));
    1317       until FindNext(SearchRec) <> 0;
    1318     FindClose(SearchRec);
    1319   end;
    1320 
    1321   function ChooseUnusedTribe: integer;
    1322   var
    1323     i, j, ColorDistance, BestColorDistance, TestColorDistance,
    1324       CountBest: integer;
    1325   begin
    1326     assert(UnusedTribeFiles.Count > 0);
    1327     result := -1;
    1328     BestColorDistance := -1;
    1329     for j := 0 to UnusedTribeFiles.Count - 1 do
    1330     begin
    1331       ColorDistance := 250; // consider differences more than this infinite
    1332       for i := 0 to nPl - 1 do
    1333         if Tribe[i] <> nil then
    1334         begin
    1335           TestColorDistance := abs(integer(UnusedTribeFiles.Objects[j])
    1336             shr 16 and $FF - Tribe[i].Color shr 16 and $FF) +
    1337             abs(integer(UnusedTribeFiles.Objects[j]) shr 8 and
    1338             $FF - Tribe[i].Color shr 8 and $FF) * 3 +
    1339             abs(integer(UnusedTribeFiles.Objects[j]) and
    1340             $FF - Tribe[i].Color and $FF) * 2;
    1341           if TestColorDistance < ColorDistance then
    1342             ColorDistance := TestColorDistance
     1455    if ColorDistance = BestColorDistance then
     1456    begin
     1457      inc(CountBest);
     1458      if DelphiRandom(CountBest) = 0 then
     1459        result := j
     1460    end
     1461  end;
     1462end;
     1463
     1464procedure TMainScreen.ShowEnemyShipChange(ShowShipChange: TShowShipChange);
     1465var
     1466  i, TestCost, MostCost: integer;
     1467  Ship1Plus, Ship2Plus: boolean;
     1468begin
     1469  with ShowShipChange, MessgExDlg do
     1470  begin
     1471    case Reason of
     1472      scrProduction:
     1473        begin
     1474          OpenSound := 'SHIP_BUILT';
     1475          MessgText := Tribe[Ship1Owner].TPhrase('SHIPBUILT');
     1476          IconKind := mikShip;
     1477          IconIndex := Ship1Owner;
    13431478        end;
    1344       if ColorDistance > BestColorDistance then
    1345       begin
    1346         CountBest := 0;
    1347         BestColorDistance := ColorDistance
     1479
     1480      scrDestruction:
     1481        begin
     1482          OpenSound := 'SHIP_DESTROYED';
     1483          MessgText := Tribe[Ship1Owner].TPhrase('SHIPDESTROYED');
     1484          IconKind := mikImp;
     1485        end;
     1486
     1487      scrTrade:
     1488        begin
     1489          OpenSound := 'SHIP_TRADED';
     1490          Ship1Plus := false;
     1491          Ship2Plus := false;
     1492          for i := 0 to nShipPart - 1 do
     1493          begin
     1494            if Ship1Change[i] > 0 then
     1495              Ship1Plus := true;
     1496            if Ship2Change[i] > 0 then
     1497              Ship2Plus := true;
     1498          end;
     1499          if Ship1Plus and Ship2Plus then
     1500            MessgText := Tribe[Ship1Owner].TPhrase('SHIPBITRADE1') + ' ' +
     1501              Tribe[Ship2Owner].TPhrase('SHIPBITRADE2')
     1502          else if Ship1Plus then
     1503            MessgText := Tribe[Ship1Owner].TPhrase('SHIPUNITRADE1') + ' ' +
     1504              Tribe[Ship2Owner].TPhrase('SHIPUNITRADE2')
     1505          else // if Ship2Plus then
     1506            MessgText := Tribe[Ship2Owner].TPhrase('SHIPUNITRADE1') + ' ' +
     1507              Tribe[Ship1Owner].TPhrase('SHIPUNITRADE2');
     1508          IconKind := mikImp;
     1509        end;
     1510
     1511      scrCapture:
     1512        begin
     1513          OpenSound := 'SHIP_CAPTURED';
     1514          MessgText := Tribe[Ship2Owner].TPhrase('SHIPCAPTURE1') + ' ' +
     1515            Tribe[Ship1Owner].TPhrase('SHIPCAPTURE2');
     1516          IconKind := mikShip;
     1517          IconIndex := Ship2Owner;
     1518        end
     1519    end;
     1520
     1521    if IconKind = mikImp then
     1522    begin
     1523      MostCost := 0;
     1524      for i := 0 to nShipPart - 1 do
     1525      begin
     1526        TestCost := abs(Ship1Change[i]) * Imp[imShipComp + i].Cost;
     1527        if TestCost > MostCost then
     1528        begin
     1529          MostCost := TestCost;
     1530          IconIndex := imShipComp + i
     1531        end
    13481532      end;
    1349       if ColorDistance = BestColorDistance then
    1350       begin
    1351         inc(CountBest);
    1352         if DelphiRandom(CountBest) = 0 then
    1353           result := j
    1354       end
    13551533    end;
    1356   end;
    1357 
    1358   procedure ShowEnemyShipChange(ShowShipChange: TShowShipChange);
    1359   var
    1360     i, TestCost, MostCost: integer;
    1361     Ship1Plus, Ship2Plus: boolean;
    1362   begin
    1363     with ShowShipChange, MessgExDlg do
    1364     begin
    1365       case Reason of
    1366         scrProduction:
    1367           begin
    1368             OpenSound := 'SHIP_BUILT';
    1369             MessgText := Tribe[Ship1Owner].TPhrase('SHIPBUILT');
    1370             IconKind := mikShip;
    1371             IconIndex := Ship1Owner;
    1372           end;
    1373 
    1374         scrDestruction:
    1375           begin
    1376             OpenSound := 'SHIP_DESTROYED';
    1377             MessgText := Tribe[Ship1Owner].TPhrase('SHIPDESTROYED');
    1378             IconKind := mikImp;
    1379           end;
    1380 
    1381         scrTrade:
    1382           begin
    1383             OpenSound := 'SHIP_TRADED';
    1384             Ship1Plus := false;
    1385             Ship2Plus := false;
    1386             for i := 0 to nShipPart - 1 do
    1387             begin
    1388               if Ship1Change[i] > 0 then
    1389                 Ship1Plus := true;
    1390               if Ship2Change[i] > 0 then
    1391                 Ship2Plus := true;
    1392             end;
    1393             if Ship1Plus and Ship2Plus then
    1394               MessgText := Tribe[Ship1Owner].TPhrase('SHIPBITRADE1') + ' ' +
    1395                 Tribe[Ship2Owner].TPhrase('SHIPBITRADE2')
    1396             else if Ship1Plus then
    1397               MessgText := Tribe[Ship1Owner].TPhrase('SHIPUNITRADE1') + ' ' +
    1398                 Tribe[Ship2Owner].TPhrase('SHIPUNITRADE2')
    1399             else // if Ship2Plus then
    1400               MessgText := Tribe[Ship2Owner].TPhrase('SHIPUNITRADE1') + ' ' +
    1401                 Tribe[Ship1Owner].TPhrase('SHIPUNITRADE2');
    1402             IconKind := mikImp;
    1403           end;
    1404 
    1405         scrCapture:
    1406           begin
    1407             OpenSound := 'SHIP_CAPTURED';
    1408             MessgText := Tribe[Ship2Owner].TPhrase('SHIPCAPTURE1') + ' ' +
    1409               Tribe[Ship1Owner].TPhrase('SHIPCAPTURE2');
    1410             IconKind := mikShip;
    1411             IconIndex := Ship2Owner;
    1412           end
    1413       end;
    1414 
    1415       if IconKind = mikImp then
    1416       begin
    1417         MostCost := 0;
    1418         for i := 0 to nShipPart - 1 do
    1419         begin
    1420           TestCost := abs(Ship1Change[i]) * Imp[imShipComp + i].Cost;
    1421           if TestCost > MostCost then
    1422           begin
    1423             MostCost := TestCost;
    1424             IconIndex := imShipComp + i
    1425           end
    1426         end;
    1427       end;
    1428 
    1429       Kind := mkOk;
    1430       ShowModal;
    1431     end;
    1432   end;
    1433 
    1434   procedure InitModule;
    1435   var
    1436     x, y, i, j, Domain: integer;
    1437   begin
    1438     { search icons for advances: }
    1439     for i := 0 to nAdv - 1 do
    1440       if i in FutureTech then
    1441         AdvIcon[i] := 96 + i - futResearchTechnology
    1442       else
    1443       begin
    1444         AdvIcon[i] := -1;
    1445         for Domain := 0 to nDomains - 1 do
    1446           for j := 0 to nUpgrade - 1 do
    1447             if upgrade[Domain, j].Preq = i then
    1448               if AdvIcon[i] >= 0 then
     1534
     1535    Kind := mkOk;
     1536    ShowModal;
     1537  end;
     1538end;
     1539
     1540procedure TMainScreen.InitModule;
     1541var
     1542  x, y, i, j, Domain: integer;
     1543begin
     1544  { search icons for advances: }
     1545  for i := 0 to nAdv - 1 do
     1546    if i in FutureTech then
     1547      AdvIcon[i] := 96 + i - futResearchTechnology
     1548    else
     1549    begin
     1550      AdvIcon[i] := -1;
     1551      for Domain := 0 to nDomains - 1 do
     1552        for j := 0 to nUpgrade - 1 do
     1553          if upgrade[Domain, j].Preq = i then
     1554            if AdvIcon[i] >= 0 then
     1555              AdvIcon[i] := 85
     1556            else
     1557              AdvIcon[i] := 86 + Domain;
     1558      for j := 0 to nFeature - 1 do
     1559        if Feature[j].Preq = i then
     1560          for Domain := 0 to nDomains - 1 do
     1561            if 1 shl Domain and Feature[j].Domains <> 0 then
     1562              if (AdvIcon[i] >= 0) and (AdvIcon[i] <> 86 + Domain) then
    14491563                AdvIcon[i] := 85
    14501564              else
    14511565                AdvIcon[i] := 86 + Domain;
    1452         for j := 0 to nFeature - 1 do
    1453           if Feature[j].Preq = i then
    1454             for Domain := 0 to nDomains - 1 do
    1455               if 1 shl Domain and Feature[j].Domains <> 0 then
    1456                 if (AdvIcon[i] >= 0) and (AdvIcon[i] <> 86 + Domain) then
    1457                   AdvIcon[i] := 85
    1458                 else
    1459                   AdvIcon[i] := 86 + Domain;
    1460         for j := 28 to nImp - 1 do
    1461           if Imp[j].Preq = i then
    1462             AdvIcon[i] := j;
    1463         for j := 28 to nImp - 1 do
    1464           if (Imp[j].Preq = i) and (Imp[j].Kind <> ikCommon) then
    1465             AdvIcon[i] := j;
    1466         for j := 0 to nJob - 1 do
    1467           if i = JobPreq[j] then
    1468             AdvIcon[i] := 84;
    1469         for j := 0 to 27 do
    1470           if Imp[j].Preq = i then
    1471             AdvIcon[i] := j;
    1472         if AdvIcon[i] < 0 then
    1473           if AdvValue[i] < 1000 then
    1474             AdvIcon[i] := -7
    1475           else
    1476             AdvIcon[i] := 24 + AdvValue[i] div 1000;
    1477         for j := 2 to nGov - 1 do
    1478           if GovPreq[j] = i then
    1479             AdvIcon[i] := j - 8;
    1480       end;
    1481     AdvIcon[adConscription] := 86 + dGround;
    1482 
    1483     UnusedTribeFiles := tstringlist.Create;
    1484     UnusedTribeFiles.Sorted := true;
    1485     TribeNames := tstringlist.Create;
    1486 
    1487     for x := 0 to 11 do
    1488       for y := 0 to 1 do
    1489         MiniColors[x, y] := GrExt[HGrSystem].Data.Canvas.Pixels[66 + x, 67 + y];
    1490     IsoEngine.Init(InitEnemyModel);
    1491     if not IsoEngine.ApplyTileSize(xxt, yyt) and ((xxt <> 48) or (yyt <> 24))
    1492     then
    1493       ApplyTileSize(48, 24);
    1494     // non-default tile size is missing a file, switch to default
    1495     MainMap := TIsoMap.Create;
    1496     MainMap.SetOutput(offscreen);
    1497 
    1498     HGrStdUnits := LoadGraphicSet('StdUnits.png');
    1499     SmallImp := TDpiBitmap.Create;
    1500     SmallImp.PixelFormat := pf24bit;
    1501     InitSmallImp;
    1502     SoundPreloadDone := 0;
    1503     StartRunning := false;
    1504     StayOnTop_Ensured := false;
    1505 
    1506     sb := TPVScrollbar.Create(Self);
    1507     sb.OnUpdate := ScrollBarUpdate;
    1508   end; { InitModule }
    1509 
    1510 // sound blocks for preload
     1566      for j := 28 to nImp - 1 do
     1567        if Imp[j].Preq = i then
     1568          AdvIcon[i] := j;
     1569      for j := 28 to nImp - 1 do
     1570        if (Imp[j].Preq = i) and (Imp[j].Kind <> ikCommon) then
     1571          AdvIcon[i] := j;
     1572      for j := 0 to nJob - 1 do
     1573        if i = JobPreq[j] then
     1574          AdvIcon[i] := 84;
     1575      for j := 0 to 27 do
     1576        if Imp[j].Preq = i then
     1577          AdvIcon[i] := j;
     1578      if AdvIcon[i] < 0 then
     1579        if AdvValue[i] < 1000 then
     1580          AdvIcon[i] := -7
     1581        else
     1582          AdvIcon[i] := 24 + AdvValue[i] div 1000;
     1583      for j := 2 to nGov - 1 do
     1584        if GovPreq[j] = i then
     1585          AdvIcon[i] := j - 8;
     1586    end;
     1587  AdvIcon[adConscription] := 86 + dGround;
     1588
     1589  UnusedTribeFiles := tstringlist.Create;
     1590  UnusedTribeFiles.Sorted := true;
     1591  TribeNames := tstringlist.Create;
     1592
     1593  for x := 0 to 11 do
     1594    for y := 0 to 1 do
     1595      MiniColors[x, y] := GrExt[HGrSystem].Data.Canvas.Pixels[66 + x, 67 + y];
     1596  IsoEngine.Init(InitEnemyModel);
     1597  if not IsoEngine.ApplyTileSize(xxt, yyt) and ((xxt <> 48) or (yyt <> 24) or (xxt <> 72))
     1598  then
     1599    ApplyTileSize(48, 24);
     1600  // non-default tile size is missing a file, switch to default
     1601  MainMap := TIsoMap.Create;
     1602  MainMap.SetOutput(offscreen);
     1603
     1604  HGrStdUnits := LoadGraphicSet('StdUnits.png');
     1605  SmallImp := TDpiBitmap.Create;
     1606  SmallImp.PixelFormat := pf24bit;
     1607  InitSmallImp;
     1608  SoundPreloadDone := 0;
     1609  StartRunning := false;
     1610  StayOnTop_Ensured := false;
     1611
     1612  sb := TPVScrollbar.Create(Self);
     1613  sb.OnUpdate := ScrollBarUpdate;
     1614end; { InitModule }
     1615
     1616procedure TMainScreen.InitTurn(NewPlayer: integer);
    15111617const
    1512   sbStart = $01;
    1513   sbWonder = $02;
    1514   sbScience = $04;
    1515   sbContact = $08;
    1516   sbTurn = $10;
    1517   sbAll = $FF;
    1518 
    1519   procedure SoundPreload(Check: integer);
    1520   const
    1521     nStartBlock = 27;
    1522     StartBlock: array [0 .. nStartBlock - 1] of string = ('INVALID', 'TURNEND',
    1523       'DISBAND', 'CHEAT', 'MSG_DEFAULT', 'WARNING_DISORDER', 'WARNING_FAMINE',
    1524       'WARNING_LOWSUPPORT', 'WARNING_LOWFUNDS', 'MOVE_MOUNTAIN', 'MOVE_LOAD',
    1525       'MOVE_UNLOAD', 'MOVE_DIE', 'NOMOVE_TIME', 'NOMOVE_DOMAIN',
    1526       'NOMOVE_DEFAULT', 'CITY_SELLIMP', 'CITY_REBUILDIMP', 'CITY_BUYPROJECT',
    1527       'CITY_UTILIZE', 'NEWMODEL_0', 'NEWADVANCE_0', 'AGE_0', 'REVOLUTION',
    1528       'NEWGOV', 'CITY_INVALIDTYPE', 'MSG_GAMEOVER');
    1529 
    1530     nWonderBlock = 6;
    1531     WonderBlock: array [0 .. nWonderBlock - 1] of string = ('WONDER_BUILT',
    1532       'WONDER_CAPTURED', 'WONDER_EXPIRED', 'WONDER_DESTROYED', 'MSG_COLDWAR',
    1533       'NEWADVANCE_GRLIB');
    1534 
    1535     nScienceBlock = 17;
    1536     ScienceBlock: array [0 .. nScienceBlock - 1] of string = ('MOVE_PARACHUTE',
    1537       'MOVE_PLANESTART', 'MOVE_PLANELANDING', 'MOVE_COVERT', 'NEWMODEL_1',
    1538       'NEWMODEL_2', 'NEWMODEL_3', 'NEWADVANCE_1', 'NEWADVANCE_2',
    1539       'NEWADVANCE_3', 'AGE_1', 'AGE_2', 'AGE_3', 'SHIP_BUILT', 'SHIP_TRADED',
    1540       'SHIP_CAPTURED', 'SHIP_DESTROYED');
    1541 
    1542     nContactBlock = 20;
    1543     ContactBlock: array [0 .. nContactBlock - 1] of string = ('NEWTREATY',
    1544       'CANCELTREATY', 'ACCEPTOFFER', 'MSG_WITHDRAW', 'MSG_BANKRUPT',
    1545       'CONTACT_0', 'CONTACT_1', 'CONTACT_2', 'CONTACT_3', 'CONTACT_4',
    1546       'CONTACT_5', 'CONTACT_5', 'CONTACT_6', 'NEGO_REJECTED', 'MOVE_CAPTURE',
    1547       'MOVE_EXPEL', 'NOMOVE_TREATY', 'NOMOVE_ZOC', 'NOMOVE_SUBMARINE',
    1548       'NOMOVE_STEALTH');
    1549 
    1550   var
    1551     i, cix, mix: integer;
    1552     need: boolean;
    1553     mi: TModelInfo;
    1554   begin
    1555     if Check and sbStart and not SoundPreloadDone <> 0 then
    1556     begin
    1557       for i := 0 to nStartBlock - 1 do
    1558         PreparePlay(StartBlock[i]);
    1559       SoundPreloadDone := SoundPreloadDone or sbStart;
    1560     end;
    1561     if Check and sbWonder and not SoundPreloadDone <> 0 then
    1562     begin
    1563       need := false;
    1564       for i := 0 to 27 do
    1565         if MyRO.Wonder[i].CityID <> -1 then
    1566           need := true;
    1567       if need then
    1568       begin
    1569         for i := 0 to nWonderBlock - 1 do
    1570           PreparePlay(WonderBlock[i]);
    1571         SoundPreloadDone := SoundPreloadDone or sbWonder;
    1572       end;
    1573     end;
    1574     if (Check and sbScience and not SoundPreloadDone <> 0) and
    1575       (MyRO.Tech[adScience] >= tsApplicable) then
    1576     begin
    1577       for i := 0 to nScienceBlock - 1 do
    1578         PreparePlay(ScienceBlock[i]);
    1579       SoundPreloadDone := SoundPreloadDone or sbScience;
    1580     end;
    1581     if (Check and sbContact and not SoundPreloadDone <> 0) and
    1582       (MyRO.nEnemyModel + MyRO.nEnemyCity > 0) then
    1583     begin
    1584       for i := 0 to nContactBlock - 1 do
    1585         PreparePlay(ContactBlock[i]);
    1586       SoundPreloadDone := SoundPreloadDone or sbContact;
    1587     end;
    1588     if Check and sbTurn <> 0 then
    1589     begin
    1590       if MyRO.Happened and phShipComplete <> 0 then
    1591         PreparePlay('MSG_YOUWIN');
    1592       if MyData.ToldAlive <> MyRO.Alive then
    1593         PreparePlay('MSG_EXTINCT');
    1594       for cix := 0 to MyRO.nCity - 1 do
    1595         with MyCity[cix] do
    1596           if (Loc >= 0) and (Flags and CityRepMask <> 0) then
    1597             for i := 0 to 12 do
    1598               if 1 shl i and Flags and CityRepMask <> 0 then
    1599                 PreparePlay(CityEventSoundItem[i]);
    1600       for mix := 0 to MyRO.nModel - 1 do
    1601         with MyModel[mix] do
    1602           if Attack > 0 then
    1603           begin
    1604             MakeModelInfo(me, mix, MyModel[mix], mi);
    1605             PreparePlay(AttackSound(ModelCode(mi)));
    1606           end
    1607     end
    1608   end;
    1609 
    1610   procedure InitTurn(p: integer);
    1611   const
    1612     nAdvBookIcon = 16;
    1613     AdvBookIcon: array [0 .. nAdvBookIcon - 1] of record Adv,
    1614       Icon: integer end = ((Adv: adPolyTheism; Icon: woZeus),
    1615       (Adv: adBronzeWorking; Icon: woColossus), (Adv: adMapMaking;
    1616       Icon: woLighthouse), (Adv: adPoetry; Icon: imTheater), (Adv: adMonotheism;
    1617       Icon: woMich), (Adv: adPhilosophy; Icon: woLeo), (Adv: adTheoryOfGravity;
    1618       Icon: woNewton), (Adv: adSteel; Icon: woEiffel), (Adv: adDemocracy;
    1619       Icon: woLiberty), (Adv: adAutomobile; Icon: imHighways),
    1620       (Adv: adSanitation; Icon: imSewer), (Adv: adElectronics; Icon: woHoover),
    1621       (Adv: adNuclearFission; Icon: woManhattan), (Adv: adRecycling;
    1622       Icon: imRecycling), (Adv: adComputers; Icon: imResLab),
    1623       (Adv: adSpaceFlight; Icon: woMIR));
    1624   var
    1625     Domain, p1, i, ad, uix, cix, MoveOptions, MoveResult, Loc1, Dist,
    1626       NewAgeCenterTo, Bankrupt, ShipMore, Winners, NewGovAvailable, dx,
    1627       dy: integer;
    1628     MoveAdviceData: TMoveAdviceData;
    1629     Picture: TModelPictureInfo;
    1630     s, Item, Item2: string;
    1631     UpdatePanel, OwnWonder, ok, Stop, ShowCityList, WondersOnly,
    1632       AllowCityScreen: boolean;
    1633   begin
    1634     if IsMultiPlayerGame and (p <> me) then
    1635     begin
    1636       UnitInfoBtn.Visible := false;
    1637       UnitBtn.Visible := false;
    1638       TerrainBtn.Visible := false;
    1639       EOT.Visible := false;
    1640     end;
    1641     if IsMultiPlayerGame and (p <> me) and
    1642       (G.RO[0].Happened and phShipComplete = 0) then
    1643     begin // inter player screen
    1644       for i := 0 to ControlCount - 1 do
    1645         if Controls[i] is TButtonC then
    1646           Controls[i].Visible := false;
    1647       me := -1;
    1648       SetMainTextureByAge(-1);
    1649       with Panel.Canvas do
    1650       begin
    1651         Brush.Color := $000000;
    1652         FillRect(Rect(0, 0, Panel.width, Panel.height));
    1653         Brush.Style := bsClear;
    1654       end;
    1655       with TopBar.Canvas do
    1656       begin
    1657         Brush.Color := $000000;
    1658         FillRect(Rect(0, 0, TopBar.width, TopBar.height));
    1659         Brush.Style := bsClear;
    1660       end;
    1661       Invalidate;
    1662 
    1663       s := TurnToString(G.RO[0].Turn);
    1664       if supervising then
    1665         SimpleMessage(Format(Phrases.Lookup('SUPERTURN'), [s]))
    1666       else
    1667         SimpleMessage(Format(Tribe[NewPlayer].TPhrase('TURN'), [s]));
    1668     end;
     1618  nAdvBookIcon = 16;
     1619  AdvBookIcon: array [0 .. nAdvBookIcon - 1] of record Adv,
     1620    Icon: integer end = ((Adv: adPolyTheism; Icon: woZeus),
     1621    (Adv: adBronzeWorking; Icon: woColossus), (Adv: adMapMaking;
     1622    Icon: woLighthouse), (Adv: adPoetry; Icon: imTheater), (Adv: adMonotheism;
     1623    Icon: woMich), (Adv: adPhilosophy; Icon: woLeo), (Adv: adTheoryOfGravity;
     1624    Icon: woNewton), (Adv: adSteel; Icon: woEiffel), (Adv: adDemocracy;
     1625    Icon: woLiberty), (Adv: adAutomobile; Icon: imHighways),
     1626    (Adv: adSanitation; Icon: imSewer), (Adv: adElectronics; Icon: woHoover),
     1627    (Adv: adNuclearFission; Icon: woManhattan), (Adv: adRecycling;
     1628    Icon: imRecycling), (Adv: adComputers; Icon: imResLab),
     1629    (Adv: adSpaceFlight; Icon: woMIR));
     1630var
     1631  p1, i, ad, uix, cix, MoveOptions, MoveResult, Loc1,
     1632    NewAgeCenterTo, Winners, NewGovAvailable, dx,
     1633    dy: integer;
     1634  MoveAdviceData: TMoveAdviceData;
     1635  Picture: TModelPictureInfo;
     1636  s, Item, Item2: string;
     1637  UpdatePanel, OwnWonder, ok, Stop, ShowCityList, WondersOnly,
     1638    AllowCityScreen: boolean;
     1639begin
     1640  if IsMultiPlayerGame and (NewPlayer <> me) then
     1641  begin
     1642    UnitInfoBtn.Visible := false;
     1643    UnitBtn.Visible := false;
     1644    TerrainBtn.Visible := false;
     1645    EOT.Visible := false;
     1646  end;
     1647  if IsMultiPlayerGame and (NewPlayer <> me) and
     1648    (G.RO[0].Happened and phShipComplete = 0) then
     1649  begin // inter player screen
    16691650    for i := 0 to ControlCount - 1 do
    16701651      if Controls[i] is TButtonC then
    1671         Controls[i].Visible := true;
    1672 
    1673     ItsMeAgain(p);
    1674     MyData := G.RO[p].Data;
    1675     if not supervising then
    1676       SoundPreload(sbAll);
    1677     if (me = 0) and ((MyRO.Turn = 0) or (ClientMode = cResume)) then
    1678       Invalidate; // colorize empty space
    1679 
    1680     if not supervising then
    1681     begin
    1682 
    1683       { if MyRO.Happened and phGameEnd<>0 then
    1684         begin
    1685         Age:=3;
    1686         SetMainTextureByAge(-1);
     1652        Controls[i].Visible := false;
     1653    me := -1;
     1654    SetMainTextureByAge(-1);
     1655    with Panel.Canvas do
     1656    begin
     1657      Brush.Color := $000000;
     1658      FillRect(Rect(0, 0, Panel.width, Panel.height));
     1659      Brush.Style := bsClear;
     1660    end;
     1661    with TopBar.Canvas do
     1662    begin
     1663      Brush.Color := $000000;
     1664      FillRect(Rect(0, 0, TopBar.width, TopBar.height));
     1665      Brush.Style := bsClear;
     1666    end;
     1667    Invalidate;
     1668
     1669    s := TurnToString(G.RO[0].Turn);
     1670    if supervising then
     1671      SimpleMessage(Format(Phrases.Lookup('SUPERTURN'), [s]))
     1672    else
     1673      SimpleMessage(Format(Tribe[NewPlayer].TPhrase('TURN'), [s]));
     1674  end;
     1675  for i := 0 to ControlCount - 1 do
     1676    if Controls[i] is TButtonC then
     1677      Controls[i].Visible := true;
     1678
     1679  ItsMeAgain(NewPlayer);
     1680  MyData := G.RO[NewPlayer].Data;
     1681  if not supervising then
     1682    SoundPreload(sbAll);
     1683  if (me = 0) and ((MyRO.Turn = 0) or (ClientMode = cResume)) then
     1684    Invalidate; // colorize empty space
     1685
     1686  if not supervising then
     1687  begin
     1688
     1689    { if MyRO.Happened and phGameEnd<>0 then
     1690      begin
     1691      Age:=3;
     1692      SetMainTextureByAge(-1);
     1693      end
     1694      else }
     1695    begin
     1696      Age := GetAge(me);
     1697      if SetMainTextureByAge(Age) then
     1698        EOT.Invalidate; // has visible background parts in its bounds
     1699    end;
     1700    // age:=MyRO.Turn mod 4; //!!!
     1701    if ClientMode = cMovieTurn then
     1702      EOT.ButtonIndex := eotCancel
     1703    else if ClientMode < scContact then
     1704      EOT.ButtonIndex := eotGray
     1705    else
     1706      EOT.ButtonIndex := eotBackToNego;
     1707  end
     1708  else
     1709  begin
     1710    Age := 0;
     1711    SetMainTextureByAge(-1);
     1712    if ClientMode = cMovieTurn then
     1713      EOT.ButtonIndex := eotCancel
     1714    else
     1715      EOT.ButtonIndex := eotBlinkOn;
     1716  end;
     1717  InitCityMark(MainTexture);
     1718  CityDlg.CheckAge;
     1719  NatStatDlg.CheckAge;
     1720  UnitStatDlg.CheckAge;
     1721  HelpDlg.Difficulty := G.Difficulty[me];
     1722
     1723  UnFocus := -1;
     1724  MarkCityLoc := -1;
     1725  BlinkON := false;
     1726  BlinkTime := -1;
     1727  Tracking := false;
     1728  TurnComplete := false;
     1729
     1730  if (ToldSlavery < 0) or
     1731    ((ToldSlavery = 1) <> (MyRO.Wonder[woPyramids].EffectiveOwner >= 0)) then
     1732  begin
     1733    if MyRO.Wonder[woPyramids].EffectiveOwner >= 0 then
     1734      ToldSlavery := 1
     1735    else
     1736      ToldSlavery := 0;
     1737    for p1 := 0 to nPl - 1 do
     1738      if (Tribe[p1] <> nil) and (Tribe[p1].mixSlaves >= 0) then
     1739        with Picture do
     1740        begin // replace unit picture
     1741          mix := Tribe[p1].mixSlaves;
     1742          if ToldSlavery = 1 then
     1743            pix := pixSlaves
     1744          else
     1745            pix := pixNoSlaves;
     1746          Hash := 0;
     1747          GrName := 'StdUnits.png';
     1748          Tribe[p1].SetModelPicture(Picture, true);
    16871749        end
    1688         else }
    1689       begin
    1690         Age := GetAge(me);
    1691         if SetMainTextureByAge(Age) then
    1692           EOT.Invalidate; // has visible background parts in its bounds
     1750  end;
     1751
     1752  if not supervising and (ClientMode = cTurn) then
     1753  begin
     1754    for cix := 0 to MyRO.nCity - 1 do
     1755      if (MyCity[cix].Loc >= 0) and
     1756        ((MyRO.Turn = 0) or (MyCity[cix].Flags and chFounded <> 0)) then
     1757        MyCity[cix].Status := MyCity[cix].Status and
     1758          not csResourceWeightsMask or (3 shl 4);
     1759    // new city, set to maximum growth
     1760  end;
     1761  if (ClientMode = cTurn) or (ClientMode = cContinue) then
     1762    CityOptimizer_BeginOfTurn; // maybe peace was made or has ended
     1763  SumCities(TaxSum, ScienceSum);
     1764
     1765  if ClientMode = cMovieTurn then
     1766  begin
     1767    UnitInfoBtn.Visible := false;
     1768    UnitBtn.Visible := false;
     1769    TerrainBtn.Visible := false;
     1770    EOT.Hint := Phrases.Lookup('BTN_STOP');
     1771    EOT.Visible := true;
     1772  end
     1773  else if ClientMode < scContact then
     1774  begin
     1775    UnitInfoBtn.Visible := UnFocus >= 0;
     1776    UnitBtn.Visible := UnFocus >= 0;
     1777    CheckTerrainBtnVisible;
     1778    TurnComplete := supervising;
     1779    EOT.Hint := Phrases.Lookup('BTN_ENDTURN');
     1780    EOT.Visible := Server(sTurn - sExecute, me, 0, nil^) >= rExecuted;
     1781  end
     1782  else
     1783  begin
     1784    UnitInfoBtn.Visible := false;
     1785    UnitBtn.Visible := false;
     1786    TerrainBtn.Visible := false;
     1787    EOT.Hint := Phrases.Lookup('BTN_NEGO');
     1788    EOT.Visible := true;
     1789  end;
     1790  SetTroopLoc(-1);
     1791  MapValid := false;
     1792  NewAgeCenterTo := 0;
     1793  if ((MyRO.Turn = 0) and not supervising or IsMultiPlayerGame or
     1794    (ClientMode = cResume)) and (MyRO.nCity > 0) then
     1795  begin
     1796    Loc1 := MyCity[0].Loc;
     1797    if (ClientMode = cTurn) and (MyRO.Turn = 0) then
     1798    begin // move city out of center to not be covered by welcome screen
     1799      dx := MapWidth div (xxt * 5);
     1800      if dx > 5 then
     1801        dx := 5;
     1802      dy := MapHeight div (yyt * 5);
     1803      if dy > 5 then
     1804        dy := 5;
     1805      if Loc1 >= G.lx * G.ly div 2 then
     1806      begin
     1807        NewAgeCenterTo := -1;
     1808        Loc1 := dLoc(Loc1, -dx, -dy)
     1809      end
     1810      else
     1811      begin
     1812        NewAgeCenterTo := 1;
     1813        Loc1 := dLoc(Loc1, -dx, dy);
     1814      end
     1815    end;
     1816    Centre(Loc1)
     1817  end;
     1818
     1819  for i := 0 to DpiScreen.FormCount - 1 do
     1820    if DpiScreen.Forms[i] is TBufferedDrawDlg then
     1821      DpiScreen.Forms[i].Enabled := true;
     1822
     1823  if ClientMode <> cResume then
     1824  begin
     1825    PaintAll;
     1826    if (MyRO.Happened and phChangeGov <> 0) and (MyRO.NatBuilt[imPalace] > 0)
     1827    then
     1828      ImpImage(Panel.Canvas, ClientWidth - xPalace, yPalace, imPalace,
     1829        gAnarchy { , GameMode<>cMovie } );
     1830    // first turn after anarchy -- don't show despotism palace!
     1831    Update;
     1832    for i := 0 to DpiScreen.FormCount - 1 do
     1833      if (DpiScreen.Forms[i].Visible) and (DpiScreen.Forms[i] is TBufferedDrawDlg)
     1834      then
     1835      begin
     1836        if @DpiScreen.Forms[i].OnShow <> nil then
     1837          DpiScreen.Forms[i].OnShow(nil);
     1838        DpiScreen.Forms[i].Invalidate;
     1839        DpiScreen.Forms[i].Update;
    16931840      end;
    1694       // age:=MyRO.Turn mod 4; //!!!
    1695       if ClientMode = cMovieTurn then
    1696         EOT.ButtonIndex := eotCancel
    1697       else if ClientMode < scContact then
    1698         EOT.ButtonIndex := eotGray
    1699       else
    1700         EOT.ButtonIndex := eotBackToNego;
    1701     end
    1702     else
    1703     begin
    1704       Age := 0;
    1705       SetMainTextureByAge(-1);
    1706       if ClientMode = cMovieTurn then
    1707         EOT.ButtonIndex := eotCancel
    1708       else
    1709         EOT.ButtonIndex := eotBlinkOn;
    1710     end;
    1711     InitCityMark(MainTexture);
    1712     CityDlg.CheckAge;
    1713     NatStatDlg.CheckAge;
    1714     UnitStatDlg.CheckAge;
    1715     HelpDlg.Difficulty := G.Difficulty[me];
    1716 
    1717     UnFocus := -1;
    1718     MarkCityLoc := -1;
    1719     BlinkON := false;
    1720     BlinkTime := -1;
    1721     Tracking := false;
    1722     TurnComplete := false;
    1723 
    1724     if (ToldSlavery < 0) or
    1725       ((ToldSlavery = 1) <> (MyRO.Wonder[woPyramids].EffectiveOwner >= 0)) then
    1726     begin
    1727       if MyRO.Wonder[woPyramids].EffectiveOwner >= 0 then
    1728         ToldSlavery := 1
    1729       else
    1730         ToldSlavery := 0;
    1731       for p1 := 0 to nPl - 1 do
    1732         if (Tribe[p1] <> nil) and (Tribe[p1].mixSlaves >= 0) then
    1733           with Picture do
    1734           begin // replace unit picture
    1735             mix := Tribe[p1].mixSlaves;
    1736             if ToldSlavery = 1 then
    1737               pix := pixSlaves
    1738             else
    1739               pix := pixNoSlaves;
    1740             Hash := 0;
    1741             GrName := 'StdUnits.png';
    1742             Tribe[p1].SetModelPicture(Picture, true);
     1841
     1842    if MyRO.Happened and phGameEnd <> 0 then
     1843      with MessgExDlg do
     1844      begin // game ended
     1845        if MyRO.Happened and phExtinct <> 0 then
     1846        begin
     1847          OpenSound := 'MSG_GAMEOVER';
     1848          MessgText := Tribe[me].TPhrase('GAMEOVER');
     1849          IconKind := mikBigIcon;
     1850          IconIndex := 8;
     1851        end
     1852        else if MyRO.Happened and phShipComplete <> 0 then
     1853        begin
     1854          Winners := 0;
     1855          for p1 := 0 to nPl - 1 do
     1856            if 1 shl p1 and MyRO.Alive <> 0 then
     1857            begin
     1858              Winners := Winners or 1 shl p1;
     1859              for i := 0 to nShipPart - 1 do
     1860                if MyRO.Ship[p1].Parts[i] < ShipNeed[i] then
     1861                  Winners := Winners and not(1 shl p1);
     1862            end;
     1863          assert(Winners <> 0);
     1864          if Winners and (1 shl me) <> 0 then
     1865          begin
     1866            s := '';
     1867            for p1 := 0 to nPl - 1 do
     1868              if (p1 <> me) and (1 shl p1 and Winners <> 0) then
     1869                if s = '' then
     1870                  s := Tribe[p1].TPhrase('SHORTNAME')
     1871                else
     1872                  s := Format(Phrases.Lookup('SHAREDWIN_CONCAT'),
     1873                    [s, Tribe[p1].TPhrase('SHORTNAME')]);
     1874
     1875            OpenSound := 'MSG_YOUWIN';
     1876            MessgText := Tribe[me].TPhrase('MYSPACESHIP');
     1877            if s <> '' then
     1878              MessgText := MessgText + '\' +
     1879                Format(Phrases.Lookup('SHAREDWIN'), [s]);
     1880            IconKind := mikBigIcon;
     1881            IconIndex := 9;
    17431882          end
    1744     end;
    1745 
    1746     if not supervising and (ClientMode = cTurn) then
    1747     begin
    1748       for cix := 0 to MyRO.nCity - 1 do
    1749         if (MyCity[cix].Loc >= 0) and
    1750           ((MyRO.Turn = 0) or (MyCity[cix].Flags and chFounded <> 0)) then
    1751           MyCity[cix].Status := MyCity[cix].Status and
    1752             not csResourceWeightsMask or (3 shl 4);
    1753       // new city, set to maximum growth
    1754     end;
    1755     if (ClientMode = cTurn) or (ClientMode = cContinue) then
    1756       CityOptimizer_BeginOfTurn; // maybe peace was made or has ended
    1757     SumCities(TaxSum, ScienceSum);
    1758 
    1759     if ClientMode = cMovieTurn then
    1760     begin
    1761       UnitInfoBtn.Visible := false;
    1762       UnitBtn.Visible := false;
    1763       TerrainBtn.Visible := false;
    1764       EOT.Hint := Phrases.Lookup('BTN_STOP');
    1765       EOT.Visible := true;
    1766     end
    1767     else if ClientMode < scContact then
    1768     begin
    1769       UnitInfoBtn.Visible := UnFocus >= 0;
    1770       UnitBtn.Visible := UnFocus >= 0;
    1771       CheckTerrainBtnVisible;
    1772       TurnComplete := supervising;
    1773       EOT.Hint := Phrases.Lookup('BTN_ENDTURN');
    1774       EOT.Visible := Server(sTurn - sExecute, me, 0, nil^) >= rExecuted;
    1775     end
    1776     else
    1777     begin
    1778       UnitInfoBtn.Visible := false;
    1779       UnitBtn.Visible := false;
    1780       TerrainBtn.Visible := false;
    1781       EOT.Hint := Phrases.Lookup('BTN_NEGO');
    1782       EOT.Visible := true;
    1783     end;
    1784     SetTroopLoc(-1);
    1785     MapValid := false;
    1786     NewAgeCenterTo := 0;
    1787     if ((MyRO.Turn = 0) and not supervising or IsMultiPlayerGame or
    1788       (ClientMode = cResume)) and (MyRO.nCity > 0) then
    1789     begin
    1790       Loc1 := MyCity[0].Loc;
    1791       if (ClientMode = cTurn) and (MyRO.Turn = 0) then
    1792       begin // move city out of center to not be covered by welcome screen
    1793         dx := MapWidth div (xxt * 5);
    1794         if dx > 5 then
    1795           dx := 5;
    1796         dy := MapHeight div (yyt * 5);
    1797         if dy > 5 then
    1798           dy := 5;
    1799         if Loc1 >= G.lx * G.ly div 2 then
    1800         begin
    1801           NewAgeCenterTo := -1;
    1802           Loc1 := dLoc(Loc1, -dx, -dy)
    1803         end
    1804         else
    1805         begin
    1806           NewAgeCenterTo := 1;
    1807           Loc1 := dLoc(Loc1, -dx, dy);
    1808         end
    1809       end;
    1810       Centre(Loc1)
    1811     end;
    1812 
    1813     for i := 0 to DpiScreen.FormCount - 1 do
    1814       if DpiScreen.Forms[i] is TBufferedDrawDlg then
    1815         DpiScreen.Forms[i].Enabled := true;
    1816 
    1817     if ClientMode <> cResume then
    1818     begin
    1819       PaintAll;
    1820       if (MyRO.Happened and phChangeGov <> 0) and (MyRO.NatBuilt[imPalace] > 0)
    1821       then
    1822         ImpImage(Panel.Canvas, ClientWidth - xPalace, yPalace, imPalace,
    1823           gAnarchy { , GameMode<>cMovie } );
    1824       // first turn after anarchy -- don't show despotism palace!
    1825       Update;
    1826       for i := 0 to DpiScreen.FormCount - 1 do
    1827         if (DpiScreen.Forms[i].Visible) and (DpiScreen.Forms[i] is TBufferedDrawDlg)
    1828         then
    1829         begin
    1830           if @DpiScreen.Forms[i].OnShow <> nil then
    1831             DpiScreen.Forms[i].OnShow(nil);
    1832           DpiScreen.Forms[i].Invalidate;
    1833           DpiScreen.Forms[i].Update;
    1834         end;
    1835 
    1836       if MyRO.Happened and phGameEnd <> 0 then
    1837         with MessgExDlg do
    1838         begin // game ended
    1839           if MyRO.Happened and phExtinct <> 0 then
    1840           begin
    1841             OpenSound := 'MSG_GAMEOVER';
    1842             MessgText := Tribe[me].TPhrase('GAMEOVER');
    1843             IconKind := mikBigIcon;
    1844             IconIndex := 8;
    1845           end
    1846           else if MyRO.Happened and phShipComplete <> 0 then
    1847           begin
    1848             Winners := 0;
    1849             for p1 := 0 to nPl - 1 do
    1850               if 1 shl p1 and MyRO.Alive <> 0 then
    1851               begin
    1852                 Winners := Winners or 1 shl p1;
    1853                 for i := 0 to nShipPart - 1 do
    1854                   if MyRO.Ship[p1].Parts[i] < ShipNeed[i] then
    1855                     Winners := Winners and not(1 shl p1);
    1856               end;
    1857             assert(Winners <> 0);
    1858             if Winners and (1 shl me) <> 0 then
    1859             begin
    1860               s := '';
    1861               for p1 := 0 to nPl - 1 do
    1862                 if (p1 <> me) and (1 shl p1 and Winners <> 0) then
    1863                   if s = '' then
    1864                     s := Tribe[p1].TPhrase('SHORTNAME')
    1865                   else
    1866                     s := Format(Phrases.Lookup('SHAREDWIN_CONCAT'),
    1867                       [s, Tribe[p1].TPhrase('SHORTNAME')]);
    1868 
    1869               OpenSound := 'MSG_YOUWIN';
    1870               MessgText := Tribe[me].TPhrase('MYSPACESHIP');
    1871               if s <> '' then
    1872                 MessgText := MessgText + '\' +
    1873                   Format(Phrases.Lookup('SHAREDWIN'), [s]);
    1874               IconKind := mikBigIcon;
    1875               IconIndex := 9;
    1876             end
    1877             else
    1878             begin
    1879               assert(me = 0);
    1880               OpenSound := 'MSG_GAMEOVER';
    1881               MessgText := '';
    1882               for p1 := 0 to nPl - 1 do
    1883                 if Winners and (1 shl p1) <> 0 then
    1884                   MessgText := MessgText + Tribe[p1].TPhrase('SPACESHIP1');
    1885               MessgText := MessgText + '\' + Phrases.Lookup('SPACESHIP2');
    1886               IconKind := mikEnemyShipComplete;
    1887             end
    1888           end
    1889           else { if MyRO.Happened and fTimeUp<>0 then }
     1883          else
    18901884          begin
    18911885            assert(me = 0);
    18921886            OpenSound := 'MSG_GAMEOVER';
    1893             if not supervising then
    1894               MessgText := Tribe[me].TPhrase('TIMEUP')
    1895             else
    1896               MessgText := Phrases.Lookup('TIMEUPSUPER');
    1897             IconKind := mikImp;
    1898             IconIndex := 22;
    1899           end;
    1900           Kind := mkOk;
    1901           ShowModal;
    1902           if MyRO.Happened and phExtinct = 0 then
    1903           begin
    1904             p1 := 0;
    1905             while (p1 < nPl - 1) and (Winners and (1 shl p1) = 0) do
    1906               inc(p1);
    1907             if MyRO.Happened and phShipComplete = 0 then
    1908               DiaDlg.ShowNewContent_Charts(wmModal);
    1909           end;
    1910           TurnComplete := true;
    1911           exit;
     1887            MessgText := '';
     1888            for p1 := 0 to nPl - 1 do
     1889              if Winners and (1 shl p1) <> 0 then
     1890                MessgText := MessgText + Tribe[p1].TPhrase('SPACESHIP1');
     1891            MessgText := MessgText + '\' + Phrases.Lookup('SPACESHIP2');
     1892            IconKind := mikEnemyShipComplete;
     1893          end
     1894        end
     1895        else { if MyRO.Happened and fTimeUp<>0 then }
     1896        begin
     1897          assert(me = 0);
     1898          OpenSound := 'MSG_GAMEOVER';
     1899          if not supervising then
     1900            MessgText := Tribe[me].TPhrase('TIMEUP')
     1901          else
     1902            MessgText := Phrases.Lookup('TIMEUPSUPER');
     1903          IconKind := mikImp;
     1904          IconIndex := 22;
    19121905        end;
    1913       if not supervising and (1 shl me and MyRO.Alive = 0) then
    1914       begin
     1906        Kind := mkOk;
     1907        ShowModal;
     1908        if MyRO.Happened and phExtinct = 0 then
     1909        begin
     1910          p1 := 0;
     1911          while (p1 < nPl - 1) and (Winners and (1 shl p1) = 0) do
     1912            inc(p1);
     1913          if MyRO.Happened and phShipComplete = 0 then
     1914            DiaDlg.ShowNewContent_Charts(wmModal);
     1915        end;
    19151916        TurnComplete := true;
    19161917        exit;
    19171918      end;
    1918 
    1919       if (ClientMode = cContinue) and
    1920         (DipMem[me].SentCommand and $FF0F = scContact) then
    1921         // contact was refused
    1922         if MyRO.Treaty[DipMem[me].pContact] >= trPeace then
    1923           ContactRefused(DipMem[me].pContact, 'FRREJECTED')
    1924         else
    1925           SoundMessage(Tribe[DipMem[me].pContact].TPhrase('FRREJECTED'),
    1926             'NEGO_REJECTED');
    1927 
    1928       if not supervising and (Age > MyData.ToldAge) and
    1929         ((Age > 0) or (ClientMode <> cMovieTurn)) then
    1930         with MessgExDlg do
    1931         begin
    1932           if Age = 0 then
     1919    if not supervising and (1 shl me and MyRO.Alive = 0) then
     1920    begin
     1921      TurnComplete := true;
     1922      exit;
     1923    end;
     1924
     1925    if (ClientMode = cContinue) and
     1926      (DipMem[me].SentCommand and $FF0F = scContact) then
     1927      // contact was refused
     1928      if MyRO.Treaty[DipMem[me].pContact] >= trPeace then
     1929        ContactRefused(DipMem[me].pContact, 'FRREJECTED')
     1930      else
     1931        SoundMessage(Tribe[DipMem[me].pContact].TPhrase('FRREJECTED'),
     1932          'NEGO_REJECTED');
     1933
     1934    if not supervising and (Age > MyData.ToldAge) and
     1935      ((Age > 0) or (ClientMode <> cMovieTurn)) then
     1936      with MessgExDlg do
     1937      begin
     1938        if Age = 0 then
     1939        begin
     1940          if Phrases2FallenBackToEnglish then
    19331941          begin
    1934             if Phrases2FallenBackToEnglish then
    1935             begin
    1936               s := Tribe[me].TPhrase('AGE0');
    1937               MessgText :=
    1938                 Format(s, [TurnToString(MyRO.Turn), CityName(MyCity[0].ID)])
    1939             end
    1940             else
    1941             begin
    1942               s := Tribe[me].TString(Phrases2.Lookup('AGE0'));
    1943               MessgText := Format(s, [TurnToString(MyRO.Turn)]);
    1944             end
     1942            s := Tribe[me].TPhrase('AGE0');
     1943            MessgText :=
     1944              Format(s, [TurnToString(MyRO.Turn), CityName(MyCity[0].ID)])
    19451945          end
    19461946          else
    19471947          begin
    1948             s := Tribe[me].TPhrase('AGE' + char(48 + Age));
     1948            s := Tribe[me].TString(Phrases2.Lookup('AGE0'));
    19491949            MessgText := Format(s, [TurnToString(MyRO.Turn)]);
    1950           end;
    1951           IconKind := mikAge;
    1952           IconIndex := Age;
    1953           { if age=0 then } Kind := mkOk
    1954           { else begin Kind:=mkOkHelp; HelpKind:=hkAdv; HelpNo:=AgePreq[age]; end };
    1955           CenterTo := NewAgeCenterTo;
    1956           OpenSound := 'AGE_' + char(48 + Age);
    1957           ShowModal;
    1958           MyData.ToldAge := Age;
    1959           if Age > 0 then
    1960             MyData.ToldTech[AgePreq[Age]] := MyRO.Tech[AgePreq[Age]];
    1961         end;
    1962 
    1963       if MyData.ToldAlive <> MyRO.Alive then
    1964       begin
    1965         for p1 := 0 to nPl - 1 do
    1966           if (MyData.ToldAlive - MyRO.Alive) and (1 shl p1) <> 0 then
    1967             with MessgExDlg do
    1968             begin
    1969               OpenSound := 'MSG_EXTINCT';
    1970               s := Tribe[p1].TPhrase('EXTINCT');
    1971               MessgText := Format(s, [TurnToString(MyRO.Turn)]);
    1972               if MyRO.Alive = 1 shl me then
    1973                 MessgText := MessgText + Phrases.Lookup('EXTINCTALL');
    1974               Kind := mkOk;
    1975               IconKind := mikImp;
    1976               IconIndex := 21;
    1977               ShowModal;
    1978             end;
    1979         if (ClientMode <> cMovieTurn) and not supervising then
    1980           DiaDlg.ShowNewContent_Charts(wmModal);
    1981       end;
    1982 
    1983       // tell changes of own credibility
    1984       if not supervising then
    1985       begin
    1986         if RoughCredibility(MyRO.Credibility) <>
    1987           RoughCredibility(MyData.ToldOwnCredibility) then
    1988         begin
    1989           if RoughCredibility(MyRO.Credibility) >
    1990             RoughCredibility(MyData.ToldOwnCredibility) then
    1991             s := Phrases.Lookup('CREDUP')
    1992           else
    1993             s := Phrases.Lookup('CREDDOWN');
    1994           TribeMessage(me, Format(s, [Phrases.Lookup('CREDIBILITY',
    1995             RoughCredibility(MyRO.Credibility))]), '');
    1996         end;
    1997         MyData.ToldOwnCredibility := MyRO.Credibility;
    1998       end;
    1999 
    2000       for i := 0 to 27 do
    2001       begin
    2002         OwnWonder := false;
    2003         for cix := 0 to MyRO.nCity - 1 do
    2004           if (MyCity[cix].Loc >= 0) and (MyCity[cix].ID = MyRO.Wonder[i].CityID)
    2005           then
    2006             OwnWonder := true;
    2007         if MyRO.Wonder[i].CityID <> MyData.ToldWonders[i].CityID then
    2008         begin
    2009           if MyRO.Wonder[i].CityID = -2 then
    2010             with MessgExDlg do
    2011             begin { tell about destroyed wonders }
    2012               OpenSound := 'WONDER_DESTROYED';
    2013               MessgText := Format(Phrases.Lookup('WONDERDEST'),
    2014                 [Phrases.Lookup('IMPROVEMENTS', i)]);
    2015               Kind := mkOkHelp;
    2016               HelpKind := hkImp;
    2017               HelpNo := i;
    2018               IconKind := mikImp;
    2019               IconIndex := i;
    2020               ShowModal;
    2021             end
    2022           else
    2023           begin
    2024             if i = woManhattan then
    2025               if MyRO.Wonder[i].EffectiveOwner > me then
    2026                 MyData.ColdWarStart := MyRO.Turn - 1
    2027               else
    2028                 MyData.ColdWarStart := MyRO.Turn;
    2029             if not OwnWonder then
    2030               with MessgExDlg do
    2031               begin { tell about newly built wonders }
    2032                 if i = woManhattan then
    2033                 begin
    2034                   OpenSound := 'MSG_COLDWAR';
    2035                   s := Tribe[MyRO.Wonder[i].EffectiveOwner].TPhrase('COLDWAR')
    2036                 end
    2037                 else if MyRO.Wonder[i].EffectiveOwner >= 0 then
    2038                 begin
    2039                   OpenSound := 'WONDER_BUILT';
    2040                   s := Tribe[MyRO.Wonder[i].EffectiveOwner]
    2041                     .TPhrase('WONDERBUILT')
    2042                 end
    2043                 else
    2044                 begin
    2045                   OpenSound := 'MSG_DEFAULT';
    2046                   s := Phrases.Lookup('WONDERBUILTEXP');
    2047                   // already expired when built
    2048                 end;
    2049                 MessgText := Format(s, [Phrases.Lookup('IMPROVEMENTS', i),
    2050                   CityName(MyRO.Wonder[i].CityID)]);
    2051                 Kind := mkOkHelp;
    2052                 HelpKind := hkImp;
    2053                 HelpNo := i;
    2054                 IconKind := mikImp;
    2055                 IconIndex := i;
    2056                 ShowModal;
    2057               end
    20581950          end
    20591951        end
    2060         else if (MyRO.Wonder[i].EffectiveOwner <> MyData.ToldWonders[i]
    2061           .EffectiveOwner) and (MyRO.Wonder[i].CityID > -2) then
    2062           if MyRO.Wonder[i].EffectiveOwner < 0 then
     1952        else
     1953        begin
     1954          s := Tribe[me].TPhrase('AGE' + char(48 + Age));
     1955          MessgText := Format(s, [TurnToString(MyRO.Turn)]);
     1956        end;
     1957        IconKind := mikAge;
     1958        IconIndex := Age;
     1959        { if age=0 then } Kind := mkOk
     1960        { else begin Kind:=mkOkHelp; HelpKind:=hkAdv; HelpNo:=AgePreq[age]; end };
     1961        CenterTo := NewAgeCenterTo;
     1962        OpenSound := 'AGE_' + char(48 + Age);
     1963        ShowModal;
     1964        MyData.ToldAge := Age;
     1965        if Age > 0 then
     1966          MyData.ToldTech[AgePreq[Age]] := MyRO.Tech[AgePreq[Age]];
     1967      end;
     1968
     1969    if MyData.ToldAlive <> MyRO.Alive then
     1970    begin
     1971      for p1 := 0 to nPl - 1 do
     1972        if (MyData.ToldAlive - MyRO.Alive) and (1 shl p1) <> 0 then
     1973          with MessgExDlg do
    20631974          begin
    2064             if i <> woMIR then
    2065               with MessgExDlg do
    2066               begin { tell about expired wonders }
    2067                 OpenSound := 'WONDER_EXPIRED';
    2068                 MessgText := Format(Phrases.Lookup('WONDEREXP'),
    2069                   [Phrases.Lookup('IMPROVEMENTS', i),
    2070                   CityName(MyRO.Wonder[i].CityID)]);
    2071                 Kind := mkOkHelp;
    2072                 HelpKind := hkImp;
    2073                 HelpNo := i;
    2074                 IconKind := mikImp;
    2075                 IconIndex := i;
    2076                 ShowModal;
     1975            OpenSound := 'MSG_EXTINCT';
     1976            s := Tribe[p1].TPhrase('EXTINCT');
     1977            MessgText := Format(s, [TurnToString(MyRO.Turn)]);
     1978            if MyRO.Alive = 1 shl me then
     1979              MessgText := MessgText + Phrases.Lookup('EXTINCTALL');
     1980            Kind := mkOk;
     1981            IconKind := mikImp;
     1982            IconIndex := 21;
     1983            ShowModal;
     1984          end;
     1985      if (ClientMode <> cMovieTurn) and not supervising then
     1986        DiaDlg.ShowNewContent_Charts(wmModal);
     1987    end;
     1988
     1989    // tell changes of own credibility
     1990    if not supervising then
     1991    begin
     1992      if RoughCredibility(MyRO.Credibility) <>
     1993        RoughCredibility(MyData.ToldOwnCredibility) then
     1994      begin
     1995        if RoughCredibility(MyRO.Credibility) >
     1996          RoughCredibility(MyData.ToldOwnCredibility) then
     1997          s := Phrases.Lookup('CREDUP')
     1998        else
     1999          s := Phrases.Lookup('CREDDOWN');
     2000        TribeMessage(me, Format(s, [Phrases.Lookup('CREDIBILITY',
     2001          RoughCredibility(MyRO.Credibility))]), '');
     2002      end;
     2003      MyData.ToldOwnCredibility := MyRO.Credibility;
     2004    end;
     2005
     2006    for i := 0 to 27 do
     2007    begin
     2008      OwnWonder := false;
     2009      for cix := 0 to MyRO.nCity - 1 do
     2010        if (MyCity[cix].Loc >= 0) and (MyCity[cix].ID = MyRO.Wonder[i].CityID)
     2011        then
     2012          OwnWonder := true;
     2013      if MyRO.Wonder[i].CityID <> MyData.ToldWonders[i].CityID then
     2014      begin
     2015        if MyRO.Wonder[i].CityID = -2 then
     2016          with MessgExDlg do
     2017          begin { tell about destroyed wonders }
     2018            OpenSound := 'WONDER_DESTROYED';
     2019            MessgText := Format(Phrases.Lookup('WONDERDEST'),
     2020              [Phrases.Lookup('IMPROVEMENTS', i)]);
     2021            Kind := mkOkHelp;
     2022            HelpKind := hkImp;
     2023            HelpNo := i;
     2024            IconKind := mikImp;
     2025            IconIndex := i;
     2026            ShowModal;
     2027          end
     2028        else
     2029        begin
     2030          if i = woManhattan then
     2031            if MyRO.Wonder[i].EffectiveOwner > me then
     2032              MyData.ColdWarStart := MyRO.Turn - 1
     2033            else
     2034              MyData.ColdWarStart := MyRO.Turn;
     2035          if not OwnWonder then
     2036            with MessgExDlg do
     2037            begin { tell about newly built wonders }
     2038              if i = woManhattan then
     2039              begin
     2040                OpenSound := 'MSG_COLDWAR';
     2041                s := Tribe[MyRO.Wonder[i].EffectiveOwner].TPhrase('COLDWAR')
    20772042              end
    2078           end
    2079           else if (MyData.ToldWonders[i].EffectiveOwner >= 0) and not OwnWonder
    2080           then
    2081             with MessgExDlg do
    2082             begin { tell about capture of wonders }
    2083               OpenSound := 'WONDER_CAPTURED';
    2084               s := Tribe[MyRO.Wonder[i].EffectiveOwner].TPhrase('WONDERCAPT');
     2043              else if MyRO.Wonder[i].EffectiveOwner >= 0 then
     2044              begin
     2045                OpenSound := 'WONDER_BUILT';
     2046                s := Tribe[MyRO.Wonder[i].EffectiveOwner]
     2047                  .TPhrase('WONDERBUILT')
     2048              end
     2049              else
     2050              begin
     2051                OpenSound := 'MSG_DEFAULT';
     2052                s := Phrases.Lookup('WONDERBUILTEXP');
     2053                // already expired when built
     2054              end;
    20852055              MessgText := Format(s, [Phrases.Lookup('IMPROVEMENTS', i),
    20862056                CityName(MyRO.Wonder[i].CityID)]);
     
    20912061              IconIndex := i;
    20922062              ShowModal;
    2093             end;
    2094       end;
    2095 
    2096       if MyRO.Turn = MyData.ColdWarStart + ColdWarTurns then
    2097       begin
    2098         SoundMessageEx(Phrases.Lookup('COLDWAREND'), 'MSG_DEFAULT');
    2099         MyData.ColdWarStart := -ColdWarTurns - 1
    2100       end;
    2101 
    2102       TellNewModels;
    2103     end; // ClientMode<>cResume
    2104     MyData.ToldAlive := MyRO.Alive;
    2105     move(MyRO.Wonder, MyData.ToldWonders, SizeOf(MyData.ToldWonders));
    2106 
    2107     NewGovAvailable := -1;
    2108     if ClientMode <> cResume then
    2109     begin // tell about new techs
    2110       for ad := 0 to nAdv - 1 do
    2111         if (MyRO.TestFlags and tfAllTechs = 0) and
    2112           ((MyRO.Tech[ad] >= tsApplicable) <> (MyData.ToldTech[ad] >=
    2113           tsApplicable)) or (ad in FutureTech) and
    2114           (MyRO.Tech[ad] <> MyData.ToldTech[ad]) then
     2063            end
     2064        end
     2065      end
     2066      else if (MyRO.Wonder[i].EffectiveOwner <> MyData.ToldWonders[i]
     2067        .EffectiveOwner) and (MyRO.Wonder[i].CityID > -2) then
     2068        if MyRO.Wonder[i].EffectiveOwner < 0 then
     2069        begin
     2070          if i <> woMIR then
     2071            with MessgExDlg do
     2072            begin { tell about expired wonders }
     2073              OpenSound := 'WONDER_EXPIRED';
     2074              MessgText := Format(Phrases.Lookup('WONDEREXP'),
     2075                [Phrases.Lookup('IMPROVEMENTS', i),
     2076                CityName(MyRO.Wonder[i].CityID)]);
     2077              Kind := mkOkHelp;
     2078              HelpKind := hkImp;
     2079              HelpNo := i;
     2080              IconKind := mikImp;
     2081              IconIndex := i;
     2082              ShowModal;
     2083            end
     2084        end
     2085        else if (MyData.ToldWonders[i].EffectiveOwner >= 0) and not OwnWonder
     2086        then
    21152087          with MessgExDlg do
    2116           begin
    2117             Item := 'RESEARCH_GENERAL';
    2118             if GameMode <> cMovie then
    2119               OpenSound := 'NEWADVANCE_' + char(48 + Age);
    2120             Item2 := Phrases.Lookup('ADVANCES', ad);
    2121             if ad in FutureTech then
    2122               Item2 := Item2 + ' ' + IntToStr(MyRO.Tech[ad]);
    2123             MessgText := Format(Phrases.Lookup(Item), [Item2]);
     2088          begin { tell about capture of wonders }
     2089            OpenSound := 'WONDER_CAPTURED';
     2090            s := Tribe[MyRO.Wonder[i].EffectiveOwner].TPhrase('WONDERCAPT');
     2091            MessgText := Format(s, [Phrases.Lookup('IMPROVEMENTS', i),
     2092              CityName(MyRO.Wonder[i].CityID)]);
    21242093            Kind := mkOkHelp;
    2125             HelpKind := hkAdv;
    2126             HelpNo := ad;
    2127             IconKind := mikBook;
    2128             IconIndex := -1;
    2129             for i := 0 to nAdvBookIcon - 1 do
    2130               if AdvBookIcon[i].Adv = ad then
    2131                 IconIndex := AdvBookIcon[i].Icon;
     2094            HelpKind := hkImp;
     2095            HelpNo := i;
     2096            IconKind := mikImp;
     2097            IconIndex := i;
    21322098            ShowModal;
    2133             MyData.ToldTech[ad] := MyRO.Tech[ad];
    2134             for i := gMonarchy to nGov - 1 do
    2135               if GovPreq[i] = ad then
    2136                 NewGovAvailable := i;
    21372099          end;
    21382100    end;
    21392101
    2140     ShowCityList := false;
    2141     if ClientMode = cTurn then
    2142     begin
    2143       if (MyRO.Happened and phTech <> 0) and (MyData.FarTech <> adNexus) then
    2144         ChooseResearch;
    2145 
    2146       UpdatePanel := false;
    2147       if MyRO.Happened and phChangeGov <> 0 then
    2148       begin
    2149         ModalSelectDlg.ShowNewContent(wmModal, kGov);
    2150         Play('NEWGOV');
    2151         Server(sSetGovernment, me, ModalSelectDlg.result, nil^);
    2152         CityOptimizer_BeginOfTurn;
    2153         UpdatePanel := true;
    2154       end;
    2155     end; // ClientMode=cTurn
    2156 
    2157     if not supervising and ((ClientMode = cTurn) or (ClientMode = cMovieTurn))
    2158     then
     2102    if MyRO.Turn = MyData.ColdWarStart + ColdWarTurns then
     2103    begin
     2104      SoundMessageEx(Phrases.Lookup('COLDWAREND'), 'MSG_DEFAULT');
     2105      MyData.ColdWarStart := -ColdWarTurns - 1
     2106    end;
     2107
     2108    TellNewModels;
     2109  end; // ClientMode<>cResume
     2110  MyData.ToldAlive := MyRO.Alive;
     2111  move(MyRO.Wonder, MyData.ToldWonders, SizeOf(MyData.ToldWonders));
     2112
     2113  NewGovAvailable := -1;
     2114  if ClientMode <> cResume then
     2115  begin // tell about new techs
     2116    for ad := 0 to nAdv - 1 do
     2117      if (MyRO.TestFlags and tfAllTechs = 0) and
     2118        ((MyRO.Tech[ad] >= tsApplicable) <> (MyData.ToldTech[ad] >=
     2119        tsApplicable)) or (ad in FutureTech) and
     2120        (MyRO.Tech[ad] <> MyData.ToldTech[ad]) then
     2121        with MessgExDlg do
     2122        begin
     2123          Item := 'RESEARCH_GENERAL';
     2124          if GameMode <> cMovie then
     2125            OpenSound := 'NEWADVANCE_' + char(48 + Age);
     2126          Item2 := Phrases.Lookup('ADVANCES', ad);
     2127          if ad in FutureTech then
     2128            Item2 := Item2 + ' ' + IntToStr(MyRO.Tech[ad]);
     2129          MessgText := Format(Phrases.Lookup(Item), [Item2]);
     2130          Kind := mkOkHelp;
     2131          HelpKind := hkAdv;
     2132          HelpNo := ad;
     2133          IconKind := mikBook;
     2134          IconIndex := -1;
     2135          for i := 0 to nAdvBookIcon - 1 do
     2136            if AdvBookIcon[i].Adv = ad then
     2137              IconIndex := AdvBookIcon[i].Icon;
     2138          ShowModal;
     2139          MyData.ToldTech[ad] := MyRO.Tech[ad];
     2140          for i := gMonarchy to nGov - 1 do
     2141            if GovPreq[i] = ad then
     2142              NewGovAvailable := i;
     2143        end;
     2144  end;
     2145
     2146  ShowCityList := false;
     2147  if ClientMode = cTurn then
     2148  begin
     2149    if (MyRO.Happened and phTech <> 0) and (MyData.FarTech <> adNexus) then
     2150      ChooseResearch;
     2151
     2152    UpdatePanel := false;
     2153    if MyRO.Happened and phChangeGov <> 0 then
     2154    begin
     2155      ModalSelectDlg.ShowNewContent(wmModal, kGov);
     2156      Play('NEWGOV');
     2157      Server(sSetGovernment, me, ModalSelectDlg.result, nil^);
     2158      CityOptimizer_BeginOfTurn;
     2159      UpdatePanel := true;
     2160    end;
     2161  end; // ClientMode=cTurn
     2162
     2163  if not supervising and ((ClientMode = cTurn) or (ClientMode = cMovieTurn))
     2164  then
     2165    for cix := 0 to MyRO.nCity - 1 do
     2166      with MyCity[cix] do
     2167        Status := Status and not csToldBombard;
     2168
     2169  if ((ClientMode = cTurn) or (ClientMode = cMovieTurn)) and
     2170    (MyRO.Government <> gAnarchy) then
     2171  begin
     2172    // tell what happened in cities
     2173    for WondersOnly := true downto false do
    21592174      for cix := 0 to MyRO.nCity - 1 do
    21602175        with MyCity[cix] do
    2161           Status := Status and not csToldBombard;
    2162 
    2163     if ((ClientMode = cTurn) or (ClientMode = cMovieTurn)) and
    2164       (MyRO.Government <> gAnarchy) then
    2165     begin
    2166       // tell what happened in cities
    2167       for WondersOnly := true downto false do
    2168         for cix := 0 to MyRO.nCity - 1 do
    2169           with MyCity[cix] do
    2170             if (MyRO.Turn > 0) and (Loc >= 0) and (Flags and chCaptured = 0) and
    2171               (WondersOnly = (Flags and chProduction <> 0) and
    2172               (Project0 and cpImp <> 0) and (Project0 and cpIndex < 28)) then
     2176          if (MyRO.Turn > 0) and (Loc >= 0) and (Flags and chCaptured = 0) and
     2177            (WondersOnly = (Flags and chProduction <> 0) and
     2178            (Project0 and cpImp <> 0) and (Project0 and cpIndex < 28)) then
     2179          begin
     2180            if WondersOnly then
     2181              with MessgExDlg do
     2182              begin { tell about newly built wonder }
     2183                OpenSound := 'WONDER_BUILT';
     2184                s := Tribe[me].TPhrase('WONDERBUILTOWN');
     2185                MessgText :=
     2186                  Format(s, [Phrases.Lookup('IMPROVEMENTS',
     2187                  Project0 and cpIndex), CityName(ID)]);
     2188                Kind := mkOkHelp;
     2189                HelpKind := hkImp;
     2190                HelpNo := Project0 and cpIndex;
     2191                IconKind := mikImp;
     2192                IconIndex := Project0 and cpIndex;
     2193                ShowModal;
     2194              end;
     2195            if not supervising and (ClientMode = cTurn) then
    21732196            begin
    2174               if WondersOnly then
    2175                 with MessgExDlg do
    2176                 begin { tell about newly built wonder }
    2177                   OpenSound := 'WONDER_BUILT';
    2178                   s := Tribe[me].TPhrase('WONDERBUILTOWN');
    2179                   MessgText :=
    2180                     Format(s, [Phrases.Lookup('IMPROVEMENTS',
    2181                     Project0 and cpIndex), CityName(ID)]);
    2182                   Kind := mkOkHelp;
    2183                   HelpKind := hkImp;
    2184                   HelpNo := Project0 and cpIndex;
    2185                   IconKind := mikImp;
    2186                   IconIndex := Project0 and cpIndex;
    2187                   ShowModal;
    2188                 end;
    2189               if not supervising and (ClientMode = cTurn) then
     2197              AllowCityScreen := true;
     2198              if (Status and 7 <> 0) and
     2199                (Project and (cpImp + cpIndex) = cpImp + imTrGoods) then
     2200                if (MyData.ImpOrder[Status and 7 - 1, 0] >= 0) then
     2201                begin
     2202                  if AutoBuild(cix, MyData.ImpOrder[Status and 7 - 1]) then
     2203                    AllowCityScreen := false
     2204                  else if Flags and chProduction <> 0 then
     2205                    Flags := (Flags and not chProduction) or chAllImpsMade
     2206                end
     2207                else
     2208                  Flags := Flags or chTypeDel;
     2209              if (Size >= NeedAqueductSize) and
     2210                (MyRO.Tech[Imp[imAqueduct].Preq] < tsApplicable) or
     2211                (Size >= NeedSewerSize) and
     2212                (MyRO.Tech[Imp[imSewer].Preq] < tsApplicable) then
     2213                Flags := Flags and not chNoGrowthWarning;
     2214              // don't remind of unknown building
     2215              if Flags and chNoSettlerProd = 0 then
     2216                Status := Status and not csToldDelay
     2217              else if Status and csToldDelay = 0 then
     2218                Status := Status or csToldDelay
     2219              else
     2220                Flags := Flags and not chNoSettlerProd;
     2221              if mRepScreens.Checked then
    21902222              begin
    2191                 AllowCityScreen := true;
    2192                 if (Status and 7 <> 0) and
    2193                   (Project and (cpImp + cpIndex) = cpImp + imTrGoods) then
    2194                   if (MyData.ImpOrder[Status and 7 - 1, 0] >= 0) then
     2223                if (Flags and CityRepMask <> 0) and AllowCityScreen then
     2224                begin { show what happened in cities }
     2225                  SetTroopLoc(MyCity[cix].Loc);
     2226                  MarkCityLoc := MyCity[cix].Loc;
     2227                  PanelPaint;
     2228                  CityDlg.CloseAction := None;
     2229                  CityDlg.ShowNewContent(wmModal, MyCity[cix].Loc,
     2230                    Flags and CityRepMask);
     2231                  UpdatePanel := true;
     2232                end
     2233              end
     2234              else { if mRepList.Checked then }
     2235              begin
     2236                if Flags and CityRepMask <> 0 then
     2237                  ShowCityList := true
     2238              end
     2239            end
     2240          end; { city loop }
     2241  end; // ClientMode=cTurn
     2242
     2243  if ClientMode = cTurn then
     2244  begin
     2245    if NewGovAvailable >= 0 then
     2246      with MessgExDlg do
     2247      begin
     2248        MessgText := Format(Phrases.Lookup('AUTOREVOLUTION'),
     2249          [Phrases.Lookup('GOVERNMENT', NewGovAvailable)]);
     2250        Kind := mkYesNo;
     2251        IconKind := mikPureIcon;
     2252        IconIndex := 6 + NewGovAvailable;
     2253        ShowModal;
     2254        if ModalResult = mrOK then
     2255        begin
     2256          Play('REVOLUTION');
     2257          Server(sRevolution, me, 0, nil^);
     2258        end
     2259      end;
     2260  end; // ClientMode=cTurn
     2261
     2262  if (ClientMode = cTurn) or (ClientMode = cMovieTurn) then
     2263  begin
     2264    if MyRO.Happened and phGliderLost <> 0 then
     2265      ContextMessage(Phrases.Lookup('GLIDERLOST'), 'MSG_DEFAULT',
     2266        hkModel, 200);
     2267    if MyRO.Happened and phPlaneLost <> 0 then
     2268      ContextMessage(Phrases.Lookup('PLANELOST'), 'MSG_DEFAULT',
     2269        hkFeature, mcFuel);
     2270    if MyRO.Happened and phPeaceEvacuation <> 0 then
     2271      for p1 := 0 to nPl - 1 do
     2272        if 1 shl p1 and MyData.PeaceEvaHappened <> 0 then
     2273          SoundMessageEx(Tribe[p1].TPhrase('WITHDRAW'), 'MSG_DEFAULT');
     2274    if MyRO.Happened and phPeaceViolation <> 0 then
     2275      for p1 := 0 to nPl - 1 do
     2276        if (1 shl p1 and MyRO.Alive <> 0) and (MyRO.EvaStart[p1] = MyRO.Turn)
     2277        then
     2278          SoundMessageEx(Format(Tribe[p1].TPhrase('VIOLATION'),
     2279            [TurnToString(MyRO.Turn + PeaceEvaTurns - 1)]), 'MSG_WITHDRAW');
     2280    TellNewContacts;
     2281  end;
     2282
     2283  if ClientMode = cMovieTurn then
     2284    Update
     2285  else if ClientMode = cTurn then
     2286  begin
     2287    if UpdatePanel then
     2288      UpdateViews;
     2289    DpiApplication.ProcessMessages;
     2290
     2291    if not supervising then
     2292      for uix := 0 to MyRO.nUn - 1 do
     2293        with MyUn[uix] do
     2294          if Loc >= 0 then
     2295          begin
     2296            if Flags and unWithdrawn <> 0 then
     2297              Status := 0;
     2298            if Health = 100 then
     2299              Status := Status and not usRecover;
     2300            if (Master >= 0) or UnitExhausted(uix) then
     2301              Status := Status and not usWaiting
     2302            else
     2303              Status := Status or usWaiting;
     2304            CheckToldNoReturn(uix);
     2305            if Status and usGoto <> 0 then
     2306            begin { continue multi-turn goto }
     2307              SetUnFocus(uix);
     2308              SetTroopLoc(Loc);
     2309              FocusOnLoc(TroopLoc, flRepaintPanel or flImmUpdate);
     2310              if Status shr 16 = $7FFF then
     2311                MoveResult := GetMoveAdvice(UnFocus, maNextCity,
     2312                  MoveAdviceData)
     2313              else
     2314                MoveResult := GetMoveAdvice(UnFocus, Status shr 16,
     2315                  MoveAdviceData);
     2316              if MoveResult >= rExecuted then
     2317              begin // !!! Shinkansen
     2318                MoveResult := eOK;
     2319                ok := true;
     2320                for i := 0 to MoveAdviceData.nStep - 1 do
     2321                begin
     2322                  Loc1 := dLoc(Loc, MoveAdviceData.dx[i],
     2323                    MoveAdviceData.dy[i]);
     2324                  if (MyMap[Loc1] and (fCity or fOwned) = fCity)
     2325                  // don't capture cities during auto move
     2326                    or (MyMap[Loc1] and (fUnit or fOwned) = fUnit) then
     2327                  // don't attack during auto move
    21952328                  begin
    2196                     if AutoBuild(cix, MyData.ImpOrder[Status and 7 - 1]) then
    2197                       AllowCityScreen := false
    2198                     else if Flags and chProduction <> 0 then
    2199                       Flags := (Flags and not chProduction) or chAllImpsMade
     2329                    ok := false;
     2330                    Break
    22002331                  end
    22012332                  else
    2202                     Flags := Flags or chTypeDel;
    2203                 if (Size >= NeedAqueductSize) and
    2204                   (MyRO.Tech[Imp[imAqueduct].Preq] < tsApplicable) or
    2205                   (Size >= NeedSewerSize) and
    2206                   (MyRO.Tech[Imp[imSewer].Preq] < tsApplicable) then
    2207                   Flags := Flags and not chNoGrowthWarning;
    2208                 // don't remind of unknown building
    2209                 if Flags and chNoSettlerProd = 0 then
    2210                   Status := Status and not csToldDelay
    2211                 else if Status and csToldDelay = 0 then
    2212                   Status := Status or csToldDelay
    2213                 else
    2214                   Flags := Flags and not chNoSettlerProd;
    2215                 if mRepScreens.Checked then
    2216                 begin
    2217                   if (Flags and CityRepMask <> 0) and AllowCityScreen then
    2218                   begin { show what happened in cities }
    2219                     SetTroopLoc(MyCity[cix].Loc);
    2220                     MarkCityLoc := MyCity[cix].Loc;
    2221                     PanelPaint;
    2222                     CityDlg.CloseAction := None;
    2223                     CityDlg.ShowNewContent(wmModal, MyCity[cix].Loc,
    2224                       Flags and CityRepMask);
    2225                     UpdatePanel := true;
    2226                   end
    2227                 end
    2228                 else { if mRepList.Checked then }
    2229                 begin
    2230                   if Flags and CityRepMask <> 0 then
    2231                     ShowCityList := true
    2232                 end
    2233               end
    2234             end; { city loop }
    2235     end; // ClientMode=cTurn
    2236 
    2237     if ClientMode = cTurn then
    2238     begin
    2239       if NewGovAvailable >= 0 then
    2240         with MessgExDlg do
    2241         begin
    2242           MessgText := Format(Phrases.Lookup('AUTOREVOLUTION'),
    2243             [Phrases.Lookup('GOVERNMENT', NewGovAvailable)]);
    2244           Kind := mkYesNo;
    2245           IconKind := mikPureIcon;
    2246           IconIndex := 6 + NewGovAvailable;
    2247           ShowModal;
    2248           if ModalResult = mrOK then
    2249           begin
    2250             Play('REVOLUTION');
    2251             Server(sRevolution, me, 0, nil^);
    2252           end
    2253         end;
    2254     end; // ClientMode=cTurn
    2255 
    2256     if (ClientMode = cTurn) or (ClientMode = cMovieTurn) then
    2257     begin
    2258       if MyRO.Happened and phGliderLost <> 0 then
    2259         ContextMessage(Phrases.Lookup('GLIDERLOST'), 'MSG_DEFAULT',
    2260           hkModel, 200);
    2261       if MyRO.Happened and phPlaneLost <> 0 then
    2262         ContextMessage(Phrases.Lookup('PLANELOST'), 'MSG_DEFAULT',
    2263           hkFeature, mcFuel);
    2264       if MyRO.Happened and phPeaceEvacuation <> 0 then
    2265         for p1 := 0 to nPl - 1 do
    2266           if 1 shl p1 and MyData.PeaceEvaHappened <> 0 then
    2267             SoundMessageEx(Tribe[p1].TPhrase('WITHDRAW'), 'MSG_DEFAULT');
    2268       if MyRO.Happened and phPeaceViolation <> 0 then
    2269         for p1 := 0 to nPl - 1 do
    2270           if (1 shl p1 and MyRO.Alive <> 0) and (MyRO.EvaStart[p1] = MyRO.Turn)
    2271           then
    2272             SoundMessageEx(Format(Tribe[p1].TPhrase('VIOLATION'),
    2273               [TurnToString(MyRO.Turn + PeaceEvaTurns - 1)]), 'MSG_WITHDRAW');
    2274       TellNewContacts;
    2275     end;
    2276 
    2277     if ClientMode = cMovieTurn then
    2278       Update
    2279     else if ClientMode = cTurn then
    2280     begin
    2281       if UpdatePanel then
    2282         UpdateViews;
    2283       Application.ProcessMessages;
    2284 
    2285       if not supervising then
    2286         for uix := 0 to MyRO.nUn - 1 do
    2287           with MyUn[uix] do
    2288             if Loc >= 0 then
    2289             begin
    2290               if Flags and unWithdrawn <> 0 then
    2291                 Status := 0;
    2292               if Health = 100 then
    2293                 Status := Status and not usRecover;
    2294               if (Master >= 0) or UnitExhausted(uix) then
    2295                 Status := Status and not usWaiting
    2296               else
    2297                 Status := Status or usWaiting;
    2298               CheckToldNoReturn(uix);
    2299               if Status and usGoto <> 0 then
    2300               begin { continue multi-turn goto }
    2301                 SetUnFocus(uix);
    2302                 SetTroopLoc(Loc);
    2303                 FocusOnLoc(TroopLoc, flRepaintPanel or flImmUpdate);
    2304                 if Status shr 16 = $7FFF then
    2305                   MoveResult := GetMoveAdvice(UnFocus, maNextCity,
    2306                     MoveAdviceData)
    2307                 else
    2308                   MoveResult := GetMoveAdvice(UnFocus, Status shr 16,
    2309                     MoveAdviceData);
    2310                 if MoveResult >= rExecuted then
    2311                 begin // !!! Shinkansen
    2312                   MoveResult := eOK;
    2313                   ok := true;
    2314                   for i := 0 to MoveAdviceData.nStep - 1 do
    23152333                  begin
    2316                     Loc1 := dLoc(Loc, MoveAdviceData.dx[i],
    2317                       MoveAdviceData.dy[i]);
    2318                     if (MyMap[Loc1] and (fCity or fOwned) = fCity)
    2319                     // don't capture cities during auto move
    2320                       or (MyMap[Loc1] and (fUnit or fOwned) = fUnit) then
    2321                     // don't attack during auto move
     2334                    if (Loc1 = MoveAdviceData.ToLoc) or
     2335                      (MoveAdviceData.ToLoc = maNextCity) and
     2336                      (MyMap[dLoc(Loc, MoveAdviceData.dx[i],
     2337                      MoveAdviceData.dy[i])] and fCity <> 0) then
     2338                      MoveOptions := muAutoNoWait
     2339                    else
     2340                      MoveOptions := 0;
     2341                    MoveResult := MoveUnit(MoveAdviceData.dx[i],
     2342                      MoveAdviceData.dy[i], MoveOptions);
     2343                    if (MoveResult < rExecuted) or (MoveResult = eEnemySpotted)
     2344                    then
    23222345                    begin
    23232346                      ok := false;
    23242347                      Break
    2325                     end
    2326                     else
    2327                     begin
    2328                       if (Loc1 = MoveAdviceData.ToLoc) or
    2329                         (MoveAdviceData.ToLoc = maNextCity) and
    2330                         (MyMap[dLoc(Loc, MoveAdviceData.dx[i],
    2331                         MoveAdviceData.dy[i])] and fCity <> 0) then
    2332                         MoveOptions := muAutoNoWait
    2333                       else
    2334                         MoveOptions := 0;
    2335                       MoveResult := MoveUnit(MoveAdviceData.dx[i],
    2336                         MoveAdviceData.dy[i], MoveOptions);
    2337                       if (MoveResult < rExecuted) or (MoveResult = eEnemySpotted)
    2338                       then
    2339                       begin
    2340                         ok := false;
    2341                         Break
    2342                       end;
    2343                     end
    2344                   end;
    2345                   Stop := not ok or (Loc = MoveAdviceData.ToLoc) or
    2346                     (MoveAdviceData.ToLoc = maNextCity) and
    2347                     (MyMap[Loc] and fCity <> 0)
    2348                 end
     2348                    end;
     2349                  end
     2350                end;
     2351                Stop := not ok or (Loc = MoveAdviceData.ToLoc) or
     2352                  (MoveAdviceData.ToLoc = maNextCity) and
     2353                  (MyMap[Loc] and fCity <> 0)
     2354              end
     2355              else
     2356              begin
     2357                MoveResult := eOK;
     2358                Stop := true;
     2359              end;
     2360
     2361              if MoveResult <> eDied then
     2362                if Stop then
     2363                  Status := Status and ($FFFF - usGoto)
    23492364                else
    2350                 begin
    2351                   MoveResult := eOK;
    2352                   Stop := true;
    2353                 end;
    2354 
    2355                 if MoveResult <> eDied then
    2356                   if Stop then
    2357                     Status := Status and ($FFFF - usGoto)
    2358                   else
    2359                     Status := Status and not usWaiting;
    2360               end;
    2361 
    2362               if Status and (usEnhance or usGoto) = usEnhance then
    2363               // continue terrain enhancement
    2364               begin
    2365                 MoveResult := ProcessEnhancement(uix, MyData.EnhancementJobs);
    2366                 if MoveResult <> eDied then
    2367                   if MoveResult = eJobDone then
    2368                     Status := Status and not usEnhance
    2369                   else
    2370                     Status := Status and not usWaiting;
    2371               end
     2365                  Status := Status and not usWaiting;
    23722366            end;
    2373     end; // ClientMode=cTurn
    2374 
    2375     HaveStrategyAdvice := false;
    2376     // (GameMode<>cMovie) and not supervising
    2377     // and AdvisorDlg.HaveStrategyAdvice;
    2378     GoOnPhase := true;
    2379     if supervising or (GameMode = cMovie) then
    2380     begin
     2367
     2368            if Status and (usEnhance or usGoto) = usEnhance then
     2369            // continue terrain enhancement
     2370            begin
     2371              MoveResult := ProcessEnhancement(uix, MyData.EnhancementJobs);
     2372              if MoveResult <> eDied then
     2373                if MoveResult = eJobDone then
     2374                  Status := Status and not usEnhance
     2375                else
     2376                  Status := Status and not usWaiting;
     2377            end
     2378          end;
     2379  end; // ClientMode=cTurn
     2380
     2381  HaveStrategyAdvice := false;
     2382  // (GameMode<>cMovie) and not supervising
     2383  // and AdvisorDlg.HaveStrategyAdvice;
     2384  GoOnPhase := true;
     2385  if supervising or (GameMode = cMovie) then
     2386  begin
     2387    SetTroopLoc(-1);
     2388    PaintAll
     2389  end { supervisor }
     2390  { else if (ClientMode=cTurn) and (MyRO.Turn=0) then
     2391    begin
     2392    SetUnFocus(0);
     2393    ZoomToCity(MyCity[0].Loc)
     2394    end }
     2395  else
     2396  begin
     2397    if ClientMode >= scContact then
     2398      SetUnFocus(-1)
     2399    else
     2400      NextUnit(-1, false);
     2401    if UnFocus < 0 then
     2402    begin
     2403      UnStartLoc := -1;
     2404      if IsMultiPlayerGame or (ClientMode = cResume) then
     2405        if MyRO.nCity > 0 then
     2406          FocusOnLoc(MyCity[0].Loc)
     2407        else
     2408          FocusOnLoc(G.lx * G.ly div 2);
    23812409      SetTroopLoc(-1);
    2382       PaintAll
    2383     end { supervisor }
    2384     { else if (ClientMode=cTurn) and (MyRO.Turn=0) then
    2385       begin
    2386       SetUnFocus(0);
    2387       ZoomToCity(MyCity[0].Loc)
    2388       end }
    2389     else
    2390     begin
    2391       if ClientMode >= scContact then
    2392         SetUnFocus(-1)
    2393       else
    2394         NextUnit(-1, false);
    2395       if UnFocus < 0 then
    2396       begin
    2397         UnStartLoc := -1;
    2398         if IsMultiPlayerGame or (ClientMode = cResume) then
    2399           if MyRO.nCity > 0 then
    2400             FocusOnLoc(MyCity[0].Loc)
    2401           else
    2402             FocusOnLoc(G.lx * G.ly div 2);
    2403         SetTroopLoc(-1);
    2404         PanelPaint
    2405       end;
    2406       if ShowCityList then
    2407         ListDlg.ShowNewContent(wmPersistent, kCityEvents);
     2410      PanelPaint
    24082411    end;
    2409   end; { InitTurn }
    2410 
     2412    if ShowCityList then
     2413      ListDlg.ShowNewContent(wmPersistent, kCityEvents);
     2414  end;
     2415end;
     2416
     2417procedure TMainScreen.Client(Command, NewPlayer: integer; var Data);
    24112418var
    24122419  i, j, p1, mix, ToLoc, AnimationSpeed, ShowMoveDomain, cix, ecix: integer;
     
    24162423  mi: TModelInfo;
    24172424  SkipTurn, IsAlpine, IsTreatyDeal: boolean;
    2418 
    2419 begin { >>>client }
     2425begin
    24202426  case Command of
    24212427    cTurn, cResume, cContinue, cMovieTurn, scContact, scDipStart .. scDipBreak:
     
    26292635              assert(TribeNames.Count > 0);
    26302636              ModalSelectDlg.ShowNewContent(wmModal, kTribe);
    2631               Application.ProcessMessages;
     2637              DpiApplication.ProcessMessages;
    26322638              TribeInfo.FileName := UnusedTribeFiles[ModalSelectDlg.result];
    26332639              UnusedTribeFiles.Delete(ModalSelectDlg.result);
     
    27462752          begin
    27472753            if AILogo[pLogo] <> nil then
    2748               DpiBitBlt(Canvas.Handle, (xRightPanel + 10) - (16 + 64),
    2749                 ClientHeight - PanelHeight, 64, 64, AILogo[pLogo].Canvas.Handle,
    2750                 0, 0, SRCCOPY);
     2754              DpiBitCanvas(Canvas, (xRightPanel + 10) - (16 + 64),
     2755                ClientHeight - PanelHeight, 64, 64, AILogo[pLogo].Canvas,
     2756                0, 0);
    27512757          end
    27522758        end
     
    27762782
    27772783        if Jump[pTurn] > 0 then
    2778           Application.ProcessMessages;
     2784          DpiApplication.ProcessMessages;
    27792785        if Jump[pTurn] > 0 then
    27802786          if G.RO[NewPlayer].Happened and phGameEnd <> 0 then
     
    28252831        end;
    28262832        InitTurn(NewPlayer);
    2827         Application.ProcessMessages;
     2833        DpiApplication.ProcessMessages;
    28282834        if MovieSpeed = 4 then
    28292835        begin
    28302836          Sleep(75);
    28312837          // this break will ensure speed of fast forward does not depend on cpu speed
    2832           Application.ProcessMessages;
     2838          DpiApplication.ProcessMessages;
    28332839        end
    28342840      end;
     
    29912997        assert(NewPlayer = me);
    29922998        if not idle or (GameMode = cMovie) then
    2993           Application.ProcessMessages;
     2999          DpiApplication.ProcessMessages;
    29943000        if Command = cShowCityChanged then
    29953001        begin
     
    30553061        assert(NewPlayer = me);
    30563062        if not idle or (GameMode = cMovie) then
    3057           Application.ProcessMessages;
     3063          DpiApplication.ProcessMessages;
    30583064        with TShowMove(Data) do
    30593065        begin
     
    32363242        assert(NewPlayer = me);
    32373243        if not idle or (GameMode = cMovie) then
    3238           Application.ProcessMessages;
     3244          DpiApplication.ProcessMessages;
    32393245        with TShowMove(Data) do
    32403246        begin
     
    33893395      end
    33903396  end
    3391 end; { <<<client }
     3397end;
    33923398
    33933399{ *** main part *** }
     
    34053411procedure TMainScreen.FormCreate(Sender: TObject);
    34063412var
    3407   DefaultOptionChecked: integer;
    3408   Reg: TRegistry;
    34093413  i, j: integer;
    34103414begin
     3415  MainFormKeyDown := FormKeyDown;
    34113416  BaseWin.CreateOffscreen(Offscreen);
    34123417
     
    34343439  SaveOption[20] := mAlFastMoves.Tag;
    34353440  SaveOption[21] := mAlNoMoves.Tag;
    3436   DefaultOptionChecked := 1 shl 1 + 1 shl 7 + 1 shl 10 + 1 shl 12 + 1 shl 14 +
    3437     1 shl 18 + 1 shl 19;
    3438 
    3439   Reg := TRegistry.Create;
    3440   with Reg do
    3441   try
    3442     OpenKey(AppRegistryKey, false);
    3443     if ValueExists('TileWidth') then xxt := ReadInteger('TileWidth') div 2
    3444       else xxt := 48;
    3445     if ValueExists('TileHeight') then yyt := ReadInteger('TileHeight') div 2
    3446       else yyt := 24;
    3447     if ValueExists('OptionChecked') then OptionChecked := ReadInteger('OptionChecked')
    3448       else OptionChecked := DefaultOptionChecked;
    3449     if ValueExists('MapOptionChecked') then MapOptionChecked := ReadInteger('MapOptionChecked')
    3450       else MapOptionChecked := 1 shl moCityNames;
    3451     if ValueExists('CityReport') then CityRepMask := Cardinal(ReadInteger('CityReport'))
    3452       else CityRepMask := Cardinal(not chPopIncrease and not chNoGrowthWarning and
    3453           not chCaptured);
    3454     if OptionChecked and (7 shl 16) = 0 then
    3455       OptionChecked := OptionChecked or (1 shl 16);
    3456       // old regver with no scrolling
    3457   finally
    3458     Free;
    3459   end;
    3460 
    3461   if 1 shl 13 and OptionChecked <> 0 then
    3462     SoundMode := smOff
    3463   else if 1 shl 15 and OptionChecked <> 0 then
    3464     SoundMode := smOnAlt
    3465   else
    3466     SoundMode := smOn;
    3467 
    3468   Screen.Cursors[crImpDrag] := LoadCursor(HInstance, 'DRAG');
    3469   Screen.Cursors[crFlatHand] := LoadCursor(HInstance, 'FLATHAND');
     3441
     3442  LoadSettings;
     3443
     3444  DpiScreen.Cursors[crImpDrag] := LoadCursor(HInstance, 'DRAG');
     3445  DpiScreen.Cursors[crFlatHand] := LoadCursor(HInstance, 'FLATHAND');
    34703446
    34713447  // tag-controlled language
     
    35373513procedure TMainScreen.FormDestroy(Sender: TObject);
    35383514var
    3539   i: integer;
    3540 begin
     3515  I: Integer;
     3516begin
     3517  MainFormKeyDown := nil;
    35413518  FreeAndNil(sb);
    35423519  FreeAndNil(TopBar);
     
    35443521  FreeAndNil(Buffer);
    35453522  FreeAndNil(Panel);
    3546   for i := 0 to nPl - 1 do
     3523  for I := 0 to nPl - 1 do
    35473524    if AILogo[i] <> nil then
    3548       FreeAndNil(AILogo[i]);
     3525      FreeAndNil(AILogo[I]);
    35493526  FreeAndNil(Offscreen);
    35503527end;
     
    40344011    exit;
    40354012
    4036   NoMap.BitBlt(Panel, -xMap - MapOffset, -yMap + MapHeight - overlap, xMidPanel,
     4013  NoMap.BitBltBitmap(Panel, -xMap - MapOffset, -yMap + MapHeight - overlap, xMidPanel,
    40374014    overlap, 0, 0, SRCCOPY);
    4038   NoMap.BitBlt(Panel, -xMap - MapOffset + xRightPanel,
     4015  NoMap.BitBltBitmap(Panel, -xMap - MapOffset + xRightPanel,
    40394016    -yMap + MapHeight - overlap, Panel.width - xRightPanel, overlap,
    40404017    xRightPanel, 0, SRCCOPY);
     
    40424019  begin
    40434020    if xMap < 0 then
    4044       DpiBitBlt(Canvas.Handle, MapOffset, TopBarHeight, width + xMap,
    4045         height + yMap, Buffer.Canvas.Handle, -xMap, -yMap, SRCCOPY)
     4021      DpiBitCanvas(Canvas, MapOffset, TopBarHeight, width + xMap,
     4022        height + yMap, Buffer.Canvas, -xMap, -yMap)
    40464023    else
    4047       DpiBitBlt(Canvas.Handle, xMap + MapOffset, TopBarHeight, width,
    4048         height + yMap, Buffer.Canvas.Handle, 0, -yMap, SRCCOPY)
     4024      DpiBitCanvas(Canvas, xMap + MapOffset, TopBarHeight, width,
     4025        height + yMap, Buffer.Canvas, 0, -yMap)
    40494026  end
    40504027  else
    40514028  begin
    40524029    if xMap < 0 then
    4053       DpiBitBlt(Canvas.Handle, MapOffset, TopBarHeight + yMap, width + xMap,
    4054         height, Buffer.Canvas.Handle, -xMap, 0, SRCCOPY)
     4030      DpiBitCanvas(Canvas, MapOffset, TopBarHeight + yMap, width + xMap,
     4031        height, Buffer.Canvas, -xMap, 0)
    40554032    else
    4056       DpiBitBlt(Canvas.Handle, xMap + MapOffset, TopBarHeight + yMap, width,
    4057         height, Buffer.Canvas.Handle, 0, 0, SRCCOPY);
     4033      DpiBitCanvas(Canvas, xMap + MapOffset, TopBarHeight + yMap, width,
     4034        height, Buffer.Canvas, 0, 0);
    40584035  end
    40594036end;
     
    40984075  end;
    40994076  Mini.BeginUpdate;
    4100   MiniPixel.Init(Mini);
    4101   PrevMiniPixel.Init(Mini);
     4077  MiniPixel := PixelPointer(Mini);
     4078  PrevMiniPixel := PixelPointer(Mini);
    41024079  for y := 0 to G.ly - 1 do
    41034080  begin
     
    41794156function ScrollDC(Canvas: TDpiCanvas; dx: longint; dy: longint; const lprcScroll:TRect; const lprcClip:TRect; hrgnUpdate:HRGN; lprcUpdate: PRect):Boolean;
    41804157begin
    4181   BitBltCanvas(Canvas, lprcScroll.Left + dx, lprcScroll.Top + dy, lprcScroll.Right - lprcScroll.Left, lprcScroll.Bottom - lprcScroll.Top,
    4182     Canvas, lprcScroll.Left, lprcScroll.Top, SRCCOPY);
     4158  Result := DpiBitCanvas(Canvas, lprcScroll.Left + dx, lprcScroll.Top + dy, lprcScroll.Right - lprcScroll.Left, lprcScroll.Bottom - lprcScroll.Top,
     4159    Canvas, lprcScroll.Left, lprcScroll.Top);
    41834160end;
    41844161{$ENDIF}
     
    43254302procedure TMainScreen.CopyMiniToPanel;
    43264303begin
    4327   DpiBitBlt(Panel.Canvas.Handle, xMini + 2, yMini + 2, G.lx * 2, G.ly,
    4328     Mini.Canvas.Handle, 0, 0, SRCCOPY);
     4304  DpiBitCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
     4305    Mini.Canvas, 0, 0);
    43294306  if MarkCityLoc >= 0 then
    43304307    Sprite(Panel, HGrSystem, xMini - 2 + (4 * G.lx + 2 * (MarkCityLoc mod G.lx)
     
    44144391          ClientWidth - xPalace + xSizeBig + 1, yPalace + ySizeBig + 1,
    44154392          $FFFFFF, $B0B0B0);
    4416         DpiBitBlt(Panel.Canvas.Handle, ClientWidth - xPalace, yPalace, xSizeBig,
    4417           ySizeBig, GrExt[HGrSystem2].Data.Canvas.Handle, 70, 123, SRCCOPY);
     4393        DpiBitCanvas(Panel.Canvas, ClientWidth - xPalace, yPalace, xSizeBig,
     4394          ySizeBig, GrExt[HGrSystem2].Data.Canvas, 70, 123);
    44184395      end
    44194396      else if MyRO.NatBuilt[imPalace] > 0 then
     
    50945071    else
    50955072    begin
    5096       if Application.Active and not mScrollOff.Checked then
     5073      if DpiApplication.Active and not mScrollOff.Checked then
    50975074      begin
    50985075        if mScrollFast.Checked then
     
    52725249      PaintLoc(MouseLoc, 2);
    52735250      MiniPaint;
    5274       DpiBitBlt(Panel.Canvas.Handle, xMini + 2, yMini + 2, G.lx * 2, G.ly,
    5275         Mini.Canvas.Handle, 0, 0, SRCCOPY);
     5251      DpiBitCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
     5252        Mini.Canvas, 0, 0);
    52765253      if ywmax <= 0 then
    52775254        Frame(Panel.Canvas, xMini + 2 + G.lx - MapWidth div (2 * xxt),
     
    60316008var
    60326009  ToLoc, xFromLoc, yFromLoc, xToLoc, yToLoc, xFrom, yFrom, xTo, yTo, xMin, yMin,
    6033     xRange, yRange, xw1, Step, xMoving, yMoving, yl, SliceCount: integer;
     6010    xRange, yRange, xw1, Step, xMoving, yMoving, SliceCount: integer;
    60346011  UnitInfo: TUnitInfo;
    60356012  Ticks0, Ticks: TDateTime;
     
    60966073    for Step := 0 to abs(Step1 - Step0) do
    60976074    begin
    6098       DpiBitBlt(Buffer.Canvas.Handle, 0, 0, xRange, yRange,
    6099         offscreen.Canvas.Handle, xMin, yMin, SRCCOPY);
     6075      DpiBitCanvas(Buffer.Canvas, 0, 0, xRange, yRange,
     6076        offscreen.Canvas, xMin, yMin);
    61006077      if Step1 <> Step0 then
    61016078      begin
     
    61236100        begin
    61246101          if not idle or (GameMode = cMovie) then
    6125             Application.ProcessMessages;
     6102            DpiApplication.ProcessMessages;
    61266103          {$IFDEF LINUX}
    61276104          // TODO: Force animation under linux
    6128           Application.ProcessMessages;
     6105          DpiApplication.ProcessMessages;
    61296106          {$ENDIF}
    61306107          Sleep(1);
     
    61386115  if Restore then
    61396116  begin
    6140     DpiBitBlt(Buffer.Canvas.Handle, 0, 0, xRange, yRange, offscreen.Canvas.Handle,
    6141       xMin, yMin, SRCCOPY);
     6117    DpiBitCanvas(Buffer.Canvas, 0, 0, xRange, yRange, offscreen.Canvas, xMin, yMin);
    61426118    PaintBufferToScreen(xMin, yMin, xRange, yRange);
    61436119  end;
     
    68846860  end
    68856861  else if Sender = mWebsite then
    6886     OpenURL('http://c-evo.org')
     6862    OpenURL(CevoHomepage)
    68876863  else if Sender = mRandomMap then
    68886864  begin
     
    73227298    mSmallTiles.Checked := xxt = 33;
    73237299    mNormalTiles.Checked := xxt = 48;
     7300    mBigTiles.Checked := xxt = 72;
    73247301  end
    73257302  else if Popup = StatPopup then
     
    74897466  InitPopup(Popup);
    74907467  if FullScreen then
    7491     Popup.Popup(Left + TDpiControl(Sender).Left, Top + TDpiControl(Sender).Top)
     7468    Popup.Popup(Left + TControl(Sender).Left, Top + TControl(Sender).Top)
    74927469  else
    7493     Popup.Popup(Left + TDpiControl(Sender).Left + 4, Top + TDpiControl(Sender).Top +
     7470    Popup.Popup(Left + TControl(Sender).Left + 4, Top + TControl(Sender).Top +
    74947471      GetSystemMetrics(SM_CYCAPTION) + 4);
    74957472end;
     
    75537530          yw := ywmax;
    75547531      end;
    7555       DpiBitBlt(Buffer.Canvas.Handle, 0, 0, G.lx * 2, G.ly, Mini.Canvas.Handle, 0,
    7556         0, SRCCOPY);
     7532      DpiBitCanvas(Buffer.Canvas, 0, 0, G.lx * 2, G.ly, Mini.Canvas, 0, 0);
    75577533      if ywmax <= 0 then
    75587534        Frame(Buffer.Canvas, x - xMini - 2 - MapWidth div (xxt * 2), 0,
     
    75637539          x - xMini - 2 + MapWidth div (xxt * 2) - 1, yw + MapHeight div yyt -
    75647540          2, MainTexture.clMark, MainTexture.clMark);
    7565       DpiBitBlt(Panel.Canvas.Handle, xMini + 2, yMini + 2, G.lx * 2, G.ly,
    7566         Buffer.Canvas.Handle, 0, 0, SRCCOPY);
     7541      DpiBitCanvas(Panel.Canvas, xMini + 2, yMini + 2, G.lx * 2, G.ly,
     7542        Buffer.Canvas, 0, 0);
    75677543      MainOffscreenPaint;
    75687544      RectInvalidate(xMini + 2, TopBarHeight + MapHeight - overlap + yMini + 2,
     
    75737549  end
    75747550  else
    7575     Tracking := false
     7551    Tracking := false;
    75767552end;
    75777553
     
    77157691      Brush.Style := bsClear;
    77167692    end;
    7717   DpiBitBlt(Canvas.Handle, MapOffset, TopBarHeight, MapWidth, MapHeight - overlap,
    7718     offscreen.Canvas.Handle, 0, 0, SRCCOPY);
    7719   DpiBitBlt(Canvas.Handle, 0, 0, ClientWidth, TopBarHeight, TopBar.Canvas.Handle,
    7720     0, 0, SRCCOPY);
     7693  DpiBitCanvas(Canvas, MapOffset, TopBarHeight, MapWidth, MapHeight - overlap,
     7694    offscreen.Canvas, 0, 0);
     7695  DpiBitCanvas(Canvas, 0, 0, ClientWidth, TopBarHeight, TopBar.Canvas,
     7696    0, 0);
    77217697  if xMidPanel > MapOffset then
    7722     DpiBitBlt(Canvas.Handle, xMidPanel, TopBarHeight + MapHeight - overlap,
    7723       ClientWidth div 2 - xMidPanel, overlap, offscreen.Canvas.Handle,
    7724       xMidPanel - MapOffset, MapHeight - overlap, SRCCOPY)
     7698    DpiBitCanvas(Canvas, xMidPanel, TopBarHeight + MapHeight - overlap,
     7699      ClientWidth div 2 - xMidPanel, overlap, offscreen.Canvas,
     7700      xMidPanel - MapOffset, MapHeight - overlap)
    77257701  else
    7726     DpiBitBlt(Canvas.Handle, MapOffset, TopBarHeight + MapHeight - overlap,
    7727       ClientWidth div 2 - MapOffset, overlap, offscreen.Canvas.Handle, 0,
    7728       MapHeight - overlap, SRCCOPY);
     7702    DpiBitCanvas(Canvas, MapOffset, TopBarHeight + MapHeight - overlap,
     7703      ClientWidth div 2 - MapOffset, overlap, offscreen.Canvas, 0,
     7704      MapHeight - overlap);
    77297705  if xRightPanel < MapOffset + MapWidth then
    7730     DpiBitBlt(Canvas.Handle, ClientWidth div 2, TopBarHeight + MapHeight - overlap,
    7731       xRightPanel - ClientWidth div 2, overlap, offscreen.Canvas.Handle,
    7732       ClientWidth div 2 - MapOffset, MapHeight - overlap, SRCCOPY)
     7706    DpiBitCanvas(Canvas, ClientWidth div 2, TopBarHeight + MapHeight - overlap,
     7707      xRightPanel - ClientWidth div 2, overlap, offscreen.Canvas,
     7708      ClientWidth div 2 - MapOffset, MapHeight - overlap)
    77337709  else
    7734     DpiBitBlt(Canvas.Handle, ClientWidth div 2, TopBarHeight + MapHeight - overlap,
     7710    DpiBitCanvas(Canvas, ClientWidth div 2, TopBarHeight + MapHeight - overlap,
    77357711      MapOffset + MapWidth - ClientWidth div 2, overlap,
    7736       offscreen.Canvas.Handle, ClientWidth div 2 - MapOffset,
    7737       MapHeight - overlap, SRCCOPY);
    7738   DpiBitBlt(Canvas.Handle, 0, TopBarHeight + MapHeight - overlap, xMidPanel,
    7739     overlap, Panel.Canvas.Handle, 0, 0, SRCCOPY);
    7740   DpiBitBlt(Canvas.Handle, xRightPanel, TopBarHeight + MapHeight - overlap,
    7741     Panel.width - xRightPanel, overlap, Panel.Canvas.Handle, xRightPanel,
    7742     0, SRCCOPY);
    7743   DpiBitBlt(Canvas.Handle, 0, TopBarHeight + MapHeight, Panel.width,
    7744     PanelHeight - overlap, Panel.Canvas.Handle, 0, overlap, SRCCOPY);
     7712      offscreen.Canvas, ClientWidth div 2 - MapOffset,
     7713      MapHeight - overlap);
     7714  DpiBitCanvas(Canvas, 0, TopBarHeight + MapHeight - overlap, xMidPanel,
     7715    overlap, Panel.Canvas, 0, 0);
     7716  DpiBitCanvas(Canvas, xRightPanel, TopBarHeight + MapHeight - overlap,
     7717    Panel.width - xRightPanel, overlap, Panel.Canvas, xRightPanel, 0);
     7718  DpiBitCanvas(Canvas, 0, TopBarHeight + MapHeight, Panel.width,
     7719    PanelHeight - overlap, Panel.Canvas, 0, overlap);
    77457720  if (pLogo >= 0) and (G.RO[pLogo] = nil) and (AILogo[pLogo] <> nil) then
    7746     DpiBitBlt(Canvas.Handle, xRightPanel + 10 - (16 + 64),
    7747       ClientHeight - PanelHeight, 64, 64, AILogo[pLogo].Canvas.Handle, 0,
    7748       0, SRCCOPY);
     7721    DpiBitCanvas(Canvas, xRightPanel + 10 - (16 + 64),
     7722      ClientHeight - PanelHeight, 64, 64, AILogo[pLogo].Canvas, 0, 0);
    77497723end;
    77507724
     
    77747748  InvalidateRgn(Handle, r0, false);
    77757749  DeleteObject(r0);
     7750end;
     7751
     7752procedure TMainScreen.LoadSettings;
     7753var
     7754  Reg: TRegistry;
     7755  DefaultOptionChecked: Integer;
     7756begin
     7757  DefaultOptionChecked := 1 shl 1 + 1 shl 7 + 1 shl 10 + 1 shl 12 + 1 shl 14 +
     7758    1 shl 18 + 1 shl 19;
     7759  Reg := TRegistry.Create;
     7760  with Reg do try
     7761    OpenKey(AppRegistryKey, False);
     7762    if ValueExists('TileWidth') then xxt := ReadInteger('TileWidth') div 2
     7763      else xxt := 48;
     7764    if ValueExists('TileHeight') then yyt := ReadInteger('TileHeight') div 2
     7765      else yyt := 24;
     7766    if ValueExists('OptionChecked') then OptionChecked := ReadInteger('OptionChecked')
     7767      else OptionChecked := DefaultOptionChecked;
     7768    if ValueExists('MapOptionChecked') then MapOptionChecked := ReadInteger('MapOptionChecked')
     7769      else MapOptionChecked := 1 shl moCityNames;
     7770    if ValueExists('CityReport') then CityRepMask := Cardinal(ReadInteger('CityReport'))
     7771      else CityRepMask := Cardinal(not chPopIncrease and not chNoGrowthWarning and
     7772          not chCaptured);
     7773    if OptionChecked and (7 shl 16) = 0 then
     7774      OptionChecked := OptionChecked or (1 shl 16);
     7775      // old regver with no scrolling
     7776  finally
     7777    Free;
     7778  end;
     7779
     7780  if 1 shl 13 and OptionChecked <> 0 then
     7781    SoundMode := smOff
     7782  else if 1 shl 15 and OptionChecked <> 0 then
     7783    SoundMode := smOnAlt
     7784  else
     7785    SoundMode := smOn;
    77767786end;
    77777787
     
    79897999begin
    79908000  SetTileSize(48, 24);
     8001end;
     8002
     8003procedure TMainScreen.mBigTilesClick(Sender: TObject);
     8004begin
     8005  SetTileSize(72, 36);
    79918006end;
    79928007
Note: See TracChangeset for help on using the changeset viewer.