Subversion Repositories spacemission

Rev

Rev 11 | Rev 15 | 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
//              Pausiertes Spiel: Fenster bewegen lässt das Spiel wieder starten
18
//              Zwei Fenster in Taskleiste
19
//              "Doku" in Hilfemenü einbinden, ggf. auch den Leveleditor ins Menü machen
20
//              Highscore Liste
21
//              Multilingual
22
//              Levelconverter entfernen, stattdessen einlesen abwärtskompatibel machen
23
//              hintergrundmusik als WAV anstelle MIDI
11 daniel-mar 24
 
3 daniel-mar 25
interface
26
 
27
uses
28
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, MMSystem, Dialogs,
6 daniel-mar 29
  StdCtrls, ExtCtrls, Menus, DIB, DXClass, DXSprite, DXDraws, DXInput, DXSounds,
14 daniel-mar 30
  INIFiles, ShellAPI, wininet, DirectX{$IF CompilerVersion >= 23.0},
31
  System.UITypes{$IFEND}, ComLevelReader;
3 daniel-mar 32
 
33
type
34
  TGameScene = (
35
    gsNone,
36
    gsTitle,
37
    gsMain,
38
    gsGameOver,
39
    gsNewLevel,
40
    gsWin
41
  );
42
 
43
  TGameInterval = (
44
    giMittel,
45
    giLeicht,
46
    giSchwer,
47
    giMaster
48
  );
49
 
50
  TMusicTrack = (
51
    mtNone,
52
    mtGame,
53
    mtBoss,
54
    mtScene,
55
    mtTitle
56
  );
57
 
58
  {TSoundFile = (
59
    sfNone,
60
    sfSceneMov,
61
    sfExplosion,
62
    sfHit,
63
    sfShoot,
64
    sfDanger,
65
    sfEnde,
66
    sfFrage,
67
    sfLevIntro
68
  );}
69
 
70
  TBackground = class(TBackgroundSprite)
71
  private
72
    FSpeed: Double;
73
  protected
74
    procedure DoMove(MoveCount: Integer); override;
75
  end;
76
 
77
  TBackgroundSpecial = class(TBackgroundSprite)
78
  private
79
    FSpeed: Double;
80
  protected
81
    procedure DoMove(MoveCount: Integer); override;
82
  end;
83
 
84
  TExplosion = class(TImageSprite)
85
  private
86
    FCounter: Integer;
87
  protected
88
    procedure DoMove(MoveCount: Integer); override;
89
  public
90
    constructor Create(AParent: TSprite); override;
91
  end;
92
 
93
  TPlayerSprite = class(TImageSprite)
94
  private
95
    FCounter: Integer;
96
    FMode: Integer;
97
    FTamaCount: Integer;
98
    FOldTamaTime: Integer;
99
  protected
100
    procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
101
    procedure DoMove(MoveCount: Integer); override;
102
  public
103
    constructor Create(AParent: TSprite); override;
104
    procedure FlyAway;
105
  end;
106
 
107
  TTamaSprite = class(TImageSprite)
108
  private
109
    FPlayerSprite: TPlayerSprite;
110
  protected
111
    procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
112
    procedure DoMove(MoveCount: Integer); override;
113
  public
114
    constructor Create(AParent: TSprite); override;
115
    destructor Destroy; override;
116
  end;
117
 
7 daniel-mar 118
  TEnemyClass = class of TEnemy;
3 daniel-mar 119
  TEnemy = class(TImageSprite)
120
  private
121
    FCounter: Integer;
122
    FLife: integer;
123
    FMode: Integer;
124
  protected
125
    procedure HitEnemy(ADead: Boolean); virtual;
126
  public
7 daniel-mar 127
    procedure Hit(AHitStrength: integer = 1);
11 daniel-mar 128
    constructor Create(AParent: TSprite; ALifes: integer); reintroduce; virtual;
3 daniel-mar 129
    destructor Destroy; override;
130
  end;
131
 
132
  TEnemyTama = class(TImageSprite)
133
  private
134
    FPlayerSprite: TSprite;
135
  protected
136
    procedure DoMove(MoveCount: Integer); override;
137
  public
138
    constructor Create(AParent: TSprite); override;
139
  end;
140
 
141
  TEnemyMeteor = class(TEnemy)
142
  protected
143
    procedure DoMove(MoveCount: Integer); override;
144
    procedure HitEnemy(ADead: Boolean); override;
145
  public
7 daniel-mar 146
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 147
  end;
148
 
149
  TEnemyUFO = class(TEnemy)
150
  protected
151
    procedure DoMove(MoveCount: Integer); override;
152
    procedure HitEnemy(ADead: Boolean); override;
153
  public
7 daniel-mar 154
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 155
  end;
156
 
157
  TEnemyUFO2 = class(TEnemy)
158
  private
159
    FCounter: Integer;
160
    FTamaCount: Integer;
161
    FOldTamaTime: Integer;
162
  protected
163
    procedure DoMove(MoveCount: Integer); override;
164
    procedure HitEnemy(ADead: Boolean); override;
165
  public
7 daniel-mar 166
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 167
  end;
168
 
169
  TEnemyAttacker = class(TEnemy)
170
  protected
171
    procedure DoMove(MoveCount: Integer); override;
172
    procedure HitEnemy(ADead: Boolean); override;
173
  public
7 daniel-mar 174
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 175
  end;
176
 
177
  TEnemyAttacker2 = class(TEnemy)
178
  private
179
    FCounter: Integer;
180
    FTamaF: Integer;
181
    FTamaT: Integer;
182
    FPutTama: Boolean;
183
  protected
184
    procedure DoMove(MoveCount: Integer); override;
185
    procedure HitEnemy(ADead: Boolean); override;
186
  public
7 daniel-mar 187
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 188
  end;
189
 
190
  TEnemyAttacker3 = class(TEnemy)
191
  private
192
    FCounter: Integer;
193
    FTamaCount: Integer;
194
    FOldTamaTime: Integer;
195
  protected
196
    procedure DoMove(MoveCount: Integer); override;
197
    procedure HitEnemy(ADead: Boolean); override;
198
  public
7 daniel-mar 199
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 200
  end;
201
 
202
  TEnemyBoss = class(TEnemy)
203
  private
204
    FCounter: Integer;
205
    FTamaF: Integer;
206
    FTamaT: Integer;
207
    FPutTama: Boolean;
208
    waiter1, waiter2: integer;
209
  protected
210
    procedure DoMove(MoveCount: Integer); override;
211
    procedure HitEnemy(ADead: Boolean); override;
212
  public
7 daniel-mar 213
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 214
  end;
215
 
216
  TMainForm = class(TDXForm)
217
    MainMenu: TMainMenu;
218
    Spiel: TMenuItem;
219
    GameStart: TMenuItem;
220
    GamePause: TMenuItem;
221
    Beenden: TMenuItem;
222
    Einstellungen: TMenuItem;
223
    OptionFullScreen: TMenuItem;
224
    OptionMusic: TMenuItem;
225
    Leer2: TMenuItem;
226
    Leer4: TMenuItem;
227
    Hilfe: TMenuItem;
228
    OptionSound: TMenuItem;
229
    Leer3: TMenuItem;
230
    Spielstand: TMenuItem;
231
    Leer5: TMenuItem;
232
    Neustart: TMenuItem;
233
    OptionBreitbild: TMenuItem;
234
    Spielgeschwindigkeit: TMenuItem;
235
    Leicht: TMenuItem;
236
    Mittel: TMenuItem;
237
    Schwer: TMenuItem;
238
    Informationen: TMenuItem;
239
    Leer6: TMenuItem;
240
    Leer1: TMenuItem;
241
    Cheat: TMenuItem;
242
    CheckUpdates: TMenuItem;
243
    Master: TMenuItem;
244
    procedure DXDrawFinalize(Sender: TObject);
245
    procedure DXDrawInitialize(Sender: TObject);
246
    procedure FormCreate(Sender: TObject);
247
    procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
248
    procedure DXTimerActivate(Sender: TObject);
249
    procedure DXTimerDeactivate(Sender: TObject);
250
    procedure OptionFullScreenClick(Sender: TObject);
251
    procedure DXDrawInitializing(Sender: TObject);
252
    procedure GameStartClick(Sender: TObject);
