Subversion Repositories spacemission

Rev

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

Rev Author Line No. Line
3 daniel-mar 1
unit GamMain;
2
 
14 daniel-mar 3
// TODO 2024 Review
4
// ----------------
5
//              Quellcode optimieren und klassen-namen überdenken
6
// [OK SVN 12]  Form Screen center anstelle Desktop Center
7
//              Vollbild entf.
8
// [OK SVN 10]  DPlayX.dll auskommentieren => OK!
9
//              EV CodeSign
10
//              Spielstände usw. "Spiele" Ordner speichern, Config in Registry sichern, etc.
11
//              Neue Einheiten => Medikit, Ufo das im Kreis fliegt und nicht weggeht
12
//              Bei Pause => Entweder alles grau werden lassen, oder irgendwo "Pause" hinschreiben (nur Not in die Form Caption)
13
//              Alle Notizen durchschauen
14
//              Boss schwieriger machen: Er soll auch nach links und rechts gehen?
15
//              Cooldown für Laser?
16
//              Musik und Sounds optimieren
17 daniel-mar 17
//              hintergrundmusik als WAV anstelle MIDI ... new unDelphiX contains DXMusic component for MIDI?
14 daniel-mar 18
//              Pausiertes Spiel: Fenster bewegen lässt das Spiel wieder starten
19
//              Zwei Fenster in Taskleiste
20
//              "Doku" in Hilfemenü einbinden, ggf. auch den Leveleditor ins Menü machen
21
//              Highscore Liste
15 daniel-mar 22
//              Multilingual (all strings in resourcestrings)
17 daniel-mar 23
// [OK SVN 17]  Levelconverter entfernen, stattdessen einlesen abwärtskompatibel machen
15 daniel-mar 24
//              Credits: unDelphiX (micrel.cz/Dx)
11 daniel-mar 25
 
3 daniel-mar 26
interface
27
 
28
uses
29
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, MMSystem, Dialogs,
6 daniel-mar 30
  StdCtrls, ExtCtrls, Menus, DIB, DXClass, DXSprite, DXDraws, DXInput, DXSounds,
14 daniel-mar 31
  INIFiles, ShellAPI, wininet, DirectX{$IF CompilerVersion >= 23.0},
15 daniel-mar 32
  System.UITypes{$IFEND}, ComLevelReader, ComSaveGameReader;
3 daniel-mar 33
 
34
type
35
  TGameScene = (
36
    gsNone,
37
    gsTitle,
38
    gsMain,
39
    gsGameOver,
40
    gsNewLevel,
41
    gsWin
42
  );
43
 
44
  TGameInterval = (
45
    giMittel,
46
    giLeicht,
47
    giSchwer,
48
    giMaster
49
  );
50
 
51
  TMusicTrack = (
52
    mtNone,
53
    mtGame,
54
    mtBoss,
55
    mtScene,
56
    mtTitle
57
  );
58
 
59
  {TSoundFile = (
60
    sfNone,
61
    sfSceneMov,
62
    sfExplosion,
63
    sfHit,
64
    sfShoot,
65
    sfDanger,
66
    sfEnde,
67
    sfFrage,
68
    sfLevIntro
69
  );}
70
 
71
  TBackground = class(TBackgroundSprite)
72
  private
73
    FSpeed: Double;
74
  protected
75
    procedure DoMove(MoveCount: Integer); override;
76
  end;
77
 
78
  TBackgroundSpecial = class(TBackgroundSprite)
79
  private
80
    FSpeed: Double;
81
  protected
82
    procedure DoMove(MoveCount: Integer); override;
83
  end;
84
 
85
  TExplosion = class(TImageSprite)
86
  private
87
    FCounter: Integer;
88
  protected
89
    procedure DoMove(MoveCount: Integer); override;
90
  public
91
    constructor Create(AParent: TSprite); override;
92
  end;
93
 
94
  TPlayerSprite = class(TImageSprite)
95
  private
96
    FCounter: Integer;
97
    FMode: Integer;
98
    FTamaCount: Integer;
99
    FOldTamaTime: Integer;
100
  protected
101
    procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
102
    procedure DoMove(MoveCount: Integer); override;
103
  public
104
    constructor Create(AParent: TSprite); override;
105
    procedure FlyAway;
106
  end;
107
 
108
  TTamaSprite = class(TImageSprite)
109
  private
110
    FPlayerSprite: TPlayerSprite;
111
  protected
112
    procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
113
    procedure DoMove(MoveCount: Integer); override;
114
  public
115
    constructor Create(AParent: TSprite); override;
116
    destructor Destroy; override;
117
  end;
118
 
7 daniel-mar 119
  TEnemyClass = class of TEnemy;
3 daniel-mar 120
  TEnemy = class(TImageSprite)
121
  private
122
    FCounter: Integer;
123
    FLife: integer;
124
    FMode: Integer;
125
  protected
126
    procedure HitEnemy(ADead: Boolean); virtual;
127
  public
7 daniel-mar 128
    procedure Hit(AHitStrength: integer = 1);
11 daniel-mar 129
    constructor Create(AParent: TSprite; ALifes: integer); reintroduce; virtual;
3 daniel-mar 130
    destructor Destroy; override;
131
  end;
132
 
133
  TEnemyTama = class(TImageSprite)
134
  private
135
    FPlayerSprite: TSprite;
136
  protected
137
    procedure DoMove(MoveCount: Integer); override;
138
  public
139
    constructor Create(AParent: TSprite); override;
140
  end;
141
 
142
  TEnemyMeteor = class(TEnemy)
143
  protected
144
    procedure DoMove(MoveCount: Integer); override;
145
    procedure HitEnemy(ADead: Boolean); override;
146
  public
7 daniel-mar 147
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 148
  end;
149
 
150
  TEnemyUFO = class(TEnemy)
151
  protected
152
    procedure DoMove(MoveCount: Integer); override;
153
    procedure HitEnemy(ADead: Boolean); override;
154
  public
7 daniel-mar 155
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 156
  end;
157
 
158
  TEnemyUFO2 = class(TEnemy)
159
  private
160
    FCounter: Integer;
161
    FTamaCount: Integer;
162
    FOldTamaTime: Integer;
163
  protected
164
    procedure DoMove(MoveCount: Integer); override;
165
    procedure HitEnemy(ADead: Boolean); override;
166
  public
7 daniel-mar 167
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 168
  end;
169
 
170
  TEnemyAttacker = class(TEnemy)
171
  protected
172
    procedure DoMove(MoveCount: Integer); override;
173
    procedure HitEnemy(ADead: Boolean); override;
174
  public
7 daniel-mar 175
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 176
  end;
177
 
178
  TEnemyAttacker2 = class(TEnemy)
179
  private
180
    FCounter: Integer;
181
    FTamaF: Integer;
182
    FTamaT: Integer;
183
    FPutTama: Boolean;
184
  protected
185
    procedure DoMove(MoveCount: Integer); override;
186
    procedure HitEnemy(ADead: Boolean); override;
187
  public
7 daniel-mar 188
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 189
  end;
190
 
191
  TEnemyAttacker3 = class(TEnemy)
192
  private
193
    FCounter: Integer;
194
    FTamaCount: Integer;
195
    FOldTamaTime: Integer;
196
  protected
197
    procedure DoMove(MoveCount: Integer); override;
198
    procedure HitEnemy(ADead: Boolean); override;
199
  public
7 daniel-mar 200
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 201
  end;
202
 
203
  TEnemyBoss = class(TEnemy)
204
  private
205
    FCounter: Integer;
206
    FTamaF: Integer;
207
    FTamaT: Integer;
208
    FPutTama: Boolean;
209
    waiter1, waiter2: integer;
210
  protected
211
    procedure DoMove(MoveCount: Integer); override;
212
    procedure HitEnemy(ADead: Boolean); override;
213
  public
7 daniel-mar 214
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 215
  end;
216
 
217
  TMainForm = class(TDXForm)
218
    MainMenu: TMainMenu;
219
    Spiel: TMenuItem;
220
    GameStart: TMenuItem;
221
    GamePause: TMenuItem;
222
    Beenden: TMenuItem;
223
    Einstellungen: TMenuItem;
224
    OptionFullScreen: TMenuItem;
225
    OptionMusic: TMenuItem;
226
    Leer2: TMenuItem;
227
    Leer4: TMenuItem;
228
    Hilfe: TMenuItem;
229
    OptionSound: TMenuItem;
230
    Leer3: TMenuItem;
231
    Spielstand: TMenuItem;
232
    Leer5: TMenuItem;
233
    Neustart: TMenuItem;
234
    OptionBreitbild: TMenuItem;
235
    Spielgeschwindigkeit: TMenuItem;
236
    Leicht: TMenuItem;
237
    Mittel: TMenuItem;
238
    Schwer: TMenuItem;
239
    Informationen: TMenuItem;
240
    Leer6: TMenuItem;
241
    Leer1: TMenuItem;
242
    Cheat: TMenuItem;
243
    CheckUpdates: TMenuItem;
244
    Master: TMenuItem;
245
    procedure DXDrawFinalize(Sender: TObject);
246
    procedure DXDrawInitialize(Sender: TObject);
247
    procedure FormCreate(Sender: TObject);
248
    procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
249
    procedure DXTimerActivate(Sender: TObject);
250
    procedure DXTimerDeactivate(Sender: TObject);
251
    procedure OptionFullScreenClick(Sender: TObject);
252
    procedure DXDrawInitializing(Sender: TObject);
253
    procedure GameStartClick(Sender: TObject);
254
    procedure GamePauseClick(Sender: TObject);
255
    procedure BeendenClick(Sender: TObject);
256
    procedure OptionSoundClick(Sender: TObject);
257
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
258
    procedure OptionMusicClick(Sender: TObject);
259
    procedure SpielstandClick(Sender: TObject);
260
    procedure NeustartClick(Sender: TObject);
261
    procedure OptionBreitbildClick(Sender: TObject);
262
    procedure LeichtClick(Sender: TObject);
263
    procedure MittelClick(Sender: TObject);
264
    procedure SchwerClick(Sender: TObject);
265
    procedure FormShow(Sender: TObject);
266
    procedure InformationenClick(Sender: TObject);
267
    procedure CheatClick(Sender: TObject);
268
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
269
    procedure FormDestroy(Sender: TObject);
270
    procedure CheckUpdatesClick(Sender: TObject);
271
    procedure MasterClick(Sender: TObject);
272
  private
273
    ProgrammGestartet: boolean;
274
    FInterval: TGameInterval;
275
    FScene: TGameScene;
276
    FMusic: TMusicTrack;
277
    FBlink: DWORD;
278
    FBlinkTime: DWORD;
279
    FFrame, FAngle, FCounter, FEnemyAdventPos: Integer;
280
    PlayerSprite: TPlayerSprite;
7 daniel-mar 281
    TimerCS: TRTLCriticalSection;
14 daniel-mar 282
    LevelData: TLevelData;
3 daniel-mar 283
    procedure StartScene(Scene: TGameScene);
284
    procedure EndScene;
285
    procedure BlinkStart;
286
    procedure BlinkUpdate;
287
    procedure StartSceneTitle;
288
    procedure SceneTitle;
289
    procedure EndSceneTitle;
290
    procedure StartSceneMain;
291
    procedure SceneMain;
292
    procedure EndSceneMain;
293
    procedure StartSceneGameOver;
294
    procedure SceneGameOver;
295
    procedure EndSceneGameOver;
296
    procedure StartSceneWin;
297
    procedure SceneWin;
298
    procedure EndSceneWin;
299
    procedure StartSceneNewLevel;
300
    procedure SceneNewLevel;
301
    procedure EndSceneNewLevel;
302
  public
303
    FNextScene: TGameScene;
304
    FScore: Integer;
305
    FNotSave: boolean;
306
    FLife: integer;
307
    FLevel: integer;
15 daniel-mar 308
    FGameMode: TGameMode;
3 daniel-mar 309
    FBossLife: integer;
7 daniel-mar 310
    FRestEnemies: integer;
3 daniel-mar 311
    FCheat: boolean;
312
    { VCL-Ersatz }
313
    dxdraw: TDxDraw;
314
    imagelist: TDxImageList;
315
    spriteengine: tdxspriteengine;
316
    dxsound: tdxsound;
317
    wavelist: tdxwavelist;
318
    dxinput: tdxinput;
319
    dxtimer: tdxtimer;
320
    { Level-Routinen }
321
    procedure NewLevel(lev: integer);
