Subversion Repositories plumbers

Rev

Rev 6 | Rev 8 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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