Subversion Repositories plumbers

Rev

Rev 5 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
unit Unit1;
2
 
3
// TODO: create for "unused files" box a small thumbnail, too?
4
 
5
interface
6
 
7
uses
8
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
9
  Dialogs, StdCtrls, Spin, Grids, GameBinStruct, ComCtrls, ExtCtrls, Vcl.MPlayer,
10
  Vcl.Menus;
11
 
12
const
13
  CUR_VER = '2017-08-09';
14
 
15
type
16
  TForm1 = class(TForm)
17
    ListBox1: TListBox;
18
    Button1: TButton;
19
    Button2: TButton;
20
    Button3: TButton;
21
    Button4: TButton;
22
    Button5: TButton;
23
    Button10: TButton;
24
    PageControl2: TPageControl;
25
    TabSheet4: TTabSheet;
26
    Label1: TLabel;
27
    Label2: TLabel;
28
    SpinEdit1: TSpinEdit;
29
    Edit1: TEdit;
30
    Button6: TButton;
31
    Button7: TButton;
32
    Button8: TButton;
33
    Button9: TButton;
34
    ListBox2: TListBox;
35
    TabSheet5: TTabSheet;
36
    Label3: TLabel;
37
    Image1: TImage;
38
    Label10: TLabel;
39
    Label11: TLabel;
40
    Edit2: TEdit;
41
    PageControl1: TPageControl;
42
    TabSheet1: TTabSheet;
43
    Label5: TLabel;
44
    Label4: TLabel;
45
    Label6: TLabel;
46
    SpinEdit6: TSpinEdit;
47
    SpinEdit2: TSpinEdit;
48
    SpinEdit3: TSpinEdit;
49
    SpinEdit4: TSpinEdit;
50
    SpinEdit5: TSpinEdit;
51
    ComboBox1: TComboBox;
52
    TabSheet2: TTabSheet;
53
    Label13: TLabel;
54
    Label14: TLabel;
55
    Label15: TLabel;
56
    ComboBox2: TComboBox;
57
    SpinEdit17: TSpinEdit;
58
    SpinEdit18: TSpinEdit;
59
    SpinEdit19: TSpinEdit;
60
    SpinEdit20: TSpinEdit;
61
    SpinEdit21: TSpinEdit;
62
    TabSheet3: TTabSheet;
63
    Label7: TLabel;
64
    Label8: TLabel;
65
    Label9: TLabel;
66
    ComboBox3: TComboBox;
67
    SpinEdit7: TSpinEdit;
68
    SpinEdit8: TSpinEdit;
69
    SpinEdit9: TSpinEdit;
70
    SpinEdit10: TSpinEdit;
71
    SpinEdit11: TSpinEdit;
72
    SpinEdit12: TSpinEdit;
73
    Image2: TImage;
74
    Edit3: TEdit;
75
    SpinEdit13: TSpinEdit;
76
    Label12: TLabel;
77
    Label16: TLabel;
78
    Button13: TButton;
79
    Button14: TButton;
80
    MediaPlayer1: TMediaPlayer;
81
    Timer1: TTimer;
82
    GroupBox1: TGroupBox;
83
    Label20: TLabel;
84
    Label21: TLabel;
85
    Label22: TLabel;
86
    Label23: TLabel;
87
    GroupBox2: TGroupBox;
88
    Button15: TButton;
89
    Button17: TButton;
90
    Button16: TButton;
91
    Label18: TLabel;
92
    Label17: TLabel;
93
    ListBox3: TListBox;
94
    Label19: TLabel;
95
    Label24: TLabel;
96
    Label25: TLabel;
97
    Label26: TLabel;
98
    Label27: TLabel;
99
    Label28: TLabel;
100
    Label29: TLabel;
101
    Button11: TButton;
102
    Button12: TButton;
103
    Button18: TButton;
104
    MainMenu1: TMainMenu;
105
    File1: TMenuItem;
106
    Close1: TMenuItem;
107
    Newfile1: TMenuItem;
108
    Savetogamebin1: TMenuItem;
109
    Saveandtest1: TMenuItem;
110
    N1: TMenuItem;
111
    N2: TMenuItem;
112
    Help1: TMenuItem;
113
    About1: TMenuItem;
114
    PopupMenu1: TPopupMenu;
115
    Addtoscene1: TMenuItem;
116
    procedure ListBox1Click(Sender: TObject);
117
    procedure Edit1Change(Sender: TObject);
118
    procedure Edit2Change(Sender: TObject);
119
    procedure SpinEdit1Change(Sender: TObject);
120
    procedure Button3Click(Sender: TObject);
121
    procedure FormShow(Sender: TObject);
122
    procedure SpinEdit12Change(Sender: TObject);
123
    procedure ActionTargetChange(Sender: TObject);
124
    procedure ActionSpinEditsChange(Sender: TObject);
125
    procedure Button1Click(Sender: TObject);
126
    procedure Button10Click(Sender: TObject);
127
    procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
128
      Y: Integer);
129
    procedure ListBox2Click(Sender: TObject);
130
    procedure SpinEdit13Change(Sender: TObject);
131
    procedure Edit3Change(Sender: TObject);
132
    procedure FormCreate(Sender: TObject);
133
    procedure Button13Click(Sender: TObject);
134
    procedure Button14Click(Sender: TObject);
135
    procedure Button2Click(Sender: TObject);
136
    procedure Timer1Timer(Sender: TObject);
137
    procedure Button17Click(Sender: TObject);
138
    procedure Button15Click(Sender: TObject);
139
    procedure Button16Click(Sender: TObject);
140
    procedure ListBox1DblClick(Sender: TObject);
141
    procedure ListBox2DblClick(Sender: TObject);
142
    procedure Button4Click(Sender: TObject);
143
    procedure Button5Click(Sender: TObject);
144
    procedure Button6Click(Sender: TObject);
145
    procedure Button7Click(Sender: TObject);
146
    procedure Button8Click(Sender: TObject);
147
    procedure Button9Click(Sender: TObject);
148
    procedure Image1MouseLeave(Sender: TObject);
149
    procedure ListBox3DblClick(Sender: TObject);
150
    procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
151
      Shift: TShiftState; X, Y: Integer);
152
    procedure Button11Click(Sender: TObject);
153
    procedure Button12Click(Sender: TObject);
154
    procedure Button18Click(Sender: TObject);
155
    procedure Image1MouseEnter(Sender: TObject);
156
    procedure About1Click(Sender: TObject);
157
    procedure Close1Click(Sender: TObject);