253
    procedure GamePauseClick(Sender: TObject);
254
    procedure BeendenClick(Sender: TObject);
255
    procedure OptionSoundClick(Sender: TObject);
256
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
257
    procedure OptionMusicClick(Sender: TObject);
258
    procedure SpielstandClick(Sender: TObject);
259
    procedure NeustartClick(Sender: TObject);
260
    procedure OptionBreitbildClick(Sender: TObject);
261
    procedure LeichtClick(Sender: TObject);
262
    procedure MittelClick(Sender: TObject);
263
    procedure SchwerClick(Sender: TObject);
264
    procedure FormShow(Sender: TObject);
265
    procedure InformationenClick(Sender: TObject);
266
    procedure CheatClick(Sender: TObject);
267
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
268
    procedure FormDestroy(Sender: TObject);
269
    procedure CheckUpdatesClick(Sender: TObject);
270
    procedure MasterClick(Sender: TObject);
271
  private
272
    ProgrammGestartet: boolean;
273
    FInterval: TGameInterval;
274
    FScene: TGameScene;
275
    FMusic: TMusicTrack;
276
    FBlink: DWORD;
277
    FBlinkTime: DWORD;
278
    FFrame, FAngle, FCounter, FEnemyAdventPos: Integer;
279
    PlayerSprite: TPlayerSprite;
7 daniel-mar 280
    TimerCS: TRTLCriticalSection;
14 daniel-mar 281
    LevelData: TLevelData;
3 daniel-mar 282
    procedure StartScene(Scene: TGameScene);
283
    procedure EndScene;
284
    procedure BlinkStart;
285
    procedure BlinkUpdate;
286
    procedure StartSceneTitle;
287
    procedure SceneTitle;
288
    procedure EndSceneTitle;
289
    procedure StartSceneMain;
290
    procedure SceneMain;
291
    procedure EndSceneMain;
292
    procedure StartSceneGameOver;
293
    procedure SceneGameOver;
294
    procedure EndSceneGameOver;
295
    procedure StartSceneWin;
296
    procedure SceneWin;
297
    procedure EndSceneWin;
298
    procedure StartSceneNewLevel;
299
    procedure SceneNewLevel;
300
    procedure EndSceneNewLevel;
14 daniel-mar 301
    function GetLevelFileName(lev: integer): string;
3 daniel-mar 302
  public
303
    FNextScene: TGameScene;
304
    FScore: Integer;
305
    FNotSave: boolean;
306
    FLife: integer;
307
    FLevel: integer;
308
    FMenuItem: integer;
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
1184
  Ergebnis: string;
1185
  daten: textfile;
1186
  ok: boolean;
1187
begin
14 daniel-mar 1188
  LevelData := TLevelData.Create;
1189
 
3 daniel-mar 1190
  { Beginne VCL-Ersatz }
1191
  dxtimer := tdxtimer.Create(self);
1192
  dxtimer.Interval := 33;
1193
  dxtimer.OnActivate := DXTimerActivate;
1194
  dxtimer.OnDeactivate := DXTimerDeactivate;
1195
  dxtimer.OnTimer := DXTimerTimer;
1196
  dxtimer.ActiveOnly := false;
1197
  dxtimer.Enabled := false;
1198
 
1199
  dxdraw := tdxdraw.Create(self);
1200
  dxdraw.Parent := self;
1201
  dxdraw.Align := alClient;
1202
  dxdraw.Left := 0;
1203
  dxdraw.Top := 0;
1204
  dxdraw.Width := 640;
1205
  dxdraw.Height := 480;
1206
  dxdraw.AutoInitialize := False;
1207
  dxdraw.AutoSize := False;
1208
  dxdraw.Color := clBlack;
1209
  dxdraw.Display.BitCount := 24;
1210
  dxdraw.Display.FixedBitCount := False;
1211
  dxdraw.Display.FixedRatio := False;
1212
  dxdraw.Display.FixedSize := False;
1213
  dxdraw.Display.Height := 600;
1214
  dxdraw.Display.Width := 800;
4 daniel-mar 1215
  dxdraw.Options := [doAllowReboot, doWaitVBlank, doAllowPalette256, doCenter, {doRetainedMode,} doHardware, doSelectDriver];
3 daniel-mar 1216
  dxdraw.TabOrder := 0;
1217
  dxdraw.Visible := true;
1218
  dxdraw.OnFinalize := DXDrawFinalize;
1219
  dxdraw.OnInitialize := DXDrawInitialize;
1220
  dxdraw.OnInitializing := DXDrawInitializing;
1221
 
1222
  dxsound := tdxsound.Create(self);
1223
  dxsound.AutoInitialize := false;
1224
 
1225
  dxinput := tdxinput.Create(self);
1226
  dxinput.Joystick.ForceFeedback := true;
1227
  dxinput.Keyboard.ForceFeedback := true;
1228
 
1229
  wavelist := tdxwavelist.Create(self);
1230
  wavelist.DXSound := dxsound;
1231
 
1232
  imagelist := tdximagelist.create(self);
1233
  imagelist.DXDraw := dxdraw;
1234
 
1235
  spriteengine := tdxspriteengine.create(self);
1236
  spriteengine.DXDraw := dxdraw;
1237
 
7 daniel-mar 1238
  InitializeCriticalSection(TimerCS);
1239
 
3 daniel-mar 1240
  { Ende VCL-Ersatz }
1241
 
1242
  Application.Title := 'SpaceMission '+ProgramVersion;
1243
  LoadOptions;
1244
  DXInit;
1245
  SoundInit;
1246
  MusicInit;
14 daniel-mar 1247
  ResetLevelData;
3 daniel-mar 1248
  if (paramcount = 0) and (fileexists(paramstr(1))) then // (paramcount > 0)
1249
  begin
14 daniel-mar 1250
    // TODO: In "ComSavegameReader.pas" auslagern, so wie bei "ComLevelReader.pas" 
3 daniel-mar 1251
    AssignFile(daten, paramstr(1));
1252
    Reset(daten);
1253
    ok := true;
1254
    ReadLN(daten, Ergebnis);
1255
    if Ergebnis <> '; SpaceMission '+ProgramVersion then ok := false;
1256
    ReadLN(daten, Ergebnis);
1257
    if ergebnis <> '; SAV-File' then ok := false;
1258
    if not ok then
1259
    begin
1260
      showmessage(FileError);
1261
      CloseFile(daten);
1262
      GameStartClick(GameStart);
1263
      exit;
1264
    end;
1265
    ReadLN(daten, mainform.FScore);
1266
    ReadLN(daten, mainform.FLife);
1267
    ReadLN(daten, mainform.Flevel);
1268
    ReadLN(daten, mainform.FMenuItem);
1269
    CloseFile(daten);
1270
    mainform.FNextScene := gsNewLevel;
1271
    exit;
1272
  end;
1273
  GameStartClick(GameStart);
1274
end;
1275
 
1276
procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
1277
  Shift: TShiftState);
1278
begin
1279
  if (ssAlt in Shift) and (Key=VK_RETURN) then
1280
    OptionFullScreenClick(OptionFullScreen);
1281
end;
1282
 
1283
procedure TMainForm.GameStartClick(Sender: TObject);
1284
begin
1285
  StartScene(gsTitle);
1286
end;
1287
 
1288
procedure TMainForm.GamePauseClick(Sender: TObject);
1289
begin
1290
  GamePause.Checked := not GamePause.Checked;
1291
  DXTimer.Enabled := not GamePause.Checked;
7 daniel-mar 1292
  if GamePause.Checked then
1293
    PauseMusic(FMusic)
1294
  else
3 daniel-mar 1295
    ResumeMusic(FMusic);
1296
end;
1297
 
1298
// http://www.delphipraxis.net/post43515.html
1299
Function GetHTML(AUrl: string): string;
1300
var
1301
  databuffer : array[0..4095] of char;
1302
  ResStr : string;
1303
  hSession, hfile: hInternet;
1304
  dwindex,dwcodelen,dwread,dwNumber: cardinal;
1305
  dwcode : array[1..20] of char;
1306
  res    : pchar;
1307
  Str    : pchar;
1308
begin
1309
  ResStr:='';
1310
  if system.pos('http://',lowercase(AUrl))=0 then
1311
     AUrl:='http://'+AUrl;
1312
 