14 daniel-mar 322
    procedure ResetLevelData;
3 daniel-mar 323
    { MCI-Routinen }
324
    function StatusMusic(Name: TMusicTrack): string;
325
    procedure PlayMusic(Name: TMusicTrack);
326
    //procedure StopMusic(Name: TMusicTrack);
327
    procedure PauseMusic(Name: TMusicTrack);
328
    procedure ResumeMusic(Name: TMusicTrack);
329
    procedure DestroyMusic(Name: TMusicTrack);
330
    procedure OpenMusic(Name: TMusicTrack);
331
    { Sound-Routinen }
332
    function SoundKarte: boolean;
333
    procedure PlaySound(Name: string; Wait: Boolean);
334
    { Initialisiations-Routinen }
335
    procedure DXInit;
336
    procedure SoundInit;
337
    procedure MusicInit;
338
    { Einstellungs-Routinen }
339
    procedure LoadOptions;
340
    procedure WriteOptions;
341
    { Farb-Routinen }
342
    function ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
343
    procedure PalleteAnim(Col: TRGBQuad; Time: Integer);
344
  end;
345
 
346
var
347
  MainForm: TMainForm;
348
 
7 daniel-mar 349
implementation
350
 
351
uses
352
  GamSplash, GamSpeicherung, ComInfo, GamCheat, Global;
353
 
3 daniel-mar 354
const
4 daniel-mar 355
  // TODO: ini file
3 daniel-mar 356
  conleicht = 650 div 60; // 10
357
  conmittel = 1000 div 60; // 16
358
  conschwer = 1350 div 60; // 22
359
  conmaster = 2000 div 60; // 33
360
  lives = 6;
361
 
7 daniel-mar 362
  // TODO: Auch für Enemies
363
  PLAYER_MODE_NORMAL = 0;
364
  PLAYER_MODE_DEAD = 1;
365
  PLAYER_MODE_DEAD_VANISHED = 2;
366
  PLAYER_MODE_FLYAWAY = 3;
367
  PLAYER_MODE_ENTER = 4;
3 daniel-mar 368
 
7 daniel-mar 369
  DEFAULT_ANIMSPEED = 15/1000;
3 daniel-mar 370
 
371
resourcestring
372
  FileError = 'Die Datei kann von SpaceMission nicht geöffnet werden!';
373
 
374
{$R *.DFM}
375
 
376
var // TODO: irgendwo hinpacken. irgendwo!!!
7 daniel-mar 377
  Crash2, EnemyCounter: integer;
3 daniel-mar 378
  BossExists, Crash, crashsound: boolean;
379
 
380
const
381
  DXInputButton = [isButton1, isButton2, isButton3,
382
    isButton4, isButton5, isButton6, isButton7, isButton8, isButton9, isButton10, isButton11,
383
    isButton12, isButton13, isButton14, isButton15, isButton16, isButton17, isButton18,
384
    isButton19, isButton20, isButton21, isButton22, isButton23, isButton24, isButton25,
385
    isButton26, isButton27, isButton28, isButton29, isButton30, isButton31, isButton32];
386
 
387
// TODO: Code komplett überarbeiten. Bessere Ableitungen machen
388
 
389
constructor TPlayerSprite.Create(AParent: TSprite);
390
begin
391
  inherited Create(AParent);
392
  Image := MainForm.ImageList.Items.Find('Machine');
393
  Width := Image.Width;
394
  Height := Image.Height;
395
  X := -70{20};
396
  Y := mainform.dxdraw.surfaceHeight / 2 - (height / 2);
397
  Z := 2;
398
  AnimCount := Image.PatternCount;
399
  AnimLooped := True;
4 daniel-mar 400
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 401
  FMode := PLAYER_MODE_ENTER;
402
end;
403
 
404
procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
405
begin
406
  if mainform.FCheat then exit;
407
  if (Sprite is TEnemy) or (Sprite is TEnemyTama) then
408
  begin
409
    if not crash then
410
    begin
411
      dec(MainForm.FLife);
412
      Crash := true;
413
      if MainForm.Flife=0 then
414
      begin
415
        MainForm.PlaySound('Explosion', false);
416
        Collisioned := false;
417
        FCounter := 0;
418
        FMode := PLAYER_MODE_DEAD;
419
        Done := false;
420
        Image := MainForm.ImageList.Items.Find('Explosion');
421
        Width := Image.Width;
422
        Height := Image.Height;
423
        AnimCount := Image.PatternCount;
424
        AnimLooped := False;
4 daniel-mar 425
        AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 426
        AnimPos := 0;
427
      end;
428
    end
429
    else
430
    begin
431
      if not crashsound then
432
      begin
433
        MainForm.PlaySound('Hit', False);
434
        crashsound := true;
435
      end;
436
    end;
437
  end;
438
end;
439
 
440
procedure TPlayerSprite.DoMove(MoveCount: Integer);
441
const
442
  WegduesKonstante = 1.75;
443
begin
444
  inherited DoMove(MoveCount);
445
  if FMode=PLAYER_MODE_NORMAL then
446
  begin
447
    if isUp in MainForm.DXInput.States then Y := Y - (250/1000)*MoveCount;
448
    if isDown in MainForm.DXInput.States then Y := Y + (250/1000)*MoveCount;
449
    if isLeft in MainForm.DXInput.States then X := X - (250/1000)*MoveCount;
450
    if isRight in MainForm.DXInput.States then X := X + (250/1000)*MoveCount;
451
    if X<0 then X := 0;
452
    if X>mainform.dxdraw.surfacewidth-Width then X := mainform.dxdraw.surfacewidth-Width;
453
    if Y<0 then Y := 0;
454
    if Y>mainform.dxdraw.surfaceheight-Height then Y := mainform.dxdraw.surfaceheight-Height;
455
    if isButton1 in MainForm.DXInput.States then
456
    begin
457
      if (FTamaCount<8) and (FCounter-FOldTamaTime>=100) then
458
      begin
459
        Inc(FTamaCount);
460
        with TTamaSprite.Create(Engine) do
461
        begin
462
          FPlayerSprite := Self;
463
          X := Self.X+Self.Width;
464
          Y := Self.Y+Self.Height div 2-Height div 2;
465
          Z := 10;
466
        end;
467
        FOldTamaTime := FCounter;
468
      end;
469
    end;
470
    Collision;
7 daniel-mar 471
  end
472
  else if FMode=PLAYER_MODE_DEAD then
3 daniel-mar 473
  begin
474
    if FCounter>200 then
475
    begin
476
      FCounter := 0;
477
      FMode := PLAYER_MODE_DEAD_VANISHED;
478
      Visible := false;
479
    end;
7 daniel-mar 480
  end
481
  else if FMode=PLAYER_MODE_DEAD_VANISHED then
3 daniel-mar 482
  begin
483
    if FCounter>1500 then
484
    begin
485
      MainForm.FNextScene := gsGameOver;
486
      MainForm.PlaySound('SceneMov', false);
487
      MainForm.PalleteAnim(RGBQuad(0, 0, 0), 300);
488
      Sleep(200);
489
    end;
7 daniel-mar 490
  end
491
  else if FMode=PLAYER_MODE_FLYAWAY then
3 daniel-mar 492
  begin
493
    // FUT: "Wusch" sound?
494
    X := X + MoveCount*(300/1000) * (X/MainForm.DXDraw.Width + WegduesKonstante);
495
    if X > MainForm.DXDraw.Width+Width then
496
    begin
497
      Dead;
498
      inc(mainform.FLevel);
499
      MainForm.FNextScene := gsNewLevel;
500
      MainForm.PlaySound('SceneMov', false);
501
      MainForm.PalleteAnim(RGBQuad(0, 0, 0), 300);
502
    end;
7 daniel-mar 503
  end
504
  else if FMode = PLAYER_MODE_ENTER then
3 daniel-mar 505
  begin
506
    X := X + MoveCount*(300/1000);
507
    if X > 19 then FMode := PLAYER_MODE_NORMAL;
508
  end;
509
  inc(FCounter, MoveCount);
510
end;
511
 
512
procedure TPlayerSprite.FlyAway;
513
begin
514
  FMode := PLAYER_MODE_FLYAWAY;
515
end;
516
 
517
procedure TMainForm.DXInit;
518
begin
519
  try
520
    Imagelist.Items.LoadFromFile(FDirectory+'DirectX\Graphic.dxg');
521
    ImageList.Items.MakeColorTable;
522
    DXDraw.ColorTable := ImageList.Items.ColorTable;
523
    DXDraw.DefColorTable := ImageList.Items.ColorTable;
524
    DXDraw.UpdatePalette;
525
    OptionBreitBild.enabled := OptionFullScreen.checked;
526
    DXDraw.Finalize;
527
    if OptionFullScreen.Checked then
528
    begin
529
      if not (doFullScreen in DXDraw.Options) then StoreWindow;
530
      DXDraw.Options := DXDraw.Options + [doFullScreen];
7 daniel-mar 531
    end
532
    else
3 daniel-mar 533
    begin
534
      if doFullScreen in DXDraw.Options then RestoreWindow;
535
      DXDraw.Options := DXDraw.Options - [doFullScreen];
536
    end;
537
    if not OptionBreitBild.checked then
538
    begin
539
      dxdraw.autosize := false;
540
      dxdraw.Top := 0;
541
      dxdraw.Left := 0;
4 daniel-mar 542
      dxdraw.width := 640;    // TODO: besser die dimensionen des fensters
3 daniel-mar 543
      dxdraw.height := 480;
544
      dxdraw.surfacewidth := 640;
545
      dxdraw.surfaceheight := 480;
546
    end
547
    else dxdraw.autosize := true;
548
    DXDraw.Initialize;
549
  except
550
    //Imagelist.Items.clear;
551
    //application.terminate;
552
  end;
553
end;
554
 
555
constructor TTamaSprite.Create(AParent: TSprite);
556
begin
557
  inherited Create(AParent);
558
  Image := MainForm.ImageList.Items.Find('Bounce');
559
  Z := 2;
560
  Width := Image.Width;
561
  Height := Image.Height;
562
  AnimCount := Image.PatternCount;
563
  AnimLooped := True;
4 daniel-mar 564
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 565
  MainForm.PlaySound('Shoot', False);
566
end;
567
 
568
destructor TTamaSprite.Destroy;
569
begin
570
  inherited Destroy;
571
  Dec(FPlayerSprite.FTamaCount);
572
end;
573
 
574
procedure TTamaSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
575
begin
7 daniel-mar 576
  if (Sprite is TEnemy) and not (Sprite is TEnemyTama) then
3 daniel-mar 577
  begin
578
    TEnemy(Sprite).Hit;
579
    Dead;
580
  end;
581
  Done := False;
582
end;
583
 
584
procedure TTamaSprite.DoMove(MoveCount: Integer);
585
begin
586
  inherited DoMove(MoveCount);
587
  X := X+(800/1000)*MoveCount;
588
  if X>=mainform.dxdraw.surfacewidth then Dead;
589
  Collision;
590
end;
591
 
592
procedure TBackground.DoMove(MoveCount: Integer);
593
var
594
  ran: integer;
595
begin
596
  inherited DoMove(MoveCount);
597
  X := X - MoveCount*(60/1000)*FSpeed;
598
  randomize;
599
  ran := Random(1500);
600
  if ran = 150 then
601
  begin
602
    with TBackgroundSpecial.Create(mainform.SpriteEngine.Engine) do
603
    begin
604
      SetMapSize(1, 1);
605
      Image := mainform.ImageList.Items.Find('Background-Planet1');
606
      Width := Image.Width;
607
      Height := Image.Height;
608
 
609
      Y := random(mainform.dxdraw.height);
610
      X := mainform.dxdraw.width;
611
 
612
      ran := Random(2);
613
      if ran = 0 then
614
      begin
615
        Z := -20;
616
        FSpeed := 1.8;
617
      end
618
      else if ran = 1 then
619
      begin
620
        Z := -40;
621
        FSpeed := 0.8;
622
      end
623
      else if ran = 2 then
624
      begin
625
        Z := -60;
626
        FSpeed := 0.3;
627
      end;
628
    end;
629
  end
630
  else if ran = 500 then
631
  begin
632
    with TBackgroundSpecial.Create(mainform.SpriteEngine.Engine) do
633
    begin
634
      SetMapSize(1, 1);
635
      ran := Random(4);
636
      if ran = 0 then
637
        Image := mainform.ImageList.Items.Find('Background-Red')