158
    procedure Addtoscene1Click(Sender: TObject);
159
    procedure ListBox3MouseDown(Sender: TObject; Button: TMouseButton;
160
      Shift: TShiftState; X, Y: Integer);
161
  private
162
    Game: TGameBinFile;
163
    PlayStart: Cardinal;
164
    MediaplayerOpened: boolean;
165
    StopPlayRequest: boolean;
166
    FirstTickCount: Cardinal;
167
    function CurScene: PSceneDef;
168
    procedure LoadScene;
169
    procedure Load;
170
    procedure Save;
171
    procedure ReloadActionSceneLists;
172
    function FindSceneIndex(sceneID: integer): integer;
173
    function GetGreatestSceneID: integer;
174
    function SearchSceneIDGapFromTop: integer;
175
    procedure RedrawDecisionBitmap;
176
    function CurPicture: PPictureDef;
177
    function CurPictureTimepos: Cardinal;
178
    procedure New;
179
    procedure NewScene;
180
    procedure SetupGUIAfterLoad;
181
    procedure RecalcSlideshowLength;
182
    procedure RecalcSoundtrackLength;
183
    procedure RecalcUnusedFiles;
184
    procedure HandlePossibleEmptySceneList;
185
    procedure DisableEnableSceneControls(enable: boolean);
186
    procedure DisableEnablePictureControls(enable: boolean);
187
    procedure DisableEnableFileControls(enable: boolean);
188
  end;
189
 
190
var
191
  Form1: TForm1;
192
 
193
implementation
194
 
195
{$R *.dfm}
196
 
197
uses
198
  Math, MMSystem, ShellAPI;
199
 
200
function GetSceneIDFromName(sceneName: string): Integer;
201
var
202
  sSceneID: string;
203
begin
204
  if Copy(sceneName, 1, 2) <> 'SC' then raise Exception.Create('Scene name invalid');
205
  sSceneID := Copy(sceneName, 3, 2);
206
  if not TryStrToInt(sSceneID, result) then raise Exception.Create('Scene name invalid');
207
end;
208
 
209
function _DecisecondToTime(ds: integer): string;
210
begin
211
  result := FormatDatetime('hh:nn:ss', ds / 10 / (24*60*60))+','+IntToStr(ds mod 10);
212
end;
213
 
214
{ TForm1 }
215
 
216
function TForm1.GetGreatestSceneID: integer;
217
var
218
  i: integer;
219
begin
220
  result := -1;
221
  for i := 0 to ListBox1.Items.Count - 1 do
222
  begin
223
    result := Max(result, GetSceneIDFromName(ListBox1.Items.Strings[i]));
224
  end;
225
end;
226
 
227
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
228
  Shift: TShiftState; X, Y: Integer);
229
var
230
  sE1, sE2, sE3, sE4: TSpinEdit;
231
 
232
  procedure _Go;
233
  begin
234
    if Button = mbLeft then
235
    begin
236
      sE1.Value := Round(Image1.Picture.Width*(X/Image1.Width));
237
      sE2.Value := Round(Image1.Picture.Height*(Y/Image1.Height));
238
    end
239
    else if Button = mbRight then
240
    begin
241
      sE3.Value := Round(Image1.Picture.Width*(X/Image1.Width));
242
      sE4.Value := Round(Image1.Picture.Height*(Y/Image1.Height));
243
    end;
244
  end;
245
 
246
begin
247
  if PageControl1.ActivePage = TabSheet1 then
248
  begin
249
    sE1 := SpinEdit3;
250
    sE2 := SpinEdit2;
251
    sE3 := SpinEdit4;
252
    sE4 := SpinEdit5;
253
    _Go;
254
  end
255
  else if PageControl1.ActivePage = TabSheet2 then
256
  begin
257
    sE1 := SpinEdit17;
258
    sE2 := SpinEdit18;
259
    sE3 := SpinEdit19;
260
    sE4 := SpinEdit20;
261
    _Go;
262
  end
263
  else if PageControl1.ActivePage = TabSheet3 then
264
  begin
265
    sE1 := SpinEdit7;
266
    sE2 := SpinEdit8;
267
    sE3 := SpinEdit10;
268
    sE4 := SpinEdit9;
269
    _Go;
270
  end;
271
end;
272
 
273
procedure TForm1.Image1MouseEnter(Sender: TObject);
274
begin
275
  Label28.Visible := true;
276
  Label29.Visible := true;
277
end;
278
 
279
procedure TForm1.Image1MouseLeave(Sender: TObject);
280
begin
281
  Label10.Caption := '';
282
  Label28.Visible := false;
283
  Label29.Visible := false;
284
end;
285
 
286
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
287
  Y: Integer);
288
begin
289
  label10.Caption := Format('Coords: [%d, %d]', [Round(Image1.Picture.Width*(X/Image1.Width)),
290
                                                 Round(Image1.Picture.Height*(Y/Image1.Height))]);
291
end;
292
 
293
function TForm1.SearchSceneIDGapFromTop: integer;
294
var
295
  i: integer;
296
begin
297
  result := -1;
298
  for i := 99 downto 0 do
299
  begin
300
    if ListBox1.Items.IndexOf(Format('SC%.2d', [i])) = -1 then
301
    begin
302
      result := i;
303
      exit;
304
    end;
305
  end;
306
end;
307
 
308
procedure TForm1.Button10Click(Sender: TObject);
309
begin
310
  Save;
311
  if not FileExists('ShowTime32.exe') then raise Exception.Create('ShowTime32.exe not found.');
312
  ShellExecute(Application.Handle, 'open', 'ShowTime32.exe', '', '', SW_NORMAL);
313
end;
314
 
315
procedure TForm1.Button11Click(Sender: TObject);
316
var
317
  fileName: string;
318
begin
319
  fileName := IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + CurScene^.szDecisionBmp;
320
  if not FileExists(fileName) then exit;
321
  ShellExecute(Application.Handle, 'open', PChar(fileName), '', '', SW_NORMAL);
322
end;
323
 
324
procedure TForm1.Button12Click(Sender: TObject);
325
var
326
  fileName: string;
327
begin
328
  fileName := IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + CurPicture^.szBitmapFile;
329
  if not FileExists(fileName) then exit;
330
  ShellExecute(Application.Handle, 'open', Pchar(fileName), '', '', SW_NORMAL);
331
end;
332
 
333
procedure TForm1.Button13Click(Sender: TObject);
334
var
335
  fileName: string;
336
begin
337
  fileName := CurScene^.szSceneFolder;
338
  if not DirectoryExists(fileName) then MkDir(fileName);
