source: tags/1.3.0/Start.pas

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