source: branches/delphi/Start.pas

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