339
  ShellExecute(Application.Handle, 'open', 'explorer.exe', PChar(fileName), '', SW_NORMAL);
340
end;
341
 
342
procedure TForm1.HandlePossibleEmptySceneList;
343
begin
344
  if Game.numScenes = 0 then
345
  begin
346
    PageControl2.ActivePage := nil;
347
    PageControl2.Pages[0].TabVisible := false;
348
    PageControl2.Pages[1].TabVisible := false;
349
  end
350
  else
351
  begin
352
    if PageControl2.ActivePage = nil then PageControl2.ActivePageIndex := 0;
353
    PageControl2.Pages[0].TabVisible := true;
354
    PageControl2.Pages[1].TabVisible := true;
355
  end;
356
end;
357
 
358
procedure TForm1.Button14Click(Sender: TObject);
359
begin
360
  New;
361
  HandlePossibleEmptySceneList;
362
end;
363
 
364
procedure TForm1.DisableEnableSceneControls(enable: boolean);
365
begin
366
  ListBox1.Enabled := enable;
367
  Button1.Enabled := enable;
368
  Button2.Enabled := enable;
369
  Button4.Enabled := enable;
370
  Button5.Enabled := enable;
371
end;
372
 
373
procedure TForm1.DisableEnablePictureControls(enable: boolean);
374
begin
375
  Button8.Enabled := enable;
376
  Button9.Enabled := enable;
377
  Button6.Enabled := enable;
378
  Button7.Enabled := enable;
379
end;
380
 
381
procedure TForm1.DisableEnableFileControls(enable: boolean);
382
begin
383
  Button3.Enabled := enable;
384
  Button10.Enabled := enable;
385
  Button14.Enabled := enable;
386
end;
387
 
388
procedure TForm1.Button15Click(Sender: TObject);
389
var
390
  decisionBMP: string;
391
  PictureLastFrame: Cardinal;
392
  i: integer;
393
  DecisionPicSet: boolean;
394
begin
395
  if PlayStart <> 0 then
396
  begin
397
    if MediaplayerOpened then
398
    begin
399
      if MediaPlayer1.Mode = mpPlaying then MediaPlayer1.Stop;
400
      Mediaplayer1.TimeFormat := tfMilliseconds;
401
      if CurPictureTimepos*100 < Cardinal(MediaPlayer1.Length) then
402
      begin
403
        MediaPlayer1.Position := CurPictureTimepos * 100;
404
        MediaPlayer1.Play;
405
      end;
406
    end;
407
    FirstTickCount := GetTickCount;
408
    PlayStart := GetTickCount - CurPictureTimepos * 100;
409
  end
410
  else
411
  begin
412
    DisableEnablePictureControls(false);
413
    DisableEnableSceneControls(false);
414
    DisableEnableFileControls(false);
415
    Edit1.Enabled := false;
416
    Edit3.Enabled := false;
417
    SpinEdit1.Enabled := false;
418
    SpinEdit13.Enabled := false;
419
    Label18.Font.Color := clGreen;
420
    try
421
      Timer1.Enabled := false;
422
 
423
      RecalcSoundtrackLength; // optional
424
 
425
      Mediaplayer1.FileName := Format('%s\%s', [CurScene^.szSceneFolder, CurScene^.szDialogWav]);
426
      if FileExists(Mediaplayer1.FileName) then
427
      begin
428
        Mediaplayer1.TimeFormat := tfMilliseconds;
429
        Mediaplayer1.Open;
430
        MediaplayerOpened := true;
431
        if CurPictureTimepos*100 < Cardinal(MediaPlayer1.Length) then
432
        begin
433
          MediaPlayer1.Position := CurPictureTimepos * 100;
434
          MediaPlayer1.Play;
435
        end;
436
      end
437
      else
438
      begin
439
        MediaplayerOpened := false;
440
        MediaPlayer1.FileName := '';
441
      end;
442
      PlayStart := GetTickCount - CurPictureTimepos * 100;
443
      Timer1.Enabled := true;
444
 
445
      {$REGION 'Calculate PictureLastFrame'}
446
      PictureLastFrame := 0;
447
      for i := 0 to CurScene^.numPics-1 do
448
      begin
449
        Inc(PictureLastFrame, Game.pictures[CurScene^.pictureIndex + i].duration);
450
      end;
451
      PictureLastFrame := PictureLastFrame * 100;
452
      {$ENDREGION}
453
 
454
      DecisionPicSet := false;
455
      while not Application.Terminated and
456
            not StopPlayRequest and
457
            (
458
                  (MediaPlayer1.Mode = mpPlaying) or
459
                  (GetTickCount - PlayStart <= PictureLastFrame)
460
            ) do
461
      begin
462
        if GetTickCount - PlayStart <= PictureLastFrame then
463
        begin
464
          DecisionPicSet := false;
465
          FirstTickCount := GetTickCount;
466
          while not Application.Terminated and ((GetTickCount - FirstTickCount) < CurPicture^.duration * 100) and not StopPlayRequest do
467
          begin
468
            Application.ProcessMessages;
469
            Sleep(0);
470
          end;
471
 
472
          if not Application.Terminated and (ListBox2.ItemIndex < ListBox2.Count-1) and not StopPlayRequest then
473
          begin
474
            ListBox2.ItemIndex := ListBox2.ItemIndex + 1;
475
            ListBox2Click(ListBox2);
476
          end;
477
        end
478
        else
479
        begin
480
          if not DecisionPicSet then
481
          begin
482
            decisionBMP := IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + CurScene^.szDecisionBmp;
483
            if (CurScene^.szDecisionBmp <> '') and FileExists(decisionBMP) then
484
            begin
485
              Image2.Picture.LoadFromFile(decisionBMP);
486
            end
487
            else
488
            begin
489
              Image2.Picture := nil;
490
            end;
491
            DecisionPicSet := true;
492
          end;
493
          Application.ProcessMessages;
494
          Sleep(0);
495
        end;
496
      end;
497
    finally
498
      PlayStart := 0;
499
      if MediaPlayer1.Mode = mpPlaying then MediaPlayer1.Stop;
500
      if MediaplayerOpened then MediaPlayer1.Close;
501
      StopPlayRequest := false;
502
      Label18.Font.Color := clWindowText;
503
      Timer1.Enabled := false;
504
      DisableEnableFileControls(true);
505
      DisableEnableSceneControls(true);
506
      DisableEnablePictureControls(true);
507
      Edit1.Enabled := true;
508
      SpinEdit1.Enabled := true;