1313
  // Hinzugefügt
1314
  application.ProcessMessages;
1315
 
1316
  hSession:=InternetOpen('InetURL:/1.0',
1317
                         INTERNET_OPEN_TYPE_PRECONFIG,
1318
                         nil,
1319
                         nil,
1320
                         0);
1321
  if assigned(hsession) then
1322
  begin
1323
    // Hinzugefügt
1324
    application.ProcessMessages;
1325
 
1326
    hfile:=InternetOpenUrl(
1327
           hsession,
1328
           pchar(AUrl),
1329
           nil,
1330
           0,
1331
           INTERNET_FLAG_RELOAD,
1332
           0);
1333
    dwIndex  := 0;
1334
    dwCodeLen := 10;
1335
 
1336
    // Hinzugefügt
1337
    application.ProcessMessages;
1338
 
1339
    HttpQueryInfo(hfile,
1340
                  HTTP_QUERY_STATUS_CODE,
1341
                  @dwcode,
1342
                  dwcodeLen,
1343
                  dwIndex);
1344
    res := pchar(@dwcode);
1345
    dwNumber := sizeof(databuffer)-1;
1346
    if (res ='200') or (res ='302') then
1347
    begin
1348
      while (InternetReadfile(hfile,
1349
                              @databuffer,
1350
                              dwNumber,
1351
                              DwRead)) do
1352
      begin
1353
 
1354
        // Hinzugefügt
1355
        application.ProcessMessages;
1356
 
1357
        if dwRead =0 then
1358
          break;
1359
        databuffer[dwread]:=#0;
1360
        Str := pchar(@databuffer);
1361
        resStr := resStr + Str;
1362
      end;
1363
    end
1364
    else
1365
      ResStr := 'Status:'+res;
1366
    if assigned(hfile) then
1367
      InternetCloseHandle(hfile);
1368
  end;
1369
 
1370
  // Hinzugefügt
1371
  application.ProcessMessages;
1372
 
1373
  InternetCloseHandle(hsession);
1374
  Result := resStr;
1375
end;
1376
 
1377
procedure TMainForm.CheckUpdatesClick(Sender: TObject);
1378
var
14 daniel-mar 1379
  cont: string;
3 daniel-mar 1380
begin
14 daniel-mar 1381
  cont := GetHTML('http://www.viathinksoft.de/update/?id=spacemission');
1382
  if copy(cont, 0, 7) = 'Status:' then
3 daniel-mar 1383
  begin
14 daniel-mar 1384
    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 1385
  end
1386
  else
1387
  begin
1388
    if GetHTML('http://www.viathinksoft.de/update/?id=spacemission') <> ProgramVersion then
1389
    begin
1390
      if Application.MessageBox('Eine neue Programmversion ist vorhanden. Möchten Sie diese jetzt herunterladen?', 'Information', MB_YESNO + MB_ICONASTERISK) = ID_YES then
1391
        shellexecute(application.handle, 'open', pchar('http://www.viathinksoft.de/update/?id=@spacemission'), '', '', sw_normal);
1392
    end
1393
    else
1394
    begin
1395
      Application.MessageBox('Es ist keine neue Programmversion vorhanden.', 'Information', MB_OK + MB_ICONASTERISK);
1396
    end;
1397
  end;
1398
end;
1399
 
1400
procedure TMainForm.BeendenClick(Sender: TObject);
1401
begin
1402
  close;
1403
end;
1404
 
1405
procedure TMainForm.OptionFullScreenClick(Sender: TObject);
1406
begin
1407
  OptionFullScreen.Checked := not OptionFullScreen.Checked;
1408
  DXInit;
1409
  writeoptions;
1410
end;
1411
 
1412
procedure TMainForm.OptionSoundClick(Sender: TObject);
1413
begin
1414
  OptionSound.Checked := not OptionSound.Checked;
1415
  SoundInit;
1416
  WriteOptions;
1417
end;
1418
 
1419
procedure TMainForm.SoundInit;
1420
begin
1421
  if OptionSound.Checked then
1422
  begin
1423
    if not DXSound.Initialized then
1424
    begin
1425
      try
1426
        DXSound.Initialize;
1427
        WaveList.Items.LoadFromFile(FDirectory+'DirectX\Sound.dxw');
1428
      except
1429
        OptionSound.enabled := False;
1430
        WaveList.items.clear;
1431
      end;
1432
    end;
1433
  end
1434
  else DXSound.Finalize;
1435
end;
1436
 
1437
procedure TMainForm.MusicInit;
1438
begin
1439
  optionmusic.enabled := SoundKarte;
1440
end;
1441
 
1442
procedure TMainForm.DestroyMusic(Name: TMusicTrack);
1443
begin
1444
  if Name = mtBoss then
1445
  begin