638
      else if ran = 1 then
639
        Image := mainform.ImageList.Items.Find('Background-Blue')
640
      else if ran = 2 then
641
        Image := mainform.ImageList.Items.Find('Background-Yellow')
642
      else if ran = 3 then
643
        Image := mainform.ImageList.Items.Find('Hintergrund-Rot');
644
      Width := Image.Width;
645
      Height := Image.Height;
646
 
647
      Y := random(mainform.dxdraw.height);
648
      X := mainform.dxdraw.width;
649
 
650
      { ran := Random(2);
651
      if ran = 0 then
652
      begin
653
        Z := -20;
654
        FSpeed := 1.8;
655
      end
656
      else if ran = 1 then
657
      begin
658
        Z := -40;
659
        FSpeed := 0.8;
660
      end
661
      else if ran = 2 then
662
      begin }
663
        Z := -60;
664
        FSpeed := 0.3;
665
      { end; }
666
    end;
667
  end;
668
end;
669
 
670
procedure TBackgroundSpecial.DoMove(MoveCount: Integer);
671
begin
672
  inherited DoMove(MoveCount);
673
  X := X - MoveCount*(60/1000)*FSpeed;
674
  if X<-Width then Dead;
675
end;
676
 
677
constructor TExplosion.Create(AParent: TSprite);
678
begin
679
  inherited Create(AParent);
680
  mainform.PlaySound('Explosion', false);
681
  Image := MainForm.ImageList.Items.Find('Explosion');
682
  Width := Image.Width;
683
  Height := Image.Height;
684
  AnimCount := Image.PatternCount;
685
  AnimLooped := True;
4 daniel-mar 686
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 687
  AnimPos := Random(AnimCount);
688
end;
689
 
690
procedure TExplosion.DoMove(MoveCount: Integer);
691
begin
692
  inherited DoMove(MoveCount);
693
  inc(FCounter, MoveCount);
694
  if FCounter > 2999 then dead;
695
end;
696
 
697
constructor TEnemyTama.Create(AParent: TSprite);
698
begin
699
  inherited Create(AParent);
700
  Image := MainForm.ImageList.Items.Find('Bounce2');
701
  Width := Image.Width;
702
  Height := Image.Height;
703
  AnimCount := Image.PatternCount;
704
  AnimLooped := True;
4 daniel-mar 705
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 706
  MainForm.PlaySound('Shoot', False);
707
end;
708
 
709
procedure TEnemyTama.DoMove(MoveCount: Integer);
710
begin
711
  inherited DoMove(MoveCount);
712
  X := X - MoveCount*(600/1000);
713
  if X<-Width then Dead;
714
end;
715
 
7 daniel-mar 716
procedure TEnemy.Hit(AHitStrength: integer = 1);
3 daniel-mar 717
begin
7 daniel-mar 718
  Dec(FLife, AHitStrength);
3 daniel-mar 719
  if FLife<=0 then
720
  begin
721
    Collisioned := False;
722
    HitEnemy(True);
723
  end
724
  else
725
    HitEnemy(False);
726
end;
727
 
728
procedure TEnemy.HitEnemy(ADead: Boolean);
729
begin
7 daniel-mar 730
  if ADead then
731
    MainForm.PlaySound('Explosion', False)
732
  else
733
    MainForm.PlaySound('Hit', False);
3 daniel-mar 734
end;
735
 
7 daniel-mar 736
constructor TEnemyUFO.Create(AParent: TSprite; ALifes: integer);
3 daniel-mar 737
begin
7 daniel-mar 738
  inherited Create(AParent, ALifes);
3 daniel-mar 739
  Image := MainForm.ImageList.Items.Find('Enemy-disk');
740
  Width := Image.Width;
741
  Height := Image.Height;
742
  AnimCount := Image.PatternCount;
743
  AnimLooped := True;
4 daniel-mar 744
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 745
end;
746
 
7 daniel-mar 747
constructor TEnemy.Create(AParent: TSprite; ALifes: integer);
3 daniel-mar 748
begin
749
  inherited Create(AParent);
7 daniel-mar 750
  FLife := ALifes;
751
  inc(EnemyCounter);
3 daniel-mar 752
end;
753
 
754
destructor TEnemy.Destroy;
755
begin
756
  inherited Destroy;
7 daniel-mar 757
  dec(EnemyCounter);
3 daniel-mar 758
end;
759
 
760
procedure TEnemyUFO.HitEnemy(ADead: Boolean);
761
begin
7 daniel-mar 762
  inherited HitEnemy(ADead);
763
 
3 daniel-mar 764
  if ADead then
765
  begin
766
    FMode := 2;
767
    FCounter := 0;
768
    Inc(MainForm.FScore, 1000);
769
    Image := MainForm.ImageList.Items.Find('Explosion');
770
    Width := Image.Width;
771
    Height := Image.Height;
772
    AnimCount := Image.PatternCount;
773
    AnimLooped := False;
4 daniel-mar 774
    AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 775
    AnimPos := 0;
7 daniel-mar 776
  end
777
  else
3 daniel-mar 778
  begin
779
    Inc(MainForm.FScore, 100);
780
  end;
781
end;
782
 
783
procedure TEnemyUFO2.DoMove(MoveCount: Integer);
784
begin
785
  inherited DoMove(MoveCount);
786
  if FMode=0 then
787
  begin
788
    X := X - MoveCount*(300/1000);
789
    Y := Y + Cos256(FCounter div 15)*2;
790
    if X<-Width then Dead;
791
    if FCounter-FOldTamaTime>=100 then
792
    begin
793
      Inc(FTamaCount);
794
      with TEnemyTama.Create(Engine) do
795
      begin
796
        FPlayerSprite := Self;
797
        X := Self.X;
798
        Y := Self.Y+Self.Height div 2-Height div 2;
799
        Z := 10;
800
      end;
801
      FOldTamaTime := FCounter;
802
    end;
7 daniel-mar 803
  end
804
  else if FMode=2 then
3 daniel-mar 805
  begin
806
    X := X - MoveCount*(300/1000);
807
    if FCounter>200 then Dead;
808
  end;
809
  inc(FCounter, MoveCount);
810
end;
811
 
812
procedure TEnemyUFO2.HitEnemy(ADead: Boolean);
813
begin
7 daniel-mar 814
  inherited HitEnemy(ADead);
815
 
3 daniel-mar 816
  if ADead then
817
  begin
818
    FMode := 2;
819
    FCounter := 0;
820
    Inc(MainForm.FScore, 1000);
821
    Image := MainForm.ImageList.Items.Find('Explosion');
822
    Width := Image.Width;
823
    Height := Image.Height;
824
    AnimCount := Image.PatternCount;
825
    AnimLooped := False;
4 daniel-mar 826
    AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 827
    AnimPos := 0;
7 daniel-mar 828
  end
829
  else
3 daniel-mar 830
  begin
831
    Inc(MainForm.FScore, 100);
832
  end;
833
end;
834
 
7 daniel-mar 835
constructor TEnemyUFO2.Create(AParent: TSprite; ALifes: integer);
3 daniel-mar 836
begin
7 daniel-mar 837
  inherited Create(AParent, ALifes);
3 daniel-mar 838
  Image := MainForm.ImageList.Items.Find('Enemy-disk2');
839
  Width := Image.Width;
840
  Height := Image.Height;
841
  AnimCount := Image.PatternCount;
842
  AnimLooped := True;
4 daniel-mar 843
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 844
end;
845
 
846
procedure TEnemyUFO.DoMove(MoveCount: Integer);
847
begin
848
  inherited DoMove(MoveCount);
849
  if FMode=0 then
850
  begin
851
    X := X - MoveCount*(300/1000);
852
    Y := Y + Cos256(FCounter div 15)*2;
853
    if X<-Width then Dead;
7 daniel-mar 854
  end
855
  else if FMode=2 then
3 daniel-mar 856
  begin
857
    X := X - MoveCount*(300/1000);
858
    if FCounter>200 then Dead;
859
  end;
860
  inc(FCounter, MoveCount);
861
end;
862
 
7 daniel-mar 863
constructor TEnemyAttacker.Create(AParent: TSprite; ALifes: integer);
3 daniel-mar 864
begin
7 daniel-mar 865
  inherited Create(AParent, ALifes);
3 daniel-mar 866
  Image := MainForm.ImageList.Items.Find('Enemy-Attacker');
867
  Width := Image.Width;
868
  Height := Image.Height;
869
  AnimCount := Image.PatternCount;
870
  AnimLooped := True;
4 daniel-mar 871
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 872
  PixelCheck := True;
873
end;
874
 
875
procedure TEnemyAttacker.HitEnemy(ADead: Boolean);
876
begin
7 daniel-mar 877
  inherited HitEnemy(ADead);
878
 
3 daniel-mar 879
  if ADead then
880
  begin
881
    FMode := 2;
882
    FCounter := 0;
883
    Inc(MainForm.FScore, 1000);
884
    Image := MainForm.ImageList.Items.Find('Explosion');
885
    Width := Image.Width;
886
    Height := Image.Height;
887
    AnimCount := Image.PatternCount;
888
    AnimLooped := False;
4 daniel-mar 889
    AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 890
    AnimPos := 0;
7 daniel-mar 891
  end
892
  else
3 daniel-mar 893
  begin
894
    Inc(MainForm.FScore, 100);
895
  end;
896
end;
897
 
898
procedure TEnemyAttacker.DoMove(MoveCount: Integer);
899
begin
900
  inherited DoMove(MoveCount);
901
  if FMode=0 then
902
  begin
903
    X := X - MoveCount*(300/1000)-FCounter div 128;
904
    if X < -Width then Dead;
7 daniel-mar 905
  end
906
  else if FMode=2 then
3 daniel-mar 907
  begin
908
    X := X - MoveCount*(300/1000);
909
    if FCounter>200 then Dead;
910
  end;
911
  inc(FCounter, MoveCount);
912
end;
913
 
7 daniel-mar 914
constructor TEnemyBoss.Create(AParent: TSprite; ALifes: integer);
3 daniel-mar 915
begin
7 daniel-mar 916
  inherited Create(AParent, ALifes);
3 daniel-mar 917
  Image := MainForm.ImageList.Items.Find('Enemy-boss');
918
  Width := Image.Width;
919
  Height := Image.Height;
920
  BossExists := true;
921
  MainForm.PlayMusic(mtBoss);
922
  AnimCount := Image.PatternCount;
923
  AnimLooped := True;
4 daniel-mar 924
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 925
  PixelCheck := True;
926
  Collisioned := False;
927
  MainForm.FBossLife := FLife;
928
  waiter1 := 0;
929
  waiter2 := 0;
930
end;
931
 
932
procedure TEnemyBoss.HitEnemy(ADead: Boolean);
933
begin
7 daniel-mar 934
  inherited HitEnemy(ADead);
935
 
3 daniel-mar 936
  if ADead then
937
  begin
938
    FMode := 2;
939
    FCounter := 0;
940
    Inc(MainForm.FScore, 100000);
941
    BossExists := false;
942
    dec(MainForm.FBossLife);
7 daniel-mar 943
  end
944
  else
3 daniel-mar 945
  begin
946
    Inc(MainForm.FScore, 100);
947
    dec(MainForm.FBossLife);
948
  end;
949
end;
950
 
951
procedure TEnemyBoss.DoMove(MoveCount: Integer);
952
begin
953
  inherited DoMove(MoveCount);
954
  if FMode=0 then
955
  begin
956
    if X>((mainform.dxdraw.width/4) + (mainform.dxdraw.width/2) - (width/4)){450} then
957
      X := X - MoveCount*(300/1000)
958
    else
959
    begin
960
      Collisioned := True;
961
      FMode := 1;
962
      FPutTama := True;
963
    end;
964
    Y := Y + Cos256(FCounter div 15)*5;
7 daniel-mar 965
  end
966
  else if FMode=1 then
3 daniel-mar 967
  begin
968
    Y := Y + Cos256(FCounter div 15)*5;
969
    if FPutTama then
970
    begin
971
      if FTamaT>100 then
972
      begin
973
        with TEnemyTama.Create(Engine) do
974
        begin
975
          FPlayerSprite := Self;
976
          Z := 1;
977
          X := Self.X-Width;
978
          Y := Self.Y+Self.Height div 2-Height div 2;
979
        end;
980
        Inc(FTamaF);
981
        if FTamaF>Random(30) then FPutTama := False;
982
        FTamaT := 0;
983
      end;