509
      Edit3.Enabled := true;
510
      SpinEdit13.Enabled := true;
511
      Label18.Caption := _DecisecondToTime(CurPictureTimepos);
512
      ListBox2Click(ListBox2);
513
    end;
514
  end;
515
end;
516
 
517
procedure TForm1.Button16Click(Sender: TObject);
518
begin
519
  ListBox2.ItemIndex := 0; // go to the beginning
520
  ListBox2Click(ListBox2); // load picture data
521
  Button15Click(Button15); // play
522
end;
523
 
524
procedure TForm1.Button17Click(Sender: TObject);
525
begin
526
  if PlayStart <> 0 then
527
  begin
528
    Timer1.Enabled := false;
529
    if MediaplayerOpened then MediaPlayer1.Stop;
530
    StopPlayRequest := true;
531
  end;
532
end;
533
 
534
procedure TForm1.Button18Click(Sender: TObject);
535
var
536
  fileName: string;
537
begin
538
  fileName := IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + CurScene^.szDialogWav;
539
  if not FileExists(fileName) then exit;
540
  ShellExecute(Application.Handle, 'open', PChar(fileName), '', '', SW_NORMAL);
541
end;
542
 
543
procedure TForm1.NewScene;
544
var
545
  sceneID: integer;
546
  newScene: PSceneDef;
547
begin
548
  if ListBox1.Items.Count = 100 then
549
  begin
550
    raise Exception.Create('No more space for another scene');
551
  end;
552
 
553
  sceneID := GetGreatestSceneID+1;
554
  if sceneID >= Length(Game.scenes) then sceneID := SearchSceneIDGapFromTop;
555
 
556
  newScene := Game.AddSceneAtEnd(sceneID);
557
  newScene.actions[0].nextSceneID := SCENEID_ENDGAME;
558
  ListBox1.Items.Add(newScene.szSceneFolder);
559
  ReloadActionSceneLists;
560
  HandlePossibleEmptySceneList;
561
  ListBox1.ItemIndex := ListBox1.Items.Count - 1;
562
  ListBox1Click(ListBox1);
563
end;
564
 
565
procedure TForm1.Button1Click(Sender: TObject);
566
begin
567
  NewScene;
568
end;
569
 
570
procedure TForm1.Button2Click(Sender: TObject);
571
var
572
  iScene, iAction, sceneID: integer;
573
  conflicts: TStringList;
574
  sWarning: string;
575
  bakItemindex: integer;
576
begin
577
  if ListBox1.Count = 0 then exit;
578
 
579
  (*
580
  if ListBox1.Count = 1 then
581
  begin
582
    raise Exception.Create('Can''t delete the scene if there is only one.');
583
  end;
584
  *)
585
 
586
  conflicts := TStringList.Create;
587
  try
588
    sceneID := GetSceneIDFromName(CurScene^.szSceneFolder);
589
    for iScene := 0 to Game.numScenes-1 do
590
    begin
591
      for iAction := 0 to Game.scenes[iScene].numActions-1 do
592
      begin
593
        if Game.scenes[iScene].actions[iAction].nextSceneID = sceneID then
594
        begin
595
          conflicts.Add(Format('Scene %s, action #%d', [Game.scenes[iScene].szSceneFolder, iAction+1]));
596
        end;
597
      end;
598
    end;
599
    if conflicts.Count > 0 then
600
    begin