1446
    MCISendString(pchar('stop "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1447
    MCISendString(pchar('close "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1448
  end;
1449
  if Name = mtGame then
1450
  begin
1451
    MCISendString(pchar('stop "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1452
    MCISendString(pchar('close "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1453
  end;
1454
  if Name = mtScene then
1455
  begin
1456
    MCISendString(pchar('stop "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1457
    MCISendString(pchar('close "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1458
  end;
1459
  if Name = mtTitle then
1460
  begin
1461
    MCISendString(pchar('stop "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1462
    MCISendString(pchar('close "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1463
  end;
1464
end;
1465
 
1466
procedure TMainForm.OpenMusic(Name: TMusicTrack);
1467
begin
1468
  if Name = mtBoss then
1469
    MCISendString(pchar('open "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1470
  if Name = mtGame then
1471
    MCISendString(pchar('open "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1472
  if Name = mtScene then
1473
    MCISendString(pchar('open "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1474
  if Name = mtTitle then
1475
    MCISendString(pchar('open "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1476
end;
1477
 
1478
procedure TMainForm.PauseMusic(Name: TMusicTrack);
1479
begin
1480
  if not OptionMusic.checked then exit;
1481
  if Name = mtBoss then
1482
    MCISendString(pchar('stop "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1483
  if Name = mtGame then
1484
    MCISendString(pchar('stop "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1485
  if Name = mtScene then
1486
    MCISendString(pchar('stop "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1487
  if Name = mtTitle then
1488
    MCISendString(pchar('stop "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1489
end;
1490
 
1491
procedure TMainForm.DXDrawInitializing(Sender: TObject);
1492
begin
1493
  if doFullScreen in DXDraw.Options then
1494
  begin
1495
    BorderStyle := bsNone;
1496
    DXDraw.Cursor := crNone;
7 daniel-mar 1497
  end
1498
  else
3 daniel-mar 1499
  begin
1500
    BorderStyle := bsSingle;
1501
    DXDraw.Cursor := crDefault;
1502
  end;
1503
end;
1504
 
1505
procedure TMainForm.DXDrawInitialize(Sender: TObject);
1506
begin
1507
  DXTimer.Enabled := True;
1508
end;
1509
 
1510
procedure TMainForm.DXDrawFinalize(Sender: TObject);
1511
begin
1512
  DXTimer.Enabled := False;
1513
end;
1514
 
1515
procedure TMainForm.DXTimerActivate(Sender: TObject);
1516
begin
1517
  Caption := Application.Title;
1518
  if not ProgrammGestartet then
1519
  begin
1520
    Programmgestartet := true;
1521
    exit;
1522
  end;
1523
  ResumeMusic(FMusic);
1524
end;
1525
 
1526
procedure TMainForm.DXTimerDeactivate(Sender: TObject);
1527
begin
1528
  Caption := Application.Title + ' [Pause]';
1529
  PauseMusic(FMusic);
1530
end;
1531
 
1532
function TMainForm.StatusMusic(Name: TMusicTrack): string;
1533
var
1534
  MCIStatus: array[0..255] of char;
1535
begin
1536
  if not OptionMusic.checked then exit;
1537
  if FMusic = mtGame then
1538
    MCISendString(pchar('status "'+FDirectory+'Musik\Game.mid" mode'), MCIStatus, 255, 0);
1539
  if FMusic = mtBoss then
1540
    MCISendString(pchar('status "'+FDirectory+'Musik\Boss.mid" mode'), MCIStatus, 255, 0);
1541
  if FMusic = mtScene then
1542
    MCISendString(pchar('status "'+FDirectory+'Musik\Scene.mid" mode'), MCIStatus, 255, 0);
1543
  if FMusic = mtTitle then
1544
    MCISendString(pchar('status "'+FDirectory+'Musik\Title.mid" mode'), MCIStatus, 255, 0);
1545
  result := MCIStatus;
1546
end;
1547
 
1548
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
1549
begin
7 daniel-mar 1550
  EnterCriticalSection(TimerCS);
1551
  try
1552
    if StatusMusic(FMusic) = 'stopped' then
1553
      PlayMusic(FMusic); {...}
1554
    if crash then
3 daniel-mar 1555
    begin
7 daniel-mar 1556
      inc(Crash2);
1557
      if crash2 = 30 then
1558
      begin
1559
        Crash2 := 0;
1560
        crash := false;
1561
        crashsound := false;
1562
      end;
3 daniel-mar 1563
    end;
7 daniel-mar 1564
    if not DXDraw.CanDraw then exit;
1565
    DXInput.Update;
1566
    case FScene of
1567
      gsTitle   : SceneTitle;
1568
      gsMain    : SceneMain;
1569
      gsGameOver: SceneGameOver;
1570
      gsWin     : SceneWin;
1571
      gsNewLevel: SceneNewLevel;
1572
    end;
1573
    if FNextScene<>gsNone then
1574
    begin
1575
      StartScene(FNextScene);
1576
      FNextScene := gsNone;
1577
    end;
1578
    DXDraw.Flip;
1579
  finally
1580
    LeaveCriticalSection(TimerCS);
3 daniel-mar 1581
  end;
1582
end;
1583
 
1584
procedure TMainForm.BlinkStart;
1585
begin
1586
  FBlink := 0;
1587
  FBlinkTime := GetTickCount;
1588
end;
1589
 
1590
procedure TMainForm.WriteOptions;
1591
var
1592
  INIDatei: TIniFile;
1593
begin
1594
  INIDatei := TIniFile.Create(FDirectory+'Einstellungen\SpaceMission.ini');
7 daniel-mar 1595
  try
1596
    if OptionMusic.checked then INIDatei.WriteBool('Settings', 'Music', true)
1597
      else INIDatei.WriteBool('Settings', 'Music', false);
1598
    if OptionSound.checked then INIDatei.WriteBool('Settings', 'Sound', true)
1599
      else INIDatei.WriteBool('Settings', 'Sound', false);
1600
    if OptionFullScreen.checked then INIDatei.WriteBool('Settings', 'FullScreen', true)
1601
      else INIDatei.WriteBool('Settings', 'FullScreen', false);
1602
    if OptionBreitbild.checked then INIDatei.WriteBool('Settings', 'ScreenAutoSize', true)
1603
      else INIDatei.WriteBool('Settings', 'ScreenAutoSize', false);
1604
    if FInterval = giLeicht then INIDatei.WriteInteger('Settings', 'Speed', 1);
1605
    if FInterval = giMittel then INIDatei.WriteInteger('Settings', 'Speed', 2);
1606
    if FInterval = giSchwer then INIDatei.WriteInteger('Settings', 'Speed', 3);
1607
    if FInterval = giMaster then INIDatei.WriteInteger('Settings', 'Speed', 4);
1608
  finally
1609
    INIDatei.Free;
1610
  end;
3 daniel-mar 1611
end;
1612
 
1613
procedure TMainForm.LoadOptions;
1614
var
1615
  INIDatei: TIniFile;
1616
begin
1617
  INIDatei := TIniFile.Create(FDirectory+'Einstellungen\SpaceMission.ini');
7 daniel-mar 1618
  try
1619
    optionmusic.checked := INIDatei.ReadBool('Settings', 'Music', true);
1620
    optionsound.checked := INIDatei.ReadBool('Settings', 'Sound', true);
1621
    optionfullscreen.checked := INIDatei.ReadBool('Settings', 'fullscreen', false);
1622
    OptionBreitBild.checked := INIDatei.ReadBool('Settings', 'ScreenAutoSize', true);
1623
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 1 then
1624
    begin
1625
      FInterval := giLeicht;
1626
      Leicht.checked := true;
1627
    end;
1628
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 2 then
1629
    begin
1630
      FInterval := giMittel;
1631
      Mittel.checked := true;
1632
    end;
1633
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 3 then
1634
    begin
1635
      FInterval := giSchwer;
1636
      Schwer.checked := true;
1637
    end;
1638
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 4 then
1639
    begin
1640
      FInterval := giMaster;
1641
      Master.checked := true;
1642
    end;
1643
  finally
1644
    INIDatei.Free;
3 daniel-mar 1645
  end;
1646
  WriteOptions;
1647
end;
1648
 
1649
procedure TMainForm.BlinkUpdate;
1650
begin
1651
  if GetTickCount<>FBlinkTime then
1652
  begin
1653
    FBlink := FBlink + (GetTickCount-FBlinkTime);
1654
    FBlinkTime := GetTickCount;
1655
  end;
1656
end;
1657
 
1658
procedure TMainForm.PlaySound(Name: string; Wait: Boolean);
1659
begin
1660
  if (OptionSound.Checked) and (OptionSound.Enabled) then
1661
    WaveList.Items.Find(Name).Play(Wait);
1662
end;
1663
 
1664
procedure TMainForm.PlayMusic(Name: TMusicTrack);
1665
begin
1666
  if (not mainform.active) and (mainform.visible) then //1st Programmstart
1667
    exit;
1668
  if (OptionMusic.checked) and (OptionMusic.enabled) then
1669
  begin
1670
    DestroyMusic(FMusic);
1671
    OpenMusic(Name);
1672
    ResumeMusic(Name);
1673
  end;
1674
  FMusic := Name;
1675
end;
1676
 
1677
function TMainForm.ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
1678
begin
1679
  with Result do
1680
  begin
1681
    rgbRed := Src.rgbRed+((Dest.rgbRed-Src.rgbRed)*Percent div 256);
1682
    rgbGreen := Src.rgbGreen+((Dest.rgbGreen-Src.rgbGreen)*Percent div 256);
1683
    rgbBlue := Src.rgbBlue+((Dest.rgbBlue-Src.rgbBlue)*Percent div 256);
1684
    rgbReserved := 0;
1685
  end;
1686
end;
1687
 
1688
procedure TMainForm.PalleteAnim(Col: TRGBQuad; Time: Integer);
1689
var
1690
  i: Integer;
1691
  t, t2: DWORD;
1692
  ChangePalette: Boolean;
1693
  c: Integer;
1694
begin
1695
  if DXDraw.Initialized then
1696
  begin
1697
    c := DXDraw.Surface.ColorMatch(RGB(Col.rgbRed, Col.rgbGreen, Col.rgbBlue));
1698
    ChangePalette := False;
1699
    if DXDraw.CanPaletteAnimation then
1700
    begin
1701
      t := GetTickCount;
1702
      while Abs(GetTickCount-t)<Time do
1703
      begin
1704
        t2 := Trunc(Abs(GetTickCount-t)/Time*255);
1705
        for i := 0 to 255 do
1706
          DXDraw.ColorTable[i] := ComposeColor(Col, DXDraw.DefColorTable[i], t2);
1707
        DXDraw.UpdatePalette;
1708
        ChangePalette := True;
1709
      end;
7 daniel-mar 1710
    end
1711
    else
1712
    begin
3 daniel-mar 1713
      Sleep(Time);
7 daniel-mar 1714
    end;
3 daniel-mar 1715
    for i := 0 to 4 do
1716
    begin
1717
      DXDraw.Surface.Fill(c);
1718
      DXDraw.Flip;
1719
    end;
1720
    if ChangePalette then
1721
    begin
1722
      DXDraw.ColorTable := DXDraw.DefColorTable;
1723
      DXDraw.UpdatePalette;
1724
    end;
1725
    DXDraw.Surface.Fill(c);
1726
    DXDraw.Flip;
1727
  end;
1728
end;
1729
 
1730
procedure TMainForm.StartScene(Scene: TGameScene);
1731
begin
1732
  EndScene;
1733
  DXInput.States := DXInput.States - DXInputButton;
1734
  FScene := Scene;
1735
  BlinkStart;
1736
  case FScene of
1737
    gsTitle   : StartSceneTitle;
1738
    gsMain    : StartSceneMain;
1739
    gsGameOver: StartSceneGameOver;
1740
    gsWin     : StartSceneWin;
1741
    gsNewLevel: StartSceneNewLevel;
1742
  end;
1743
end;
1744
 
1745
procedure TMainForm.StartSceneTitle;
1746
begin
1747
  sleep(500);
1748
  FCheat := false;
1749
  BossExists := false;
1750
  FLife := Lives;
1751
  FLevel := 0;
1752
  FScore := 0;
1753
  FNotSave := true;
1754
  Cheat.enabled := false;
1755
  Neustart.enabled := false;
1756
  GamePause.enabled := false;
1757
  GameStart.enabled := false;
1758
  Spielgeschwindigkeit.enabled := false;
1759
  mainform.Visible := true;
1760
  PlayMusic(mtTitle);
1761
end;
1762
 
1763
procedure TMainForm.StartSceneMain;
1764
{var
1765
  i, j: Integer;}
1766
begin
1767
  sleep(500);
1768
  FCounter := 0;
1769
  NewLevel(FLevel);
1770
  BossExists := false;
1771
  PlayMusic(mtGame);
7 daniel-mar 1772
  FEnemyAdventPos := 0;
3 daniel-mar 1773
  FFrame := -4;
1774
  PlayerSprite := TPlayerSprite.Create(SpriteEngine.Engine);
1775
  with TBackground.Create(SpriteEngine.Engine) do
1776
  begin
1777
    SetMapSize(1, 1);
1778
    Image := mainform.ImageList.Items.Find('Star3');
1779
    Z := -13;
1780
    Y := 40;
1781
    FSpeed := 1 / 2;
1782
    Tile := True;
1783
  end;
1784
  with TBackground.Create(SpriteEngine.Engine) do
1785
  begin
1786
    SetMapSize(1, 1);
1787
    Image := mainform.ImageList.Items.Find('Star2');
1788
    Z := -12;
1789
    Y := 30;
1790
    FSpeed := 1;
1791
    Tile := True;
1792
  end;
1793
  with TBackground.Create(SpriteEngine.Engine) do
1794
  begin
1795
    SetMapSize(1, 1);
1796
    Image := mainform.ImageList.Items.Find('Star1');
1797
    Z := -11;
1798
    Y := 10;
1799
    FSpeed := 2;
1800
    Tile := True;
1801
  end;
1802
  {with TBackground.Create(SpriteEngine.Engine) do
1803
  begin
1804
    SetMapSize(200, 10);
1805
    Y := 10;
1806
    Z := -13;
1807
    FSpeed := 1 / 2;
1808
    Tile := True;
1809
    for i := 0 to MapHeight-1 do
1810
    begin
1811
      for j := 0 to MapWidth-1 do
1812
      begin
1813
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 8);
1814
        if Random(100)<95 then Chips[j, i] := -1;
1815
      end;
1816
    end;
1817
  end;
1818
  with TBackground.Create(SpriteEngine.Engine) do
1819
  begin
1820
    SetMapSize(200, 10);
1821
    Y := 30;
1822
    Z := -12;
1823
    FSpeed := 1;
1824
    Tile := True;
1825
    for i := 0 to MapHeight-1 do
1826
    begin
1827
      for j := 0 to MapWidth-1 do
1828
      begin
1829
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 4);
1830
        if Random(100)<95 then Chips[j, i] := -1;
1831
      end;
1832
    end;
1833
  end;
1834
  with TBackground.Create(SpriteEngine.Engine) do
1835
  begin
1836
    SetMapSize(200, 10);
1837
    Y := 40;
1838
    Z := -11;
1839
    FSpeed := 2;
1840
    Tile := True;
1841
    for i := 0 to MapHeight-1 do
1842
    begin
1843
      for j := 0 to MapWidth-1 do
1844
      begin
1845
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 2);
1846
        if Random(100)<95 then Chips[j, i] := -1;
1847
      end;
1848
    end;
1849
  end;}
1850
  FNotSave := false;
1851
  Cheat.enabled := true;
1852
  Neustart.enabled := true;
1853
  GamePause.enabled := true;
1854
  GameStart.enabled := true;
1855
  Spielgeschwindigkeit.enabled := true;
1856
end;
1857
 
1858
procedure TMainForm.StartSceneGameOver;
1859
begin
1860
  sleep(500);
1861
  FNotSave := true;
1862
  Cheat.enabled := false;
1863
  Spielgeschwindigkeit.enabled := false;
1864
  Neustart.enabled := false;
1865
  GamePause.enabled := false;
1866
  PlayMusic(mtScene);
1867
  BossExists := false;
1868
end;
1869
 
1870
procedure TMainForm.StartSceneWin;
1871
begin
1872
  sleep(500);
1873
  FNotSave := true;
1874
  Cheat.enabled := false;
1875
  Spielgeschwindigkeit.enabled := false;
1876
  Neustart.enabled := false;
1877
  GamePause.enabled := false;
1878
  PlayMusic(mtScene);
1879
  BossExists := false;
1880
end;
1881
 
1882
procedure TMainForm.EndScene;
1883
begin
1884
  case FScene of
1885
    gsTitle   : EndSceneTitle;
1886
    gsMain    : EndSceneMain;
1887
    gsGameOver: EndSceneGameOver;
1888
    gsWin     : EndSceneWin;
1889
    gsNewLevel: EndSceneNewLevel;
1890
  end;
1891
end;
1892
 
1893
procedure TMainForm.EndSceneTitle;
1894
begin
1895
  {  Ende Title  }
1896
end;
1897
 
1898
procedure TMainForm.EndSceneMain;
1899
begin
1900
  SpriteEngine.Engine.Clear;
1901
end;
1902
 
1903
procedure TMainForm.EndSceneGameOver;
1904
begin
1905
  {  Ende GameOver  }
1906
end;
1907
 
1908
procedure TMainForm.EndSceneWin;
1909
begin
1910
  {  Ende Win  }
1911
end;
1912
 
14 daniel-mar 1913
procedure TMainForm.ResetLevelData;
3 daniel-mar 1914
begin
14 daniel-mar 1915
  LevelData.Clear;
7 daniel-mar 1916
  FRestEnemies := 0;
3 daniel-mar 1917
end;
1918
 
7 daniel-mar 1919
const
1920
  ADDITIONAL_ENEMIES_PER_LEVEL = 75;
1921
 
14 daniel-mar 1922
function TMainForm.GetLevelFileName(lev: integer): string;
7 daniel-mar 1923
begin
1924
  result := FDirectory+'Levels\Level '+inttostr(lev)+'.lev';
1925
end;
1926
 
3 daniel-mar 1927
procedure TMainForm.NewLevel(lev: integer);
1928
resourcestring
1929
  LNG_LEVEL_INVALID = 'Das Level Nr. %d ist ungültig!'+#13#10+'Das Programm wird beendet.';
1930
var
1931
  act: integer;
14 daniel-mar 1932
  Enemies: array[1..27] of TEnemyType;
7 daniel-mar 1933
  e: TEnemyAdvent;
3 daniel-mar 1934
begin
14 daniel-mar 1935
  ResetLevelData;
3 daniel-mar 1936
  if FMenuItem = 2 then
1937
  begin
14 daniel-mar 1938
    {$REGION 'Random game'}
1939
    Enemies[1] := etEnemyAttacker;
1940
    Enemies[2] := etEnemyMeteor;
1941
    Enemies[3] := etEnemyUFO;
1942
    Enemies[4] := etEnemyAttacker;
1943
    Enemies[5] := etEnemyMeteor;
1944
    Enemies[6] := etEnemyUFO;
1945
    Enemies[7] := etEnemyAttacker;
1946
    Enemies[8] := etEnemyMeteor;
1947
    Enemies[9] := etEnemyUFO;
1948
    Enemies[10] := etEnemyAttacker;
1949
    Enemies[11] := etEnemyMeteor;
1950
    Enemies[12] := etEnemyUFO;
1951
    Enemies[13] := etEnemyAttacker;
1952
    Enemies[14] := etEnemyMeteor;
1953
    Enemies[15] := etEnemyUFO;
1954
    Enemies[16] := etEnemyAttacker3;
1955
    Enemies[17] := etEnemyAttacker;
1956
    Enemies[18] := etEnemyMeteor;
1957
    Enemies[19] := etEnemyUFO;
1958
    Enemies[20] := etEnemyUFO2;
1959
    Enemies[21] := etEnemyAttacker;
1960
    Enemies[22] := etEnemyMeteor;
1961
    Enemies[23] := etEnemyUFO;
1962
    Enemies[24] := etEnemyAttacker2;
1963
    Enemies[25] := etEnemyMeteor;
1964
    Enemies[26] := etEnemyUFO;
1965
    Enemies[27] := etEnemyAttacker;
3 daniel-mar 1966
    randomize;
7 daniel-mar 1967
    FRestEnemies := lev*ADDITIONAL_ENEMIES_PER_LEVEL+1;
14 daniel-mar 1968
    SetLength(LevelData.EnemyAdventTable, FRestEnemies);
7 daniel-mar 1969
    for act := 0 to lev*ADDITIONAL_ENEMIES_PER_LEVEL-1 do
3 daniel-mar 1970
    begin
14 daniel-mar 1971
      e.enemyType := Enemies[min(random(lev+2)+1, High(Enemies))];
1972
      if e.enemyType = etEnemyAttacker2 then
7 daniel-mar 1973
      begin
14 daniel-mar 1974
        e.enemyType := Enemies[min(random(lev+2)+1, High(Enemies))]; {O_o}
7 daniel-mar 1975
      end;
1976
      e.x := act*30 + random(85-(lev+(random(lev))*2)){O_o};
1977
      e.y := random(dxdraw.surfaceheight);
14 daniel-mar 1978
      if e.enemyType = etEnemyAttacker2 then
7 daniel-mar 1979
      begin
1980
        e.lifes := random(6)+1{O_o};
1981
      end
1982
      else
1983
      begin
1984
        e.lifes := random(lev)+1;
1985
      end;
1986
 
14 daniel-mar 1987
      LevelData.EnemyAdventTable[act] := e;
3 daniel-mar 1988
    end;
14 daniel-mar 1989
    e.enemyType := etEnemyBoss;
7 daniel-mar 1990
    e.x := lev*75*30{O_o} div lev;
1991
    e.y := (dxdraw.surfaceheight div 2) - (MainForm.ImageList.Items.Find('Enemy-boss').height div 2);
1992
    e.lifes := lev*5;
14 daniel-mar 1993
    LevelData.EnemyAdventTable[lev*ADDITIONAL_ENEMIES_PER_LEVEL] := e;
1994
    Assert(FRestEnemies = Length(LevelData.EnemyAdventTable));
1995
    {$ENDREGION}
3 daniel-mar 1996
  end
1997
  else
1998
  begin
14 daniel-mar 1999
    {$REGION 'Normal game'}
7 daniel-mar 2000
    if fileexists(GetLevelFileName(lev)) then
3 daniel-mar 2001
    begin
7 daniel-mar 2002
      try
14 daniel-mar 2003
        LevelData.Load(GetLevelFileName(lev));
2004
        FRestEnemies := Length(LevelData.EnemyAdventTable);
7 daniel-mar 2005
      except
2006
        showmessage(Format(LNG_LEVEL_INVALID, [lev]));
14 daniel-mar 2007
        ResetLevelData;
3 daniel-mar 2008
      end;
2009
    end;
14 daniel-mar 2010
    {$ENDREGION}
3 daniel-mar 2011
  end;
2012
end;
2013
 
2014
procedure TMainForm.SceneTitle;
2015
var
2016
  Logo: TPictureCollectionItem;
2017
begin
2018
  DXDraw.Surface.Fill(0);
2019
  Logo := ImageList.Items.Find('Logo');
2020
  {Logo.DrawWaveX(DXDraw.Surface, (dxdraw.surfaceWidth div 2) - 181, 65, Logo.Width, Logo.Height, 0,
2021
    Trunc(16 - Cos256(FBlink div 60) * 16), 32, -FBlink div 5);}
2022
  Logo.DrawWaveX(DXDraw.Surface, trunc((dxdraw.surfaceWidth / 2) - (Logo.Width / 2)), 65, Logo.Width, Logo.Height, 0,
2023
    2, 80, Fangle * 4);
2024
  inc(Fangle);
2025
  with DXDraw.Surface.Canvas do
2026
  begin
2027
    if (isDown in MainForm.DXInput.States) and (FMenuItem=1) then FMenuItem := 2;
2028
    if ((isUp in MainForm.DXInput.States) and (FMenuItem=2)) or (FMenuItem=0) then FMenuItem := 1;
2029
    Brush.Style := bsClear;
2030
    Font.Size := 30;
2031
    if FMenuItem = 1 then
2032
    begin
2033
      Font.Color := clMaroon;
2034
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-52, 'Normales Spiel');
2035
      Textout((dxdraw.surfaceWidth div 2)-187, (dxdraw.surfaceheight div 2)-52, '>');
2036
      Font.Color := clRed;
2037
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)-50, 'Normales Spiel');
2038
      Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)-50, '>');
2039
      Font.Color := clOlive;
2040
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-2, 'Zufallslevel');
2041
      Font.Color := clYellow;
2042
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2), 'Zufallslevel');
2043
    end
2044
    else
2045
    begin
2046
      Font.Color := clOlive;
2047
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-52, 'Normales Spiel');
2048
      Font.Color := clYellow;
2049
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)-50, 'Normales Spiel');
2050
      Font.Color := clMaroon;
2051
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-2, 'Zufallslevel');
2052
      Textout((dxdraw.surfaceWidth div 2)-187, (dxdraw.surfaceheight div 2)-2, '>');
2053
      Font.Color := clRed;
2054
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2), 'Zufallslevel');
2055
      Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2), '>');
2056
    end;
2057
    { if (FBlink div 300) mod 2=0 then
2058
    begin
2059
      Font.Color := clGreen;
2060
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2061
      Font.Color := clLime;
2062
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2063
    end; }
2064
    BlinkUpdate;
2065
    Release;
2066
  end;
2067
  // Weiter mit Leertaste oder Enter
2068
  if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
2069
  begin
2070
    FLevel := 1;
7 daniel-mar 2071
    if ((FMenuItem=1) and not fileexists(GetLevelFileName(FLevel))) or ((FMenuItem=2) and (FLevel > 20)) then
3 daniel-mar 2072
    begin
2073
      //PlaySound('Frage', False);
2074
      exit;
2075
    end;
2076
    NewLevel(FLevel);
2077
    PlaySound('SceneMov', False);
2078
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2079
    Sleep(200);
2080
    StartScene(gsMain);
2081
  end;
2082
end;
2083
 
2084
procedure TMainForm.SceneMain;
2085
var
2086
  Enemy: TSprite;
14 daniel-mar 2087
  spriteClass: TEnemyClass;
3 daniel-mar 2088
begin
7 daniel-mar 2089
  case FInterval of
2090
    giMittel: SpriteEngine.Move(conleicht);
2091
    giLeicht: SpriteEngine.Move(conmittel);
2092
    giSchwer: SpriteEngine.Move(conschwer);
2093
    giMaster: SpriteEngine.Move(conmaster);
2094
  end;
3 daniel-mar 2095
  SpriteEngine.Dead;
14 daniel-mar 2096
  while (FEnemyAdventPos >= Low(LevelData.EnemyAdventTable)) and
2097
    (FEnemyAdventPos <= High(LevelData.EnemyAdventTable)) and
2098
    ((LevelData.EnemyAdventTable[FEnemyAdventPos].x / 4) <= FFrame) and
7 daniel-mar 2099
    (FRestEnemies > 0) do
3 daniel-mar 2100
  begin
7 daniel-mar 2101
    Dec(FRestEnemies);
14 daniel-mar 2102
    with LevelData.EnemyAdventTable[FEnemyAdventPos] do
3 daniel-mar 2103
    begin
14 daniel-mar 2104
      spriteClass := nil;
2105
      case enemyType of
2106
        //etUnknown: ;
2107
        etEnemyAttacker:  spriteClass := TEnemyAttacker;
2108
        etEnemyAttacker2: spriteClass := TEnemyAttacker2;
2109
        etEnemyAttacker3: spriteClass := TEnemyAttacker3;
2110
        etEnemyMeteor:    spriteClass := TEnemyMeteor;
2111
        etEnemyUFO:       spriteClass := TEnemyUFO;
2112
        etEnemyUFO2:      spriteClass := TEnemyUFO2;
2113
        etEnemyBoss:      spriteClass := TEnemyBoss;
2114
      end;
2115
      if spriteClass <> nil then
2116
      begin
2117
        Enemy := spriteClass.Create(SpriteEngine.Engine, lifes);
2118
        Enemy.x := dxdraw.surfacewidth;
2119
        //Enemy.y := y;
2120
        if y <> 0 then
2121
          Enemy.y := dxdraw.surfaceheight / (480{maximale Bandbreite im alten Format} / y)
2122
        else
2123
          Enemy.y := 0;
2124
      end;
3 daniel-mar 2125
    end;
2126
    Inc(FEnemyAdventPos);
2127
  end;
2128
  Inc(FFrame);
2129
  DXDraw.Surface.Fill(0);
2130
  if FNextScene=gsNone then
2131
  begin
2132
    SpriteEngine.Draw;
2133
    if MainForm.flife > 0 then
2134
    begin
2135
      with DXDraw.Surface.Canvas do
2136
      begin
2137
        Brush.Style := bsClear;
2138
        Font.Size := 20;
2139
        Font.Color := clOlive;
2140
        Textout(9, 9, 'Punkte: ' + FloatToStrF(FScore,ffNumber,14,0));
2141
        Font.Color := clYellow;
2142
        Textout(10, 10, 'Punkte: ' + FloatToStrF(FScore,ffNumber,14,0));
2143
        Font.Color := clMaroon;
2144
        Textout(dxdraw.surfacewidth-141, 9, 'Level: ' + IntToStr(MainForm.flevel));
2145
        Font.Color := clRed;
2146
        Textout(dxdraw.surfacewidth-140, 10, 'Level: ' + IntToStr(MainForm.flevel));
2147
        if FLife<0 then mainform.FLife := 0;
2148
        if FCheat then
2149
        begin
2150
          Font.Color := clPurple;
2151
          Textout(9, dxdraw.surfaceheight-41, 'Leben: ?');
2152
          Font.Color := clFuchsia;
2153
          Textout(10, dxdraw.surfaceheight-40, 'Leben: ?');
2154
        end
2155
        else
2156
        begin
2157
          if ((Flife = 1) and ((FBlink div 300) mod 2=0)) or (Flife <> 1) then
2158
          begin
2159
            Font.Color := clPurple;
2160
            Textout(9, dxdraw.surfaceheight-41, 'Leben: ' + IntToStr(MainForm.flife));
2161
            Font.Color := clFuchsia;
2162
            Textout(10, dxdraw.surfaceheight-40, 'Leben: ' + IntToStr(MainForm.flife));
2163
          end;
2164
          if Flife = 1 then BlinkUpdate;
2165
        end;
2166
        {if BossExists and (FBossLife>0) then
2167
        begin
2168
          Font.Color := clPurple;
2169
          Textout(449, 439, 'Boss: ' + IntToStr(FBossLife));
2170
          Font.Color := clFuchsia;
2171
          Textout(450, 440, 'Boss: ' + IntToStr(FBossLife));
2172
        end
2173
        else
2174
          if RestlicheEinheiten>0 then
2175
          begin
2176
            Font.Color := clPurple;
2177
            Textout(449, 439, 'Einheiten: ' + IntToStr(RestlicheEinheiten));
2178
            Font.Color := clFuchsia;
2179
            Textout(450, 440, 'Einheiten: ' + IntToStr(RestlicheEinheiten));
2180
          end;}
2181
        if BossExists and (FBossLife>0) then
2182
        begin
7 daniel-mar 2183
          if (FRestEnemies>0) then
3 daniel-mar 2184
          begin
2185
            Font.Color := clGreen;
2186
            Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-81, 'Boss: ' + IntToStr(FBossLife));
7 daniel-mar 2187
            Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2188
            Font.Color := clLime;
2189
            Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-80, 'Boss: ' + IntToStr(FBossLife));
7 daniel-mar 2190
            Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2191
          end;
7 daniel-mar 2192
          if (FRestEnemies<1) then
3 daniel-mar 2193
          begin
2194
            Font.Color := clGreen;
2195
            Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Boss: ' + IntToStr(FBossLife));
2196
            Font.Color := clLime;
2197
            Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Boss: ' + IntToStr(FBossLife));
2198
          end;
2199
        end;
7 daniel-mar 2200
        if (FRestEnemies>0) and not Bossexists then
3 daniel-mar 2201
        begin
2202
          Font.Color := clGreen;
7 daniel-mar 2203
          Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2204
          Font.Color := clLime;
7 daniel-mar 2205
          Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2206
        end;
2207
        Release;
2208
      end;
2209
    end
2210
    else
2211
    begin
2212
      DXDraw.Surface.Canvas.Font.Color := clGreen; // Grüne schrift bei gescheitert? FIXME
2213
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, 'Mission gescheitert!');
2214
      DXDraw.Surface.Canvas.Font.Color := clLime;
2215
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, 'Mission gescheitert!');
2216
      DXDraw.Surface.Canvas.Release;
2217
    end;
7 daniel-mar 2218
    if (EnemyCounter=0) and (FRestEnemies=0){ and (SpielerFliegtFort = false)}
3 daniel-mar 2219
    and ((BossExists and (FBossLife=0)) or not BossExists) then
2220
    begin
2221
      DXDraw.Surface.Canvas.Font.Color := clGreen;
2222
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, 'Mission erfolgreich!');
2223
      DXDraw.Surface.Canvas.Font.Color := clLime;
2224
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, 'Mission erfolgreich!');
2225
      DXDraw.Surface.Canvas.Release;
2226
      Sleep(1);
2227
      inc(FCounter);
2228
      if FCounter>150{200} then PlayerSprite.FlyAway;
2229
    end;
2230
  end;
2231
end;
2232
 
2233
procedure TMainForm.SceneGameOver;
2234
begin
2235
  DXDraw.Surface.Fill(0);
2236
  with DXDraw.Surface.Canvas do
2237
  begin
2238
    FNotSave := true;
2239
    Cheat.enabled := false;
2240
    GamePause.enabled := false;
2241
    Neustart.enabled := false;
2242
    Brush.Style := bsClear;
2243
    Font.Size := 35;
2244
    Font.Color := clMaroon;
11 daniel-mar 2245
    Textout((dxdraw.surfacewidth div 2)-127, 98, 'Game Over!');
3 daniel-mar 2246
    Font.Color := clRed;
11 daniel-mar 2247
    Textout((dxdraw.surfacewidth div 2)-125, 100, 'Game Over!');
3 daniel-mar 2248
    if (FBlink div 300) mod 2=0 then
2249
    begin
2250
      Font.Size := 30;
2251
      Font.Color := clOlive;
2252
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2253
      Font.Color := clYellow;
2254
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2255
    end;
2256
    BlinkUpdate;
2257
    Release;
2258
  end;
2259
  if isButton1 in DXInput.States then
2260
  begin
2261
    PlaySound('SceneMov', False);
2262
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2263
    Sleep(200);
2264
    StartScene(gsTitle);
2265
  end;
2266
end;
2267
 
2268
procedure TMainForm.SceneWin;
2269
begin
2270
  DXDraw.Surface.Fill(0);
2271
  with DXDraw.Surface.Canvas do
2272
  begin
2273
    FNotSave := true;
2274
    Cheat.enabled := false;
2275
    GamePause.enabled := false;
2276
    Neustart.enabled := false;
2277
    Brush.Style := bsClear;
2278
    Font.Size := 35;
2279
    Font.Color := clMaroon;
2280
    Textout((dxdraw.surfaceWidth div 2)-127, 98, 'Gewonnen!');
2281
    Font.Color := clRed;
2282
    Textout((dxdraw.surfaceWidth div 2)-125, 100, 'Gewonnen!');
2283
    if (FBlink div 300) mod 2=0 then
2284
    begin
2285
      Font.Size := 30;
2286
      Font.Color := clOlive;
2287
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2288
      Font.Color := clYellow;
2289
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2290
    end;
2291
    BlinkUpdate;
2292
    Release;
2293
  end;
2294
  if isButton1 in DXInput.States then
2295
  begin
2296
    PlaySound('SceneMov', False);
2297
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2298
    Sleep(200);
2299
    StartScene(gsTitle);
2300
  end;
2301
end;
2302
 
2303
procedure TMainForm.StartSceneNewLevel;
2304
begin
2305
  sleep(500);
2306
  FNotSave := false;
2307
  Cheat.enabled := false;
2308
  Neustart.enabled := false;
2309
  GamePause.enabled := false;
2310
  GameStart.enabled := true;
2311
  Spielgeschwindigkeit.enabled := false;
2312
  BossExists := false;
2313
  Spielgeschwindigkeit.enabled := false;
14 daniel-mar 2314
  if ((FMenuItem=1) and (not fileexists(GetLevelFileName(FLevel)))) or ((FMenuItem=2) and (FLevel > 25)) then
3 daniel-mar 2315
  begin
2316
    //PlaySound('SceneMov', False);
2317
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2318
    Sleep(200);
2319
    StartScene(gsWin);
2320
    exit;
2321
  end;
2322
  PlayMusic(mtScene);
2323
end;
2324
 
2325
procedure TMainForm.EndSceneNewLevel;
2326
begin
2327
  {  Ende NewLevel  }
2328
end;
2329
 
2330
procedure TMainForm.SceneNewLevel;
2331
begin
2332
  DXDraw.Surface.Fill(0);
2333
  with DXDraw.Surface.Canvas do
2334
  begin
2335
    Brush.Style := bsClear;
2336
    Font.Size := 40;
2337
    Font.Color := clMaroon;
2338
    Textout((dxdraw.surfaceWidth div 2)-(83+(length(inttostr(flevel))*22)), 98, 'Level '+inttostr(flevel));
2339
    Font.Color := clRed;
2340
    Textout((dxdraw.surfaceWidth div 2)-(81+(length(inttostr(flevel))*22)), 100, 'Level '+inttostr(flevel));
2341
    if (FBlink div 300) mod 2=0 then
2342
    begin
2343
      Font.Size := 30;
2344
      Font.Color := clOlive;
2345
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2346
      Font.Color := clYellow;
2347
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2348
    end;
2349
    BlinkUpdate;
2350
    Release;
2351
  end;
2352
  if isButton1 in DXInput.States then
2353
  begin
2354
    PlaySound('SceneMov', False);
2355
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2356
    Sleep(200);
2357
    StartScene(gsMain);
2358
  end;
2359
end;
2360
 
2361
procedure TMainForm.OptionMusicClick(Sender: TObject);
2362
begin
2363
  OptionMusic.Checked := not OptionMusic.Checked;
2364
  if OptionMusic.Checked then
2365
  begin
2366
    PlayMusic(FMusic)
2367
  end
2368
  else
2369
  begin
2370
    DestroyMusic(FMusic);
2371
  end;
2372
  WriteOptions;
2373
end;
2374
 
2375
procedure TMainForm.MasterClick(Sender: TObject);
2376
begin
2377
  master.checked := true;
2378
  FInterval := giMaster;
2379
  writeoptions;
2380
end;
2381
 
2382
procedure TEnemyMeteor.DoMove(MoveCount: Integer);
2383
begin
2384
  X := X - MoveCount*(250/1000);
2385
  if X < -Width then Dead;
2386
end;
2387
 
2388
procedure TEnemyMeteor.HitEnemy(ADead: Boolean);
2389
begin
7 daniel-mar 2390
  inherited HitEnemy(False);
2391
 
3 daniel-mar 2392
  if ADead then Collisioned := True;
2393
end;
2394
 
2395
{procedure TMainForm.StopMusic;
2396
begin
2397
  PauseMusic(FMusic);
2398
  MCISendString(pchar('seek "'+FDirectory+'Musik\Boss.mid" to start'), nil, 255, 0);
2399
  MCISendString(pchar('seek "'+FDirectory+'Musik\Game.mid" to start'), nil, 255, 0);
2400
  MCISendString(pchar('seek "'+FDirectory+'Musik\Title.mid" to start'), nil, 255, 0);
2401
  MCISendString(pchar('seek "'+FDirectory+'Musik\Scene.mid" to start'), nil, 255, 0);
2402
end;}
2403
 
2404
procedure TMainForm.ResumeMusic(Name: TMusicTrack);
2405
begin
2406
  if not OptionMusic.checked then exit;
2407
  if Name = mtBoss then
2408
    MCISendString(pchar('play "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
2409
  if Name = mtGame then
2410
    MCISendString(pchar('play "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
2411
  if Name = mtScene then
2412
    MCISendString(pchar('play "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
2413
  if Name = mtTitle then
2414
    MCISendString(pchar('play "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
2415
end;
2416
 
7 daniel-mar 2417
constructor TEnemyMeteor.Create(AParent: TSprite; ALifes: integer);
3 daniel-mar 2418
begin
7 daniel-mar 2419
  inherited Create(AParent, ALifes);
3 daniel-mar 2420
  Image := MainForm.ImageList.Items.Find('Enemy-Meteor');
2421
  Width := Image.Width;
2422
  Height := Image.Height;
2423
  AnimCount := Image.PatternCount;
2424
  AnimLooped := True;
4 daniel-mar 2425
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 2426
  PixelCheck := True;
2427
end;
2428
 
2429
procedure TMainForm.SpielstandClick(Sender: TObject);
2430
begin
2431
  speicherungform.showmodal;
2432
end;
2433
 
2434
procedure TMainForm.NeustartClick(Sender: TObject);
2435
begin
2436
  FLife := Lives;
2437
  FLevel := 1; // ???
2438
  FScore := 0;
7 daniel-mar 2439
  EnemyCounter := 0;
3 daniel-mar 2440
  StartScene(gsMain);
2441
  PlayMusic(mtGame);
2442
end;
2443
 
2444
procedure TMainForm.OptionBreitbildClick(Sender: TObject);
2445
begin
2446
  OptionBreitbild.Checked := not OptionBreitbild.Checked;
2447
  DXInit;
2448
  writeoptions;
2449
end;
2450
 
2451
procedure TMainForm.LeichtClick(Sender: TObject);
2452
begin
2453
  leicht.checked := true;
2454
  FInterval := giLeicht;
2455
  writeoptions;
2456
end;
2457
 
2458
procedure TMainForm.MittelClick(Sender: TObject);
2459
begin
2460
  mittel.checked := true;
2461
  FInterval := giMittel;
2462
  writeoptions;
2463
end;
2464
 
2465
procedure TMainForm.SchwerClick(Sender: TObject);
2466
begin
2467
  schwer.checked := true;
2468
  FInterval := giSchwer;
2469
  writeoptions;
2470
end;
2471
 
2472
procedure TMainForm.FormShow(Sender: TObject);
2473
begin
7 daniel-mar 2474
  if Assigned(SplashForm) then
2475
  begin
2476
    SplashForm.Hide;
2477
    FreeAndNil(SplashForm);
2478
  end;
3 daniel-mar 2479
 
2480
  dxtimer.Enabled := true;
2481
  dxtimer.ActiveOnly := true;
2482
end;
2483
 
2484
procedure TMainForm.InformationenClick(Sender: TObject);
2485
begin
2486
  dxtimer.enabled := false;
2487
  InfoForm.showmodal;
2488
  if not mainform.gamepause.checked then mainform.dxtimer.enabled := true;
2489
end;
2490
 
2491
procedure TMainForm.CheatClick(Sender: TObject);
2492
begin
2493
  CheatForm.showmodal;
2494
end;
2495
 
2496
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
2497
begin
2498
  if optionMusic.checked then DestroyMusic(FMusic);
2499
  SpriteEngine.Engine.Clear;
2500
  dxsound.Finalize;
2501
  dxinput.Destroy;
2502
  DXTimer.Enabled := False;
2503
end;
2504
 
2505
procedure TMainForm.FormDestroy(Sender: TObject);
2506
begin
7 daniel-mar 2507
  imagelist.Free;
2508
  spriteengine.Free;
3 daniel-mar 2509
  dxdraw.Free;
7 daniel-mar 2510
  wavelist.Free;
2511
  dxsound.Free;
2512
  //dxinput.Free;
3 daniel-mar 2513
  dxtimer.Free;
7 daniel-mar 2514
  DeleteCriticalSection(TimerCS);
14 daniel-mar 2515
  LevelData.Free;
3 daniel-mar 2516
end;
2517
 
2518
end.
2519