984
      FTamaT := FTamaT + MoveCount;
7 daniel-mar 985
    end
986
    else
3 daniel-mar 987
    begin
988
      FTamaT := FTamaT + MoveCount;
989
      if FTamaT>2000+Random(500) then
990
      begin
991
        FPutTama := True;
992
        FTamaF := 0;
993
        FTamaT := 0;
994
      end;
995
    end;
7 daniel-mar 996
  end
997
  else if FMode=2 then
3 daniel-mar 998
  begin
999
    inc(waiter1);
1000
    if waiter1 = 3 then
1001
    begin
1002
      waiter1 := 0;
1003
      inc(waiter2);
1004
      if waiter2 <= 20 then
1005
      begin
1006
        with TExplosion.Create(Engine) do
1007
        begin
1008
          Z := 10;
1009
          X := Self.X+Random(Self.Width)-16;
1010
          Y := Self.Y+Random(Self.Height)-16;
1011
        end;
1012
      end
1013
      else
1014
      begin
1015
        Inc(MainForm.FScore, 1000);
1016
        FMode := 3;
1017
      end;
1018
    end;
7 daniel-mar 1019
  end
1020
  else if FMode=3 then
3 daniel-mar 1021
  begin
7 daniel-mar 1022
    if FCounter>4000 then Dead;
3 daniel-mar 1023
  end;
1024
  inc(FCounter, MoveCount);
1025
end;
1026
 
7 daniel-mar 1027
constructor TEnemyAttacker2.Create(AParent: TSprite; ALifes: integer);
3 daniel-mar 1028
begin
7 daniel-mar 1029
  inherited Create(AParent, ALifes);
3 daniel-mar 1030
  Image := MainForm.ImageList.Items.Find('Enemy-Attacker2');
1031
  Width := Image.Width;
1032
  Height := Image.Height;
1033
  AnimCount := Image.PatternCount;
1034
  AnimLooped := True;
4 daniel-mar 1035
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 1036
  PixelCheck := True;
1037
end;
1038
 
1039
procedure TEnemyAttacker2.HitEnemy(ADead: Boolean);
1040
begin
7 daniel-mar 1041
  inherited HitEnemy(ADead);
1042
 
3 daniel-mar 1043
  if ADead then
1044
  begin
1045
    FMode := 2;
1046
    FCounter := 0;
1047
    Inc(MainForm.FScore, 5000);
1048
    Image := MainForm.ImageList.Items.Find('Explosion');
1049
    Width := Image.Width;
1050
    Height := Image.Height;
1051
    AnimCount := Image.PatternCount;
1052
    AnimLooped := False;
4 daniel-mar 1053
    AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 1054
    AnimPos := 0;
7 daniel-mar 1055
  end
1056
  else
3 daniel-mar 1057
  begin
1058
    Inc(MainForm.FScore, 100);
1059
  end;
1060
end;
1061
 
1062
procedure TEnemyAttacker2.DoMove(MoveCount: Integer);
1063
begin
1064
  inherited DoMove(MoveCount);
1065
  if FMode=0 then
1066
  begin
1067
    if X>((mainform.dxdraw.width/4) + (mainform.dxdraw.width/2) - (width/2)){450} then
1068
      X := X - MoveCount*(300/1000)
1069
    else
1070
    begin
1071
      Collisioned := True;
1072
      FMode := 1;
1073
      FPutTama := True;
1074
    end;
1075
    Y := Y + Cos256(FCounter div 15)*5;
7 daniel-mar 1076
  end
1077
  else if FMode=1 then
3 daniel-mar 1078
  begin
1079
    Y := Y + Cos256(FCounter div 15)*5;
1080
    if FPutTama then
1081
    begin
1082
      if FTamaT>100 then
1083
      begin
1084
        with TEnemyTama.Create(Engine) do
1085
        begin
1086
          FPlayerSprite := Self;
1087
          Z := 1;
1088
          X := Self.X-Width;
1089
          Y := Self.Y+Self.Height div 2-Height div 2;
1090
        end;
1091
        Inc(FTamaF);
1092
        if FTamaF>Random(30) then FPutTama := False;
1093
        FTamaT := 0;
1094
      end;
1095
      FTamaT := FTamaT + MoveCount;
7 daniel-mar 1096
    end
1097
    else
3 daniel-mar 1098
    begin
1099
      FTamaT := FTamaT + MoveCount;
1100
      if FTamaT>2000+Random(500) then
1101
      begin
1102
        FPutTama := True;
1103
        FTamaF := 0;
1104
        FTamaT := 0;
1105
      end;
1106
    end;
7 daniel-mar 1107
  end
1108
  else if FMode=2 then
3 daniel-mar 1109
  begin
1110
    if FCounter>200 then Dead;
1111
  end;
1112
  inc(FCounter, MoveCount);
1113
end;
1114
 
1115
procedure TEnemyAttacker3.HitEnemy(ADead: Boolean);
1116
begin
7 daniel-mar 1117
  inherited HitEnemy(ADead);
1118
 
3 daniel-mar 1119
  if ADead then
1120
  begin
1121
    FMode := 1;
1122
    FCounter := 0;
1123
    Inc(MainForm.FScore, 5000);
1124
    Image := MainForm.ImageList.Items.Find('Explosion');
1125
    Width := Image.Width;
1126
    Height := Image.Height;
1127
    AnimCount := Image.PatternCount;
1128
    AnimLooped := False;
4 daniel-mar 1129
    AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 1130
    AnimPos := 0;
7 daniel-mar 1131
  end
1132
  else
3 daniel-mar 1133
  begin
1134
    Inc(MainForm.FScore, 100);
1135
  end;
1136
end;
1137
 
1138
procedure TEnemyAttacker3.DoMove(MoveCount: Integer);
1139
begin
1140
  inherited DoMove(MoveCount);
1141
  if FMode=0 then
1142
  begin
1143
    X := X - (250/1000)*MoveCount;
1144
    if X<-Width then Dead;
1145
    if FCounter-FOldTamaTime>=100 then
1146
    begin
1147
      Inc(FTamaCount);
1148
      with TEnemyTama.Create(Engine) do
1149
      begin
1150
        FPlayerSprite := Self;
1151
        X := Self.X;
1152
        Y := Self.Y+Self.Height div 2-Height div 2;
1153
        Z := 10;
1154
      end;
1155
      FOldTamaTime := FCounter;
1156
     end;
7 daniel-mar 1157
  end
1158
  else if FMode=1 then
3 daniel-mar 1159
  begin
1160
    if FCounter>200 then Dead;
1161
  end;
1162
  inc(FCounter, MoveCount);
1163
end;
1164
 
7 daniel-mar 1165
constructor TEnemyAttacker3.Create(AParent: TSprite; ALifes: integer);
3 daniel-mar 1166
begin
7 daniel-mar 1167
  inherited Create(AParent, ALifes);
3 daniel-mar 1168
  Image := MainForm.ImageList.Items.Find('Enemy-Attacker3');
1169
  Width := Image.Width;
1170
  Height := Image.Height;
1171
  AnimCount := Image.PatternCount;
1172
  AnimLooped := True;
4 daniel-mar 1173
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 1174
  PixelCheck := True;
1175
end;
1176
 
1177
function TMainForm.SoundKarte: boolean;
1178
begin
1179
  result := WaveOutGetNumDevs > 0;
1180
end;
1181
 
1182
procedure TMainForm.FormCreate(Sender: TObject);
1183
var
15 daniel-mar 1184
  SavGame: TSaveData;
3 daniel-mar 1185
begin
14 daniel-mar 1186
  LevelData := TLevelData.Create;
1187
 
3 daniel-mar 1188
  { Beginne VCL-Ersatz }
1189
  dxtimer := tdxtimer.Create(self);
1190
  dxtimer.Interval := 33;
1191
  dxtimer.OnActivate := DXTimerActivate;
1192
  dxtimer.OnDeactivate := DXTimerDeactivate;
1193
  dxtimer.OnTimer := DXTimerTimer;
1194
  dxtimer.ActiveOnly := false;
1195
  dxtimer.Enabled := false;
1196
 
1197
  dxdraw := tdxdraw.Create(self);
1198
  dxdraw.Parent := self;
1199
  dxdraw.Align := alClient;
1200
  dxdraw.Left := 0;
1201
  dxdraw.Top := 0;
1202
  dxdraw.Width := 640;
1203
  dxdraw.Height := 480;
1204
  dxdraw.AutoInitialize := False;
1205
  dxdraw.AutoSize := False;
1206
  dxdraw.Color := clBlack;
1207
  dxdraw.Display.BitCount := 24;
1208
  dxdraw.Display.FixedBitCount := False;
1209
  dxdraw.Display.FixedRatio := False;
1210
  dxdraw.Display.FixedSize := False;
1211
  dxdraw.Display.Height := 600;
1212
  dxdraw.Display.Width := 800;
4 daniel-mar 1213
  dxdraw.Options := [doAllowReboot, doWaitVBlank, doAllowPalette256, doCenter, {doRetainedMode,} doHardware, doSelectDriver];
3 daniel-mar 1214
  dxdraw.TabOrder := 0;
1215
  dxdraw.Visible := true;
1216
  dxdraw.OnFinalize := DXDrawFinalize;
1217
  dxdraw.OnInitialize := DXDrawInitialize;
1218
  dxdraw.OnInitializing := DXDrawInitializing;
1219
 
1220
  dxsound := tdxsound.Create(self);
1221
  dxsound.AutoInitialize := false;
1222
 
1223
  dxinput := tdxinput.Create(self);
1224
  dxinput.Joystick.ForceFeedback := true;
1225
  dxinput.Keyboard.ForceFeedback := true;
1226
 
1227
  wavelist := tdxwavelist.Create(self);
1228
  wavelist.DXSound := dxsound;
1229
 
1230
  imagelist := tdximagelist.create(self);
1231
  imagelist.DXDraw := dxdraw;
1232
 
1233
  spriteengine := tdxspriteengine.create(self);
1234
  spriteengine.DXDraw := dxdraw;
1235
 
7 daniel-mar 1236
  InitializeCriticalSection(TimerCS);
1237
 
3 daniel-mar 1238
  { Ende VCL-Ersatz }
1239
 
1240
  Application.Title := 'SpaceMission '+ProgramVersion;
1241
  LoadOptions;
1242
  DXInit;
1243
  SoundInit;
1244
  MusicInit;
14 daniel-mar 1245
  ResetLevelData;
3 daniel-mar 1246
  if (paramcount = 0) and (fileexists(paramstr(1))) then // (paramcount > 0)
1247
  begin
15 daniel-mar 1248
    SavGame := TSaveData.Create;
1249
    try
1250
      try
1251
        SavGame.Load(paramstr(1));
1252
        mainform.FScore := SavGame.FScore;
1253
        mainform.FLife := SavGame.FLife;
1254
        mainform.FLevel := SavGame.FLevel;
1255
        mainform.FGameMode := SavGame.FGameMode;
1256
      except
1257
        showmessage(FileError);
1258
        GameStartClick(GameStart);
1259
        exit;
1260
      end;
1261
    finally
1262
      FreeAndNil(SavGame);
3 daniel-mar 1263
    end;
1264
    mainform.FNextScene := gsNewLevel;
1265
    exit;
1266
  end;
1267
  GameStartClick(GameStart);
1268
end;
1269
 
1270
procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
1271
  Shift: TShiftState);
1272
begin
1273
  if (ssAlt in Shift) and (Key=VK_RETURN) then
1274
    OptionFullScreenClick(OptionFullScreen);
1275
end;
1276
 
1277
procedure TMainForm.GameStartClick(Sender: TObject);
1278
begin
1279
  StartScene(gsTitle);
1280
end;
1281
 
1282
procedure TMainForm.GamePauseClick(Sender: TObject);
1283
begin
1284
  GamePause.Checked := not GamePause.Checked;
1285
  DXTimer.Enabled := not GamePause.Checked;
7 daniel-mar 1286
  if GamePause.Checked then
1287
    PauseMusic(FMusic)
1288
  else
3 daniel-mar 1289
    ResumeMusic(FMusic);
1290
end;
1291
 
1292
// http://www.delphipraxis.net/post43515.html
1293
Function GetHTML(AUrl: string): string;
1294
var
1295
  databuffer : array[0..4095] of char;
1296
  ResStr : string;
1297
  hSession, hfile: hInternet;
1298
  dwindex,dwcodelen,dwread,dwNumber: cardinal;