601
      raise Exception.Create('Can''t delete this scene. There are following dependencies:'+#13#10#13#10+conflicts.Text);
602
    end;
603
  finally
604
    FreeAndNil(conflicts);
605
  end;
606
 
607
  sWarning := Format('Do you really want to delete scene %s?', [CurScene^.szSceneFolder]);
608
  if (ListBox1.ItemIndex = 0) and (ListBox1.Count >= 2) then
609
    sWarning := Format('Attention: This will make %s to your new intro sequence. Is that OK?', [ListBox1.Items[ListBox1.ItemIndex+1]]);
610
  if (MessageDlg(sWarning, mtConfirmation, mbYesNoCancel, 0) <> mrYes) then
611
  begin
612
    Exit;
613
  end;
614
 
615
  Game.DeleteScene(ListBox1.ItemIndex);
616
  Dec(Game.numScenes);
617
 
618
  bakItemindex := ListBox1.ItemIndex;
619
  ListBox1.Items.Delete(bakItemindex);
620
  ReloadActionSceneLists;
621
  HandlePossibleEmptySceneList;
622
  if ListBox1.Count > 0 then
623
  begin
624
    if bakItemindex = ListBox1.Count then Dec(bakItemindex);
625
    Listbox1.ItemIndex := bakItemindex;
626
    ListBox1Click(ListBox1);
627
  end;
628
end;
629
 
630
procedure TForm1.Button3Click(Sender: TObject);
631
begin
632
  Save;
633
end;
634
 
635
procedure TForm1.Button4Click(Sender: TObject);
636
begin
637
  if ListBox1.ItemIndex <= 0 then exit;
638
  Game.SwapScene(ListBox1.ItemIndex, ListBox1.ItemIndex-1);
639
  ListBox1.Items.Exchange(ListBox1.ItemIndex, ListBox1.ItemIndex-1);
640
  ReloadActionSceneLists;
641
end;
642
 
643
procedure TForm1.Button5Click(Sender: TObject);
644
begin
645
  if ListBox1.ItemIndex = ListBox1.Count-1 then exit;
646
  Game.SwapScene(ListBox1.ItemIndex, ListBox1.ItemIndex+1);
647
  ListBox1.Items.Exchange(ListBox1.ItemIndex, ListBox1.ItemIndex+1);
648
  ReloadActionSceneLists;
649
end;
650
 
651
procedure TForm1.Button6Click(Sender: TObject);
652
var
653
  pic: PPictureDef;
654
begin
655
  pic := Game.AddPictureBetween(CurScene^.pictureIndex + Max(ListBox2.ItemIndex,0));
656
  pic.duration := 0;
657
  pic.szBitmapFile := 'DUMMY.BMP';
658
  ListBox2.Items.Insert(ListBox2.ItemIndex, '(0) DUMMY.BMP');
659
  if ListBox2.ItemIndex = -1 then
660
  begin
661
    ListBox2.ItemIndex := ListBox2.Count - 1;
662
  end
663
  else
664
  begin
665
    ListBox2.ItemIndex := ListBox2.ItemIndex - 1;
666
  end;
667
  ListBox2Click(Listbox2);
668
end;
669
 
670
procedure TForm1.Button7Click(Sender: TObject);
671
var
672
  bakIdx: integer;
673
begin
674
  if Listbox2.Count > 0 then
675
  begin
676
    bakIdx := ListBox2.ItemIndex;
677
    Game.DeletePicture(bakIdx);
678
    ListBox2.Items.Delete(bakIdx);
679
    if ListBox2.Count > 0 then
680
    begin
681
      if bakIdx = ListBox2.Count then Dec(bakIdx);
682
      ListBox2.ItemIndex := bakIdx;
683
      ListBox2Click(Listbox2);
684
    end;
685
  end;
686
end;
687
 
688
procedure TForm1.Button8Click(Sender: TObject);
689
begin
690
  if ListBox2.ItemIndex <= 0 then exit;
691
  Game.SwapPicture(CurScene^.pictureIndex+ListBox2.ItemIndex, CurScene^.pictureIndex+ListBox2.ItemIndex-1);
692
  ListBox2.Items.Exchange(ListBox2.ItemIndex, ListBox2.ItemIndex-1);
693
end;
694
 
695
procedure TForm1.Button9Click(Sender: TObject);
696
begin
697
  if ListBox2.ItemIndex = ListBox2.Count-1 then exit;
698
  Game.SwapPicture(CurScene^.pictureIndex+ListBox2.ItemIndex, CurScene^.pictureIndex+ListBox2.ItemIndex+1);
699
  ListBox2.Items.Exchange(ListBox2.ItemIndex, ListBox2.ItemIndex+1);
700
end;
701
 
702
procedure TForm1.Save;
703
var
704
  fs: TFileStream;
705
begin
706
  fs := TFileStream.Create('GAME.BIN', fmOpenWrite or fmCreate);
707
  try
708
    fs.WriteBuffer(Game, SizeOf(Game));
709
  finally
710
    FreeAndNil(fs);
711
  end;
712
end;
713
 
714
procedure TForm1.ActionTargetChange(Sender: TObject);
715
var
716
  actionIdx: integer;
717
  itemIdx: Integer;
718
begin
719
       if Sender = ComboBox1 then actionIdx := 0
720
  else if Sender = ComboBox2 then actionIdx := 1
721
  else if Sender = ComboBox3 then actionIdx := 2
722
  else raise Exception.Create('Unexpected sender for ActionTargetChange()');
723
 
724
  itemIdx := TComboBox(Sender).ItemIndex;
725
  if itemIdx = 0 then
726
    CurScene^.actions[actionIdx].nextSceneID := SCENEID_ENDGAME
727
  else if itemIdx = 1 then
728
    CurScene^.actions[actionIdx].nextSceneID := SCENEID_PREVDECISION
729
  else
730
    CurScene^.actions[actionIdx].nextSceneID := GetSceneIDFromName(ListBox1.Items[itemIdx - 2]);
731
end;
732
 
733
procedure TForm1.Addtoscene1Click(Sender: TObject);
734
var
735
  fil: string;
736
begin
737
  if ListBox3.ItemIndex = -1 then exit;
738
  fil := ListBox3.Items[ListBox3.ItemIndex];
739
  Button6.Click;
740
  Edit3.Text := fil;
741
end;
742
 
743
procedure TForm1.Edit1Change(Sender: TObject);
744
begin
745
  _WriteStringToFilename(@CurScene^.szDialogWav, Edit1.Text);
746
  RecalcSoundtrackLength;
747
  RecalcUnusedFiles;
748
 
749
  Label24.Visible := not FileExists(IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + Edit1.Text);
750
  Label25.Visible := not FileExists(IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + 'E' + Edit1.Text);
751
 
752
  Button18.Visible := CurScene^.szDialogWav <> '';
753
end;
754
 
755
procedure TForm1.Edit2Change(Sender: TObject);
756
begin
757
  _WriteStringToFilename(@CurScene^.szDecisionBmp, Edit2.Text);
758
  RecalcUnusedFiles;
759
  Label27.Visible := not FileExists(IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + Edit2.Text) and not (Edit2.Text = '');
760
  Button11.Visible := CurScene^.szDecisionBmp <> '';
761
end;
762
 
763
procedure TForm1.Edit3Change(Sender: TObject);
764
begin
765
  _WriteStringToFilename(@CurPicture^.szBitmapFile, Edit3.Text);
766
  ListBox2.Items[ListBox2.ItemIndex] := Format('(%d) %s', [CurPicture^.duration, CurPicture^.szBitmapFile]);
767
  RecalcUnusedFiles;
768
  Label26.Visible := not FileExists(IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + Edit3.Text);
769
  Button12.Visible := CurPicture^.szBitmapFile <> '';
770
end;
771
 
772
procedure TForm1.FormCreate(Sender: TObject);
773
begin
774
  PageControl1.ActivePageIndex := 0;
775
  PageControl2.ActivePageIndex := 0;
776
  Label10.Caption := '';
777
  Label21.Caption := '';
778
  Label23.Caption := '';
779
end;
780
 
781
procedure TForm1.FormShow(Sender: TObject);
782
begin
783
  if FileExists('GAME.BIN') then
784
    Load
785
  else
786
    New;
787
end;
788
 
789
function TForm1.CurScene: PSceneDef;
790
begin
791
  if ListBox1.Count = 0 then raise Exception.Create('No scene available. Please create one.');
792
  if ListBox1.ItemIndex = -1 then raise Exception.Create('No scene selected. Please select one.');
793
  result := @Game.scenes[ListBox1.ItemIndex];
794
end;
795
 
796
procedure TForm1.ListBox1Click(Sender: TObject);
797
begin
798
  LoadScene;
799
end;
800
 
801
procedure TForm1.ListBox1DblClick(Sender: TObject);
802
begin
803
  Button16Click(Button16);
804
end;
805
 
806
procedure TForm1.Close1Click(Sender: TObject);
807
begin
808
  Close;
809
end;
810
 
811
function TForm1.CurPicture: PPictureDef;
812
begin
813
  if ListBox2.Count = 0 then raise Exception.Create('No pictures available. Please create one.');
814
  if ListBox2.ItemIndex = -1 then raise Exception.Create('No pictures selected. Please select one.');
815
  result := @Game.pictures[CurScene^.pictureIndex + ListBox2.ItemIndex]
816
end;
817
 
818
function TForm1.CurPictureTimepos: Cardinal;
819
var
820
  i: integer;
821
begin
822
  result := 0;
823
  for i := curScene^.pictureIndex to curScene^.pictureIndex + ListBox2.ItemIndex - 1 do
824
  begin
825
    Inc(result, Game.pictures[i].duration);
826
  end;
827
end;
828
 
829
procedure TForm1.ListBox2Click(Sender: TObject);
830
var
831
  Filename: string;
832
begin
833
  SpinEdit13.Value := CurPicture^.duration;
834
  Edit3.Text := string(CurPicture^.szBitmapFile);
835
 
836
  Filename := string(IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + CurPicture^.szBitmapFile);
837
  if FileExists(Filename) then
838
    Image2.Picture.LoadFromFile(Filename) // TODO: keep aspect ratio
839
  else
840
    Image2.Picture := nil;
841
 
842
  Label18.Caption := _DecisecondToTime(CurPictureTimepos);
843
 
844
  if PlayStart <> 0 then
845
  begin
846
    Button15Click(Button15);
847
  end;
848
end;
849
 
850
procedure TForm1.ListBox2DblClick(Sender: TObject);
851
begin
852
  Button15Click(Button15);
853
end;
854
 
855
procedure TForm1.ListBox3DblClick(Sender: TObject);
856
var
857
  fileName: string;
858
begin
859
  if ListBox3.ItemIndex = -1 then exit;
860
  fileName := IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + ListBox3.Items[ListBox3.ItemIndex];
861
  if not FileExists(FileName) then exit;
862
  ShellExecute(Application.Handle, 'open', PChar(fileName), '', '', SW_NORMAL);
863
end;
864
 
865
procedure TForm1.ListBox3MouseDown(Sender: TObject; Button: TMouseButton;
866
  Shift: TShiftState; X, Y: Integer);
867
var
868
  APoint: TPoint;
869
  Index: integer;
870
begin
871
  if Button = mbRight then
872
  begin
873
    APoint.X := X;
874
    APoint.Y := Y;
875
    Index := TListbox(Sender).ItemAtPos(APoint, True);
876
    if Index > -1 then TListbox(Sender).Selected[Index] := True;
877
  end;
878
end;
879
 
880
procedure TForm1.SetupGUIAfterLoad;
881
var
882
  i: integer;
883
begin
884
  ListBox1.Clear;
885
  for i := 0 to Game.numScenes - 1 do
886
  begin
887
    ListBox1.Items.Add(string(Game.scenes[i].szSceneFolder));
888
  end;
889
  (*
890
  if ListBox1.Items.Count = 0 then
891
  begin
892
    NewScene;
893
  end;
894
  *)
895
 
896
  ReloadActionSceneLists;
897
  HandlePossibleEmptySceneList;
898
 
899
  if ListBox1.Count > 0 then
900
  begin
901
    ListBox1.ItemIndex := 0;
902
    ListBox1Click(Listbox1);
903
  end;
904
end;
905
 
906
procedure TForm1.New;
907
begin
908
  ZeroMemory(@Game, SizeOf(Game));
909
 
910
  SetupGUIAfterLoad;
911
end;
912
 
913
procedure TForm1.Load;
914
var
915
  fs: TFileStream;
916
begin
917
  fs := TFileStream.Create('GAME.BIN', fmOpenRead);
918
  try
919
    fs.ReadBuffer(Game, SizeOf(Game));
920
  finally
921
    FreeAndNil(fs);
922
  end;
923
 
924
  SetupGUIAfterLoad;
925
end;
926
 
927
function TForm1.FindSceneIndex(sceneID: integer): integer;
928
var
929
  i: Integer;
930
  sSceneID: string;
931
begin
932
  sSceneID := Format('SC%.2d', [sceneID]);
933
  for i := 0 to ListBox1.Count - 1 do
934
  begin
935
    if ListBox1.Items.Strings[i] = sSceneID then
936
    begin
937
      result := i;
938
      exit;
939
    end;
940
  end;
941
  result := -1;
942
end;
943
 
944
procedure TForm1.RecalcSlideshowLength;
945
var
946
  i: integer;
947
  Sum: integer;
948
begin
949
  Sum := 0;
950
  for i := CurScene^.pictureIndex to CurScene^.pictureIndex + CurScene^.numPics - 1 do
951
  begin
952
    Inc(Sum, Game.pictures[i].duration);
953
  end;
954
  Label21.Caption := _DecisecondToTime(Sum);
955
end;
956
 
957
procedure TForm1.RecalcUnusedFiles;
958
var
959
  i, idx: integer;
960
  SR: TSearchRec;
961
begin
962
  ListBox3.Clear;
963
 
964
  if FindFirst(IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + '*.*', faArchive, SR) = 0 then
965
  begin
966
    repeat
967
      ListBox3.Items.Add(SR.Name); //Fill the list
968
    until FindNext(SR) <> 0;
969
    FindClose(SR);
970
  end;
971
 
972
  for i := CurScene^.pictureIndex to CurScene^.pictureIndex+CurScene^.numPics-1 do
973
  begin
974
    idx := ListBox3.Items.IndexOf(Game.pictures[i].szBitmapFile);
975
    if idx <> -1 then ListBox3.Items.Delete(idx);
976
  end;
977
 
978
  idx := ListBox3.Items.IndexOf(Edit1.Text);
979
  if idx <> -1 then ListBox3.Items.Delete(idx);
980
  idx := ListBox3.Items.IndexOf('E'+Edit1.Text);
981
  if idx <> -1 then ListBox3.Items.Delete(idx);
982
 
983
  idx := ListBox3.Items.IndexOf(Edit2.Text);
984
  if idx <> -1 then ListBox3.Items.Delete(idx);
985
 
986
  idx := ListBox3.Items.IndexOf(Edit3.Text);
987
  if idx <> -1 then ListBox3.Items.Delete(idx);
988
end;
989
 
990
procedure TForm1.RecalcSoundtrackLength;
991
var
992
  FileName: string;
993
begin
994
  if MediaPlayer1.Mode = mpPlaying then exit;
995
 
996
  FileName := IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + CurScene^.szDialogWav;
997
  if not FileExists(FileName) then
998
  begin
999
    Label23.Caption := 'n/a';
1000
    exit;
1001
  end;
1002
  MediaPlayer1.FileName := FileName;
1003
  MediaPlayer1.TimeFormat := tfMilliseconds;
1004
  MediaPlayer1.Open;
1005
  Label23.Caption := _DecisecondToTime(MediaPlayer1.Length div 100);
1006
  MediaPlayer1.Close;
1007
end;
1008
 
1009
procedure TForm1.LoadScene;
1010
 
1011
  procedure _SelectActionComboBox(ComboBox: TComboBox; sceneID: SmallInt);
1012
  var
1013
    idx: Integer;
1014
  begin
1015
    if sceneID = SCENEID_ENDGAME then
1016
      ComboBox.ItemIndex := 0
1017
    else if sceneID = SCENEID_PREVDECISION then
1018
      ComboBox.ItemIndex := 1
1019
    else
1020
    begin
1021
      idx := FindSceneIndex(sceneID);
1022
      if idx = -1 then
1023
        ComboBox.ItemIndex := -1
1024
      else
1025
        ComboBox.ItemIndex := 2 + idx;
1026
    end;
1027
  end;
1028
 
1029
  procedure _PreparePictureList;
1030
  var
1031
    i: integer;
1032
    pic: PPictureDef;
1033
  begin
1034
    ListBox2.Clear;
1035
 
1036
    if CurScene^.numPics = 0 then
1037
    begin
1038
      pic := Game.AddPictureBetween(CurScene^.pictureIndex + Max(ListBox2.ItemIndex,0));
1039
      pic.duration := 0;
1040
      pic.szBitmapFile := 'DUMMY.BMP';
1041
    end;
1042
 
1043
    for i := CurScene^.pictureIndex to CurScene^.pictureIndex + CurScene^.numPics - 1 do
1044
    begin
1045
      Listbox2.Items.Add(Format('(%d) %s', [Game.pictures[i].duration, Game.pictures[i].szBitmapFile]));
1046
    end;
1047
  end;
1048
 
1049
begin
1050
  SpinEdit1.Value := GetSceneIDFromName(CurScene^.szSceneFolder);
1051
  Edit1.Text := string(CurScene^.szDialogWav);
1052
  Edit2.Text := string(CurScene^.szDecisionBmp);
1053
 
1054
  _PreparePictureList;
1055
  ListBox2.ItemIndex := 0;
1056
  ListBox2Click(Listbox2);
1057
 
1058
  _SelectActionComboBox(ComboBox1, CurScene^.actions[0].nextSceneID);
1059
  _SelectActionComboBox(ComboBox2, CurScene^.actions[1].nextSceneID);
1060
  _SelectActionComboBox(ComboBox3, CurScene^.actions[2].nextSceneID);
1061
 
1062
  SpinEdit12.Value := CurScene^.numActions;
1063
  SpinEdit12Change(SpinEdit12);
1064
  PageControl1.ActivePageIndex := 0;
1065
 
1066
  SpinEdit3.Value  := CurScene^.actions[0].cHotspotTopLeft.X;
1067
  SpinEdit17.Value := CurScene^.actions[1].cHotspotTopLeft.X;
1068
  SpinEdit7.Value  := CurScene^.actions[2].cHotspotTopLeft.X;
1069
  SpinEdit2.Value  := CurScene^.actions[0].cHotspotTopLeft.Y;
1070
  SpinEdit18.Value := CurScene^.actions[1].cHotspotTopLeft.Y;
1071
  SpinEdit8.Value  := CurScene^.actions[2].cHotspotTopLeft.Y;
1072
  SpinEdit4.Value  := CurScene^.actions[0].cHotspotBottomRight.X;
1073
  SpinEdit19.Value := CurScene^.actions[1].cHotspotBottomRight.X;
1074
  SpinEdit10.Value := CurScene^.actions[2].cHotspotBottomRight.X;
1075
  SpinEdit5.Value  := CurScene^.actions[0].cHotspotBottomRight.Y;
1076
  SpinEdit20.Value := CurScene^.actions[1].cHotspotBottomRight.Y;
1077
  SpinEdit9.Value  := CurScene^.actions[2].cHotspotBottomRight.Y;
1078
  SpinEdit6.Value  := CurScene^.actions[0].scoreDelta;
1079
  SpinEdit21.Value := CurScene^.actions[1].scoreDelta;
1080
  SpinEdit11.Value := CurScene^.actions[2].scoreDelta;
1081
 
1082
  RedrawDecisionBitmap;
1083
 
1084
  RecalcSlideshowLength;
1085
  RecalcSoundtrackLength;
1086
 
1087
  RecalcUnusedFiles;
1088
end;
1089
 
1090
procedure TForm1.ReloadActionSceneLists;
1091
 
1092
  procedure _ReloadActionSceneLists(ComboBox: TComboBox);
1093
  var
1094
    prevSelection: string;
1095
    i: Integer;
1096
  begin
1097
    prevSelection := ComboBox.Text;
1098
    try
1099
      ComboBox.Items.Clear;
1100
      ComboBox.Items.Add('Terminate program');
1101
      ComboBox.Items.Add('Previous decision');
1102
      ComboBox.Items.AddStrings(ListBox1.Items);
1103
    finally
1104
      ComboBox.ItemIndex := 0;
1105
      for i := ComboBox.Items.Count - 1 downto 0 do
1106
      begin
1107
        if ComboBox.Items.Strings[i] = prevSelection then
1108
        begin
1109
          ComboBox.ItemIndex := i;
1110
        end;
1111
      end;
1112
    end;
1113
  end;
1114
 
1115
begin
1116
  _ReloadActionSceneLists(ComboBox1);
1117
  _ReloadActionSceneLists(ComboBox2);
1118
  _ReloadActionSceneLists(ComboBox3);
1119
end;
1120
 
1121
procedure TForm1.SpinEdit12Change(Sender: TObject);
1122
begin
1123
  TabSheet3.TabVisible := SpinEdit12.Value >= 3;
1124
  if PageControl1.ActivePage = TabSheet3 then PageControl1.ActivePage := TabSheet2;
1125
 
1126
  TabSheet2.TabVisible := SpinEdit12.Value >= 2;
1127
  if PageControl1.ActivePage = TabSheet2 then PageControl1.ActivePage := TabSheet1;
1128
 
1129
  // TabSheet1.TabVisible := SpinEdit12.Value >= 1;
1130
 
1131
  CurScene^.numActions := SpinEdit12.Value;
1132
 
1133
  // QUE: zero data of actions which are inactive (numActions<action)?
1134
end;
1135
 
1136
procedure TForm1.SpinEdit13Change(Sender: TObject);
1137
begin
1138
  if SpinEdit13.Text = '' then exit;
1139
  CurPicture^.duration := SpinEdit13.Value;
1140
  ListBox2.Items[ListBox2.ItemIndex] := Format('(%d) %s', [CurPicture^.duration, CurPicture^.szBitmapFile]);
1141
  RecalcSlideshowLength;
1142
end;
1143
 
1144
procedure TForm1.SpinEdit1Change(Sender: TObject);
1145
 
1146
  function _CountNumScenes(str: string): integer;
1147
  var
1148
    i: integer;
1149
  begin
1150
    result := 0;
1151
    for i := 0 to ListBox1.Count-1 do
1152
    begin
1153
      if ListBox1.Items[i] = str then Inc(result);
1154
    end;
1155
  end;
1156
 
1157
var
1158
  sNew: string;
1159
begin
1160
  // TODO: warn if dependencies are broken
1161
 
1162
  if SpinEdit1.Text = '' then exit;
1163
  CurScene; // verify that a scene exists and is selected
1164
  sNew := Format('SC%.2d', [SpinEdit1.Value]);
1165
  ListBox1.Items[ListBox1.ItemIndex] := sNew;
1166
  Label17.Visible := _CountNumScenes(sNew) > 1;
1167
  ReloadActionSceneLists;
1168
  _WriteStringToFilename(@CurScene^.szSceneFolder, ListBox1.Items[ListBox1.ItemIndex]);
1169
end;
1170
 
1171
procedure TForm1.Timer1Timer(Sender: TObject);
1172
var
1173
  ms: Cardinal;
1174
begin
1175
  ms := GetTickCount - PlayStart;
1176
  Label18.Caption := FormatDatetime('hh:nn:ss', ms / 1000 / (24*60*60)) + ',' + IntToStr(ms mod 1000 div 100);
1177
end;
1178
 
1179
procedure TForm1.About1Click(Sender: TObject);
1180
begin
1181
  ShowMessage('Plumbers Dont''t Wear Ties - GAME.BIN editor (can be also used to create new games based on the "ShowTime" engine!)'+#13#10#13#10+'Written by Daniel Marschall (www.daniel-marschall.de)'+#13#10#13#10+'Published by ViaThinkSoft (www.viathinksoft.com).'+#13#10#13#10+'Current version: ' + CUR_VER);
1182
end;
1183
 
1184
procedure TForm1.ActionSpinEditsChange(Sender: TObject);
1185
begin
1186
  if TSpinEdit(Sender).Text = '' then exit; // user is about to enter a negative value
1187
  if TSpinEdit(Sender).Text = '-' then exit; // user is about to enter a negative value
1188
 
1189
       if Sender = SpinEdit3  then CurScene^.actions[0].cHotspotTopLeft.X := TSpinEdit(Sender).Value
1190
  else if Sender = SpinEdit17 then CurScene^.actions[1].cHotspotTopLeft.X := TSpinEdit(Sender).Value
1191
  else if Sender = SpinEdit7  then CurScene^.actions[2].cHotspotTopLeft.X := TSpinEdit(Sender).Value
1192
  else if Sender = SpinEdit2  then CurScene^.actions[0].cHotspotTopLeft.Y := TSpinEdit(Sender).Value
1193
  else if Sender = SpinEdit18 then CurScene^.actions[1].cHotspotTopLeft.Y := TSpinEdit(Sender).Value
1194
  else if Sender = SpinEdit8  then CurScene^.actions[2].cHotspotTopLeft.Y := TSpinEdit(Sender).Value
1195
  else if Sender = SpinEdit4  then CurScene^.actions[0].cHotspotBottomRight.X := TSpinEdit(Sender).Value
1196
  else if Sender = SpinEdit19 then CurScene^.actions[1].cHotspotBottomRight.X := TSpinEdit(Sender).Value
1197
  else if Sender = SpinEdit10 then CurScene^.actions[2].cHotspotBottomRight.X := TSpinEdit(Sender).Value
1198
  else if Sender = SpinEdit5  then CurScene^.actions[0].cHotspotBottomRight.Y := TSpinEdit(Sender).Value
1199
  else if Sender = SpinEdit20 then CurScene^.actions[1].cHotspotBottomRight.Y := TSpinEdit(Sender).Value
1200
  else if Sender = SpinEdit9  then CurScene^.actions[2].cHotspotBottomRight.Y := TSpinEdit(Sender).Value
1201
  else if Sender = SpinEdit6  then CurScene^.actions[0].scoreDelta := TSpinEdit(Sender).Value
1202
  else if Sender = SpinEdit21 then CurScene^.actions[1].scoreDelta := TSpinEdit(Sender).Value
1203
  else if Sender = SpinEdit11 then CurScene^.actions[2].scoreDelta := TSpinEdit(Sender).Value;
1204
 
1205
  RedrawDecisionBitmap;
1206
end;
1207
 
1208
procedure TForm1.RedrawDecisionBitmap;
1209
var
1210
  Filename: string;
1211
begin
1212
  FileName := string(IncludeTrailingPathDelimiter(CurScene^.szSceneFolder) + Edit2.Text);
1213
  if FileExists(FileName) then
1214
    Image1.Picture.Bitmap.LoadFromFile(FileName) // TODO: keep aspect ratio
1215
  else
1216
    Image1.Picture := nil;
1217
 
1218
  Image1.Picture.Bitmap.PixelFormat := pf24bit; // Extend the palette, so we have red, green and blue guaranteed.
1219
 
1220
  Image1.Canvas.Brush.Style := bsDiagCross;
1221
 
1222
  if (SpinEdit3.Value < SpinEdit4.Value) and (SpinEdit2.Value < SpinEdit5.Value) then
1223
  begin
1224
    Image1.Canvas.Pen.Color := clRed;
1225
    Image1.Canvas.Brush.Color := clRed;
1226
    Image1.Canvas.Rectangle(SpinEdit3.Value,  SpinEdit2.Value,  SpinEdit4.Value,  SpinEdit5.Value);
1227
  end;
1228
 
1229
  if (SpinEdit17.Value < SpinEdit19.Value) and (SpinEdit18.Value < SpinEdit20.Value) then
1230
  begin
1231
    Image1.Canvas.Pen.Color := clLime;
1232
    Image1.Canvas.Brush.Color := clLime;
1233
    Image1.Canvas.Rectangle(SpinEdit17.Value, SpinEdit18.Value, SpinEdit19.Value, SpinEdit20.Value);
1234
  end;
1235
 
1236
  if (SpinEdit7.Value < SpinEdit10.Value) and (SpinEdit8.Value < SpinEdit9.Value) then
1237
  begin
1238
    Image1.Canvas.Pen.Color := clBlue;
1239
    Image1.Canvas.Brush.Color := clBlue;
1240
    Image1.Canvas.Rectangle(SpinEdit7.Value,  SpinEdit8.Value,  SpinEdit10.Value, SpinEdit9.Value);
1241
  end;
1242
end;
1243
 
1244
end.