source: trunk/Start.pas@ 352

Last change on this file since 352 was 352, checked in by chronos, 8 months ago
  • Modified: TTexture changed from record to class.
  • Modified: Code cleanup.
File size: 64.5 KB
Line 
1{$INCLUDE Switches.inc}
2unit Start;
3
4interface
5
6uses
7 GameServer, Messg, ButtonBase, ButtonA, ButtonC, ButtonB, Area, Types,
8 LCLIntf, LCLType, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls,
9 Menus, Registry, DrawDlg, fgl, Protocol, UMiniMap;
10
11type
12 TPlayerSlot = class
13 DiffUpBtn: TButtonC;
14 DiffDownBtn: TButtonC;
15 MultiBtn: TButtonC;
16 OfferMultiple: Boolean;
17 Rect: TRect;
18 end;
19
20 TPlayerSlots = class(TFPGObjectList<TPlayerSlot>)
21 end;
22
23 TStartPage = (
24 pgStartRandom,
25 pgStartMap,
26 pgNoLoad,
27 pgLoad,
28 pgEditRandom,
29 pgEditMap,
30 pgMain
31 );
32
33 TStartTab = (tbMain, tbMap, tbNew, tbPrevious);
34 TMainAction = (maConfig, maManual, maCredits, maAIDev, maWeb, maNone);
35 TMainActionSet = set of TMainAction;
36
37 { TStartDlg }
38
39 TStartDlg = class(TDrawDlg)
40 PopupMenu1: TPopupMenu;
41 StartBtn: TButtonA;
42 Down1Btn: TButtonC;
43 Up1Btn: TButtonC;
44 List: TListBox;
45 RenameBtn: TButtonB;
46 DeleteBtn: TButtonB;
47 Down2Btn: TButtonC;
48 Up2Btn: TButtonC;
49 QuitBtn: TButtonB;
50 CustomizeBtn: TButtonC;
51 AutoDiffUpBtn: TButtonC;
52 AutoDiffDownBtn: TButtonC;
53 AutoEnemyUpBtn: TButtonC;
54 AutoEnemyDownBtn: TButtonC;
55 ReplayBtn: TButtonB;
56 procedure StartBtnClick(Sender: TObject);
57 procedure FormPaint(Sender: TObject);
58 procedure FormShow(Sender: TObject);
59 procedure FormHide(Sender: TObject);
60 procedure FormClose(Sender: TObject; var Action: TCloseAction);
61 procedure FormCreate(Sender: TObject);
62 procedure FormDestroy(Sender: TObject);
63 procedure BrainClick(Sender: TObject);
64 procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
65 procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
66 Shift: TShiftState; x, y: integer);
67 procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
68 Shift: TShiftState; x, y: integer);
69 procedure FormMouseMove(Sender: TObject; Shift: TShiftState; x, y: integer);
70 procedure Up1BtnClick(Sender: TObject);
71 procedure Down1BtnClick(Sender: TObject);
72 procedure ListClick(Sender: TObject);
73 procedure RenameBtnClick(Sender: TObject);
74 procedure DeleteBtnClick(Sender: TObject);
75 procedure DiffBtnClick(Sender: TObject);
76 procedure MultiBtnClick(Sender: TObject);
77 procedure Up2BtnClick(Sender: TObject);
78 procedure Down2BtnClick(Sender: TObject);
79 procedure QuitBtnClick(Sender: TObject);
80 procedure CustomizeBtnClick(Sender: TObject);
81 procedure AutoDiffUpBtnClick(Sender: TObject);
82 procedure AutoDiffDownBtnClick(Sender: TObject);
83 procedure AutoEnemyUpBtnClick(Sender: TObject);
84 procedure AutoEnemyDownBtnClick(Sender: TObject);
85 procedure ReplayBtnClick(Sender: TObject);
86 public
87 EmptyPicture: TBitmap;
88 procedure UpdateFormerGames;
89 procedure UpdateMaps;
90 private
91 WorldSize: Integer;
92 StartLandMass: Integer;
93 MaxTurn: Integer;
94 AutoEnemies: Integer;
95 AutoDiff: Integer;
96 MultiControl: Integer;
97 Page: TStartPage;
98 ShowTab: TStartTab;
99 Tab: TStartTab;
100 Diff0: Integer;
101 BrainDefault: TBrain;
102 nMapLandTiles: Integer;
103 nMapStartPositions: Integer;
104 LoadTurn: Integer;
105 LastTurn: Integer;
106 { last turn of selected former game }
107 SlotAvailable: Integer;
108 PlayerPopupIndex: Integer; { brain concerned by brain context menu }
109 ListIndex: array [TStartTab] of Integer;
110 MapFileName: string;
111 FormerGames: TStringList;
112 Maps: TStringList;
113 LogoBuffer: TBitmap;
114 // BookDate: string;
115 PlayerSlots: TPlayerSlots;
116 ActionsOffered: TMainActionSet;
117 SelectedAction: TMainAction;
118 TurnValid: Boolean;
119 Tracking: Boolean;
120 DefaultAI: string;
121 MiniMap: TMiniMap;
122 LastGame: string;
123 procedure DrawAction(y, IconIndex: integer; HeaderItem, TextItem: string);
124 procedure InitPopup(PlayerIndex: Integer);
125 procedure OfferBrain(Brain: TBrain; FixedLines: Integer);
126 procedure PaintInfo;
127 procedure ChangePage(NewPage: TStartPage);
128 procedure ChangeTab(NewTab: TStartTab);
129 procedure UnlistBackupFile(FileName: string);
130 procedure SmartInvalidate(x0, y0, x1, y1: integer;
131 invalidateTab0: boolean = false); overload;
132 procedure LoadConfig;
133 procedure SaveConfig;
134 procedure LoadAiBrainsPictures;
135 procedure UpdateInterface;
136 end;
137
138var
139 StartDlg: TStartDlg;
140
141
142implementation
143
144uses
145 Global, Directories, Direct, ScreenTools, Inp, Back, Settings, UKeyBindings;
146
147{$R *.lfm}
148
149const
150 // predefined world size
151 // attention: lx*ly+1 must be prime!
152 { MaxWorldSize=8;
153 lxpre: array[0..nWorldSize-1] of integer =(30,40,50,60,70,90,110,130);
154 lypre: array[0..nWorldSize-1] of integer =(46,52,60,70,84,94,110,130);
155 DefaultWorldTiles=4200; }
156 MaxWorldSize = 6;
157 WorldSizes: array [0 .. MaxWorldSize - 1] of TPoint = ((X: 30; Y: 46),
158 (X: 40; Y: 52), (X: 50; Y: 60), (X: 60; Y: 70), (X: 75; Y: 82),
159 (X: 100; Y: 96));
160 DefaultWorldTiles = 4150;
161 DefaultWorldSize = 3;
162 DefaultLandMass = 30;
163
164 nPlOffered = 9;
165 yMain = 14;
166 xActionIcon = 55;
167 xAction = 111;
168 yAction = 60;
169 ActionPitch = 56;
170 ActionSideBorder = 24;
171 ActionBottomBorder = 10;
172 wBuffer = 91;
173 x0Mini = 437;
174 y0Mini = 178;
175 xTurnSlider = 346;
176 yTurnSlider = 262;
177 wTurnSlider = 168;
178 yLogo = 74;
179 xDefault = 234;
180 yDefault = 148;
181 x0Brain = 146;
182 y0Brain = 148;
183 dxBrain = 104;
184 dyBrain = 80;
185 xBrain: array [0 .. nPlOffered - 1] of integer = (x0Brain, x0Brain,
186 x0Brain + dxBrain, x0Brain + dxBrain, x0Brain + dxBrain, x0Brain,
187 x0Brain - dxBrain, x0Brain - dxBrain, x0Brain - dxBrain);
188 yBrain: array [0 .. nPlOffered - 1] of integer = (y0Brain, y0Brain - dyBrain,
189 y0Brain - dyBrain, y0Brain, y0Brain + dyBrain, y0Brain + dyBrain,
190 y0Brain + dyBrain, y0Brain, y0Brain - dyBrain);
191 TabOffset = -115;
192 TabSize = 159;
193 TabHeight = 40;
194
195 InitAlive: array [1 .. nPl] of integer = (1, 1 + 2, 1 + 2 + 32,
196 1 + 2 + 8 + 128, 1 + 2 + 8 + 32 + 128, 1 + 2 + 8 + 16 + 64 + 128,
197 1 + 2 + 4 + 16 + 32 + 64 + 256, 511 - 32, 511, 511 - 32, 511, 511 - 32, 511,
198 511 - 32, 511);
199 InitMulti: array [nPlOffered + 1 .. nPl] of integer = (256, 256, 256 + 128,
200 256 + 128, 256 + 128 + 64, 256 + 128 + 64);
201
202 PlayerAutoDiff: array [1 .. 5] of integer = (1, 1, 2, 2, 3);
203 EnemyAutoDiff: array [1 .. 5] of integer = (4, 3, 2, 1, 1);
204
205{ TStartDlg }
206
207procedure TStartDlg.FormCreate(Sender: TObject);
208var
209 x, i: Integer;
210 PlayerSlot: TPlayerSlot;
211 AIBrains: TBrains;
212begin
213 PlayerSlots := TPlayerSlots.Create;
214 PlayerSlots.Count := nPlOffered;
215 for I := 0 to PlayerSlots.Count - 1 do begin
216 PlayerSlot := TPlayerSlot.Create;
217 PlayerSlot.Rect := Bounds(xBrain[I], YBrain[I], 0, 0);
218 PlayerSlots[I] := PlayerSlot;
219 end;
220 LoadConfig;
221 LoadAssets;
222
223 ActionsOffered := [maConfig, maManual, maCredits, maWeb];
224 if FileExists(HomeDir + AITemplateFileName) then
225 Include(ActionsOffered, maAIDev);
226
227 BrainDefault := nil;
228 for i := Brains.IndexOf(BrainRandom) to Brains.Count - 1 do
229 if AnsiCompareFileName(DefaultAI, Brains[i].FileName) = 0 then
230 BrainDefault := Brains[i];
231 if (BrainDefault = BrainRandom) and (Brains.GetKindCount(btAI) < 2) then
232 BrainDefault := nil;
233 if (not Assigned(BrainDefault)) and (Brains.GetKindCount(btAI) > 0) then
234 begin
235 AIBrains := TBrains.Create(False);
236 Brains.GetByKind(btAI, AIBrains);
237 BrainDefault := Brains[0];
238 FreeAndNil(AIBrains);
239 end; // default AI not found, use any
240
241 DirectDlg.Left := (Screen.Width - DirectDlg.Width) div 2;
242 DirectDlg.Top := (Screen.Height - DirectDlg.Height) div 2;
243
244 UpdateInterface;
245
246 Canvas.Font.Assign(UniFont[ftNormal]);
247 Canvas.Brush.Style := bsClear;
248
249 QuitBtn.Hint := Phrases.Lookup('STARTCONTROLS', 0);
250 ReplayBtn.Hint := Phrases.Lookup('BTN_REPLAY');
251 PlayerSlots.Count := nPlOffered;
252 for i := 0 to PlayerSlots.Count - 1 do
253 with PlayerSlots[i] do begin
254 DiffUpBtn := TButtonC.Create(self);
255 DiffUpBtn.Graphic := HGrSystem.Data;
256 DiffUpBtn.left := xBrain[i] - 18;
257 DiffUpBtn.top := yBrain[i] + 39;
258 DiffUpBtn.ButtonIndex := 1;
259 DiffUpBtn.Parent := self;
260 DiffUpBtn.OnClick := DiffBtnClick;
261 DiffDownBtn := TButtonC.Create(self);
262 DiffDownBtn.Graphic := HGrSystem.Data;
263 DiffDownBtn.left := xBrain[i] - 18;
264 DiffDownBtn.top := yBrain[i] + 51;
265 DiffDownBtn.ButtonIndex := 0;
266 DiffDownBtn.Parent := self;
267 DiffDownBtn.OnClick := DiffBtnClick;
268 end;
269 for i := 6 to 8 do
270 with PlayerSlots[i] do begin
271 MultiBtn := TButtonC.Create(self);
272 MultiBtn.Graphic := HGrSystem.Data;
273 MultiBtn.left := xBrain[i] - 18;
274 MultiBtn.top := yBrain[i];
275 MultiBtn.Parent := self;
276 MultiBtn.OnClick := MultiBtnClick;
277 OfferMultiple := True;
278 end;
279
280 x := BiColorTextWidth(Canvas, Phrases.Lookup('STARTCONTROLS', 7)) div 2;
281 CustomizeBtn.left := x0Brain + 32 - 16 - x;
282 if AutoDiff < 0 then
283 CustomizeBtn.ButtonIndex := 3
284 else
285 CustomizeBtn.ButtonIndex := 2;
286
287 BitBltBitmap(BrainNoTerm.Picture, 0, 0, 64, 64, HGrSystem2.Data, 1, 111);
288 BitBltBitmap(BrainSuperVirtual.Picture, 0, 0, 64, 64, HGrSystem2.Data, 66, 111);
289 BitBltBitmap(BrainTerm.Picture, 0, 0, 64, 64, HGrSystem2.Data, 131, 111);
290 BitBltBitmap(BrainRandom.Picture, 0, 0, 64, 64, HGrSystem2.Data, 131, 46);
291 LoadAiBrainsPictures;
292
293 EmptyPicture := TBitmap.Create;
294 EmptyPicture.PixelFormat := pf24bit;
295 EmptyPicture.SetSize(64, 64);
296 EmptyPicture.Canvas.FillRect(0, 0, EmptyPicture.Width, EmptyPicture.Height);
297 LogoBuffer := TBitmap.Create;
298 LogoBuffer.PixelFormat := pf24bit;
299 LogoBuffer.SetSize(wBuffer, 56);
300 LogoBuffer.Canvas.FillRect(0, 0, LogoBuffer.Width, LogoBuffer.Height);
301
302 MiniMap := TMiniMap.Create;
303 InitButtons;
304
305 PlayersBrain[0] := BrainTerm;
306 SlotAvailable := -1;
307 Tab := tbNew;
308 Diff0 := 2;
309 TurnValid := False;
310 Tracking := False;
311 FormerGames := TStringList.Create;
312 UpdateFormerGames;
313 MapFileName := '';
314 Maps := TStringList.Create;
315 UpdateMaps;
316end;
317
318procedure TStartDlg.FormDestroy(Sender: TObject);
319begin
320 SaveConfig;
321 FreeAndNil(FormerGames);
322 FreeAndNil(Maps);
323 FreeAndNil(EmptyPicture);
324 FreeAndNil(LogoBuffer);
325 FreeAndNil(PlayerSlots);
326 FreeAndNil(MiniMap);
327end;
328
329procedure TStartDlg.SmartInvalidate(x0, y0, x1, y1: integer;
330 invalidateTab0: boolean);
331var
332 i: integer;
333 r0, r1: HRgn;
334begin
335 r0 := CreateRectRgn(x0, y0, x1, y1);
336 for i := 0 to ControlCount - 1 do
337 if not (Controls[i] is TArea) and Controls[i].Visible then
338 begin
339 with Controls[i].BoundsRect do
340 r1 := CreateRectRgn(left, top, Right, Bottom);
341 CombineRgn(r0, r0, r1, RGN_DIFF);
342 DeleteObject(r1);
343 end;
344 if not invalidateTab0 then begin
345 r1 := CreateRectRgn(0, 0, 6 + 36, 3 + 38); // tab 0 icon
346 CombineRgn(r0, r0, r1, RGN_DIFF);
347 DeleteObject(r1);
348 end;
349 InvalidateRgn(Handle, r0, false);
350 DeleteObject(r0);
351end;
352
353procedure TStartDlg.LoadConfig;
354var
355 Reg: TRegistry;
356 I: Integer;
357 S: string;
358 ResolutionX, ResolutionY, ResolutionBPP, ResolutionFreq: Integer;
359 ScreenMode: Integer;
360begin
361 Reg := TRegistry.Create;
362 with Reg do try
363 // Initialize AI assignment
364 OpenKey(AppRegistryKey + '\AI', True);
365 for I := 0 to nPlOffered - 1 do begin
366 if I = 0 then S := ':StdIntf'
367 else S := 'StdAI';
368 if not ValueExists('Control' + IntToStr(I)) then
369 WriteString('Control' + IntToStr(I), S);
370 if not ValueExists('Diff' + IntToStr(I)) then
371 WriteInteger('Diff' + IntToStr(I), 2);
372 end;
373
374 OpenKey(AppRegistryKey, True);
375 if ValueExists('Gamma') then Gamma := ReadInteger('Gamma')
376 else Gamma := 100;
377 if Gamma <> 100 then InitGammaLookupTable;
378 if ValueExists('Locale') then LocaleCode := ReadString('Locale')
379 else LocaleCode := '';
380 if ValueExists('WorldSize') then WorldSize := Reg.ReadInteger('WorldSize')
381 else WorldSize := DefaultWorldSize;
382 if ValueExists('LandMass') then StartLandMass := Reg.ReadInteger('LandMass')
383 else StartLandMass := DefaultLandMass;
384 if ValueExists('MaxTurn') then MaxTurn := Reg.ReadInteger('MaxTurn')
385 else MaxTurn := 800;
386 if ValueExists('DefaultAI') then DefaultAI := Reg.ReadString('DefaultAI')
387 else DefaultAI := 'StdAI';
388 if ValueExists('AutoEnemies') then AutoEnemies := Reg.ReadInteger('AutoEnemies')
389 else AutoEnemies := 8;
390 if ValueExists('AutoDiff') then AutoDiff := Reg.ReadInteger('AutoDiff')
391 else AutoDiff := 1;
392 if ValueExists('StartTab') then ShowTab := TStartTab(Reg.ReadInteger('StartTab'))
393 else ShowTab := tbNew;
394 if ValueExists('LastGame') then LastGame := Reg.ReadString('LastGame')
395 else LastGame := '';
396
397 if ValueExists('ScreenMode') then
398 ScreenMode := ReadInteger('ScreenMode')
399 else ScreenMode := 1;
400 FullScreen := ScreenMode > 0;
401 if ValueExists('ResolutionX') then
402 ResolutionX := ReadInteger('ResolutionX');
403 if ValueExists('ResolutionY') then
404 ResolutionY := ReadInteger('ResolutionY');
405 if ValueExists('ResolutionBPP') then
406 ResolutionBPP := ReadInteger('ResolutionBPP');
407 if ValueExists('ResolutionFreq') then
408 ResolutionFreq := ReadInteger('ResolutionFreq');
409 if ValueExists('MultiControl') then
410 MultiControl := ReadInteger('MultiControl')
411 else MultiControl := 0;
412 {$IFDEF WINDOWS}
413 if ScreenMode = 2 then
414 ChangeResolution(ResolutionX, ResolutionY, ResolutionBPP,
415 ResolutionFreq);
416 {$ENDIF}
417 finally
418 Free;
419 end;
420end;
421
422procedure TStartDlg.SaveConfig;
423var
424 Reg: TRegistry;
425begin
426 Reg := TRegistry.Create;
427 with Reg do try
428 OpenKey(AppRegistryKey, True);
429 WriteInteger('WorldSize', WorldSize);
430 WriteInteger('LandMass', StartLandMass);
431 WriteString('Locale', LocaleCode);
432 WriteInteger('Gamma', Gamma);
433 if FullScreen then WriteInteger('ScreenMode', 1)
434 else WriteInteger('ScreenMode', 0);
435 WriteInteger('MultiControl', MultiControl);
436 WriteInteger('StartTab', Integer(ShowTab));
437 WriteString('LastGame', LastGame);
438 finally
439 Free;
440 end;
441end;
442
443procedure TStartDlg.LoadAiBrainsPictures;
444var
445 AIBrains: TBrains;
446 I: Integer;
447 TextSize: TSize;
448begin
449 AIBrains := TBrains.Create(False);
450 Brains.GetByKind(btAI, AIBrains);
451 for i := 0 to AIBrains.Count - 1 do
452 with AIBrains[I] do begin
453 if not LoadGraphicFile(AIBrains[i].Picture, GetAiDir + DirectorySeparator +
454 FileName + DirectorySeparator + FileName + '.png', [gfNoError]) then begin
455 with AIBrains[i].Picture.Canvas do begin
456 Brush.Color := $904830;
457 FillRect(Rect(0, 0, 64, 64));
458 Font.Assign(UniFont[ftTiny]);
459 Font.Style := [];
460 Font.Color := $5FDBFF;
461 TextSize := TextExtent(FileName);
462 Textout(32 - TextSize.Width div 2,
463 32 - TextSize.Height div 2, FileName);
464 end;
465 end;
466 end;
467 FreeAndNil(AIBrains);
468end;
469
470procedure TStartDlg.UpdateInterface;
471var
472 r0, r1: HRgn;
473 Location: TPoint;
474begin
475 if FullScreen then begin
476 Location := Point((Screen.Width - 800) * 3 div 8,
477 Screen.Height - Height - (Screen.Height - 600) div 3);
478 BoundsRect := Bounds(Location.X, Location.Y, Width, Height);
479
480 r0 := CreateRectRgn(0, 0, Width, Height);
481 r1 := CreateRectRgn(TabOffset + 4 * TabSize + 2, 0, Width, TabHeight);
482 CombineRgn(r0, r0, r1, RGN_DIFF);
483 DeleteObject(r1);
484 r1 := CreateRectRgn(QuitBtn.Left, QuitBtn.Top, QuitBtn.Left + QuitBtn.Width,
485 QuitBtn.top + QuitBtn.Height);
486 CombineRgn(r0, r0, r1, RGN_OR);
487 DeleteObject(r1);
488 SetWindowRgn(Handle, r0, False);
489 DeleteObject(r0); // causes crash with Windows 95
490 end else begin
491 BoundsRect := Bounds((Screen.Width - Width) div 2,
492 (Screen.Height - Height) div 2, Width, Height)
493 end;
494end;
495
496procedure TStartDlg.DrawAction(y, IconIndex: integer; HeaderItem, TextItem: string);
497begin
498 Canvas.Font.Assign(UniFont[ftCaption]);
499 Canvas.Font.Style := Canvas.Font.Style + [fsUnderline];
500 RisedTextOut(Canvas, xAction, y - 3, Phrases2.Lookup(HeaderItem));
501 Canvas.Font.Assign(UniFont[ftNormal]);
502 BiColorTextOut(Canvas, Colors.Canvas.Pixels[clkAge0 - 1, cliDimmedText],
503 $000000, xAction, y + 21, Phrases2.Lookup(TextItem));
504
505 UnshareBitmap(LogoBuffer);
506 BitBltCanvas(LogoBuffer.Canvas, 0, 0, 50, 50, Canvas,
507 xActionIcon - 2, y - 2);
508 GlowFrame(LogoBuffer, 8, 8, 34, 34, $202020);
509 BitBltCanvas(Canvas, xActionIcon - 2, y - 2, 50, 50,
510 LogoBuffer.Canvas, 0, 0);
511 BitBltCanvas(Canvas, xActionIcon, y, 40, 40, BigImp.Canvas,
512 (IconIndex mod 7) * xSizeBig + 8, (IconIndex div 7) * ySizeBig);
513 RFrame(Canvas, xActionIcon - 1, y - 1, xActionIcon + 40, y + 40,
514 $000000, $000000);
515end;
516
517procedure TStartDlg.FormPaint(Sender: TObject);
518const
519 TabNames: array[TStartTab] of Integer = (0, 11, 3, 4);
520var
521 i, w, h, xMini, yMini, y: integer;
522 s: string;
523 Tab2: TStartTab;
524 MainAction: TMainAction;
525begin
526 PaintBackground(self, 3, 3, TabOffset + 4 * TabSize - 4, TabHeight - 3);
527 PaintBackground(self, 3, TabHeight + 3, ClientWidth - 6,
528 ClientHeight - TabHeight - 6);
529 with Canvas do
530 begin
531 Brush.Color := $000000;
532 FillRect(Rect(0, 1, ClientWidth, 3));
533 FillRect(Rect(TabOffset + 4 * TabSize + 2, 0, ClientWidth, TabHeight));
534 Brush.Style := bsClear;
535 end;
536 if Page in [pgStartRandom, pgStartMap] then
537 begin
538 Frame(Canvas, 328, yMain + 112 - 15, ClientWidth, Up2Btn.top + 38,
539 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
540 if AutoDiff > 0 then
541 begin
542 Frame(Canvas, -1 { x0Brain-dxBrain } ,
543 yMain + 112 - 15 { Up1Btn.Top-12 }{ y0Brain-dyBrain } ,
544 x0Brain + dxBrain + 64, Up2Btn.top + 38 { y0Brain+dyBrain+64 } ,
545 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
546 end;
547 end
548 else if Page <> pgMain then
549 Frame(Canvas, 328, Up1Btn.top - 15, ClientWidth, Up2Btn.top + 38,
550 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
551 Frame(Canvas, 0, 0, ClientWidth - 1, ClientHeight - 1, 0, 0);
552
553 // draw tabs
554 Frame(Canvas, 2, 2 + 2 * integer(Tab <> tbMain), TabOffset + (0 + 1) * TabSize - 1,
555 TabHeight, MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
556 Frame(Canvas, 1, 1 + 2 * integer(Tab <> tbMain), TabOffset + (0 + 1) * TabSize,
557 TabHeight, MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
558 Canvas.Pixels[1, 1 + 2 * integer(Tab <> tbMain)] := MainTexture.ColorBevelShade;
559 for Tab2 := tbMap to tbPrevious do
560 begin
561 Frame(Canvas, TabOffset + Integer(Tab2) * TabSize + 2, 2 + 2 * integer(Tab <> Tab2),
562 TabOffset + (Integer(Tab2) + 1) * TabSize - 1, TabHeight, MainTexture.ColorBevelLight,
563 MainTexture.ColorBevelShade);
564 Frame(Canvas, TabOffset + Integer(Tab2) * TabSize + 1, 1 + 2 * integer(Tab <> Tab2),
565 TabOffset + (Integer(Tab2) + 1) * TabSize, TabHeight, MainTexture.ColorBevelLight,
566 MainTexture.ColorBevelShade);
567 Canvas.Pixels[TabOffset + Integer(Tab2) * TabSize + 1, 1 + 2 * integer(Tab <> Tab2)] :=
568 MainTexture.ColorBevelShade;
569 end;
570 Canvas.Font.Assign(UniFont[ftNormal]);
571 for Tab2 := tbMap to tbPrevious do
572 begin
573 s := Phrases.Lookup('STARTCONTROLS', TabNames[Tab2]);
574 RisedTextOut(Canvas, TabOffset + Integer(Tab2) * TabSize + 1 +
575 (TabSize - BiColorTextWidth(Canvas, s)) div 2,
576 10 + 2 * integer(Tab <> Tab2), s);
577 end;
578 Frame(Canvas, TabOffset + 4 * TabSize + 1, -1, ClientWidth, TabHeight,
579 $000000, $000000);
580 Frame(Canvas, 1, TabHeight + 1, ClientWidth - 2, ClientHeight - 2,
581 MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
582 Frame(Canvas, 2, TabHeight + 2, ClientWidth - 3, ClientHeight - 3,
583 MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
584 if Tab = tbMain then
585 begin
586 PaintBackground(self, 3, TabHeight - 1, TabSize - 4 - 3 + TabOffset + 3, 4);
587 Canvas.Pixels[2, TabHeight] := MainTexture.ColorBevelLight;
588 end
589 else
590 begin
591 PaintBackground(self, TabOffset + 3 + Integer(Tab) * TabSize, TabHeight - 1,
592 TabSize - 4, 4);
593 Canvas.Pixels[TabOffset + Integer(Tab) * TabSize + 2, TabHeight] :=
594 MainTexture.ColorBevelLight;
595 end;
596 Canvas.Pixels[TabOffset + (Integer(Tab) + 1) * TabSize - 1, TabHeight + 1] :=
597 MainTexture.ColorBevelShade;
598 if Tab < tbPrevious then
599 Frame(Canvas, TabOffset + (Integer(Tab) + 1) * TabSize + 1, 3,
600 TabOffset + (Integer(Tab) + 1) * TabSize + 2, TabHeight, MainTexture.ColorBevelShade,
601 MainTexture.ColorBevelShade); // Tab shadow
602
603 // Paint menu logo
604 UnshareBitmap(LogoBuffer);
605 BitBltCanvas(LogoBuffer.Canvas, 0, 0, MenuLogo.Width, MenuLogo.Height, Canvas, 6,
606 3 + 2 * integer(Tab <> tbMain));
607
608 ImageOp_BCC(LogoBuffer, Templates.Data, 0, 0, MenuLogo.Left, MenuLogo.Top,
609 MenuLogo.Width, MenuLogo.Height - 9, $BFBF20, $4040DF); // logo part 1
610 ImageOp_BCC(LogoBuffer, Templates.Data, 10, 27, MenuLogo.Left + 10,
611 MenuLogo.Top + 27, MenuLogo.Width - 10, 9, $BFBF20, $4040DF); // logo part 2
612 BitBltCanvas(Canvas, 6, 3 + 2 * integer(Tab <> tbMain), MenuLogo.Width, MenuLogo.Height,
613 LogoBuffer.Canvas, 0, 0);
614
615 if Page = pgMain then begin
616 if SelectedAction <> maNone then // mark selected action
617 for i := 0 to (ClientWidth - 2 * ActionSideBorder) div wBuffer + 1 do
618 begin
619 w := ClientWidth - 2 * ActionSideBorder - i * wBuffer;
620 if w > wBuffer then
621 w := wBuffer;
622 h := ActionPitch;
623 if yAction + Integer(SelectedAction) * ActionPitch - 8 + h > ClientHeight - ActionBottomBorder
624 then
625 h := ClientHeight - ActionBottomBorder -
626 (yAction + Integer(SelectedAction) * ActionPitch - 8);
627
628 UnshareBitmap(LogoBuffer);
629 BitBltCanvas(LogoBuffer.Canvas, 0, 0, w, h, Canvas,
630 ActionSideBorder + i * wBuffer, yAction + Integer(SelectedAction) * ActionPitch
631 - 8);
632 MakeBlue(LogoBuffer, 0, 0, w, h);
633 BitBltCanvas(Canvas, ActionSideBorder + i * wBuffer,
634 yAction + Integer(SelectedAction) * ActionPitch - 8, w, h,
635 LogoBuffer.Canvas, 0, 0);
636 end;
637 y := yAction;
638 for MainAction := Low(TMainActionSet) to High(TMainActionSet) do
639 begin
640 if MainAction in ActionsOffered then
641 case MainAction of
642 maConfig: DrawAction(y, 25, 'ACTIONHEADER_CONFIG', 'ACTION_CONFIG');
643 maManual: DrawAction(y, 19, 'ACTIONHEADER_MANUAL', 'ACTION_MANUAL');
644 maCredits: DrawAction(y, 22, 'ACTIONHEADER_CREDITS', 'ACTION_CREDITS');
645 maAIDev: DrawAction(y, 24, 'ACTIONHEADER_AIDEV', 'ACTION_AIDEV');
646 maWeb:
647 begin
648 Canvas.Font.Assign(UniFont[ftCaption]);
649 // Canvas.Font.Style:=Canvas.Font.Style+[fsUnderline];
650 RisedTextOut(Canvas, xActionIcon + 99, y,
651 Format(Phrases2.Lookup('ACTIONHEADER_WEB'), [CevoHomepageShort]));
652 Canvas.Font.Assign(UniFont[ftNormal]);
653
654 UnshareBitmap(LogoBuffer);
655 BitBltCanvas(LogoBuffer.Canvas, 0, 0, LinkArrows.Width, LinkArrows.Height, Canvas,
656 xActionIcon, y + 2);
657 ImageOp_BCC(LogoBuffer, Templates.Data, Point(0, 0), LinkArrows.BoundsRect, 0,
658 Colors.Canvas.Pixels[clkAge0 - 1, cliDimmedText]);
659 BitBltCanvas(Canvas, xActionIcon, y + 2, LinkArrows.Width, LinkArrows.Height,
660 LogoBuffer.Canvas, 0, 0);
661 end;
662 end;
663 Inc(y, ActionPitch);
664 end;
665 end
666 else if Page in [pgStartRandom, pgStartMap] then
667 begin
668 UnderlinedTitleValue(Canvas, Phrases.Lookup('STARTCONTROLS', 10),
669 TurnToString(MaxTurn), 344, y0Mini + 61, 170);
670
671 s := Phrases.Lookup('STARTCONTROLS', 7);
672 w := Canvas.TextWidth(s);
673 LoweredTextOut(Canvas, -2, MainTexture, x0Brain + 32 - w div 2,
674 y0Brain + dyBrain + 69, s);
675
676 InitOrnament;
677 if AutoDiff < 0 then
678 begin
679 for i := 12 to 19 do
680 if (i < 13) or (i > 17) then
681 begin
682 BitBltCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
683 HGrSystem2.Mask.Canvas, Ornament.Left, Ornament.Top, SRCAND);
684 BitBltCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
685 HGrSystem2.Data.Canvas, Ornament.Left, Ornament.Top, SRCPAINT);
686 end;
687 PaintLogo(Canvas, 69 + 11 * 27, yLogo, MainTexture.ColorBevelLight,
688 MainTexture.ColorBevelShade);
689
690 for i := 0 to nPlOffered - 1 do
691 if 1 shl i and SlotAvailable <> 0 then
692 begin
693 if Assigned(PlayersBrain[i]) then
694 FrameImage(Canvas, PlayersBrain[i].Picture, xBrain[i], yBrain[i],
695 64, 64, 0, 0, true)
696 else
697 FrameImage(Canvas, EmptyPicture, xBrain[i], yBrain[i], 64, 64,
698 0, 0, true);
699 if Assigned(PlayersBrain[I]) and (PlayersBrain[i].Kind in [btTerm, btRandom, btAI]) then
700 begin
701 BitBltCanvas(Canvas, xBrain[i] - 18, yBrain[i] + 19, 12, 14,
702 HGrSystem.Data.Canvas, 134 + (Difficulty[i] - 1) *
703 13, 28);
704 Frame(Canvas, xBrain[i] - 19, yBrain[i] + 18, xBrain[i] - 18 + 12,
705 yBrain[i] + (19 + 14), $000000, $000000);
706 RFrame(Canvas, PlayerSlots[i].DiffUpBtn.left - 1, PlayerSlots[i].DiffUpBtn.top - 1,
707 PlayerSlots[i].DiffUpBtn.left + 12, PlayerSlots[i].DiffUpBtn.top + 24,
708 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
709 with Canvas do
710 begin
711 Brush.Color := $000000;
712 FillRect(Rect(xBrain[i] - 5, yBrain[i] + 25, xBrain[i] - 2,
713 yBrain[i] + 27));
714 Brush.Style := bsClear;
715 end;
716 if PlayerSlots[I].OfferMultiple then
717 begin
718 RFrame(Canvas, PlayerSlots[I].MultiBtn.left - 1, PlayerSlots[I].MultiBtn.top - 1,
719 PlayerSlots[I].MultiBtn.left + 12, PlayerSlots[I].MultiBtn.top + 12,
720 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
721 BitBltCanvas(Canvas, xBrain[i] - 31, yBrain[i], 13, 12,
722 HGrSystem.Data.Canvas, 88, 47);
723 end;
724 end;
725 if Assigned(PlayersBrain[i]) then
726 begin
727 PlayerSlots[i].DiffUpBtn.Hint := Format(Phrases.Lookup('STARTCONTROLS', 9),
728 [PlayersBrain[i].Name]);
729 PlayerSlots[i].DiffDownBtn.Hint := PlayerSlots[i].DiffUpBtn.Hint;
730 end;
731 end;
732 end
733 else
734 begin
735 DLine(Canvas, 24, 198, yMain + 140 + 19, MainTexture.ColorBevelLight,
736 MainTexture.ColorBevelShade);
737 RisedTextOut(Canvas, 24 { x0Brain+32-BiColorTextWidth(Canvas,s) div 2 } ,
738 yMain + 140 { y0Mini-77 } , Phrases.Lookup('STARTCONTROLS', 15));
739 if Page = pgStartRandom then
740 s := IntToStr(AutoEnemies)
741 else if nMapStartPositions = 0 then
742 s := '0'
743 else
744 s := IntToStr(nMapStartPositions - 1);
745 RisedTextOut(Canvas, 198 - BiColorTextWidth(Canvas, s), yMain + 140, s);
746
747 DLine(Canvas, 24, xDefault - 6, yMain + 164 + 19,
748 MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
749 RisedTextOut(Canvas, 24 { x0Brain+32-BiColorTextWidth(Canvas,s) div 2 } ,
750 yMain + 164 { y0Mini-77 } , Phrases.Lookup('STARTCONTROLS', 16));
751 if AutoDiff = 1 then
752 FrameImage(Canvas, BrainBeginner.Picture, xDefault, yDefault, 64,
753 64, 0, 0, false)
754 else
755 FrameImage(Canvas, BrainDefault.Picture, xDefault, yDefault, 64, 64,
756 0, 0, true);
757 DLine(Canvas, 56, 272, y0Mini + 61 + 19, MainTexture.ColorBevelLight,
758 MainTexture.ColorBevelShade);
759
760 RisedTextOut(Canvas, 56, y0Mini + 61,
761 Phrases.Lookup('STARTCONTROLS', 14));
762 s := Phrases.Lookup('AUTODIFF', AutoDiff - 1);
763 RisedTextOut(Canvas, 272 - BiColorTextWidth(Canvas, s), y0Mini + 61, s);
764
765 for i := 0 to 19 do
766 if (i < 2) or (i > 6) then
767 begin
768 BitBltCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
769 HGrSystem2.Mask.Canvas, Ornament.Left, Ornament.Top, SRCAND);
770 BitBltCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
771 HGrSystem2.Data.Canvas, Ornament.Left, Ornament.Top, SRCPAINT);
772 end;
773 PaintLogo(Canvas, 69, yLogo, MainTexture.ColorBevelLight,
774 MainTexture.ColorBevelShade);
775 end;
776 end
777 else if Page = pgLoad then
778 begin
779 // RisedTextOut(Canvas,x0Mini+2-BiColorTextWidth(Canvas,BookDate) div 2,y0Mini-73,BookDate);
780 if LastTurn > 0 then
781 begin
782 PaintProgressBar(Canvas, 6, xTurnSlider, yTurnSlider, 0,
783 LoadTurn * wTurnSlider div LastTurn, wTurnSlider, MainTexture);
784 Frame(Canvas, xTurnSlider - 2, yTurnSlider - 2, xTurnSlider + wTurnSlider
785 + 1, yTurnSlider + 8, $B0B0B0, $FFFFFF);
786 RFrame(Canvas, xTurnSlider - 3, yTurnSlider - 3, xTurnSlider + wTurnSlider
787 + 2, yTurnSlider + 9, $FFFFFF, $B0B0B0);
788 end
789 else
790 DLine(Canvas, 344, 514, y0Mini + 61 + 19, MainTexture.ColorBevelLight,
791 MainTexture.ColorBevelShade);
792 RisedTextOut(Canvas, 344, y0Mini + 61, Phrases.Lookup('STARTCONTROLS', 8));
793 s := TurnToString(LoadTurn);
794 RisedTextOut(Canvas, 514 - BiColorTextWidth(Canvas, s), y0Mini + 61, s);
795 end
796 else if Page = pgEditRandom then
797 begin
798 UnderlinedTitleValue(Canvas, Phrases.Lookup('STARTCONTROLS', 5),
799 IntToStr((WorldSizes[WorldSize].X * WorldSizes[WorldSize].Y * 20 +
800 DefaultWorldTiles div 2) div DefaultWorldTiles * 5) + '%',
801 344, y0Mini - 77, 170);
802 UnderlinedTitleValue(Canvas, Phrases.Lookup('STARTCONTROLS', 6),
803 IntToStr(StartLandMass) + '%', 344, y0Mini + 61, 170);
804 end
805 else if Page = pgEditMap then
806 begin
807 // DLine(Canvas,344,514,y0Mini+61+19,MainTexture.ColorBevelLight,MainTexture.ColorBevelShade);
808 s := Format(Phrases2.Lookup('MAPPROP'),
809 [(nMapLandTiles * 100 + 556) div 1112,
810 // 1112 is typical for world with 100% size and default land mass
811 nMapStartPositions]);
812 RisedTextOut(Canvas, x0Mini - BiColorTextWidth(Canvas, s) div 2,
813 y0Mini + 61, s);
814 end;
815
816 if StartBtn.Visible then
817 BtnFrame(Canvas, StartBtn.BoundsRect, MainTexture);
818 if Up2Btn.Visible then
819 RFrame(Canvas, Up2Btn.left - 1, Up2Btn.top - 1, Up2Btn.left + 12,
820 Up2Btn.top + 24, MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
821 if Up1Btn.Visible then
822 RFrame(Canvas, Up1Btn.left - 1, Up1Btn.top - 1, Up1Btn.left + 12,
823 Up1Btn.top + 24, MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
824 if AutoDiffUpBtn.Visible then
825 RFrame(Canvas, AutoDiffUpBtn.left - 1, AutoDiffUpBtn.top - 1,
826 AutoDiffUpBtn.left + 12, AutoDiffUpBtn.top + 24, MainTexture.ColorBevelShade,
827 MainTexture.ColorBevelLight);
828 if AutoEnemyUpBtn.Visible then
829 RFrame(Canvas, AutoEnemyUpBtn.left - 1, AutoEnemyUpBtn.top - 1,
830 AutoEnemyUpBtn.left + 12, AutoEnemyUpBtn.top + 24,
831 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
832 if CustomizeBtn.Visible then
833 RFrame(Canvas, CustomizeBtn.left - 1, CustomizeBtn.top - 1,
834 CustomizeBtn.left + 12, CustomizeBtn.top + 12, MainTexture.ColorBevelShade,
835 MainTexture.ColorBevelLight);
836 if List.Visible then
837 EditFrame(Canvas, List.BoundsRect, MainTexture);
838 if RenameBtn.Visible then
839 BtnFrame(Canvas, RenameBtn.BoundsRect, MainTexture);
840 if DeleteBtn.Visible then
841 BtnFrame(Canvas, DeleteBtn.BoundsRect, MainTexture);
842 if Page = pgLoad then
843 BtnFrame(Canvas, ReplayBtn.BoundsRect, MainTexture);
844
845 if not (Page in [pgMain, pgNoLoad]) then
846 begin
847 xMini := x0Mini - MiniMap.Size.X;
848 yMini := y0Mini - MiniMap.Size.Y div 2;
849 Frame(Canvas, xMini, yMini, xMini + 3 + MiniMap.Size.X * 2,
850 yMini + 3 + MiniMap.Size.Y, MainTexture.ColorBevelLight,
851 MainTexture.ColorBevelShade);
852 Frame(Canvas, xMini + 1, yMini + 1, xMini + 2 + MiniMap.Size.X * 2,
853 yMini + 2 + MiniMap.Size.Y, MainTexture.ColorBevelShade,
854 MainTexture.ColorBevelLight);
855
856 s := '';
857 if MiniMap.Mode = mmPicture then
858 begin
859 BitBltCanvas(Canvas, xMini + 2, yMini + 2, MiniMap.Size.X * 2, MiniMap.Size.Y,
860 MiniMap.Bitmap.Canvas, 0, 0);
861 if Page = pgStartRandom then
862 s := Phrases.Lookup('RANMAP')
863 end
864 else if MiniMap.Mode = mmMultiPlayer then
865 s := Phrases.Lookup('MPMAP')
866 else if Page = pgStartMap then
867 s := Copy(MapFileName, 1, Length(MapFileName) - Length(CevoMapExt))
868 else if Page = pgEditMap then
869 s := List.Items[List.ItemIndex]
870 else if Page = pgNoLoad then
871 s := Phrases.Lookup('NOGAMES');
872 if s <> '' then
873 RisedTextOut(Canvas, x0Mini + 2 - BiColorTextWidth(Canvas, s) div 2,
874 y0Mini - 8, s);
875 end;
876end;
877
878procedure TStartDlg.FormShow(Sender: TObject);
879begin
880 MainTexture.Age := -1;
881 List.Font.Color := MainTexture.ColorMark;
882
883 Fill(EmptyPicture.Canvas, Bounds(0, 0, 64, 64),
884 Point((Maintexture.Width - 64) div 2, (Maintexture.Height - 64) div 2));
885
886 DarkenImage(EmptyPicture, 28);
887
888 Difficulty[0] := Diff0;
889
890 SelectedAction := maNone;
891 if ShowTab = tbPrevious then
892 PreviewMap(StartLandMass); // avoid delay on first TabX change
893 ChangeTab(ShowTab);
894 Background.Enabled := False;
895end;
896
897procedure TStartDlg.UnlistBackupFile(FileName: string);
898var
899 I: Integer;
900begin
901 if FileName[1] <> '~' then
902 FileName := '~' + FileName;
903 I := FormerGames.Count - 1;
904 while (I >= 0) and (AnsiCompareFileName(FormerGames[I], FileName) <> 0) do
905 Dec(I);
906 if I >= 0 then
907 begin
908 FormerGames.Delete(I);
909 if ListIndex[tbNew] = I then
910 ListIndex[tbNew] := 0
911 end;
912end;
913
914procedure TStartDlg.StartBtnClick(Sender: TObject);
915var
916 I, GameCount, MapCount: Integer;
917 FileName: string;
918 Reg: TRegistry;
919begin
920 case Page of
921 pgLoad:
922 begin // load
923 FileName := List.Items[List.ItemIndex];
924 if LoadGame(GetSavedDir + DirectorySeparator, FileName + CevoExt, LoadTurn, false)
925 then
926 UnlistBackupFile(FileName)
927 else
928 SimpleMessage(Phrases.Lookup('LOADERR'));
929 SlotAvailable := -1;
930 end;
931 pgStartRandom, pgStartMap:
932 if Assigned(PlayersBrain[0]) then
933 begin
934 if (Page = pgStartMap) and (nMapStartPositions = 0) and (AutoDiff > 0)
935 then
936 begin
937 SimpleMessage(Phrases.Lookup('NOSTARTPOS'));
938 Exit;
939 end;
940
941 Reg := TRegistry.Create;
942 with Reg do
943 try
944 OpenKey(AppRegistryKey, true);
945 if ValueExists('GameCount') then GameCount := ReadInteger('GameCount')
946 else GameCount := 0;
947
948 if (AutoDiff < 0) and (PlayersBrain[0].Kind = btNoTerm) then
949 FileName := 'Round' + IntToStr(GetProcessID())
950 else begin
951 Inc(GameCount);
952 FileName := Format(Phrases.Lookup('GAME'), [GameCount]);
953 end;
954
955 // Save settings and AI assignment
956 if Page = pgStartRandom then begin
957 SaveConfig;
958 OpenKey(AppRegistryKey + '\AI', True);
959 if AutoDiff < 0 then
960 for I := 0 to nPlOffered - 1 do begin
961 if not Assigned(PlayersBrain[I]) then
962 Reg.WriteString('Control' + IntToStr(I), '')
963 else Reg.WriteString('Control' + IntToStr(I),
964 PlayersBrain[I].FileName);
965 WriteInteger('Diff' + IntToStr(I), Difficulty[I]);
966 end;
967 end;
968
969 OpenKey(AppRegistryKey, True);
970 if AutoDiff > 0 then
971 begin
972 WriteString('DefaultAI', BrainDefault.FileName);
973 SlotAvailable := 0; // PlayerSlot will be invalid hereafter
974 PlayersBrain[0] := BrainTerm;
975 Difficulty[0] := PlayerAutoDiff[AutoDiff];
976 for I := 1 to nPl - 1 do
977 if (Page = pgStartRandom) and (I <= AutoEnemies) or
978 (Page = pgStartMap) and (I < nMapStartPositions) then begin
979 if AutoDiff = 1 then PlayersBrain[I] := BrainBeginner
980 else PlayersBrain[I] := BrainDefault;
981 Difficulty[I] := EnemyAutoDiff[AutoDiff];
982 end else PlayersBrain[I] := nil;
983 end else begin
984 for I := 6 to 8 do
985 if (PlayersBrain[0].Kind <> btNoTerm) and (MultiControl and (1 shl I) <> 0)
986 then begin
987 PlayersBrain[I + 3] := PlayersBrain[I];
988 Difficulty[I + 3] := Difficulty[I];
989 PlayersBrain[I + 6] := PlayersBrain[I];
990 Difficulty[I + 6] := Difficulty[I];
991 end else begin
992 PlayersBrain[I + 3] := nil;
993 PlayersBrain[I + 6] := nil;
994 end;
995 end;
996
997 WriteInteger('AutoDiff', AutoDiff);
998 WriteInteger('AutoEnemies', AutoEnemies);
999 WriteInteger('MaxTurn', MaxTurn);
1000 WriteInteger('GameCount', GameCount);
1001 finally
1002 Free;
1003 end;
1004
1005 StartNewGame(GetSavedDir + DirectorySeparator, FileName + CevoExt, MapFileName,
1006 WorldSizes[WorldSize].X, WorldSizes[WorldSize].Y, StartLandMass, MaxTurn);
1007 UnlistBackupFile(FileName);
1008 end;
1009 pgEditMap:
1010 EditMap(GetMapsDir + DirectorySeparator + MapFileName, lxmax, lymax, StartLandMass);
1011 pgEditRandom: // new map
1012 begin
1013 Reg := TRegistry.Create;
1014 with Reg do
1015 try
1016 OpenKey(AppRegistryKey, True);
1017 if ValueExists('MapCount') then MapCount := ReadInteger('MapCount')
1018 else MapCount := 0;
1019 Inc(MapCount);
1020 WriteInteger('MapCount', MapCount);
1021 finally
1022 Free;
1023 end;
1024 MapFileName := Format(Phrases.Lookup('MAP'), [MapCount]) + CevoMapExt;
1025 EditMap(GetMapsDir + DirectorySeparator + MapFileName,
1026 WorldSizes[WorldSize].X, WorldSizes[WorldSize].Y, StartLandMass);
1027 end;
1028 end;
1029end;
1030
1031procedure TStartDlg.PaintInfo;
1032begin
1033 case Page of
1034 pgStartRandom: begin
1035 MiniMap.Mode := mmPicture;
1036 MiniMap.PaintRandom(3, StartLandMass, WorldSizes[WorldSize]);
1037 end;
1038 pgNoLoad: begin
1039 MiniMap.Mode := mmNone;
1040 MiniMap.Size := WorldSizes[DefaultWorldSize];
1041 end;
1042 pgLoad: begin
1043 MiniMap.LoadFromLogFile(GetSavedDir + DirectorySeparator +
1044 List.Items[List.ItemIndex] + CevoExt, LastTurn, WorldSizes[DefaultWorldSize]);
1045 // BookDate:=DateToStr(FileDateToDateTime(FileAge(FileName)));
1046 if not TurnValid then begin
1047 LoadTurn := LastTurn;
1048 SmartInvalidate(xTurnSlider - 2, y0Mini + 61,
1049 xTurnSlider + wTurnSlider + 2, yTurnSlider + 9);
1050 end;
1051 TurnValid := True;
1052 end;
1053 pgEditRandom: begin
1054 MapFileName := '';
1055 MiniMap.Mode := mmPicture;
1056 MiniMap.PaintRandom(4, StartLandMass, WorldSizes[WorldSize]);
1057 end;
1058 pgStartMap, pgEditMap:
1059 begin
1060 if Page = pgEditMap then
1061 MapFileName := List.Items[List.ItemIndex] + CevoMapExt;
1062 MiniMap.LoadFromMapFile(GetMapsDir + DirectorySeparator + MapFileName,
1063 nMapLandTiles, nMapStartPositions);
1064 if Page = pgEditMap then
1065 SmartInvalidate(x0Mini - 112, y0Mini + 61, x0Mini + 112, y0Mini + 91);
1066 end;
1067 end;
1068 SmartInvalidate(x0Mini - lxmax, y0Mini - lymax div 2,
1069 x0Mini - lxmax + 2 * lxmax + 4, y0Mini - lymax div 2 + lymax + 4);
1070end;
1071
1072procedure TStartDlg.BrainClick(Sender: TObject);
1073var
1074 I: Integer;
1075begin
1076 // Play('BUTTON_UP');
1077 if PlayerPopupIndex < 0 then
1078 begin // change default AI
1079 BrainDefault := Brains[TMenuItem(Sender).Tag];
1080 SmartInvalidate(xDefault, yDefault, xDefault + 64, yDefault + 64);
1081 end
1082 else
1083 begin
1084 if Assigned(PlayersBrain[PlayerPopupIndex]) then
1085 PlayersBrain[PlayerPopupIndex].Flags := PlayersBrain[PlayerPopupIndex].Flags and not fUsed;
1086 if TMenuItem(Sender).Tag = -1 then begin
1087 PlayersBrain[PlayerPopupIndex] := nil;
1088 PlayerSlots[PlayerPopupIndex].DiffUpBtn.Visible := False;
1089 PlayerSlots[PlayerPopupIndex].DiffDownBtn.Visible := False;
1090 if PlayerSlots[PlayerPopupIndex].OfferMultiple then begin
1091 PlayerSlots[PlayerPopupIndex].MultiBtn.Visible := False;
1092 PlayerSlots[PlayerPopupIndex].MultiBtn.ButtonIndex := 2 + (MultiControl shr PlayerPopupIndex) and 1;
1093 end;
1094 MultiControl := MultiControl and not (1 shl PlayerPopupIndex);
1095 end else begin
1096 PlayersBrain[PlayerPopupIndex] := Brains[TMenuItem(Sender).Tag];
1097 PlayerSlots[PlayerPopupIndex].DiffUpBtn.Visible := PlayersBrain[PlayerPopupIndex].Kind in [btTerm, btRandom, btAI];
1098 PlayerSlots[PlayerPopupIndex].DiffDownBtn.Visible := PlayersBrain[PlayerPopupIndex].Kind in [btTerm, btRandom, btAI];
1099 if PlayerSlots[PlayerPopupIndex].OfferMultiple then begin
1100 PlayerSlots[PlayerPopupIndex].MultiBtn.Visible := PlayersBrain[PlayerPopupIndex].Kind in [btTerm, btRandom, btAI];
1101 PlayerSlots[PlayerPopupIndex].MultiBtn.ButtonIndex := 2 + (MultiControl shr PlayerPopupIndex) and 1;
1102 end;
1103 PlayersBrain[PlayerPopupIndex].Flags := PlayersBrain[PlayerPopupIndex].Flags or fUsed;
1104 if PlayersBrain[PlayerPopupIndex].Kind in [btNoTerm, btSuperVirtual] then
1105 Difficulty[PlayerPopupIndex] := 0 { supervisor }
1106 else
1107 Difficulty[PlayerPopupIndex] := 2;
1108 if (Page = pgStartRandom) and (PlayerSlots[PlayerPopupIndex].OfferMultiple) and
1109 (not Assigned(PlayersBrain[PlayerPopupIndex])) then
1110 MultiControl := MultiControl and not (1 shl PlayerPopupIndex);
1111 if (PlayerPopupIndex = 0) and (MapFileName <> '') then
1112 ChangePage(Page);
1113 if PlayersBrain[PlayerPopupIndex].Kind = btNoTerm then
1114 begin // turn all local players off
1115 for I := 1 to PlayerSlots.Count - 1 do
1116 if PlayersBrain[I].Kind = btTerm then begin
1117 PlayersBrain[I] := nil;
1118 PlayerSlots[I].DiffUpBtn.Visible := false;
1119 PlayerSlots[I].DiffUpBtn.Tag := 0;
1120 PlayerSlots[I].DiffDownBtn.Visible := false;
1121 PlayerSlots[I].DiffDownBtn.Tag := 0;
1122 if PlayerSlots[I].OfferMultiple then begin
1123 PlayerSlots[I].MultiBtn.Visible := false;
1124 PlayerSlots[I].MultiBtn.Tag := 0;
1125 end;
1126 SmartInvalidate(xBrain[I] - 31, yBrain[I] - 1, xBrain[I] + 64,
1127 PlayerSlots[I].DiffUpBtn.top + 25);
1128 end;
1129 BrainTerm.Flags := BrainTerm.Flags and not fUsed;
1130 end;
1131 end;
1132 SmartInvalidate(xBrain[PlayerPopupIndex] - 31, yBrain[PlayerPopupIndex] - 1,
1133 xBrain[PlayerPopupIndex] + 64, PlayerSlots[PlayerPopupIndex].DiffUpBtn.top + 25);
1134 end;
1135end;
1136
1137procedure TStartDlg.OfferBrain(Brain: TBrain; FixedLines: Integer);
1138var
1139 J: Integer;
1140 MenuItem: TMenuItem;
1141begin
1142 MenuItem := TMenuItem.Create(PopupMenu1);
1143 if not Assigned(Brain) then MenuItem.Caption := Phrases.Lookup('NOMOD')
1144 else MenuItem.Caption := Brain.Name;
1145 MenuItem.Tag := Brains.IndexOf(Brain);
1146 MenuItem.OnClick := BrainClick;
1147 J := FixedLines;
1148 while (J < PopupMenu1.Items.Count) and
1149 (StrIComp(pchar(MenuItem.Caption), pchar(PopupMenu1.Items[J].Caption)) > 0) do
1150 Inc(J);
1151 MenuItem.RadioItem := True;
1152 if (PlayerPopupIndex < 0) then MenuItem.Checked := BrainDefault = Brain
1153 else MenuItem.Checked := PlayersBrain[PlayerPopupIndex] = Brain;
1154 PopupMenu1.Items.Insert(J, MenuItem);
1155end;
1156
1157procedure TStartDlg.InitPopup(PlayerIndex: Integer);
1158var
1159 I: Integer;
1160 FixedLines: integer;
1161 MenuItem: TMenuItem;
1162 AIBrains: TBrains;
1163begin
1164 PlayerPopupIndex := PlayerIndex;
1165 EmptyMenu(PopupMenu1.Items);
1166 if PlayerPopupIndex < 0 then begin // select default AI
1167 FixedLines := 0;
1168 if Brains.GetKindCount(btAI) >= 2 then begin
1169 OfferBrain(BrainRandom, FixedLines);
1170 Inc(FixedLines);
1171 end;
1172 AIBrains := TBrains.Create(False);
1173 Brains.GetByKind(btAI, AIBrains);
1174 for I := 0 to AIBrains.Count - 1 do // offer available AIs
1175 if AIBrains[I].Flags and fMultiple <> 0 then
1176 OfferBrain(AIBrains[I], FixedLines);
1177 FreeAndNil(AIBrains);
1178 end else begin
1179 FixedLines := 0;
1180 if PlayerPopupIndex > 0 then begin
1181 OfferBrain(nil, FixedLines);
1182 Inc(FixedLines);
1183 end;
1184 for I := Brains.IndexOf(BrainTerm) downto 0 do // offer game interfaces
1185 if (PlayerPopupIndex = 0) or (Brains[i].Kind = btTerm) and
1186 (PlayersBrain[0].Kind <> btNoTerm) then begin
1187 OfferBrain(Brains[I], FixedLines);
1188 Inc(FixedLines);
1189 end;
1190 if PlayerPopupIndex > 0 then begin
1191 MenuItem := TMenuItem.Create(PopupMenu1);
1192 MenuItem.Caption := '-';
1193 PopupMenu1.Items.Add(MenuItem);
1194 Inc(FixedLines);
1195 if Brains.GetKindCount(btAI) >= 2 then begin
1196 OfferBrain(BrainRandom, FixedLines);
1197 Inc(FixedLines);
1198 end;
1199 AIBrains := TBrains.Create(False);
1200 Brains.GetByKind(btAI, AIBrains);
1201 for I := 0 to AIBrains.Count - 1 do // offer available AIs
1202 if (AIBrains[I].Flags and fMultiple <> 0) or (AIBrains[I].Flags and fUsed = 0)
1203 or (Brains[I] = PlayersBrain[PlayerPopupIndex]) then
1204 OfferBrain(AIBrains[i], FixedLines);
1205 FreeAndNil(AIBrains);
1206 end;
1207 end;
1208end;
1209
1210procedure TStartDlg.UpdateFormerGames;
1211var
1212 I: Integer;
1213 F: TSearchRec;
1214begin
1215 FormerGames.Clear;
1216 if FindFirst(GetSavedDir + DirectorySeparator + '*' + CevoExt, $21, F) = 0 then
1217 repeat
1218 I := FormerGames.Count;
1219 while (I > 0) and (F.Time < integer(FormerGames.Objects[I - 1])) do
1220 Dec(I);
1221 FormerGames.InsertObject(I, Copy(F.Name, 1, Length(F.Name) - 5),
1222 TObject(F.Time));
1223 until FindNext(F) <> 0;
1224 FindClose(F);
1225 I := FormerGames.IndexOf(LastGame);
1226 if I >= 0 then ListIndex[tbPrevious] := I
1227 else ListIndex[tbPrevious] := FormerGames.Count - 1;
1228 TurnValid := False;
1229end;
1230
1231procedure TStartDlg.UpdateMaps;
1232var
1233 f: TSearchRec;
1234begin
1235 Maps.Clear;
1236 if FindFirst(GetMapsDir + DirectorySeparator + '*' + CevoMapExt, $21, f) = 0 then
1237 repeat
1238 Maps.Add(Copy(f.Name, 1, Length(f.Name) - Length(CevoMapExt)));
1239 until FindNext(f) <> 0;
1240 FindClose(F);
1241 Maps.Sort;
1242 Maps.Insert(0, Phrases.Lookup('RANMAP'));
1243 ListIndex[tbMain] := Maps.IndexOf(Copy(MapFileName, 1, Length(MapFileName) - Length(CevoMapExt)));
1244 if ListIndex[tbMain] < 0 then
1245 ListIndex[tbMain] := 0;
1246end;
1247
1248procedure TStartDlg.ChangePage(NewPage: TStartPage);
1249var
1250 i, j, p1: integer;
1251 s: string;
1252 Reg: TRegistry;
1253 InvalidateTab0: boolean;
1254begin
1255 InvalidateTab0 := (Page = pgMain) or (NewPage = pgMain);
1256 Page := NewPage;
1257 case Page of
1258 pgStartRandom, pgStartMap:
1259 begin
1260 StartBtn.Caption := Phrases.Lookup('STARTCONTROLS', 1);
1261 if Page = pgStartRandom then
1262 i := nPlOffered
1263 else
1264 begin
1265 i := nMapStartPositions;
1266 if i = 0 then
1267 begin
1268 PlayersBrain[0] := BrainSuperVirtual;
1269 Difficulty[0] := 0
1270 end;
1271 if PlayersBrain[0].Kind in [btNoTerm, btSuperVirtual] then
1272 inc(i);
1273 if i > nPl then
1274 i := nPl;
1275 if i <= nPlOffered then
1276 MultiControl := 0
1277 else
1278 MultiControl := InitMulti[i];
1279 end;
1280 if InitAlive[i] <> SlotAvailable then
1281 if Page = pgStartRandom then
1282 begin // restore AI assignment of last start
1283 Reg := TRegistry.Create;
1284 with Reg do
1285 try
1286 OpenKey(AppRegistryKey + '\AI', True);
1287 for p1 := 0 to nPlOffered - 1 do begin
1288 PlayersBrain[p1] := nil;
1289 s := ReadString('Control' + IntToStr(p1));
1290 Difficulty[p1] := ReadInteger('Diff' + IntToStr(p1));
1291 if s <> '' then
1292 for j := 0 to Brains.Count - 1 do
1293 if AnsiCompareFileName(s, Brains[j].FileName) = 0 then
1294 PlayersBrain[p1] := Brains[j];
1295 end;
1296 finally
1297 Free;
1298 end;
1299 end
1300 else
1301 for p1 := 1 to nPl - 1 do
1302 if 1 shl p1 and InitAlive[i] <> 0 then
1303 begin
1304 PlayersBrain[p1] := BrainDefault;
1305 Difficulty[p1] := 2;
1306 end
1307 else
1308 PlayersBrain[p1] := nil;
1309 SlotAvailable := InitAlive[i];
1310 for i := 0 to nPlOffered - 1 do
1311 if (AutoDiff < 0) and Assigned(PlayersBrain[i]) and
1312 (PlayersBrain[i].Kind in [btTerm, btRandom, btAI]) then
1313 begin
1314 PlayerSlots[i].DiffUpBtn.Tag := 768;
1315 PlayerSlots[i].DiffDownBtn.Tag := 768;
1316 end
1317 else
1318 begin
1319 PlayerSlots[i].DiffUpBtn.Tag := 0;
1320 PlayerSlots[i].DiffDownBtn.Tag := 0;
1321 end;
1322 for i := 6 to 8 do
1323 if (AutoDiff < 0) and Assigned(PlayersBrain[i]) and
1324 (PlayersBrain[i].Kind in [btTerm, btRandom, btAI]) then
1325 begin
1326 PlayerSlots[i].MultiBtn.Tag := 768;
1327 PlayerSlots[i].MultiBtn.ButtonIndex := 2 + (MultiControl shr i) and 1;
1328 PlayerSlots[i].MultiBtn.Enabled := Page = pgStartRandom
1329 end
1330 else
1331 PlayerSlots[i].MultiBtn.Tag := 0;
1332 if (AutoDiff > 0) and (Page <> pgStartMap) then
1333 begin
1334 AutoEnemyUpBtn.Tag := 768;
1335 AutoEnemyDownBtn.Tag := 768;
1336 end
1337 else
1338 begin
1339 AutoEnemyUpBtn.Tag := 0;
1340 AutoEnemyDownBtn.Tag := 0;
1341 end;
1342 if AutoDiff > 0 then
1343 begin
1344 AutoDiffUpBtn.Tag := 768;
1345 AutoDiffDownBtn.Tag := 768;
1346 end
1347 else
1348 begin
1349 AutoDiffUpBtn.Tag := 0;
1350 AutoDiffDownBtn.Tag := 0;
1351 end;
1352 end;
1353
1354 pgNoLoad, pgLoad:
1355 begin
1356 StartBtn.Caption := Phrases.Lookup('STARTCONTROLS', 2);
1357 RenameBtn.Hint := Phrases.Lookup('BTN_RENGAME');
1358 DeleteBtn.Hint := Phrases.Lookup('BTN_DELGAME');
1359 end;
1360
1361 pgEditRandom, pgEditMap:
1362 begin
1363 StartBtn.Caption := Phrases.Lookup('STARTCONTROLS', 12);
1364 RenameBtn.Hint := Phrases.Lookup('BTN_RENMAP');
1365 DeleteBtn.Hint := Phrases.Lookup('BTN_DELMAP');
1366 end;
1367 end;
1368
1369 PaintInfo;
1370 for i := 0 to ControlCount - 1 do
1371 Controls[i].Visible := Controls[i].Tag and (256 shl Integer(Page)) <> 0;
1372 if Page = pgLoad then
1373 ReplayBtn.Visible := MiniMap.Mode <> mmMultiPlayer;
1374 List.Invalidate;
1375 SmartInvalidate(0, 0, ClientWidth, ClientHeight, invalidateTab0);
1376end;
1377
1378procedure TStartDlg.ChangeTab(NewTab: TStartTab);
1379begin
1380 Tab := NewTab;
1381 case Tab of
1382 tbMap:
1383 List.Items.Assign(Maps);
1384 tbPrevious:
1385 List.Items.Assign(FormerGames);
1386 end;
1387 if Tab <> tbNew then
1388 if List.Count > 0 then begin
1389 if (ListIndex[Tab] < List.Count) and (ListIndex[Tab] >= 0) then begin
1390 List.ItemIndex := ListIndex[Tab];
1391 end else List.ItemIndex := 0;
1392 end else List.ItemIndex := -1;
1393 case Tab of
1394 tbMain:
1395 ChangePage(pgMain);
1396 tbMap:
1397 if List.ItemIndex = 0 then
1398 ChangePage(pgEditRandom)
1399 else
1400 ChangePage(pgEditMap);
1401 tbNew:
1402 if MapFileName = '' then
1403 ChangePage(pgStartRandom)
1404 else
1405 ChangePage(pgStartMap);
1406 tbPrevious:
1407 if FormerGames.Count = 0 then
1408 ChangePage(pgNoLoad)
1409 else
1410 ChangePage(pgLoad);
1411 end;
1412end;
1413
1414procedure TStartDlg.FormMouseDown(Sender: TObject; Button: TMouseButton;
1415 Shift: TShiftState; x, y: integer);
1416var
1417 I: Integer;
1418begin
1419 if (y < TabHeight + 1) and (x - TabOffset < TabSize * 4) and
1420 ((x - TabOffset) div TabSize <> Integer(Tab)) then
1421 begin
1422 // Play('BUTTON_DOWN');
1423 ListIndex[Tab] := List.ItemIndex;
1424 ChangeTab(TStartTab((x - TabOffset) div TabSize));
1425 end
1426 else if Page = pgMain then
1427 begin
1428 case SelectedAction of
1429 maConfig:
1430 begin
1431 SettingsDlg := TSettingsDlg.Create(nil);
1432 if SettingsDlg.ShowModal = mrOk then begin
1433 LoadAssets;
1434 Invalidate;
1435 UpdateInterface;
1436 Background.UpdateInterface;
1437 end;
1438 FreeAndNil(SettingsDlg);
1439 end;
1440 maManual:
1441 DirectHelp(cStartHelp);
1442 maCredits:
1443 DirectHelp(cStartCredits);
1444 maAIDev:
1445 OpenDocument(HomeDir + AITemplateFileName);
1446 maWeb:
1447 OpenURL(CevoHomepage);
1448 end;
1449 end
1450 else if (AutoDiff < 0) and ((Page = pgStartRandom) or (Page = pgStartMap) and
1451 (nMapStartPositions > 0)) then
1452 begin
1453 for I := 0 to nPlOffered - 1 do
1454 if (1 shl I and SlotAvailable <> 0) and (x >= xBrain[I]) and
1455 (y >= yBrain[I]) and (x < xBrain[I] + 64) and (y < yBrain[I] + 64) then
1456 begin
1457 InitPopup(I);
1458 if yBrain[I] > y0Brain then
1459 PopupMenu1.Popup(left + xBrain[I] + 4, top + yBrain[I] + 60)
1460 else
1461 PopupMenu1.Popup(left + xBrain[I] + 4, top + yBrain[I] + 4);
1462 end
1463 end
1464 else if (AutoDiff > 1) and ((Page = pgStartRandom) or (Page = pgStartMap)) and
1465 (x >= xDefault) and (y >= yDefault) and (x < xDefault + 64) and
1466 (y < yDefault + 64) then
1467 if Brains.GetKindCount(btAI) < 2 then
1468 SimpleMessage(Phrases.Lookup('NOALTAI'))
1469 else
1470 begin
1471 InitPopup(-1);
1472 PopupMenu1.Popup(left + xDefault + 4, top + yDefault + 4);
1473 end
1474 else if (Page = pgLoad) and (LastTurn > 0) and (y >= yTurnSlider) and
1475 (y < yTurnSlider + 7) and (x >= xTurnSlider) and
1476 (x <= xTurnSlider + wTurnSlider) then
1477 begin
1478 LoadTurn := LastTurn * (x - xTurnSlider) div wTurnSlider;
1479 SmartInvalidate(xTurnSlider - 2, y0Mini + 61, xTurnSlider + wTurnSlider + 2,
1480 yTurnSlider + 9);
1481 Tracking := True;
1482 end;
1483end;
1484
1485procedure TStartDlg.Up2BtnClick(Sender: TObject);
1486begin
1487 case Page of
1488 pgStartRandom, pgStartMap:
1489 if MaxTurn < 1400 then
1490 begin
1491 inc(MaxTurn, 200);
1492 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 82);
1493 end;
1494 pgLoad:
1495 if LoadTurn < LastTurn then
1496 begin
1497 inc(LoadTurn);
1498 SmartInvalidate(xTurnSlider - 2, y0Mini + 61, xTurnSlider + wTurnSlider
1499 + 2, yTurnSlider + 9);
1500 end;
1501 pgEditRandom:
1502 if StartLandMass < 96 then
1503 begin
1504 inc(StartLandMass, 5);
1505 PaintInfo;
1506 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 61 + 21);
1507 end;
1508 end;
1509end;
1510
1511procedure TStartDlg.Down2BtnClick(Sender: TObject);
1512begin
1513 case Page of
1514 pgStartRandom, pgStartMap:
1515 if MaxTurn > 400 then
1516 begin
1517 dec(MaxTurn, 200);
1518 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 82);
1519 end;
1520 pgLoad:
1521 if LoadTurn > 0 then
1522 begin
1523 dec(LoadTurn);
1524 SmartInvalidate(xTurnSlider - 2, y0Mini + 61, xTurnSlider + wTurnSlider
1525 + 2, yTurnSlider + 9);
1526 end;
1527 pgEditRandom:
1528 if StartLandMass > 10 then
1529 begin
1530 dec(StartLandMass, 5);
1531 PaintInfo;
1532 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 61 + 21);
1533 end;
1534 end;
1535end;
1536
1537procedure TStartDlg.Up1BtnClick(Sender: TObject);
1538begin
1539 if WorldSize < MaxWorldSize - 1 then
1540 begin
1541 Inc(WorldSize);
1542 PaintInfo;
1543 SmartInvalidate(344, y0Mini - 77, 510, y0Mini - 77 + 21);
1544 end;
1545end;
1546
1547procedure TStartDlg.Down1BtnClick(Sender: TObject);
1548begin
1549 if WorldSize > 0 then
1550 begin
1551 Dec(WorldSize);
1552 PaintInfo;
1553 SmartInvalidate(344, y0Mini - 77, 510, y0Mini - 77 + 21);
1554 end;
1555end;
1556
1557procedure TStartDlg.FormClose(Sender: TObject; var Action: TCloseAction);
1558begin
1559 DirectDlg.Close;
1560end;
1561
1562procedure TStartDlg.ListClick(Sender: TObject);
1563var
1564 I: Integer;
1565begin
1566 if (Tab = tbMap) and ((List.ItemIndex = 0) <> (Page = pgEditRandom)) then
1567 begin
1568 if List.ItemIndex = 0 then
1569 Page := pgEditRandom
1570 else
1571 Page := pgEditMap;
1572 for I := 0 to ControlCount - 1 do
1573 Controls[I].Visible := Controls[I].Tag and (256 shl Integer(Page)) <> 0;
1574 SmartInvalidate(328, Up1Btn.top - 12, ClientWidth, Up2Btn.top + 35);
1575 end;
1576 if Page = pgLoad then
1577 TurnValid := False;
1578 PaintInfo;
1579 if Page = pgLoad then
1580 ReplayBtn.Visible := MiniMap.Mode <> mmMultiPlayer;
1581end;
1582
1583procedure TStartDlg.RenameBtnClick(Sender: TObject);
1584var
1585 i: integer;
1586 NewName: string;
1587 f: file;
1588 ok: boolean;
1589begin
1590 if List.ItemIndex >= 0 then
1591 begin
1592 if Page = pgLoad then
1593 InputDlg.Caption := Phrases.Lookup('TITLE_BOOKNAME')
1594 else
1595 InputDlg.Caption := Phrases.Lookup('TITLE_MAPNAME');
1596 InputDlg.EInput.Text := List.Items[List.ItemIndex];
1597 InputDlg.CenterToRect(BoundsRect);
1598 InputDlg.ShowModal;
1599 NewName := InputDlg.EInput.Text;
1600 while (NewName <> '') and (NewName[1] = '~') do
1601 Delete(NewName, 1, 1);
1602 if (InputDlg.ModalResult = mrOK) and (NewName <> '') and
1603 (NewName <> List.Items[List.ItemIndex]) then
1604 begin
1605 for i := 1 to Length(NewName) do
1606 if NewName[i] in ['\', '/', ':', '*', '?', '"', '<', '>', '|'] then
1607 begin
1608 SimpleMessage(Format(Phrases.Lookup('NOFILENAME'), [NewName[i]]));
1609 exit
1610 end;
1611 if Page = pgLoad then
1612 AssignFile(f, GetSavedDir + DirectorySeparator + List.Items[List.ItemIndex] + CevoExt)
1613 else
1614 AssignFile(f, GetMapsDir + DirectorySeparator + List.Items[List.ItemIndex] +
1615 CevoMapExt);
1616 ok := true;
1617 try
1618 if Page = pgLoad then
1619 Rename(f, GetSavedDir + DirectorySeparator + NewName + CevoExt)
1620 else
1621 Rename(f, GetMapsDir + DirectorySeparator + NewName + CevoMapExt);
1622 except
1623 // Play('INVALID');
1624 ok := false
1625 end;
1626 if Page <> pgLoad then
1627 try // rename map picture
1628 AssignFile(f, GetMapsDir + DirectorySeparator + List.Items[List.ItemIndex]
1629 + '.png');
1630 Rename(f, GetMapsDir + DirectorySeparator + NewName + '.png');
1631 except
1632 end;
1633 if ok then
1634 begin
1635 if Page = pgLoad then
1636 FormerGames[List.ItemIndex] := NewName
1637 else
1638 Maps[List.ItemIndex] := NewName;
1639 List.Items[List.ItemIndex] := NewName;
1640 if Page = pgEditMap then
1641 PaintInfo;
1642 List.Invalidate;
1643 end;
1644 end;
1645 end;
1646end;
1647
1648procedure TStartDlg.DeleteBtnClick(Sender: TObject);
1649var
1650 iDel: integer;
1651 f: file;
1652begin
1653 if List.ItemIndex >= 0 then
1654 begin
1655 if Page = pgLoad then
1656 MessgDlg.MessgText := Phrases.Lookup('DELETEQUERY')
1657 else
1658 MessgDlg.MessgText := Phrases.Lookup('MAPDELETEQUERY');
1659 MessgDlg.Kind := mkOKCancel;
1660 MessgDlg.ShowModal;
1661 if MessgDlg.ModalResult = mrOK then
1662 begin
1663 if Page = pgLoad then
1664 AssignFile(f, GetSavedDir + DirectorySeparator + List.Items[List.ItemIndex] + CevoExt)
1665 else
1666 AssignFile(f, GetMapsDir + DirectorySeparator + List.Items[List.ItemIndex] +
1667 CevoMapExt);
1668 Erase(f);
1669 iDel := List.ItemIndex;
1670 if Page = pgLoad then
1671 FormerGames.Delete(iDel)
1672 else
1673 Maps.Delete(iDel);
1674 List.Items.Delete(iDel);
1675 if List.Items.Count = 0 then
1676 ChangePage(pgNoLoad)
1677 else
1678 begin
1679 if iDel = 0 then
1680 List.ItemIndex := 0
1681 else
1682 List.ItemIndex := iDel - 1;
1683 if (Page = pgEditMap) and (List.ItemIndex = 0) then
1684 ChangePage(pgEditRandom)
1685 else
1686 begin
1687 List.Invalidate;
1688 if Page = pgLoad then
1689 TurnValid := false;
1690 PaintInfo;
1691 if Page = pgLoad then
1692 ReplayBtn.Visible := MiniMap.Mode <> mmMultiPlayer;
1693 end;
1694 end;
1695 end;
1696 end;
1697end;
1698
1699procedure TStartDlg.DiffBtnClick(Sender: TObject);
1700var
1701 I: Integer;
1702begin
1703 for I := 0 to nPlOffered - 1 do
1704 if (Sender = PlayerSlots[I].DiffUpBtn) and (Difficulty[I] < 3) or
1705 (Sender = PlayerSlots[I].DiffDownBtn) and (Difficulty[I] > 1) then
1706 begin
1707 if Sender = PlayerSlots[I].DiffUpBtn then
1708 Inc(Difficulty[I])
1709 else
1710 Dec(Difficulty[I]);
1711 SmartInvalidate(xBrain[I] - 18, yBrain[I] + 19, xBrain[I] - 18 + 12,
1712 yBrain[I] + (19 + 14));
1713 end;
1714end;
1715
1716procedure TStartDlg.MultiBtnClick(Sender: TObject);
1717var
1718 I: Integer;
1719begin
1720 for I := 6 to 8 do
1721 if Sender = PlayerSlots[I].MultiBtn then
1722 begin
1723 MultiControl := MultiControl xor (1 shl I);
1724 TButtonC(Sender).ButtonIndex := 2 + (MultiControl shr I) and 1;
1725 end;
1726end;
1727
1728procedure TStartDlg.FormHide(Sender: TObject);
1729begin
1730 Diff0 := Difficulty[0];
1731 ListIndex[Tab] := List.ItemIndex;
1732 ShowTab := Tab;
1733 Background.Enabled := True;
1734 LastGame := FormerGames[ListIndex[tbPrevious]];
1735end;
1736
1737procedure TStartDlg.QuitBtnClick(Sender: TObject);
1738begin
1739 Close;
1740end;
1741
1742procedure TStartDlg.FormKeyDown(Sender: TObject; var Key: Word;
1743 Shift: TShiftState);
1744var
1745 ShortCut: TShortCut;
1746begin
1747 ShortCut := KeyToShortCut(Key, Shift);
1748 if BFullScreen.Test(ShortCut) then begin
1749 FullScreen := not FullScreen;
1750 UpdateInterface;
1751 Background.UpdateInterface;
1752 SetFocus;
1753 end else
1754 if BHelp.Test(ShortCut) then
1755 DirectHelp(cStartHelp);
1756end;
1757
1758procedure TStartDlg.CustomizeBtnClick(Sender: TObject);
1759begin
1760 AutoDiff := -AutoDiff;
1761 CustomizeBtn.ButtonIndex := CustomizeBtn.ButtonIndex xor 1;
1762 ChangePage(Page);
1763end;
1764
1765procedure TStartDlg.AutoDiffUpBtnClick(Sender: TObject);
1766begin
1767 if AutoDiff < 5 then
1768 begin
1769 Inc(AutoDiff);
1770 SmartInvalidate(120, y0Mini + 61, 272, y0Mini + 61 + 21);
1771 SmartInvalidate(xDefault - 2, yDefault - 2, xDefault + 64 + 2,
1772 yDefault + 64 + 2);
1773 end;
1774end;
1775
1776procedure TStartDlg.AutoDiffDownBtnClick(Sender: TObject);
1777begin
1778 if AutoDiff > 1 then
1779 begin
1780 Dec(AutoDiff);
1781 SmartInvalidate(120, y0Mini + 61, 272, y0Mini + 61 + 21);
1782 SmartInvalidate(xDefault - 2, yDefault - 2, xDefault + 64 + 2,
1783 yDefault + 64 + 2);
1784 end;
1785end;
1786
1787procedure TStartDlg.FormMouseUp(Sender: TObject; Button: TMouseButton;
1788 Shift: TShiftState; x, y: integer);
1789begin
1790 Tracking := False;
1791end;
1792
1793procedure TStartDlg.FormMouseMove(Sender: TObject; Shift: TShiftState;
1794 x, y: integer);
1795var
1796 OldLoadTurn: Integer;
1797 NewSelectedAction: TMainAction;
1798begin
1799 if Tracking then
1800 begin
1801 x := x - xTurnSlider;
1802 if x < 0 then
1803 x := 0
1804 else if x > wTurnSlider then
1805 x := wTurnSlider;
1806 OldLoadTurn := LoadTurn;
1807 LoadTurn := LastTurn * x div wTurnSlider;
1808 if LoadTurn < OldLoadTurn then
1809 begin
1810 SmartInvalidate(xTurnSlider + LoadTurn * wTurnSlider div LastTurn,
1811 yTurnSlider, xTurnSlider + OldLoadTurn * wTurnSlider div LastTurn + 1,
1812 yTurnSlider + 7);
1813 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 82);
1814 end
1815 else if LoadTurn > OldLoadTurn then
1816 begin
1817 SmartInvalidate(xTurnSlider + OldLoadTurn * wTurnSlider div LastTurn,
1818 yTurnSlider, xTurnSlider + LoadTurn * wTurnSlider div LastTurn + 1,
1819 yTurnSlider + 7);
1820 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 82);
1821 end;
1822 end
1823 else if Page = pgMain then
1824 begin
1825 if (x >= ActionSideBorder) and (x < ClientWidth - ActionSideBorder) and
1826 (y >= yAction - 8) and (y < ClientHeight - ActionBottomBorder) then
1827 begin
1828 NewSelectedAction := TMainAction((y - (yAction - 8)) div ActionPitch);
1829 if not (NewSelectedAction in ActionsOffered) then
1830 NewSelectedAction := maNone;
1831 end
1832 else
1833 NewSelectedAction := maNone;
1834 if NewSelectedAction <> SelectedAction then
1835 begin
1836 if SelectedAction <> maNone then
1837 SmartInvalidate(ActionSideBorder, yAction + Integer(SelectedAction) * ActionPitch
1838 - 8, ClientWidth - ActionSideBorder, yAction + (Integer(SelectedAction) + 1) *
1839 ActionPitch - 8);
1840 SelectedAction := NewSelectedAction;
1841 if SelectedAction <> maNone then
1842 SmartInvalidate(ActionSideBorder, yAction + Integer(SelectedAction) * ActionPitch
1843 - 8, ClientWidth - ActionSideBorder, yAction + (Integer(SelectedAction) + 1) *
1844 ActionPitch - 8);
1845 end;
1846 end;
1847end;
1848
1849procedure TStartDlg.AutoEnemyUpBtnClick(Sender: TObject);
1850begin
1851 if AutoEnemies < nPl - 1 then
1852 begin
1853 Inc(AutoEnemies);
1854 SmartInvalidate(160, yMain + 140, 198, yMain + 140 + 21);
1855 end;
1856end;
1857
1858procedure TStartDlg.AutoEnemyDownBtnClick(Sender: TObject);
1859begin
1860 if AutoEnemies > 0 then
1861 begin
1862 Dec(AutoEnemies);
1863 SmartInvalidate(160, yMain + 140, 198, yMain + 140 + 21);
1864 end;
1865end;
1866
1867procedure TStartDlg.ReplayBtnClick(Sender: TObject);
1868begin
1869 LoadGame(GetSavedDir + DirectorySeparator, List.Items[List.ItemIndex] + CevoExt,
1870 LastTurn, True);
1871 SlotAvailable := -1;
1872end;
1873
1874
1875end.
Note: See TracBrowser for help on using the repository browser.