1299
  dwcode : array[1..20] of char;
1300
  res    : pchar;
1301
  Str    : pchar;
1302
begin
1303
  ResStr:='';
1304
  if system.pos('http://',lowercase(AUrl))=0 then
1305
     AUrl:='http://'+AUrl;
1306
 
1307
  // Hinzugefügt
1308
  application.ProcessMessages;
1309
 
1310
  hSession:=InternetOpen('InetURL:/1.0',
1311
                         INTERNET_OPEN_TYPE_PRECONFIG,
1312
                         nil,
1313
                         nil,
1314
                         0);
1315
  if assigned(hsession) then
1316
  begin
1317
    // Hinzugefügt
1318
    application.ProcessMessages;
1319
 
1320
    hfile:=InternetOpenUrl(
1321
           hsession,
1322
           pchar(AUrl),
1323
           nil,
1324
           0,
1325
           INTERNET_FLAG_RELOAD,
1326
           0);
1327
    dwIndex  := 0;
1328
    dwCodeLen := 10;
1329
 
1330
    // Hinzugefügt
1331
    application.ProcessMessages;
1332
 
1333
    HttpQueryInfo(hfile,
1334
                  HTTP_QUERY_STATUS_CODE,
1335
                  @dwcode,
1336
                  dwcodeLen,
1337
                  dwIndex);
1338
    res := pchar(@dwcode);
1339
    dwNumber := sizeof(databuffer)-1;
1340
    if (res ='200') or (res ='302') then
1341
    begin
1342
      while (InternetReadfile(hfile,
1343
                              @databuffer,
1344
                              dwNumber,
1345
                              DwRead)) do
1346
      begin
1347
 
1348
        // Hinzugefügt
1349
        application.ProcessMessages;
1350
 
1351
        if dwRead =0 then
1352
          break;
1353
        databuffer[dwread]:=#0;
1354
        Str := pchar(@databuffer);
1355
        resStr := resStr + Str;
1356
      end;
1357
    end
1358
    else
1359
      ResStr := 'Status:'+res;
1360
    if assigned(hfile) then
1361
      InternetCloseHandle(hfile);
1362
  end;
1363
 
1364
  // Hinzugefügt
1365
  application.ProcessMessages;
1366
 
1367
  InternetCloseHandle(hsession);
1368
  Result := resStr;
1369
end;
1370
 
1371
procedure TMainForm.CheckUpdatesClick(Sender: TObject);
1372
var
14 daniel-mar 1373
  cont: string;
3 daniel-mar 1374
begin
14 daniel-mar 1375
  cont := GetHTML('http://www.viathinksoft.de/update/?id=spacemission');
1376
  if copy(cont, 0, 7) = 'Status:' then
3 daniel-mar 1377
  begin
14 daniel-mar 1378
    Application.MessageBox('Ein Fehler ist aufgetreten. Wahrscheinlich ist keine Internetverbindung aufgebaut, oder der der ViaThinkSoft-Server vorübergehend offline.', 'Fehler', MB_OK + MB_ICONERROR)
3 daniel-mar 1379
  end
1380
  else
1381
  begin
1382
    if GetHTML('http://www.viathinksoft.de/update/?id=spacemission') <> ProgramVersion then
1383
    begin
1384
      if Application.MessageBox('Eine neue Programmversion ist vorhanden. Möchten Sie diese jetzt herunterladen?', 'Information', MB_YESNO + MB_ICONASTERISK) = ID_YES then
1385
        shellexecute(application.handle, 'open', pchar('http://www.viathinksoft.de/update/?id=@spacemission'), '', '', sw_normal);
1386
    end
1387
    else
1388
    begin
1389
      Application.MessageBox('Es ist keine neue Programmversion vorhanden.', 'Information', MB_OK + MB_ICONASTERISK);
1390
    end;
1391
  end;
1392
end;
1393
 
1394
procedure TMainForm.BeendenClick(Sender: TObject);
1395
begin
1396
  close;
1397
end;
1398
 
1399
procedure TMainForm.OptionFullScreenClick(Sender: TObject);
1400
begin
1401
  OptionFullScreen.Checked := not OptionFullScreen.Checked;
1402
  DXInit;
1403
  writeoptions;
1404
end;
1405
 
1406
procedure TMainForm.OptionSoundClick(Sender: TObject);
1407
begin
1408
  OptionSound.Checked := not OptionSound.Checked;
1409
  SoundInit;
1410
  WriteOptions;
1411
end;
1412
 
1413
procedure TMainForm.SoundInit;
1414
begin
1415
  if OptionSound.Checked then
1416
  begin
1417
    if not DXSound.Initialized then
1418
    begin
1419
      try
1420
        DXSound.Initialize;
1421
        WaveList.Items.LoadFromFile(FDirectory+'DirectX\Sound.dxw');
1422
      except
1423
        OptionSound.enabled := False;
1424
        WaveList.items.clear;
1425
      end;
1426
    end;
1427
  end
1428
  else DXSound.Finalize;
1429
end;
1430
 
1431
procedure TMainForm.MusicInit;
1432
begin
1433
  optionmusic.enabled := SoundKarte;
1434
end;
1435
 
1436
procedure TMainForm.DestroyMusic(Name: TMusicTrack);
1437
begin
1438
  if Name = mtBoss then
1439
  begin
