Subversion Repositories plumbers

Rev

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