1440
    MCISendString(pchar('stop "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1441
    MCISendString(pchar('close "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1442
  end;
1443
  if Name = mtGame then
1444
  begin
1445
    MCISendString(pchar('stop "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1446
    MCISendString(pchar('close "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1447
  end;
1448
  if Name = mtScene then
1449
  begin
1450
    MCISendString(pchar('stop "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1451
    MCISendString(pchar('close "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1452
  end;
1453
  if Name = mtTitle then
1454
  begin
1455
    MCISendString(pchar('stop "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1456
    MCISendString(pchar('close "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1457
  end;
1458
end;
1459
 
1460
procedure TMainForm.OpenMusic(Name: TMusicTrack);
1461
begin
1462
  if Name = mtBoss then
1463
    MCISendString(pchar('open "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1464
  if Name = mtGame then
1465
    MCISendString(pchar('open "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1466
  if Name = mtScene then
1467
    MCISendString(pchar('open "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1468
  if Name = mtTitle then
1469
    MCISendString(pchar('open "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1470
end;
1471
 
1472
procedure TMainForm.PauseMusic(Name: TMusicTrack);
1473
begin
1474
  if not OptionMusic.checked then exit;
1475
  if Name = mtBoss then
1476
    MCISendString(pchar('stop "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1477
  if Name = mtGame then
1478
    MCISendString(pchar('stop "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1479
  if Name = mtScene then
1480
    MCISendString(pchar('stop "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1481
  if Name = mtTitle then
1482
    MCISendString(pchar('stop "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1483
end;
1484
 
1485
procedure TMainForm.DXDrawInitializing(Sender: TObject);
1486
begin
1487
  if doFullScreen in DXDraw.Options then
1488
  begin
1489
    BorderStyle := bsNone;
1490
    DXDraw.Cursor := crNone;
7 daniel-mar 1491
  end
1492
  else
3 daniel-mar 1493
  begin
1494
    BorderStyle := bsSingle;
1495
    DXDraw.Cursor := crDefault;
1496
  end;
1497
end;
1498
 
1499
procedure TMainForm.DXDrawInitialize(Sender: TObject);
1500
begin
1501
  DXTimer.Enabled := True;
1502
end;
1503
 
1504
procedure TMainForm.DXDrawFinalize(Sender: TObject);
1505
begin
1506
  DXTimer.Enabled := False;
1507
end;
1508
 
1509
procedure TMainForm.DXTimerActivate(Sender: TObject);
1510
begin
1511
  Caption := Application.Title;
1512
  if not ProgrammGestartet then
1513
  begin
1514
    Programmgestartet := true;
1515
    exit;
1516
  end;
1517
  ResumeMusic(FMusic);
1518
end;
1519
 
1520
procedure TMainForm.DXTimerDeactivate(Sender: TObject);
1521
begin
1522
  Caption := Application.Title + ' [Pause]';
1523
  PauseMusic(FMusic);
1524
end;
1525
 
1526
function TMainForm.StatusMusic(Name: TMusicTrack): string;
1527
var
1528
  MCIStatus: array[0..255] of char;
1529
begin
1530
  if not OptionMusic.checked then exit;
1531
  if FMusic = mtGame then
1532
    MCISendString(pchar('status "'+FDirectory+'Musik\Game.mid" mode'), MCIStatus, 255, 0);
1533
  if FMusic = mtBoss then
1534
    MCISendString(pchar('status "'+FDirectory+'Musik\Boss.mid" mode'), MCIStatus, 255, 0);
1535
  if FMusic = mtScene then
1536
    MCISendString(pchar('status "'+FDirectory+'Musik\Scene.mid" mode'), MCIStatus, 255, 0);
1537
  if FMusic = mtTitle then
1538
    MCISendString(pchar('status "'+FDirectory+'Musik\Title.mid" mode'), MCIStatus, 255, 0);
1539
  result := MCIStatus;
1540
end;
1541
 
1542
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
1543
begin
7 daniel-mar 1544
  EnterCriticalSection(TimerCS);
1545
  try
1546
    if StatusMusic(FMusic) = 'stopped' then
1547
      PlayMusic(FMusic); {...}
1548
    if crash then
3 daniel-mar 1549
    begin
7 daniel-mar 1550
      inc(Crash2);
1551
      if crash2 = 30 then
1552
      begin
1553
        Crash2 := 0;
1554
        crash := false;
1555
        crashsound := false;
1556
      end;
3 daniel-mar 1557
    end;
7 daniel-mar 1558
    if not DXDraw.CanDraw then exit;
1559
    DXInput.Update;
1560
    case FScene of
1561
      gsTitle   : SceneTitle;
1562
      gsMain    : SceneMain;
1563
      gsGameOver: SceneGameOver;
1564
      gsWin     : SceneWin;
1565
      gsNewLevel: SceneNewLevel;
1566
    end;
1567
    if FNextScene<>gsNone then
1568
    begin
1569
      StartScene(FNextScene);
1570
      FNextScene := gsNone;
1571
    end;
1572
    DXDraw.Flip;
1573
  finally
1574
    LeaveCriticalSection(TimerCS);
3 daniel-mar 1575
  end;
1576
end;
1577
 
1578
procedure TMainForm.BlinkStart;
1579
begin
1580
  FBlink := 0;
1581
  FBlinkTime := GetTickCount;
1582
end;
1583
 
1584
procedure TMainForm.WriteOptions;
1585
var
1586
  INIDatei: TIniFile;
1587
begin
1588
  INIDatei := TIniFile.Create(FDirectory+'Einstellungen\SpaceMission.ini');
7 daniel-mar 1589
  try
1590
    if OptionMusic.checked then INIDatei.WriteBool('Settings', 'Music', true)
1591
      else INIDatei.WriteBool('Settings', 'Music', false);
1592
    if OptionSound.checked then INIDatei.WriteBool('Settings', 'Sound', true)
1593
      else INIDatei.WriteBool('Settings', 'Sound', false);
1594
    if OptionFullScreen.checked then INIDatei.WriteBool('Settings', 'FullScreen', true)
1595
      else INIDatei.WriteBool('Settings', 'FullScreen', false);
1596
    if OptionBreitbild.checked then INIDatei.WriteBool('Settings', 'ScreenAutoSize', true)
1597
      else INIDatei.WriteBool('Settings', 'ScreenAutoSize', false);
1598
    if FInterval = giLeicht then INIDatei.WriteInteger('Settings', 'Speed', 1);
1599
    if FInterval = giMittel then INIDatei.WriteInteger('Settings', 'Speed', 2);
1600
    if FInterval = giSchwer then INIDatei.WriteInteger('Settings', 'Speed', 3);
1601
    if FInterval = giMaster then INIDatei.WriteInteger('Settings', 'Speed', 4);
1602
  finally
1603
    INIDatei.Free;
1604
  end;
3 daniel-mar 1605
end;
1606
 
1607
procedure TMainForm.LoadOptions;
1608
var
1609
  INIDatei: TIniFile;
1610
begin
1611
  INIDatei := TIniFile.Create(FDirectory+'Einstellungen\SpaceMission.ini');
7 daniel-mar 1612
  try
1613
    optionmusic.checked := INIDatei.ReadBool('Settings', 'Music', true);
1614
    optionsound.checked := INIDatei.ReadBool('Settings', 'Sound', true);
1615
    optionfullscreen.checked := INIDatei.ReadBool('Settings', 'fullscreen', false);
1616
    OptionBreitBild.checked := INIDatei.ReadBool('Settings', 'ScreenAutoSize', true);
1617
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 1 then
1618
    begin
1619
      FInterval := giLeicht;
1620
      Leicht.checked := true;
1621
    end;
1622
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 2 then
1623
    begin
1624
      FInterval := giMittel;
1625
      Mittel.checked := true;
1626
    end;
1627
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 3 then
1628
    begin
1629
      FInterval := giSchwer;
1630
      Schwer.checked := true;
1631
    end;
1632
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 4 then
1633
    begin
1634
      FInterval := giMaster;
1635
      Master.checked := true;
1636
    end;
1637
  finally
1638
    INIDatei.Free;
3 daniel-mar 1639
  end;
1640
  WriteOptions;
1641
end;
1642
 
1643
procedure TMainForm.BlinkUpdate;
1644
begin
1645
  if GetTickCount<>FBlinkTime then
1646
  begin
1647
    FBlink := FBlink + (GetTickCount-FBlinkTime);
1648
    FBlinkTime := GetTickCount;
1649
  end;
1650
end;
1651
 
1652
procedure TMainForm.PlaySound(Name: string; Wait: Boolean);
1653
begin
1654
  if (OptionSound.Checked) and (OptionSound.Enabled) then
1655
    WaveList.Items.Find(Name).Play(Wait);
1656
end;
1657
 
1658
procedure TMainForm.PlayMusic(Name: TMusicTrack);
1659
begin
1660
  if (not mainform.active) and (mainform.visible) then //1st Programmstart
1661
    exit;
1662
  if (OptionMusic.checked) and (OptionMusic.enabled) then
1663
  begin
1664
    DestroyMusic(FMusic);
1665
    OpenMusic(Name);
1666
    ResumeMusic(Name);
1667
  end;
1668
  FMusic := Name;
1669
end;
1670
 
1671
function TMainForm.ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
1672
begin
1673
  with Result do
1674
  begin
1675
    rgbRed := Src.rgbRed+((Dest.rgbRed-Src.rgbRed)*Percent div 256);
1676
    rgbGreen := Src.rgbGreen+((Dest.rgbGreen-Src.rgbGreen)*Percent div 256);
1677
    rgbBlue := Src.rgbBlue+((Dest.rgbBlue-Src.rgbBlue)*Percent div 256);
1678
    rgbReserved := 0;
1679
  end;
1680
end;
1681
 
1682
procedure TMainForm.PalleteAnim(Col: TRGBQuad; Time: Integer);
1683
var
1684
  i: Integer;
1685
  t, t2: DWORD;
1686
  ChangePalette: Boolean;
1687
  c: Integer;
1688
begin
1689
  if DXDraw.Initialized then
1690
  begin
1691
    c := DXDraw.Surface.ColorMatch(RGB(Col.rgbRed, Col.rgbGreen, Col.rgbBlue));
1692
    ChangePalette := False;
1693
    if DXDraw.CanPaletteAnimation then
1694
    begin
1695
      t := GetTickCount;
1696
      while Abs(GetTickCount-t)<Time do
1697
      begin
1698
        t2 := Trunc(Abs(GetTickCount-t)/Time*255);
1699
        for i := 0 to 255 do
1700
          DXDraw.ColorTable[i] := ComposeColor(Col, DXDraw.DefColorTable[i], t2);
1701
        DXDraw.UpdatePalette;
1702
        ChangePalette := True;
1703
      end;
7 daniel-mar 1704
    end
1705
    else
1706
    begin
3 daniel-mar 1707
      Sleep(Time);
7 daniel-mar 1708
    end;
3 daniel-mar 1709
    for i := 0 to 4 do
1710
    begin
1711
      DXDraw.Surface.Fill(c);
1712
      DXDraw.Flip;
1713
    end;
1714
    if ChangePalette then
1715
    begin
1716
      DXDraw.ColorTable := DXDraw.DefColorTable;
1717
      DXDraw.UpdatePalette;
1718
    end;
1719
    DXDraw.Surface.Fill(c);
1720
    DXDraw.Flip;
1721
  end;
1722
end;
1723
 
1724
procedure TMainForm.StartScene(Scene: TGameScene);
1725
begin
1726
  EndScene;
1727
  DXInput.States := DXInput.States - DXInputButton;
1728
  FScene := Scene;
1729
  BlinkStart;
1730
  case FScene of
1731
    gsTitle   : StartSceneTitle;
1732
    gsMain    : StartSceneMain;
1733
    gsGameOver: StartSceneGameOver;
1734
    gsWin     : StartSceneWin;
1735
    gsNewLevel: StartSceneNewLevel;
1736
  end;
1737
end;
1738
 
1739
procedure TMainForm.StartSceneTitle;
1740
begin
1741
  sleep(500);
1742
  FCheat := false;
1743
  BossExists := false;
1744
  FLife := Lives;
1745
  FLevel := 0;
1746
  FScore := 0;
1747
  FNotSave := true;
1748
  Cheat.enabled := false;
1749
  Neustart.enabled := false;
1750
  GamePause.enabled := false;
1751
  GameStart.enabled := false;
1752
  Spielgeschwindigkeit.enabled := false;
1753
  mainform.Visible := true;
1754
  PlayMusic(mtTitle);
1755
end;
1756
 
1757
procedure TMainForm.StartSceneMain;
1758
{var
1759
  i, j: Integer;}
1760
begin
1761
  sleep(500);
1762
  FCounter := 0;
1763
  NewLevel(FLevel);
1764
  BossExists := false;
1765
  PlayMusic(mtGame);
7 daniel-mar 1766
  FEnemyAdventPos := 0;
3 daniel-mar 1767
  FFrame := -4;
1768
  PlayerSprite := TPlayerSprite.Create(SpriteEngine.Engine);
1769
  with TBackground.Create(SpriteEngine.Engine) do
1770
  begin
1771
    SetMapSize(1, 1);
1772
    Image := mainform.ImageList.Items.Find('Star3');
1773
    Z := -13;
1774
    Y := 40;
1775
    FSpeed := 1 / 2;
1776
    Tile := True;
1777
  end;
1778
  with TBackground.Create(SpriteEngine.Engine) do
1779
  begin
1780
    SetMapSize(1, 1);
1781
    Image := mainform.ImageList.Items.Find('Star2');
1782
    Z := -12;
1783
    Y := 30;
1784
    FSpeed := 1;
1785
    Tile := True;
1786
  end;
1787
  with TBackground.Create(SpriteEngine.Engine) do
1788
  begin
1789
    SetMapSize(1, 1);
1790
    Image := mainform.ImageList.Items.Find('Star1');
1791
    Z := -11;
1792
    Y := 10;
1793
    FSpeed := 2;
1794
    Tile := True;
1795
  end;
1796
  {with TBackground.Create(SpriteEngine.Engine) do
1797
  begin
1798
    SetMapSize(200, 10);
1799
    Y := 10;
1800
    Z := -13;
1801
    FSpeed := 1 / 2;
1802
    Tile := True;
1803
    for i := 0 to MapHeight-1 do
1804
    begin
1805
      for j := 0 to MapWidth-1 do
1806
      begin
1807
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 8);
1808
        if Random(100)<95 then Chips[j, i] := -1;
1809
      end;
1810
    end;
1811
  end;
1812
  with TBackground.Create(SpriteEngine.Engine) do
1813
  begin
1814
    SetMapSize(200, 10);
1815
    Y := 30;
1816
    Z := -12;
1817
    FSpeed := 1;
1818
    Tile := True;
1819
    for i := 0 to MapHeight-1 do
1820
    begin
1821
      for j := 0 to MapWidth-1 do
1822
      begin
1823
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 4);
1824
        if Random(100)<95 then Chips[j, i] := -1;
1825
      end;
1826
    end;
1827
  end;
1828
  with TBackground.Create(SpriteEngine.Engine) do
1829
  begin
1830
    SetMapSize(200, 10);
1831
    Y := 40;
1832
    Z := -11;
1833
    FSpeed := 2;
1834
    Tile := True;
1835
    for i := 0 to MapHeight-1 do
1836
    begin
1837
      for j := 0 to MapWidth-1 do
1838
      begin
1839
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 2);
1840
        if Random(100)<95 then Chips[j, i] := -1;
1841
      end;
1842
    end;
1843
  end;}
1844
  FNotSave := false;
1845
  Cheat.enabled := true;
1846
  Neustart.enabled := true;
1847
  GamePause.enabled := true;
1848
  GameStart.enabled := true;
1849
  Spielgeschwindigkeit.enabled := true;
1850
end;
1851
 
1852
procedure TMainForm.StartSceneGameOver;
1853
begin
1854
  sleep(500);
1855
  FNotSave := true;
1856
  Cheat.enabled := false;
1857
  Spielgeschwindigkeit.enabled := false;
1858
  Neustart.enabled := false;
1859
  GamePause.enabled := false;
1860
  PlayMusic(mtScene);
1861
  BossExists := false;
1862
end;
1863
 
1864
procedure TMainForm.StartSceneWin;
1865
begin
1866
  sleep(500);
1867
  FNotSave := true;
1868
  Cheat.enabled := false;
1869
  Spielgeschwindigkeit.enabled := false;
1870
  Neustart.enabled := false;
1871
  GamePause.enabled := false;
1872
  PlayMusic(mtScene);
1873
  BossExists := false;
1874
end;
1875
 
1876
procedure TMainForm.EndScene;
1877
begin
1878
  case FScene of
1879
    gsTitle   : EndSceneTitle;
1880
    gsMain    : EndSceneMain;
1881
    gsGameOver: EndSceneGameOver;
1882
    gsWin     : EndSceneWin;
1883
    gsNewLevel: EndSceneNewLevel;
1884
  end;
1885
end;
1886
 
1887
procedure TMainForm.EndSceneTitle;
1888
begin
1889
  {  Ende Title  }
1890
end;
1891
 
1892
procedure TMainForm.EndSceneMain;
1893
begin
1894
  SpriteEngine.Engine.Clear;
1895
end;
1896
 
1897
procedure TMainForm.EndSceneGameOver;
1898
begin
1899
  {  Ende GameOver  }
1900
end;
1901
 
1902
procedure TMainForm.EndSceneWin;
1903
begin
1904
  {  Ende Win  }
1905
end;
1906
 
14 daniel-mar 1907
procedure TMainForm.ResetLevelData;
3 daniel-mar 1908
begin
14 daniel-mar 1909
  LevelData.Clear;
7 daniel-mar 1910
  FRestEnemies := 0;
3 daniel-mar 1911
end;
1912
 
7 daniel-mar 1913
const
1914
  ADDITIONAL_ENEMIES_PER_LEVEL = 75;
1915
 
3 daniel-mar 1916
procedure TMainForm.NewLevel(lev: integer);
1917
resourcestring
1918
  LNG_LEVEL_INVALID = 'Das Level Nr. %d ist ungültig!'+#13#10+'Das Programm wird beendet.';
1919
var
1920
  act: integer;
14 daniel-mar 1921
  Enemies: array[1..27] of TEnemyType;
7 daniel-mar 1922
  e: TEnemyAdvent;
3 daniel-mar 1923
begin
14 daniel-mar 1924
  ResetLevelData;
15 daniel-mar 1925
  if FGameMode = gmRandom then
3 daniel-mar 1926
  begin
14 daniel-mar 1927
    {$REGION 'Random game'}
1928
    Enemies[1] := etEnemyAttacker;
1929
    Enemies[2] := etEnemyMeteor;
1930
    Enemies[3] := etEnemyUFO;
1931
    Enemies[4] := etEnemyAttacker;
1932
    Enemies[5] := etEnemyMeteor;
1933
    Enemies[6] := etEnemyUFO;
1934
    Enemies[7] := etEnemyAttacker;
1935
    Enemies[8] := etEnemyMeteor;
1936
    Enemies[9] := etEnemyUFO;
1937
    Enemies[10] := etEnemyAttacker;
1938
    Enemies[11] := etEnemyMeteor;
1939
    Enemies[12] := etEnemyUFO;
1940
    Enemies[13] := etEnemyAttacker;
1941
    Enemies[14] := etEnemyMeteor;
1942
    Enemies[15] := etEnemyUFO;
1943
    Enemies[16] := etEnemyAttacker3;
1944
    Enemies[17] := etEnemyAttacker;
1945
    Enemies[18] := etEnemyMeteor;
1946
    Enemies[19] := etEnemyUFO;
1947
    Enemies[20] := etEnemyUFO2;
1948
    Enemies[21] := etEnemyAttacker;
1949
    Enemies[22] := etEnemyMeteor;
1950
    Enemies[23] := etEnemyUFO;
1951
    Enemies[24] := etEnemyAttacker2;
1952
    Enemies[25] := etEnemyMeteor;
1953
    Enemies[26] := etEnemyUFO;
1954
    Enemies[27] := etEnemyAttacker;
3 daniel-mar 1955
    randomize;
7 daniel-mar 1956
    FRestEnemies := lev*ADDITIONAL_ENEMIES_PER_LEVEL+1;
14 daniel-mar 1957
    SetLength(LevelData.EnemyAdventTable, FRestEnemies);
7 daniel-mar 1958
    for act := 0 to lev*ADDITIONAL_ENEMIES_PER_LEVEL-1 do
3 daniel-mar 1959
    begin
14 daniel-mar 1960
      e.enemyType := Enemies[min(random(lev+2)+1, High(Enemies))];
1961
      if e.enemyType = etEnemyAttacker2 then
7 daniel-mar 1962
      begin
14 daniel-mar 1963
        e.enemyType := Enemies[min(random(lev+2)+1, High(Enemies))]; {O_o}
7 daniel-mar 1964
      end;
1965
      e.x := act*30 + random(85-(lev+(random(lev))*2)){O_o};
1966
      e.y := random(dxdraw.surfaceheight);
14 daniel-mar 1967
      if e.enemyType = etEnemyAttacker2 then
7 daniel-mar 1968
      begin
1969
        e.lifes := random(6)+1{O_o};
1970
      end
1971
      else
1972
      begin
1973
        e.lifes := random(lev)+1;
1974
      end;
1975
 
14 daniel-mar 1976
      LevelData.EnemyAdventTable[act] := e;
3 daniel-mar 1977
    end;
14 daniel-mar 1978
    e.enemyType := etEnemyBoss;
7 daniel-mar 1979
    e.x := lev*75*30{O_o} div lev;
1980
    e.y := (dxdraw.surfaceheight div 2) - (MainForm.ImageList.Items.Find('Enemy-boss').height div 2);
1981
    e.lifes := lev*5;
14 daniel-mar 1982
    LevelData.EnemyAdventTable[lev*ADDITIONAL_ENEMIES_PER_LEVEL] := e;
1983
    Assert(FRestEnemies = Length(LevelData.EnemyAdventTable));
1984
    {$ENDREGION}
3 daniel-mar 1985
  end
1986
  else
1987
  begin
14 daniel-mar 1988
    {$REGION 'Normal game'}
7 daniel-mar 1989
    if fileexists(GetLevelFileName(lev)) then
3 daniel-mar 1990
    begin
7 daniel-mar 1991
      try
14 daniel-mar 1992
        LevelData.Load(GetLevelFileName(lev));
1993
        FRestEnemies := Length(LevelData.EnemyAdventTable);
7 daniel-mar 1994
      except
1995
        showmessage(Format(LNG_LEVEL_INVALID, [lev]));
14 daniel-mar 1996
        ResetLevelData;
3 daniel-mar 1997
      end;
1998
    end;
14 daniel-mar 1999
    {$ENDREGION}
3 daniel-mar 2000
  end;
2001
end;
2002
 
2003
procedure TMainForm.SceneTitle;
2004
var
2005
  Logo: TPictureCollectionItem;
2006
begin
2007
  DXDraw.Surface.Fill(0);
2008
  Logo := ImageList.Items.Find('Logo');
2009
  {Logo.DrawWaveX(DXDraw.Surface, (dxdraw.surfaceWidth div 2) - 181, 65, Logo.Width, Logo.Height, 0,
2010
    Trunc(16 - Cos256(FBlink div 60) * 16), 32, -FBlink div 5);}
2011
  Logo.DrawWaveX(DXDraw.Surface, trunc((dxdraw.surfaceWidth / 2) - (Logo.Width / 2)), 65, Logo.Width, Logo.Height, 0,
2012
    2, 80, Fangle * 4);
2013
  inc(Fangle);
2014
  with DXDraw.Surface.Canvas do
2015
  begin
15 daniel-mar 2016
    if (isDown in MainForm.DXInput.States) and (FGameMode=gmLevels) then FGameMode := gmRandom;
2017
    if ((isUp in MainForm.DXInput.States) and (FGameMode=gmRandom)) or (FGameMode=gmUnknown) then FGameMode := gmLevels;
3 daniel-mar 2018
    Brush.Style := bsClear;
2019
    Font.Size := 30;
15 daniel-mar 2020
    if FGameMode = gmLevels then
3 daniel-mar 2021
    begin
2022
      Font.Color := clMaroon;
2023
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-52, 'Normales Spiel');
2024
      Textout((dxdraw.surfaceWidth div 2)-187, (dxdraw.surfaceheight div 2)-52, '>');
2025
      Font.Color := clRed;
2026
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)-50, 'Normales Spiel');
2027
      Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)-50, '>');
2028
      Font.Color := clOlive;
2029
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-2, 'Zufallslevel');
2030
      Font.Color := clYellow;
2031
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2), 'Zufallslevel');
2032
    end
2033
    else
2034
    begin
2035
      Font.Color := clOlive;
2036
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-52, 'Normales Spiel');
2037
      Font.Color := clYellow;
2038
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)-50, 'Normales Spiel');
2039
      Font.Color := clMaroon;
2040
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-2, 'Zufallslevel');
2041
      Textout((dxdraw.surfaceWidth div 2)-187, (dxdraw.surfaceheight div 2)-2, '>');
2042
      Font.Color := clRed;
2043
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2), 'Zufallslevel');
2044
      Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2), '>');
2045
    end;
2046
    { if (FBlink div 300) mod 2=0 then
2047
    begin
2048
      Font.Color := clGreen;
2049
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2050
      Font.Color := clLime;
2051
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2052
    end; }
2053
    BlinkUpdate;
2054
    Release;
2055
  end;
2056
  // Weiter mit Leertaste oder Enter
2057
  if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
2058
  begin
2059
    FLevel := 1;
15 daniel-mar 2060
    if ((FGameMode=gmLevels) and not fileexists(GetLevelFileName(FLevel))) or ((FGameMode=gmRandom) and (FLevel > 20)) then
3 daniel-mar 2061
    begin
2062
      //PlaySound('Frage', False);
2063
      exit;
2064
    end;
2065
    NewLevel(FLevel);
2066
    PlaySound('SceneMov', False);
2067
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2068
    Sleep(200);
2069
    StartScene(gsMain);
2070
  end;
2071
end;
2072
 
2073
procedure TMainForm.SceneMain;
2074
var
2075
  Enemy: TSprite;
14 daniel-mar 2076
  spriteClass: TEnemyClass;
3 daniel-mar 2077
begin
7 daniel-mar 2078
  case FInterval of
2079
    giMittel: SpriteEngine.Move(conleicht);
2080
    giLeicht: SpriteEngine.Move(conmittel);
2081
    giSchwer: SpriteEngine.Move(conschwer);
2082
    giMaster: SpriteEngine.Move(conmaster);
2083
  end;
3 daniel-mar 2084
  SpriteEngine.Dead;
14 daniel-mar 2085
  while (FEnemyAdventPos >= Low(LevelData.EnemyAdventTable)) and
2086
    (FEnemyAdventPos <= High(LevelData.EnemyAdventTable)) and
2087
    ((LevelData.EnemyAdventTable[FEnemyAdventPos].x / 4) <= FFrame) and
7 daniel-mar 2088
    (FRestEnemies > 0) do
3 daniel-mar 2089
  begin
7 daniel-mar 2090
    Dec(FRestEnemies);
14 daniel-mar 2091
    with LevelData.EnemyAdventTable[FEnemyAdventPos] do
3 daniel-mar 2092
    begin
14 daniel-mar 2093
      spriteClass := nil;
2094
      case enemyType of
2095
        //etUnknown: ;
2096
        etEnemyAttacker:  spriteClass := TEnemyAttacker;
2097
        etEnemyAttacker2: spriteClass := TEnemyAttacker2;
2098
        etEnemyAttacker3: spriteClass := TEnemyAttacker3;
2099
        etEnemyMeteor:    spriteClass := TEnemyMeteor;
2100
        etEnemyUFO:       spriteClass := TEnemyUFO;
2101
        etEnemyUFO2:      spriteClass := TEnemyUFO2;
2102
        etEnemyBoss:      spriteClass := TEnemyBoss;
2103
      end;
2104
      if spriteClass <> nil then
2105
      begin
2106
        Enemy := spriteClass.Create(SpriteEngine.Engine, lifes);
2107
        Enemy.x := dxdraw.surfacewidth;
2108
        //Enemy.y := y;
2109
        if y <> 0 then
2110
          Enemy.y := dxdraw.surfaceheight / (480{maximale Bandbreite im alten Format} / y)
2111
        else
2112
          Enemy.y := 0;
2113
      end;
3 daniel-mar 2114
    end;
2115
    Inc(FEnemyAdventPos);
2116
  end;
2117
  Inc(FFrame);
2118
  DXDraw.Surface.Fill(0);
2119
  if FNextScene=gsNone then
2120
  begin
2121
    SpriteEngine.Draw;
2122
    if MainForm.flife > 0 then
2123
    begin
2124
      with DXDraw.Surface.Canvas do
2125
      begin
2126
        Brush.Style := bsClear;
2127
        Font.Size := 20;
2128
        Font.Color := clOlive;
2129
        Textout(9, 9, 'Punkte: ' + FloatToStrF(FScore,ffNumber,14,0));
2130
        Font.Color := clYellow;
2131
        Textout(10, 10, 'Punkte: ' + FloatToStrF(FScore,ffNumber,14,0));
2132
        Font.Color := clMaroon;
2133
        Textout(dxdraw.surfacewidth-141, 9, 'Level: ' + IntToStr(MainForm.flevel));
2134
        Font.Color := clRed;
2135
        Textout(dxdraw.surfacewidth-140, 10, 'Level: ' + IntToStr(MainForm.flevel));
2136
        if FLife<0 then mainform.FLife := 0;
2137
        if FCheat then
2138
        begin
2139
          Font.Color := clPurple;
2140
          Textout(9, dxdraw.surfaceheight-41, 'Leben: ?');
2141
          Font.Color := clFuchsia;
2142
          Textout(10, dxdraw.surfaceheight-40, 'Leben: ?');
2143
        end
2144
        else
2145
        begin
2146
          if ((Flife = 1) and ((FBlink div 300) mod 2=0)) or (Flife <> 1) then
2147
          begin
2148
            Font.Color := clPurple;
2149
            Textout(9, dxdraw.surfaceheight-41, 'Leben: ' + IntToStr(MainForm.flife));
2150
            Font.Color := clFuchsia;
2151
            Textout(10, dxdraw.surfaceheight-40, 'Leben: ' + IntToStr(MainForm.flife));
2152
          end;
2153
          if Flife = 1 then BlinkUpdate;
2154
        end;
2155
        {if BossExists and (FBossLife>0) then
2156
        begin
2157
          Font.Color := clPurple;
2158
          Textout(449, 439, 'Boss: ' + IntToStr(FBossLife));
2159
          Font.Color := clFuchsia;
2160
          Textout(450, 440, 'Boss: ' + IntToStr(FBossLife));
2161
        end
2162
        else
2163
          if RestlicheEinheiten>0 then
2164
          begin
2165
            Font.Color := clPurple;
2166
            Textout(449, 439, 'Einheiten: ' + IntToStr(RestlicheEinheiten));
2167
            Font.Color := clFuchsia;
2168
            Textout(450, 440, 'Einheiten: ' + IntToStr(RestlicheEinheiten));
2169
          end;}
2170
        if BossExists and (FBossLife>0) then
2171
        begin
7 daniel-mar 2172
          if (FRestEnemies>0) then
3 daniel-mar 2173
          begin
2174
            Font.Color := clGreen;
2175
            Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-81, 'Boss: ' + IntToStr(FBossLife));
7 daniel-mar 2176
            Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2177
            Font.Color := clLime;
2178
            Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-80, 'Boss: ' + IntToStr(FBossLife));
7 daniel-mar 2179
            Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2180
          end;
7 daniel-mar 2181
          if (FRestEnemies<1) then
3 daniel-mar 2182
          begin
2183
            Font.Color := clGreen;
2184
            Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Boss: ' + IntToStr(FBossLife));
2185
            Font.Color := clLime;
2186
            Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Boss: ' + IntToStr(FBossLife));
2187
          end;
2188
        end;
7 daniel-mar 2189
        if (FRestEnemies>0) and not Bossexists then
3 daniel-mar 2190
        begin
2191
          Font.Color := clGreen;
7 daniel-mar 2192
          Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2193
          Font.Color := clLime;
7 daniel-mar 2194
          Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2195
        end;
2196
        Release;
2197
      end;
2198
    end
2199
    else
2200
    begin
2201
      DXDraw.Surface.Canvas.Font.Color := clGreen; // Grüne schrift bei gescheitert? FIXME
2202
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, 'Mission gescheitert!');
2203
      DXDraw.Surface.Canvas.Font.Color := clLime;
2204
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, 'Mission gescheitert!');
2205
      DXDraw.Surface.Canvas.Release;
2206
    end;
7 daniel-mar 2207
    if (EnemyCounter=0) and (FRestEnemies=0){ and (SpielerFliegtFort = false)}
3 daniel-mar 2208
    and ((BossExists and (FBossLife=0)) or not BossExists) then
2209
    begin
2210
      DXDraw.Surface.Canvas.Font.Color := clGreen;
2211
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, 'Mission erfolgreich!');
2212
      DXDraw.Surface.Canvas.Font.Color := clLime;
2213
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, 'Mission erfolgreich!');
2214
      DXDraw.Surface.Canvas.Release;
2215
      Sleep(1);
2216
      inc(FCounter);
2217
      if FCounter>150{200} then PlayerSprite.FlyAway;
2218
    end;
2219
  end;
2220
end;
2221
 
2222
procedure TMainForm.SceneGameOver;
2223
begin
2224
  DXDraw.Surface.Fill(0);
2225
  with DXDraw.Surface.Canvas do
2226
  begin
2227
    FNotSave := true;
2228
    Cheat.enabled := false;
2229
    GamePause.enabled := false;
2230
    Neustart.enabled := false;
2231
    Brush.Style := bsClear;
2232
    Font.Size := 35;
2233
    Font.Color := clMaroon;
11 daniel-mar 2234
    Textout((dxdraw.surfacewidth div 2)-127, 98, 'Game Over!');
3 daniel-mar 2235
    Font.Color := clRed;
11 daniel-mar 2236
    Textout((dxdraw.surfacewidth div 2)-125, 100, 'Game Over!');
3 daniel-mar 2237
    if (FBlink div 300) mod 2=0 then
2238
    begin
2239
      Font.Size := 30;
2240
      Font.Color := clOlive;
2241
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2242
      Font.Color := clYellow;
2243
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2244
    end;
2245
    BlinkUpdate;
2246
    Release;
2247
  end;
2248
  if isButton1 in DXInput.States then
2249
  begin
2250
    PlaySound('SceneMov', False);
2251
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2252
    Sleep(200);
2253
    StartScene(gsTitle);
2254
  end;
2255
end;
2256
 
2257
procedure TMainForm.SceneWin;
2258
begin
2259
  DXDraw.Surface.Fill(0);
2260
  with DXDraw.Surface.Canvas do
2261
  begin
2262
    FNotSave := true;
2263
    Cheat.enabled := false;
2264
    GamePause.enabled := false;
2265
    Neustart.enabled := false;
2266
    Brush.Style := bsClear;
2267
    Font.Size := 35;
2268
    Font.Color := clMaroon;
2269
    Textout((dxdraw.surfaceWidth div 2)-127, 98, 'Gewonnen!');
2270
    Font.Color := clRed;
2271
    Textout((dxdraw.surfaceWidth div 2)-125, 100, 'Gewonnen!');
2272
    if (FBlink div 300) mod 2=0 then
2273
    begin
2274
      Font.Size := 30;
2275
      Font.Color := clOlive;
2276
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2277
      Font.Color := clYellow;
2278
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2279
    end;
2280
    BlinkUpdate;
2281
    Release;
2282
  end;
2283
  if isButton1 in DXInput.States then
2284
  begin
2285
    PlaySound('SceneMov', False);
2286
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2287
    Sleep(200);
2288
    StartScene(gsTitle);
2289
  end;
2290
end;
2291
 
2292
procedure TMainForm.StartSceneNewLevel;
2293
begin
2294
  sleep(500);
2295
  FNotSave := false;
2296
  Cheat.enabled := false;
2297
  Neustart.enabled := false;
2298
  GamePause.enabled := false;
2299
  GameStart.enabled := true;
2300
  Spielgeschwindigkeit.enabled := false;
2301
  BossExists := false;
2302
  Spielgeschwindigkeit.enabled := false;
15 daniel-mar 2303
  if ((FGameMode=gmLevels) and (not fileexists(GetLevelFileName(FLevel)))) or ((FGameMode=gmRandom) and (FLevel > 25)) then
3 daniel-mar 2304
  begin
2305
    //PlaySound('SceneMov', False);
2306
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2307
    Sleep(200);
2308
    StartScene(gsWin);
2309
    exit;
2310
  end;
2311
  PlayMusic(mtScene);
2312
end;
2313
 
2314
procedure TMainForm.EndSceneNewLevel;
2315
begin
2316
  {  Ende NewLevel  }
2317
end;
2318
 
2319
procedure TMainForm.SceneNewLevel;
2320
begin
2321
  DXDraw.Surface.Fill(0);
2322
  with DXDraw.Surface.Canvas do
2323
  begin
2324
    Brush.Style := bsClear;
2325
    Font.Size := 40;
2326
    Font.Color := clMaroon;
2327
    Textout((dxdraw.surfaceWidth div 2)-(83+(length(inttostr(flevel))*22)), 98, 'Level '+inttostr(flevel));
2328
    Font.Color := clRed;
2329
    Textout((dxdraw.surfaceWidth div 2)-(81+(length(inttostr(flevel))*22)), 100, 'Level '+inttostr(flevel));
2330
    if (FBlink div 300) mod 2=0 then
2331
    begin
2332
      Font.Size := 30;
2333
      Font.Color := clOlive;
2334
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2335
      Font.Color := clYellow;
2336
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2337
    end;
2338
    BlinkUpdate;
2339
    Release;
2340
  end;
2341
  if isButton1 in DXInput.States then
2342
  begin
2343
    PlaySound('SceneMov', False);
2344
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2345
    Sleep(200);
2346
    StartScene(gsMain);
2347
  end;
2348
end;
2349
 
2350
procedure TMainForm.OptionMusicClick(Sender: TObject);
2351
begin
2352
  OptionMusic.Checked := not OptionMusic.Checked;
2353
  if OptionMusic.Checked then
2354
  begin
2355
    PlayMusic(FMusic)
2356
  end
2357
  else
2358
  begin
2359
    DestroyMusic(FMusic);
2360
  end;
2361
  WriteOptions;
2362
end;
2363
 
2364
procedure TMainForm.MasterClick(Sender: TObject);
2365
begin
2366
  master.checked := true;
2367
  FInterval := giMaster;
2368
  writeoptions;
2369
end;
2370
 
2371
procedure TEnemyMeteor.DoMove(MoveCount: Integer);
2372
begin
2373
  X := X - MoveCount*(250/1000);
2374
  if X < -Width then Dead;
2375
end;
2376
 
2377
procedure TEnemyMeteor.HitEnemy(ADead: Boolean);
2378
begin
7 daniel-mar 2379
  inherited HitEnemy(False);
2380
 
3 daniel-mar 2381
  if ADead then Collisioned := True;
2382
end;
2383
 
2384
{procedure TMainForm.StopMusic;
2385
begin
2386
  PauseMusic(FMusic);
2387
  MCISendString(pchar('seek "'+FDirectory+'Musik\Boss.mid" to start'), nil, 255, 0);
2388
  MCISendString(pchar('seek "'+FDirectory+'Musik\Game.mid" to start'), nil, 255, 0);
2389
  MCISendString(pchar('seek "'+FDirectory+'Musik\Title.mid" to start'), nil, 255, 0);
2390
  MCISendString(pchar('seek "'+FDirectory+'Musik\Scene.mid" to start'), nil, 255, 0);
2391
end;}
2392
 
2393
procedure TMainForm.ResumeMusic(Name: TMusicTrack);
2394
begin
2395
  if not OptionMusic.checked then exit;
2396
  if Name = mtBoss then
2397
    MCISendString(pchar('play "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
2398
  if Name = mtGame then
2399
    MCISendString(pchar('play "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
2400
  if Name = mtScene then
2401
    MCISendString(pchar('play "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
2402
  if Name = mtTitle then
2403
    MCISendString(pchar('play "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
2404
end;
2405
 
7 daniel-mar 2406
constructor TEnemyMeteor.Create(AParent: TSprite; ALifes: integer);
3 daniel-mar 2407
begin
7 daniel-mar 2408
  inherited Create(AParent, ALifes);
3 daniel-mar 2409
  Image := MainForm.ImageList.Items.Find('Enemy-Meteor');
2410
  Width := Image.Width;
2411
  Height := Image.Height;
2412
  AnimCount := Image.PatternCount;
2413
  AnimLooped := True;
4 daniel-mar 2414
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 2415
  PixelCheck := True;
2416
end;
2417
 
2418
procedure TMainForm.SpielstandClick(Sender: TObject);
2419
begin
2420
  speicherungform.showmodal;
2421
end;
2422
 
2423
procedure TMainForm.NeustartClick(Sender: TObject);
2424
begin
2425
  FLife := Lives;
2426
  FLevel := 1; // ???
2427
  FScore := 0;
7 daniel-mar 2428
  EnemyCounter := 0;
3 daniel-mar 2429
  StartScene(gsMain);
2430
  PlayMusic(mtGame);
2431
end;
2432
 
2433
procedure TMainForm.OptionBreitbildClick(Sender: TObject);
2434
begin
2435
  OptionBreitbild.Checked := not OptionBreitbild.Checked;
2436
  DXInit;
2437
  writeoptions;
2438
end;
2439
 
2440
procedure TMainForm.LeichtClick(Sender: TObject);
2441
begin
2442
  leicht.checked := true;
2443
  FInterval := giLeicht;
2444
  writeoptions;
2445
end;
2446
 
2447
procedure TMainForm.MittelClick(Sender: TObject);
2448
begin
2449
  mittel.checked := true;
2450
  FInterval := giMittel;
2451
  writeoptions;
2452
end;
2453
 
2454
procedure TMainForm.SchwerClick(Sender: TObject);
2455
begin
2456
  schwer.checked := true;
2457
  FInterval := giSchwer;
2458
  writeoptions;
2459
end;
2460
 
2461
procedure TMainForm.FormShow(Sender: TObject);
2462
begin
7 daniel-mar 2463
  if Assigned(SplashForm) then
2464
  begin
2465
    SplashForm.Hide;
2466
    FreeAndNil(SplashForm);
2467
  end;
3 daniel-mar 2468
 
2469
  dxtimer.Enabled := true;
2470
  dxtimer.ActiveOnly := true;
2471
end;
2472
 
2473
procedure TMainForm.InformationenClick(Sender: TObject);
2474
begin
2475
  dxtimer.enabled := false;
2476
  InfoForm.showmodal;
2477
  if not mainform.gamepause.checked then mainform.dxtimer.enabled := true;
2478
end;
2479
 
2480
procedure TMainForm.CheatClick(Sender: TObject);
2481
begin
2482
  CheatForm.showmodal;
2483
end;
2484
 
2485
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
2486
begin
2487
  if optionMusic.checked then DestroyMusic(FMusic);
2488
  SpriteEngine.Engine.Clear;
2489
  dxsound.Finalize;
2490
  dxinput.Destroy;
2491
  DXTimer.Enabled := False;
2492
end;
2493
 
2494
procedure TMainForm.FormDestroy(Sender: TObject);
2495
begin
7 daniel-mar 2496
  imagelist.Free;
2497
  spriteengine.Free;
3 daniel-mar 2498
  dxdraw.Free;
7 daniel-mar 2499
  wavelist.Free;
2500
  dxsound.Free;
2501
  //dxinput.Free;
3 daniel-mar 2502
  dxtimer.Free;
7 daniel-mar 2503
  DeleteCriticalSection(TimerCS);
14 daniel-mar 2504
  LevelData.Free;
3 daniel-mar 2505
end;
2506
 
2507
end.
2508