Subversion Repositories spacemission

Rev

Rev 90 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 90 Rev 97
1
unit GamMain;
1
unit GamMain;
2
 
2
 
3
interface
3
interface
4
 
4
 
5
uses
5
uses
6
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
6
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7
  StdCtrls, ExtCtrls, Menus, DIB, DXClass, DXSprite, DXDraws, DXInput, DXSounds,
7
  StdCtrls, ExtCtrls, Menus, DIB, DXClass, DXSprite, DXDraws, DXInput, DXSounds,
8
  ShellAPI, DirectX{$IF CompilerVersion >= 23.0},
8
  ShellAPI, DirectX{$IF CompilerVersion >= 23.0},
9
  System.UITypes{$IFEND}, ComLevelReader, DirectMusic, Global;
9
  System.UITypes{$IFEND}, ComLevelReader, DirectMusic, Global;
10
 
10
 
11
type
11
type
12
  TGameScene = (
12
  TGameScene = (
13
    gsNone,
13
    gsNone,
14
    gsTitle,
14
    gsTitle,
15
    gsMain,
15
    gsMain,
16
    gsGameOver,
16
    gsGameOver,
17
    gsNewLevel,
17
    gsNewLevel,
18
    gsWin
18
    gsWin
19
  );
19
  );
20
 
20
 
21
  TGameInterval = (
21
  TGameInterval = (
22
    giLeicht,
22
    giLeicht,
23
    giMittel,
23
    giMittel,
24
    giSchwer,
24
    giSchwer,
25
    giMaster
25
    giMaster
26
  );
26
  );
27
 
27
 
28
  TBackground = class(TBackgroundSprite)
28
  TBackground = class(TBackgroundSprite)
29
  strict private
29
  strict private
30
    FSpeed: Double;
30
    FSpeed: Double;
31
  strict protected
31
  strict protected
32
    procedure DoMove(MoveCount: Integer); override;
32
    procedure DoMove(MoveCount: Integer); override;
33
  public
33
  public
34
    property Speed: Double read FSpeed write FSpeed;
34
    property Speed: Double read FSpeed write FSpeed;
35
  end;
35
  end;
36
 
36
 
37
  TBackgroundSpecial = class(TBackgroundSprite)
37
  TBackgroundSpecial = class(TBackgroundSprite)
38
  strict private
38
  strict private
39
    FSpeed: Double;
39
    FSpeed: Double;
40
  strict protected
40
  strict protected
41
    procedure DoMove(MoveCount: Integer); override;
41
    procedure DoMove(MoveCount: Integer); override;
42
  public
42
  public
43
    property Speed: Double read FSpeed write FSpeed;
43
    property Speed: Double read FSpeed write FSpeed;
44
  end;
44
  end;
45
 
45
 
46
  TExplosion = class(TImageSprite)
46
  TExplosion = class(TImageSprite)
47
  strict private
47
  strict private
48
    FCounter: Integer;
48
    FCounter: Integer;
49
  strict protected
49
  strict protected
50
    procedure DoMove(MoveCount: Integer); override;
50
    procedure DoMove(MoveCount: Integer); override;
51
  public
51
  public
52
    constructor Create(AParent: TSprite); override;
52
    constructor Create(AParent: TSprite); override;
53
  end;
53
  end;
54
 
54
 
55
  TPlayerOrEnemyOrItemState = (
55
  TPlayerOrEnemyOrItemState = (
56
    pesUnknown,
56
    pesUnknown,
57
    pesNormal,
57
    pesNormal,
58
    pesExploding, // only boss, as preparation of pesDead
58
    pesExploding, // only boss, as preparation of pesDead
59
    pesDead,
59
    pesDead,
60
    pesDeadVanished,
60
    pesDeadVanished,
61
    pesFlyaway, // only player at mission end
61
    pesFlyaway, // only player at mission end
62
    pesEntering,
62
    pesEntering,
63
    pesHovering // only some kind of enemies
63
    pesHovering // only some kind of enemies
64
  );
64
  );
65
 
65
 
66
  TPlayerOrEnemyOrItem = class abstract (TImageSprite)
66
  TPlayerOrEnemyOrItem = class abstract (TImageSprite)
67
  strict protected
67
  strict protected
68
    FState: TPlayerOrEnemyOrItemState;
68
    FState: TPlayerOrEnemyOrItemState;
69
  public
69
  public
70
    property State: TPlayerOrEnemyOrItemState read FState;
70
    property State: TPlayerOrEnemyOrItemState read FState;
71
  end;
71
  end;
72
 
72
 
73
  TPlayerSprite = class(TPlayerOrEnemyOrItem)
73
  TPlayerSprite = class(TPlayerOrEnemyOrItem)
74
  private
74
  private
75
    FTamaCount: Integer; // accessed by TPlayerTamaSprite.Destroy
75
    FTamaCount: Integer; // accessed by TPlayerTamaSprite.Destroy
76
  strict private
76
  strict private
77
    FCounter: Integer;
77
    FCounter: Integer;
78
    FOldTamaTime: Integer;
78
    FOldTamaTime: Integer;
79
  strict protected
79
  strict protected
80
    procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
80
    procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
81
    procedure DoMove(MoveCount: Integer); override;
81
    procedure DoMove(MoveCount: Integer); override;
82
  public
82
  public
83
    constructor Create(AParent: TSprite); override;
83
    constructor Create(AParent: TSprite); override;
84
    procedure FlyAway;
84
    procedure FlyAway;
85
  end;
85
  end;
86
 
86
 
87
  TPlayerTamaSprite = class(TImageSprite)
87
  TPlayerTamaSprite = class(TImageSprite)
88
  strict private
88
  strict private
89
    FPlayerSprite: TPlayerSprite;
89
    FPlayerSprite: TPlayerSprite;
90
  strict protected
90
  strict protected
91
    property PlayerSprite: TPlayerSprite read FPlayerSprite write FPlayerSprite;
91
    property PlayerSprite: TPlayerSprite read FPlayerSprite write FPlayerSprite;
92
    procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
92
    procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
93
    procedure DoMove(MoveCount: Integer); override;
93
    procedure DoMove(MoveCount: Integer); override;
94
  public
94
  public
95
    constructor Create(AParent: TSprite; APlayerSprite: TPlayerSprite); reintroduce;
95
    constructor Create(AParent: TSprite; APlayerSprite: TPlayerSprite); reintroduce;
96
    destructor Destroy; override;
96
    destructor Destroy; override;
97
  end;
97
  end;
98
 
98
 
99
  TEnemyClass = class of TEnemy;
99
  TEnemyClass = class of TEnemy;
100
  TEnemy = class abstract (TPlayerOrEnemyOrItem)
100
  TEnemy = class abstract (TPlayerOrEnemyOrItem)
101
  strict protected
101
  strict protected
102
    FCounter: Integer;
102
    FCounter: Integer;
103
    FLife: integer;
103
    FLife: integer;
104
    procedure HitEnemy(ADead: Boolean); virtual;
104
    procedure HitEnemy(ADead: Boolean); virtual;
105
  public
105
  public
106
    property Life: integer read FLife;
106
    property Life: integer read FLife;
107
    procedure Hit(AHitStrength: integer = 1);
107
    procedure Hit(AHitStrength: integer = 1);
108
    constructor Create(AParent: TSprite; ALifes: integer); reintroduce; virtual;
108
    constructor Create(AParent: TSprite; ALifes: integer); reintroduce; virtual;
109
    destructor Destroy; override;
109
    destructor Destroy; override;
110
  end;
110
  end;
111
 
111
 
112
  TEnemyTama = class(TImageSprite)
112
  TEnemyTama = class(TImageSprite)
113
  strict private
113
  strict private
114
    FEnemySprite: TSprite;
114
    FEnemySprite: TSprite;
115
  strict protected
115
  strict protected
116
    property EnemySprite: TSprite read FEnemySprite write FEnemySprite;
116
    property EnemySprite: TSprite read FEnemySprite write FEnemySprite;
117
    procedure DoMove(MoveCount: Integer); override;
117
    procedure DoMove(MoveCount: Integer); override;
118
  public
118
  public
119
    constructor Create(AParent: TSprite; AEnemySprite: TSprite); reintroduce;
119
    constructor Create(AParent: TSprite; AEnemySprite: TSprite); reintroduce;
120
  end;
120
  end;
121
 
121
 
122
  TEnemyMeteor = class(TEnemy)
122
  TEnemyMeteor = class(TEnemy)
123
  strict protected
123
  strict protected
124
    procedure DoMove(MoveCount: Integer); override;
124
    procedure DoMove(MoveCount: Integer); override;
125
    procedure HitEnemy(ADead: Boolean); override;
125
    procedure HitEnemy(ADead: Boolean); override;
126
  public
126
  public
127
    constructor Create(AParent: TSprite; ALifes: integer); override;
127
    constructor Create(AParent: TSprite; ALifes: integer); override;
128
  end;
128
  end;
129
 
129
 
130
  TEnemyUFO = class(TEnemy)
130
  TEnemyUFO = class(TEnemy)
131
  strict protected
131
  strict protected
132
    procedure DoMove(MoveCount: Integer); override;
132
    procedure DoMove(MoveCount: Integer); override;
133
    procedure HitEnemy(ADead: Boolean); override;
133
    procedure HitEnemy(ADead: Boolean); override;
134
  public
134
  public
135
    constructor Create(AParent: TSprite; ALifes: integer); override;
135
    constructor Create(AParent: TSprite; ALifes: integer); override;
136
  end;
136
  end;
137
 
137
 
138
  TEnemyUFO2 = class(TEnemy)
138
  TEnemyUFO2 = class(TEnemy)
139
  strict private
139
  strict private
140
    FCounter: Integer;
140
    FCounter: Integer;
141
    FTamaCount: Integer;
141
    FTamaCount: Integer;
142
    FOldTamaTime: Integer;
142
    FOldTamaTime: Integer;
143
  strict protected
143
  strict protected
144
    procedure DoMove(MoveCount: Integer); override;
144
    procedure DoMove(MoveCount: Integer); override;
145
    procedure HitEnemy(ADead: Boolean); override;
145
    procedure HitEnemy(ADead: Boolean); override;
146
  public
146
  public
147
    constructor Create(AParent: TSprite; ALifes: integer); override;
147
    constructor Create(AParent: TSprite; ALifes: integer); override;
148
  end;
148
  end;
149
 
149
 
150
  TEnemyAttacker = class(TEnemy)
150
  TEnemyAttacker = class(TEnemy)
151
  strict protected
151
  strict protected
152
    procedure DoMove(MoveCount: Integer); override;
152
    procedure DoMove(MoveCount: Integer); override;
153
    procedure HitEnemy(ADead: Boolean); override;
153
    procedure HitEnemy(ADead: Boolean); override;
154
  public
154
  public
155
    constructor Create(AParent: TSprite; ALifes: integer); override;
155
    constructor Create(AParent: TSprite; ALifes: integer); override;
156
  end;
156
  end;
157
 
157
 
158
  TEnemyAttacker2 = class(TEnemy)
158
  TEnemyAttacker2 = class(TEnemy)
159
  strict private
159
  strict private
160
    FCounter: Integer;
160
    FCounter: Integer;
161
    FTamaF: Integer;
161
    FTamaF: Integer;
162
    FTamaT: Integer;
162
    FTamaT: Integer;
163
    FPutTama: Boolean;
163
    FPutTama: Boolean;
164
  strict protected
164
  strict protected
165
    procedure DoMove(MoveCount: Integer); override;
165
    procedure DoMove(MoveCount: Integer); override;
166
    procedure HitEnemy(ADead: Boolean); override;
166
    procedure HitEnemy(ADead: Boolean); override;
167
  public
167
  public
168
    constructor Create(AParent: TSprite; ALifes: integer); override;
168
    constructor Create(AParent: TSprite; ALifes: integer); override;
169
  end;
169
  end;
170
 
170
 
171
  TEnemyAttacker3 = class(TEnemy)
171
  TEnemyAttacker3 = class(TEnemy)
172
  strict private
172
  strict private
173
    FCounter: Integer;
173
    FCounter: Integer;
174
    FTamaCount: Integer;
174
    FTamaCount: Integer;
175
    FOldTamaTime: Integer;
175
    FOldTamaTime: Integer;
176
  strict protected
176
  strict protected
177
    procedure DoMove(MoveCount: Integer); override;
177
    procedure DoMove(MoveCount: Integer); override;
178
    procedure HitEnemy(ADead: Boolean); override;
178
    procedure HitEnemy(ADead: Boolean); override;
179
  public
179
  public
180
    constructor Create(AParent: TSprite; ALifes: integer); override;
180
    constructor Create(AParent: TSprite; ALifes: integer); override;
181
  end;
181
  end;
182
 
182
 
183
  TEnemyBoss = class(TEnemy)
183
  TEnemyBoss = class(TEnemy)
184
  strict private
184
  strict private
185
    FCounter: Integer;
185
    FCounter: Integer;
186
    FTamaF: Integer;
186
    FTamaF: Integer;
187
    FTamaT: Integer;
187
    FTamaT: Integer;
188
    FPutTama: Boolean;
188
    FPutTama: Boolean;
189
    waiter1, waiter2: integer;
189
    waiter1, waiter2: integer;
190
  strict protected
190
  strict protected
191
    procedure DoMove(MoveCount: Integer); override;
191
    procedure DoMove(MoveCount: Integer); override;
192
    procedure HitEnemy(ADead: Boolean); override;
192
    procedure HitEnemy(ADead: Boolean); override;
193
  public
193
  public
194
    constructor Create(AParent: TSprite; ALifes: integer); override;
194
    constructor Create(AParent: TSprite; ALifes: integer); override;
195
    destructor Destroy; override;
195
    destructor Destroy; override;
196
  end;
196
  end;
197
 
197
 
198
  TItemClass = class of TItem;
198
  TItemClass = class of TItem;
199
  TItem = class abstract (TPlayerOrEnemyOrItem)
199
  TItem = class abstract (TPlayerOrEnemyOrItem)
200
  strict protected
200
  strict protected
201
    procedure DoMove(MoveCount: Integer); override;
201
    procedure DoMove(MoveCount: Integer); override;
202
  public
202
  public
203
    procedure Collected; virtual;
203
    procedure Collected; virtual;
204
  end;
204
  end;
205
 
205
 
206
  TItemMedikit = class(TItem)
206
  TItemMedikit = class(TItem)
207
  public
207
  public
208
    procedure Collected; override;
208
    procedure Collected; override;
209
    constructor Create(AParent: TSprite); override;
209
    constructor Create(AParent: TSprite); override;
210
  end;
210
  end;
211
 
211
 
212
  TMainForm = class(TDXForm)
212
  TMainForm = class(TDXForm)
213
    MainMenu: TMainMenu;
213
    MainMenu: TMainMenu;
214
    Spiel: TMenuItem;
214
    Spiel: TMenuItem;
215
    GameStart: TMenuItem;
215
    GameStart: TMenuItem;
216
    GamePause: TMenuItem;
216
    GamePause: TMenuItem;
217
    Beenden: TMenuItem;
217
    Beenden: TMenuItem;
218
    Einstellungen: TMenuItem;
218
    Einstellungen: TMenuItem;
219
    OptionMusic: TMenuItem;
219
    OptionMusic: TMenuItem;
220
    Hilfe: TMenuItem;
220
    Hilfe: TMenuItem;
221
    OptionSound: TMenuItem;
221
    OptionSound: TMenuItem;
222
    Leer3: TMenuItem;
222
    Leer3: TMenuItem;
223
    Spielstand: TMenuItem;
223
    Spielstand: TMenuItem;
224
    Leer5: TMenuItem;
224
    Leer5: TMenuItem;
225
    Neustart: TMenuItem;
225
    Neustart: TMenuItem;
226
    Spielgeschwindigkeit: TMenuItem;
226
    Spielgeschwindigkeit: TMenuItem;
227
    Leicht: TMenuItem;
227
    Leicht: TMenuItem;
228
    Mittel: TMenuItem;
228
    Mittel: TMenuItem;
229
    Schwer: TMenuItem;
229
    Schwer: TMenuItem;
230
    Informationen: TMenuItem;
230
    Informationen: TMenuItem;
231
    Leer6: TMenuItem;
231
    Leer6: TMenuItem;
232
    Leer1: TMenuItem;
232
    Leer1: TMenuItem;
233
    Cheat: TMenuItem;
233
    Cheat: TMenuItem;
234
    CheckUpdates: TMenuItem;
234
    CheckUpdates: TMenuItem;
235
    Master: TMenuItem;
235
    Master: TMenuItem;
236
    Hilfe1: TMenuItem;
236
    Hilfe1: TMenuItem;
237
    N1: TMenuItem;
237
    N1: TMenuItem;
238
    Wasgibtesneues1: TMenuItem;
238
    Wasgibtesneues1: TMenuItem;
239
    procedure DXDrawFinalize(Sender: TObject);
239
    procedure DXDrawFinalize(Sender: TObject);
240
    procedure DXDrawInitialize(Sender: TObject);
240
    procedure DXDrawInitialize(Sender: TObject);
241
    procedure FormCreate(Sender: TObject);
241
    procedure FormCreate(Sender: TObject);
242
    procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
242
    procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
243
    procedure DXTimerActivate(Sender: TObject);
243
    procedure DXTimerActivate(Sender: TObject);
244
    procedure DXTimerDeactivate(Sender: TObject);
244
    procedure DXTimerDeactivate(Sender: TObject);
245
    procedure DXDrawInitializing(Sender: TObject);
245
    procedure DXDrawInitializing(Sender: TObject);
246
    procedure GameStartClick(Sender: TObject);
246
    procedure GameStartClick(Sender: TObject);
247
    procedure GamePauseClick(Sender: TObject);
247
    procedure GamePauseClick(Sender: TObject);
248
    procedure BeendenClick(Sender: TObject);
248
    procedure BeendenClick(Sender: TObject);
249
    procedure OptionSoundClick(Sender: TObject);
249
    procedure OptionSoundClick(Sender: TObject);
250
    procedure OptionMusicClick(Sender: TObject);
250
    procedure OptionMusicClick(Sender: TObject);
251
    procedure SpielstandClick(Sender: TObject);
251
    procedure SpielstandClick(Sender: TObject);
252
    procedure NeustartClick(Sender: TObject);
252
    procedure NeustartClick(Sender: TObject);
253
    procedure LeichtClick(Sender: TObject);
253
    procedure LeichtClick(Sender: TObject);
254
    procedure MittelClick(Sender: TObject);
254
    procedure MittelClick(Sender: TObject);
255
    procedure SchwerClick(Sender: TObject);
255
    procedure SchwerClick(Sender: TObject);
256
    procedure MasterClick(Sender: TObject);
256
    procedure MasterClick(Sender: TObject);
257
    procedure FormShow(Sender: TObject);
257
    procedure FormShow(Sender: TObject);
258
    procedure InformationenClick(Sender: TObject);
258
    procedure InformationenClick(Sender: TObject);
259
    procedure CheatClick(Sender: TObject);
259
    procedure CheatClick(Sender: TObject);
260
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
260
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
261
    procedure FormDestroy(Sender: TObject);
261
    procedure FormDestroy(Sender: TObject);
262
    procedure CheckUpdatesClick(Sender: TObject);
262
    procedure CheckUpdatesClick(Sender: TObject);
263
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
263
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
264
    procedure HilfeTopicClick(Sender: TObject);
264
    procedure HilfeTopicClick(Sender: TObject);
265
  private
265
  private
266
    ProgrammGestartet: boolean;
266
    ProgrammGestartet: boolean;
267
    FSpeed: integer;
267
    FSpeed: integer;
268
    FScene: TGameScene;
268
    FScene: TGameScene;
269
    FMusic: TSpaceMissionMusicTrack;
269
    FMusic: TSpaceMissionMusicTrack;
270
    FBlink: DWORD;
270
    FBlink: DWORD;
271
    FBlinkTime: DWORD;
271
    FBlinkTime: DWORD;
272
    FFrame, FAngle, FCounter, FEnemyAdventPos: Integer;
272
    FFrame, FAngle, FCounter, FEnemyAdventPos: Integer;
273
    PlayerSprite: TPlayerSprite;
273
    PlayerSprite: TPlayerSprite;
274
    TimerCS: TRTLCriticalSection;
274
    TimerCS: TRTLCriticalSection;
275
    procedure StartScene(Scene: TGameScene);
275
    procedure StartScene(Scene: TGameScene);
276
    procedure EndScene;
276
    procedure EndScene;
277
    procedure BlinkStart;
277
    procedure BlinkStart;
278
    procedure BlinkUpdate;
278
    procedure BlinkUpdate;
279
    procedure StartSceneTitle;
279
    procedure StartSceneTitle;
280
    procedure SceneTitle;
280
    procedure SceneTitle;
281
    procedure EndSceneTitle;
281
    procedure EndSceneTitle;
282
    procedure StartSceneMain;
282
    procedure StartSceneMain;
283
    procedure SceneMain;
283
    procedure SceneMain;
284
    procedure EndSceneMain;
284
    procedure EndSceneMain;
285
    procedure StartSceneGameOver;
285
    procedure StartSceneGameOver;
286
    procedure SceneGameOver;
286
    procedure SceneGameOver;
287
    procedure EndSceneGameOver;
287
    procedure EndSceneGameOver;
288
    procedure StartSceneWin;
288
    procedure StartSceneWin;
289
    procedure SceneWin;
289
    procedure SceneWin;
290
    procedure EndSceneWin;
290
    procedure EndSceneWin;
291
    procedure StartSceneNewLevel;
291
    procedure StartSceneNewLevel;
292
    procedure SceneNewLevel;
292
    procedure SceneNewLevel;
293
    procedure EndSceneNewLevel;
293
    procedure EndSceneNewLevel;
294
    procedure LevelNeuStarten;
294
    procedure LevelNeuStarten;
295
  private
295
  private
296
    { Diverse temporäre Variablen }
296
    { Diverse temporäre Variablen }
297
    Crash2: integer;
297
    Crash2: integer;
298
    EnemyCounter: integer;
298
    EnemyCounter: integer;
299
    Crash: boolean;
299
    Crash: boolean;
300
    crashsound: boolean;
300
    crashsound: boolean;
301
  public
301
  public
302
    FNextScene: TGameScene;
302
    FNextScene: TGameScene;
303
    FScore: Integer;
303
    FScore: Integer;
304
    FBoss: TEnemyBoss;
304
    FBoss: TEnemyBoss;
305
    FNotSave: boolean;
305
    FNotSave: boolean;
306
    FLife: integer;
306
    FLife: integer;
307
    FLevel: integer;
307
    FLevel: integer;
308
    FGameMode: TGameMode;
308
    FGameMode: TGameMode;
309
    FLifeAtLevelStart: integer;
309
    FLifeAtLevelStart: integer;
310
    FScoreAtLevelStart: integer;
310
    FScoreAtLevelStart: integer;
311
    FLevelDataAlreadyLoaded: boolean;
311
    FLevelDataAlreadyLoaded: boolean;
312
    FRestEnemies: integer;
312
    FRestEnemies: integer;
313
    FCheats: TCheatSet;
313
    FCheats: TCheatSet;
314
    { VCL-Ersatz }
314
    { VCL-Ersatz }
315
    dxdraw: TDxDraw;
315
    dxdraw: TDxDraw;
316
    imagelist: TDxImageList;
316
    imagelist: TDxImageList;
317
    spriteengine: tdxspriteengine;
317
    spriteengine: tdxspriteengine;
318
    dxsound: tdxsound;
318
    dxsound: tdxsound;
319
    dxmusic: tdxmusic;
319
    dxmusic: tdxmusic;
320
    wavelist: tdxwavelist;
320
    wavelist: tdxwavelist;
321
    dxinput: tdxinput;
321
    dxinput: tdxinput;
322
    dxtimer: tdxtimer;
322
    dxtimer: tdxtimer;
323
    { Level-Routinen }
323
    { Level-Routinen }
324
    LevelData: TLevelData;
324
    LevelData: TLevelData;
325
    procedure NewLevel(lev: integer);
325
    procedure NewLevel(lev: integer);
326
    procedure ResetLevelData;
326
    procedure ResetLevelData;
327
    { Musik-Routinen }
327
    { Musik-Routinen }
328
    procedure MusicSwitchTrack(Name: TSpaceMissionMusicTrack);
328
    procedure MusicSwitchTrack(Name: TSpaceMissionMusicTrack);
329
    procedure PlayMusic(Name: TSpaceMissionMusicTrack);
329
    procedure PlayMusic(Name: TSpaceMissionMusicTrack);
330
    procedure StopMusic(Name: TSpaceMissionMusicTrack);
330
    procedure StopMusic(Name: TSpaceMissionMusicTrack);
331
    procedure ResumeMusic(Name: TSpaceMissionMusicTrack);
331
    procedure ResumeMusic(Name: TSpaceMissionMusicTrack);
332
    procedure PauseMusic(Name: TSpaceMissionMusicTrack);
332
    procedure PauseMusic(Name: TSpaceMissionMusicTrack);
333
    { Sound-Routinen }
333
    { Sound-Routinen }
334
    procedure PlaySound(Sound: TSpaceMissionSound; Wait: Boolean);
334
    procedure PlaySound(Sound: TSpaceMissionSound; Wait: Boolean);
335
    { Grafik-Routinen }
335
    { Grafik-Routinen }
336
    function GetSpriteGraphic(Sprite: TSpaceMissionGraphicSprite): TPictureCollectionItem;
336
    function GetSpriteGraphic(Sprite: TSpaceMissionGraphicSprite): TPictureCollectionItem;
337
    { Initialisiations-Routinen }
337
    { Initialisiations-Routinen }
338
    procedure DXInit;
338
    procedure DXInit;
339
    procedure SoundInit;
339
    procedure SoundInit;
340
    procedure MusicInit;
340
    procedure MusicInit;
341
    { Einstellungs-Routinen }
341
    { Einstellungs-Routinen }
342
    procedure LoadOptions;
342
    procedure LoadOptions;
343
    procedure WriteOptions;
343
    procedure WriteOptions;
344
    { Farb-Routinen }
344
    { Farb-Routinen }
345
    function ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
345
    function ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
346
    procedure PalleteAnim(Col: TRGBQuad; Time: Integer);
346
    procedure PalleteAnim(Col: TRGBQuad; Time: Integer);
347
  end;
347
  end;
348
 
348
 
349
var
349
var
350
  MainForm: TMainForm;
350
  MainForm: TMainForm;
351
 
351
 
352
implementation
352
implementation
353
 
353
 
354
uses
354
uses
355
  GamSplash, GamSpeicherung, ComInfo, GamCheat, MMSystem, Registry,
355
  GamSplash, GamSpeicherung, ComInfo, GamCheat, MMSystem, Registry,
356
  ComHilfe;
356
  ComHilfe;
357
 
357
 
358
{$R *.DFM}
358
{$R *.DFM}
359
 
359
 
360
const
360
const
361
  DXInputButton = [isButton1, isButton2, isButton3,
361
  DXInputButton = [isButton1, isButton2, isButton3,
362
    isButton4, isButton5, isButton6, isButton7, isButton8, isButton9, isButton10, isButton11,
362
    isButton4, isButton5, isButton6, isButton7, isButton8, isButton9, isButton10, isButton11,
363
    isButton12, isButton13, isButton14, isButton15, isButton16, isButton17, isButton18,
363
    isButton12, isButton13, isButton14, isButton15, isButton16, isButton17, isButton18,
364
    isButton19, isButton20, isButton21, isButton22, isButton23, isButton24, isButton25,
364
    isButton19, isButton20, isButton21, isButton22, isButton23, isButton24, isButton25,
365
    isButton26, isButton27, isButton28, isButton29, isButton30, isButton31, isButton32];
365
    isButton26, isButton27, isButton28, isButton29, isButton30, isButton31, isButton32];
366
 
366
 
367
resourcestring
367
resourcestring
368
  SWeiterMitLeertaste = 'Weiter mit Leertaste';
368
  SWeiterMitLeertaste = 'Weiter mit Leertaste';
369
 
369
 
370
{ TBackground }
370
{ TBackground }
371
 
371
 
372
procedure TBackground.DoMove(MoveCount: Integer);
372
procedure TBackground.DoMove(MoveCount: Integer);
373
var
373
var
374
  ran: integer;
374
  ran: integer;
375
  bgs: TBackgroundSpecial;
375
  bgs: TBackgroundSpecial;
376
begin
376
begin
377
  inherited DoMove(MoveCount);
377
  inherited DoMove(MoveCount);
378
  X := X - MoveCount*(60/1000)*FSpeed;
378
  X := X - MoveCount*(60/1000)*FSpeed;
379
  ran := Random(1500);
379
  ran := Random(1500);
380
  if ran = 150 then
380
  if ran = 150 then
381
  begin
381
  begin
382
    bgs := TBackgroundSpecial.Create(mainform.SpriteEngine.Engine);
382
    bgs := TBackgroundSpecial.Create(mainform.SpriteEngine.Engine);
383
    bgs.SetMapSize(1, 1);
383
    bgs.SetMapSize(1, 1);
384
    bgs.Image := MainForm.GetSpriteGraphic(smgBackgroundPlanet1);
384
    bgs.Image := MainForm.GetSpriteGraphic(smgBackgroundPlanet1);
385
    bgs.Width := Image.Width;
385
    bgs.Width := Image.Width;
386
    bgs.Height := Image.Height;
386
    bgs.Height := Image.Height;
387
    bgs.Y := random(mainform.dxdraw.height);
387
    bgs.Y := random(mainform.dxdraw.height);
388
    bgs.X := mainform.dxdraw.width;
388
    bgs.X := mainform.dxdraw.width;
389
    ran := Random(2);
389
    ran := Random(2);
390
    if ran = 0 then
390
    if ran = 0 then
391
    begin
391
    begin
392
      bgs.Z := -20;
392
      bgs.Z := -20;
393
      bgs.Speed := 1.8;
393
      bgs.Speed := 1.8;
394
    end
394
    end
395
    else if ran = 1 then
395
    else if ran = 1 then
396
    begin
396
    begin
397
      bgs.Z := -40;
397
      bgs.Z := -40;
398
      bgs.Speed := 0.8;
398
      bgs.Speed := 0.8;
399
    end
399
    end
400
    else if ran = 2 then
400
    else if ran = 2 then
401
    begin
401
    begin
402
      bgs.Z := -60;
402
      bgs.Z := -60;
403
      bgs.Speed := 0.3;
403
      bgs.Speed := 0.3;
404
    end;
404
    end;
405
  end
405
  end
406
  else if ran = 500 then
406
  else if ran = 500 then
407
  begin
407
  begin
408
    bgs := TBackgroundSpecial.Create(mainform.SpriteEngine.Engine);
408
    bgs := TBackgroundSpecial.Create(mainform.SpriteEngine.Engine);
409
    bgs.SetMapSize(1, 1);
409
    bgs.SetMapSize(1, 1);
410
    ran := Random(4);
410
    ran := Random(4);
411
    if ran = 0 then
411
    if ran = 0 then
412
      bgs.Image := MainForm.GetSpriteGraphic(smgBackgroundRed)
412
      bgs.Image := MainForm.GetSpriteGraphic(smgBackgroundRed)
413
    else if ran = 1 then
413
    else if ran = 1 then
414
      bgs.Image := MainForm.GetSpriteGraphic(smgBackgroundBlue)
414
      bgs.Image := MainForm.GetSpriteGraphic(smgBackgroundBlue)
415
    else if ran = 2 then
415
    else if ran = 2 then
416
      bgs.Image := MainForm.GetSpriteGraphic(smgBackgroundYellow)
416
      bgs.Image := MainForm.GetSpriteGraphic(smgBackgroundYellow)
417
    else if ran = 3 then
417
    else if ran = 3 then
418
      bgs.Image := MainForm.GetSpriteGraphic(smgHintergrundRot);
418
      bgs.Image := MainForm.GetSpriteGraphic(smgHintergrundRot);
419
    bgs.Width := Image.Width;
419
    bgs.Width := Image.Width;
420
    bgs.Height := Image.Height;
420
    bgs.Height := Image.Height;
421
 
421
 
422
    bgs.Y := random(mainform.dxdraw.height);
422
    bgs.Y := random(mainform.dxdraw.height);
423
    bgs.X := mainform.dxdraw.width;
423
    bgs.X := mainform.dxdraw.width;
424
 
424
 
425
    { ran := Random(2);
425
    { ran := Random(2);
426
    if ran = 0 then
426
    if ran = 0 then
427
    begin
427
    begin
428
      bgs.Z := -20;
428
      bgs.Z := -20;
429
      bgs.Speed := 1.8;
429
      bgs.Speed := 1.8;
430
    end
430
    end
431
    else if ran = 1 then
431
    else if ran = 1 then
432
    begin
432
    begin
433
      bgs.Z := -40;
433
      bgs.Z := -40;
434
      bgs.Speed := 0.8;
434
      bgs.Speed := 0.8;
435
    end
435
    end
436
    else if ran = 2 then
436
    else if ran = 2 then
437
    begin }
437
    begin }
438
      bgs.Z := -60;
438
      bgs.Z := -60;
439
      bgs.Speed := 0.3;
439
      bgs.Speed := 0.3;
440
    { end; }
440
    { end; }
441
  end;
441
  end;
442
end;
442
end;
443
 
443
 
444
{ TBackgroundSpecial }
444
{ TBackgroundSpecial }
445
 
445
 
446
procedure TBackgroundSpecial.DoMove(MoveCount: Integer);
446
procedure TBackgroundSpecial.DoMove(MoveCount: Integer);
447
begin
447
begin
448
  inherited DoMove(MoveCount);
448
  inherited DoMove(MoveCount);
449
  X := X - MoveCount*(60/1000)*FSpeed;
449
  X := X - MoveCount*(60/1000)*FSpeed;
450
  if X < -Width then Dead;
450
  if X < -Width then Dead;
451
end;
451
end;
452
 
452
 
453
{ TExplosion }
453
{ TExplosion }
454
 
454
 
455
constructor TExplosion.Create(AParent: TSprite);
455
constructor TExplosion.Create(AParent: TSprite);
456
begin
456
begin
457
  inherited Create(AParent);
457
  inherited Create(AParent);
458
  mainform.PlaySound(smsExplosion, false);
458
  mainform.PlaySound(smsExplosion, false);
459
  Image := MainForm.GetSpriteGraphic(smgExplosion);
459
  Image := MainForm.GetSpriteGraphic(smgExplosion);
460
  Width := Image.Width;
460
  Width := Image.Width;
461
  Height := Image.Height;
461
  Height := Image.Height;
462
  AnimCount := Image.PatternCount;
462
  AnimCount := Image.PatternCount;
463
  AnimLooped := True;
463
  AnimLooped := True;
464
  AnimSpeed := DEFAULT_ANIMSPEED;
464
  AnimSpeed := DEFAULT_ANIMSPEED;
465
  AnimPos := Random(AnimCount);
465
  AnimPos := Random(AnimCount);
466
end;
466
end;
467
 
467
 
468
procedure TExplosion.DoMove(MoveCount: Integer);
468
procedure TExplosion.DoMove(MoveCount: Integer);
469
begin
469
begin
470
  inherited DoMove(MoveCount);
470
  inherited DoMove(MoveCount);
471
  inc(FCounter, MoveCount);
471
  inc(FCounter, MoveCount);
472
  if FCounter > 2999 then dead;
472
  if FCounter > 2999 then dead;
473
end;
473
end;
474
 
474
 
475
{ TPlayerSprite }
475
{ TPlayerSprite }
476
 
476
 
477
constructor TPlayerSprite.Create(AParent: TSprite);
477
constructor TPlayerSprite.Create(AParent: TSprite);
478
begin
478
begin
479
  inherited Create(AParent);
479
  inherited Create(AParent);
480
  FState := pesEntering;
480
  FState := pesEntering;
481
  Image := MainForm.GetSpriteGraphic(smgMachine);
481
  Image := MainForm.GetSpriteGraphic(smgMachine);
482
  Width := Image.Width;
482
  Width := Image.Width;
483
  Height := Image.Height;
483
  Height := Image.Height;
484
  X := -70{20};
484
  X := -70{20};
485
  Y := mainform.dxdraw.surfaceHeight / 2 - (height / 2);
485
  Y := mainform.dxdraw.surfaceHeight / 2 - (height / 2);
486
  Z := 2;
486
  Z := 2;
487
  AnimCount := Image.PatternCount;
487
  AnimCount := Image.PatternCount;
488
  AnimLooped := True;
488
  AnimLooped := True;
489
  AnimSpeed := DEFAULT_ANIMSPEED;
489
  AnimSpeed := DEFAULT_ANIMSPEED;
490
end;
490
end;
491
 
491
 
492
procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
492
procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
493
begin
493
begin
494
  if (Sprite is TItem) then
494
  if (Sprite is TItem) then
495
  begin
495
  begin
496
    TItem(Sprite).Collected;
496
    TItem(Sprite).Collected;
497
  end
497
  end
498
  else if ((Sprite is TEnemy) or (Sprite is TEnemyTama)) and not (ctInfiniteLives in mainform.FCheats) then
498
  else if ((Sprite is TEnemy) or (Sprite is TEnemyTama)) and not (ctInfiniteLives in mainform.FCheats) then
499
  begin
499
  begin
500
    if not mainform.crash then
500
    if not mainform.crash then
501
    begin
501
    begin
502
      dec(MainForm.FLife);
502
      dec(MainForm.FLife);
503
      mainform.Crash := true;
503
      mainform.Crash := true;
504
      if MainForm.Flife=0 then
504
      if MainForm.Flife=0 then
505
      begin
505
      begin
506
        MainForm.PlaySound(smsExplosion, false);
506
        MainForm.PlaySound(smsExplosion, false);
507
        Collisioned := false;
507
        Collisioned := false;
508
        FCounter := 0;
508
        FCounter := 0;
509
        FState := pesDead;
509
        FState := pesDead;
510
        Done := false;
510
        Done := false;
511
        Image := MainForm.GetSpriteGraphic(smgExplosion);
511
        Image := MainForm.GetSpriteGraphic(smgExplosion);
512
        Width := Image.Width;
512
        Width := Image.Width;
513
        Height := Image.Height;
513
        Height := Image.Height;
514
        AnimCount := Image.PatternCount;
514
        AnimCount := Image.PatternCount;
515
        AnimLooped := False;
515
        AnimLooped := False;
516
        AnimSpeed := DEFAULT_ANIMSPEED;
516
        AnimSpeed := DEFAULT_ANIMSPEED;
517
        AnimPos := 0;
517
        AnimPos := 0;
518
      end;
518
      end;
519
    end
519
    end
520
    else
520
    else
521
    begin
521
    begin
522
      if not mainform.crashsound then
522
      if not mainform.crashsound then
523
      begin
523
      begin
524
        MainForm.PlaySound(smsHit, False);
524
        MainForm.PlaySound(smsHit, False);
525
        mainform.crashsound := true;
525
        mainform.crashsound := true;
526
      end;
526
      end;
527
    end;
527
    end;
528
  end;
528
  end;
529
end;
529
end;
530
 
530
 
531
procedure TPlayerSprite.DoMove(MoveCount: Integer);
531
procedure TPlayerSprite.DoMove(MoveCount: Integer);
532
const
532
const
533
  WegduesKonstante = 1.75;
533
  WegduesKonstante = 1.75;
534
begin
534
begin
535
  inherited DoMove(MoveCount);
535
  inherited DoMove(MoveCount);
536
  if State = pesNormal then
536
  if State = pesNormal then
537
  begin
537
  begin
538
    if isUp in MainForm.DXInput.States then Y := Y - (250/1000)*MoveCount;
538
    if isUp in MainForm.DXInput.States then Y := Y - (250/1000)*MoveCount;
539
    if isDown in MainForm.DXInput.States then Y := Y + (250/1000)*MoveCount;
539
    if isDown in MainForm.DXInput.States then Y := Y + (250/1000)*MoveCount;
540
    if isLeft in MainForm.DXInput.States then X := X - (250/1000)*MoveCount;
540
    if isLeft in MainForm.DXInput.States then X := X - (250/1000)*MoveCount;
541
    if isRight in MainForm.DXInput.States then X := X + (250/1000)*MoveCount;
541
    if isRight in MainForm.DXInput.States then X := X + (250/1000)*MoveCount;
542
    if X<0 then X := 0;
542
    if X<0 then X := 0;
543
    if X>mainform.dxdraw.surfacewidth-Width then X := mainform.dxdraw.surfacewidth-Width;
543
    if X>mainform.dxdraw.surfacewidth-Width then X := mainform.dxdraw.surfacewidth-Width;
544
    if Y<0 then Y := 0;
544
    if Y<0 then Y := 0;
545
    if Y>mainform.dxdraw.surfaceheight-Height then Y := mainform.dxdraw.surfaceheight-Height;
545
    if Y>mainform.dxdraw.surfaceheight-Height then Y := mainform.dxdraw.surfaceheight-Height;
546
    if isButton1 in MainForm.DXInput.States then
546
    if isButton1 in MainForm.DXInput.States then
547
    begin
547
    begin
548
      if (FTamaCount<8) and (FCounter-FOldTamaTime>=100) then
548
      if (FTamaCount<8) and (FCounter-FOldTamaTime>=100) then
549
      begin
549
      begin
550
        Inc(FTamaCount);
550
        Inc(FTamaCount);
551
        with TPlayerTamaSprite.Create(Engine, Self) do
551
        with TPlayerTamaSprite.Create(Engine, Self) do
552
        begin
552
        begin
553
          X := Self.X+Self.Width;
553
          X := Self.X+Self.Width;
554
          Y := Self.Y+Self.Height div 2-Height div 2;
554
          Y := Self.Y+Self.Height div 2-Height div 2;
555
          Z := 10;
555
          Z := 10;
556
        end;
556
        end;
557
        FOldTamaTime := FCounter;
557
        FOldTamaTime := FCounter;
558
      end;
558
      end;
559
    end;
559
    end;
560
    Collision;
560
    Collision;
561
  end
561
  end
562
  else if State = pesDead then
562
  else if State = pesDead then
563
  begin
563
  begin
564
    if FCounter>200 then
564
    if FCounter>200 then
565
    begin
565
    begin
566
      FCounter := 0;
566
      FCounter := 0;
567
      FState := pesDeadVanished;
567
      FState := pesDeadVanished;
568
      Visible := false; // Cannot use "Dead;" because we need to still be able to handle pesDeadVanished
568
      Visible := false; // Cannot use "Dead;" because we need to still be able to handle pesDeadVanished
569
    end;
569
    end;
570
  end
570
  end
571
  else if State = pesDeadVanished then
571
  else if State = pesDeadVanished then
572
  begin
572
  begin
573
    if FCounter>2000 then
573
    if FCounter>2000 then
574
    begin
574
    begin
575
      MainForm.LevelNeuStarten;
575
      MainForm.LevelNeuStarten;
576
      (*
576
      (*
577
      MainForm.FNextScene := gsGameOver;
577
      MainForm.FNextScene := gsGameOver;
578
      MainForm.PlaySound(smsSceneMov, false);
578
      MainForm.PlaySound(smsSceneMov, false);
579
      MainForm.PalleteAnim(RGBQuad(0, 0, 0), 300);
579
      MainForm.PalleteAnim(RGBQuad(0, 0, 0), 300);
580
      Sleep(200);
580
      Sleep(200);
581
      *)
581
      *)
582
    end;
582
    end;
583
  end
583
  end
584
  else if State = pesFlyaway then
584
  else if State = pesFlyaway then
585
  begin
585
  begin
586
    X := X + MoveCount*(300/1000) * (X/MainForm.DXDraw.Width + WegduesKonstante);
586
    X := X + MoveCount*(300/1000) * (X/MainForm.DXDraw.Width + WegduesKonstante);
587
    if X > MainForm.DXDraw.Width+Width then
587
    if X > MainForm.DXDraw.Width+Width then
588
    begin
588
    begin
589
      Dead;
589
      Dead;
590
      inc(mainform.FLevel);
590
      inc(mainform.FLevel);
591
      MainForm.FLevelDataAlreadyLoaded := false; // allow NewLevel() to work again
591
      MainForm.FLevelDataAlreadyLoaded := false; // allow NewLevel() to work again
592
      MainForm.FNextScene := gsNewLevel;
592
      MainForm.FNextScene := gsNewLevel;
593
      MainForm.PlaySound(smsSceneMov, false);
593
      MainForm.PlaySound(smsSceneMov, false);
594
      MainForm.PalleteAnim(RGBQuad(0, 0, 0), 300);
594
      MainForm.PalleteAnim(RGBQuad(0, 0, 0), 300);
595
    end;
595
    end;
596
  end
596
  end
597
  else if State = pesEntering then
597
  else if State = pesEntering then
598
  begin
598
  begin
599
    X := X + MoveCount*(300/1000);
599
    X := X + MoveCount*(300/1000);
600
    if X > 19 then FState := pesNormal;
600
    if X > 19 then FState := pesNormal;
601
  end;
601
  end;
602
  inc(FCounter, MoveCount);
602
  inc(FCounter, MoveCount);
603
end;
603
end;
604
 
604
 
605
procedure TPlayerSprite.FlyAway;
605
procedure TPlayerSprite.FlyAway;
606
begin
606
begin
607
  FState := pesFlyaway;
607
  FState := pesFlyaway;
608
end;
608
end;
609
 
609
 
610
{ TPlayerTamaSprite }
610
{ TPlayerTamaSprite }
611
 
611
 
612
constructor TPlayerTamaSprite.Create(AParent: TSprite; APlayerSprite: TPlayerSprite);
612
constructor TPlayerTamaSprite.Create(AParent: TSprite; APlayerSprite: TPlayerSprite);
613
begin
613
begin
614
  inherited Create(AParent);
614
  inherited Create(AParent);
615
  FPlayerSprite := APlayerSprite;
615
  FPlayerSprite := APlayerSprite;
616
  Image := MainForm.GetSpriteGraphic(smgBounce);
616
  Image := MainForm.GetSpriteGraphic(smgBounce);
617
  Z := 2;
617
  Z := 2;
618
  Width := Image.Width;
618
  Width := Image.Width;
619
  Height := Image.Height;
619
  Height := Image.Height;
620
  AnimCount := Image.PatternCount;
620
  AnimCount := Image.PatternCount;
621
  AnimLooped := True;
621
  AnimLooped := True;
622
  AnimSpeed := DEFAULT_ANIMSPEED;
622
  AnimSpeed := DEFAULT_ANIMSPEED;
623
  MainForm.PlaySound(smsShoot, False);
623
  MainForm.PlaySound(smsShoot, False);
624
end;
624
end;
625
 
625
 
626
destructor TPlayerTamaSprite.Destroy;
626
destructor TPlayerTamaSprite.Destroy;
627
begin
627
begin
628
  inherited Destroy;
628
  inherited Destroy;
629
  Dec(FPlayerSprite.FTamaCount);
629
  Dec(FPlayerSprite.FTamaCount);
630
end;
630
end;
631
 
631
 
632
procedure TPlayerTamaSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
632
procedure TPlayerTamaSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
633
begin
633
begin
634
  if (Sprite is TEnemy) and not (Sprite is TEnemyTama) then
634
  if (Sprite is TEnemy) and not (Sprite is TEnemyTama) then
635
  begin
635
  begin
636
    TEnemy(Sprite).Hit;
636
    TEnemy(Sprite).Hit;
637
    Dead;
637
    Dead;
638
  end;
638
  end;
639
  Done := False;
639
  Done := False;
640
end;
640
end;
641
 
641
 
642
procedure TPlayerTamaSprite.DoMove(MoveCount: Integer);
642
procedure TPlayerTamaSprite.DoMove(MoveCount: Integer);
643
begin
643
begin
644
  inherited DoMove(MoveCount);
644
  inherited DoMove(MoveCount);
645
  X := X+(800/1000)*MoveCount;
645
  X := X+(800/1000)*MoveCount;
646
  if X>=mainform.dxdraw.surfacewidth then Dead;
646
  if X>=mainform.dxdraw.surfacewidth then Dead;
647
  Collision;
647
  Collision;
648
end;
648
end;
649
 
649
 
650
{ TEnemy }
650
{ TEnemy }
651
 
651
 
652
constructor TEnemy.Create(AParent: TSprite; ALifes: integer);
652
constructor TEnemy.Create(AParent: TSprite; ALifes: integer);
653
begin
653
begin
654
  inherited Create(AParent);
654
  inherited Create(AParent);
655
  FLife := ALifes;
655
  FLife := ALifes;
656
  inc(mainform.EnemyCounter);
656
  inc(mainform.EnemyCounter);
657
end;
657
end;
658
 
658
 
659
destructor TEnemy.Destroy;
659
destructor TEnemy.Destroy;
660
begin
660
begin
661
  inherited Destroy;
661
  inherited Destroy;
662
  dec(mainform.EnemyCounter);
662
  dec(mainform.EnemyCounter);
663
end;
663
end;
664
 
664
 
665
procedure TEnemy.Hit(AHitStrength: integer = 1);
665
procedure TEnemy.Hit(AHitStrength: integer = 1);
666
begin
666
begin
667
  Dec(FLife, AHitStrength);
667
  Dec(FLife, AHitStrength);
668
  if FLife<=0 then
668
  if FLife<=0 then
669
  begin
669
  begin
670
    Collisioned := False;
670
    Collisioned := False;
671
    HitEnemy(True);
671
    HitEnemy(True);
672
  end
672
  end
673
  else
673
  else
674
    HitEnemy(False);
674
    HitEnemy(False);
675
end;
675
end;
676
 
676
 
677
procedure TEnemy.HitEnemy(ADead: Boolean);
677
procedure TEnemy.HitEnemy(ADead: Boolean);
678
begin
678
begin
679
  if ADead then
679
  if ADead then
680
    MainForm.PlaySound(smsExplosion, False)
680
    MainForm.PlaySound(smsExplosion, False)
681
  else
681
  else
682
    MainForm.PlaySound(smsHit, False);
682
    MainForm.PlaySound(smsHit, False);
683
end;
683
end;
684
 
684
 
685
{ TEnemyTama }
685
{ TEnemyTama }
686
 
686
 
687
constructor TEnemyTama.Create(AParent: TSprite; AEnemySprite: TSprite);
687
constructor TEnemyTama.Create(AParent: TSprite; AEnemySprite: TSprite);
688
begin
688
begin
689
  inherited Create(AParent);
689
  inherited Create(AParent);
690
  FEnemySprite := AEnemySprite;
690
  FEnemySprite := AEnemySprite;
691
  Image := MainForm.GetSpriteGraphic(smgBounce2);
691
  Image := MainForm.GetSpriteGraphic(smgBounce2);
692
  Width := Image.Width;
692
  Width := Image.Width;
693
  Height := Image.Height;
693
  Height := Image.Height;
694
  AnimCount := Image.PatternCount;
694
  AnimCount := Image.PatternCount;
695
  AnimLooped := True;
695
  AnimLooped := True;
696
  AnimSpeed := DEFAULT_ANIMSPEED;
696
  AnimSpeed := DEFAULT_ANIMSPEED;
697
  MainForm.PlaySound(smsShoot, False);
697
  MainForm.PlaySound(smsShoot, False);
698
end;
698
end;
699
 
699
 
700
procedure TEnemyTama.DoMove(MoveCount: Integer);
700
procedure TEnemyTama.DoMove(MoveCount: Integer);
701
begin
701
begin
702
  inherited DoMove(MoveCount);
702
  inherited DoMove(MoveCount);
703
  X := X - MoveCount*(600/1000);
703
  X := X - MoveCount*(600/1000);
704
  if X < -Width then Dead;
704
  if X < -Width then Dead;
705
end;
705
end;
706
 
706
 
707
{ TEnemyMeteor }
707
{ TEnemyMeteor }
708
 
708
 
709
constructor TEnemyMeteor.Create(AParent: TSprite; ALifes: integer);
709
constructor TEnemyMeteor.Create(AParent: TSprite; ALifes: integer);
710
begin
710
begin
711
  inherited Create(AParent, ALifes);
711
  inherited Create(AParent, ALifes);
712
  FState := pesNormal;
712
  FState := pesNormal;
713
  Image := MainForm.GetSpriteGraphic(smgEnemyMeteor);
713
  Image := MainForm.GetSpriteGraphic(smgEnemyMeteor);
714
  Width := Image.Width;
714
  Width := Image.Width;
715
  Height := Image.Height;
715
  Height := Image.Height;
716
  AnimCount := Image.PatternCount;
716
  AnimCount := Image.PatternCount;
717
  AnimLooped := True;
717
  AnimLooped := True;
718
  AnimSpeed := DEFAULT_ANIMSPEED;
718
  AnimSpeed := DEFAULT_ANIMSPEED;
719
  PixelCheck := True;
719
  PixelCheck := True;
720
end;
720
end;
721
 
721
 
722
procedure TEnemyMeteor.HitEnemy(ADead: Boolean);
722
procedure TEnemyMeteor.HitEnemy(ADead: Boolean);
723
begin
723
begin
724
  inherited HitEnemy(False);
724
  inherited HitEnemy(False);
725
 
725
 
726
  if ADead then Collisioned := True;
726
  if ADead then Collisioned := True;
727
end;
727
end;
728
 
728
 
729
procedure TEnemyMeteor.DoMove(MoveCount: Integer);
729
procedure TEnemyMeteor.DoMove(MoveCount: Integer);
730
begin
730
begin
731
  X := X - MoveCount*(250/1000);
731
  X := X - MoveCount*(250/1000);
732
  if X < -Width then Dead;
732
  if X < -Width then Dead;
733
end;
733
end;
734
 
734
 
735
{ TEnemyUFO }
735
{ TEnemyUFO }
736
 
736
 
737
constructor TEnemyUFO.Create(AParent: TSprite; ALifes: integer);
737
constructor TEnemyUFO.Create(AParent: TSprite; ALifes: integer);
738
begin
738
begin
739
  inherited Create(AParent, ALifes);
739
  inherited Create(AParent, ALifes);
740
  FState := pesNormal;
740
  FState := pesNormal;
741
  Image := MainForm.GetSpriteGraphic(smgEnemyDisk);
741
  Image := MainForm.GetSpriteGraphic(smgEnemyDisk);
742
  Width := Image.Width;
742
  Width := Image.Width;
743
  Height := Image.Height;
743
  Height := Image.Height;
744
  AnimCount := Image.PatternCount;
744
  AnimCount := Image.PatternCount;
745
  AnimLooped := True;
745
  AnimLooped := True;
746
  AnimSpeed := DEFAULT_ANIMSPEED;
746
  AnimSpeed := DEFAULT_ANIMSPEED;
747
end;
747
end;
748
 
748
 
749
procedure TEnemyUFO.HitEnemy(ADead: Boolean);
749
procedure TEnemyUFO.HitEnemy(ADead: Boolean);
750
begin
750
begin
751
  inherited HitEnemy(ADead);
751
  inherited HitEnemy(ADead);
752
 
752
 
753
  if ADead then
753
  if ADead then
754
  begin
754
  begin
755
    FState := pesDead;
755
    FState := pesDead;
756
    FCounter := 0;
756
    FCounter := 0;
757
    Inc(MainForm.FScore, 1000);
757
    Inc(MainForm.FScore, 1000);
758
    Image := MainForm.GetSpriteGraphic(smgExplosion);
758
    Image := MainForm.GetSpriteGraphic(smgExplosion);
759
    Width := Image.Width;
759
    Width := Image.Width;
760
    Height := Image.Height;
760
    Height := Image.Height;
761
    AnimCount := Image.PatternCount;
761
    AnimCount := Image.PatternCount;
762
    AnimLooped := False;
762
    AnimLooped := False;
763
    AnimSpeed := DEFAULT_ANIMSPEED;
763
    AnimSpeed := DEFAULT_ANIMSPEED;
764
    AnimPos := 0;
764
    AnimPos := 0;
765
  end
765
  end
766
  else
766
  else
767
  begin
767
  begin
768
    Inc(MainForm.FScore, 100);
768
    Inc(MainForm.FScore, 100);
769
  end;
769
  end;
770
end;
770
end;
771
 
771
 
772
procedure TEnemyUFO.DoMove(MoveCount: Integer);
772
procedure TEnemyUFO.DoMove(MoveCount: Integer);
773
begin
773
begin
774
  inherited DoMove(MoveCount);
774
  inherited DoMove(MoveCount);
775
  if State = pesNormal then
775
  if State = pesNormal then
776
  begin
776
  begin
777
    X := X - MoveCount*(300/1000);
777
    X := X - MoveCount*(300/1000);
778
    Y := Y + Cos256(FCounter div 15)*2;
778
    Y := Y + Cos256(FCounter div 15)*2;
779
    if X < -Width then Dead;
779
    if X < -Width then Dead;
780
  end
780
  end
781
  else if State = pesDead then
781
  else if State = pesDead then
782
  begin
782
  begin
783
    X := X - MoveCount*(300/1000);
783
    X := X - MoveCount*(300/1000);
784
    if FCounter>200 then
784
    if FCounter>200 then
785
    begin
785
    begin
786
      FState := pesDeadVanished;
786
      FState := pesDeadVanished;
787
      Dead;
787
      Dead;
788
    end;
788
    end;
789
  end;
789
  end;
790
  inc(FCounter, MoveCount);
790
  inc(FCounter, MoveCount);
791
end;
791
end;
792
 
792
 
793
{ TEnemyUFO2 }
793
{ TEnemyUFO2 }
794
 
794
 
795
constructor TEnemyUFO2.Create(AParent: TSprite; ALifes: integer);
795
constructor TEnemyUFO2.Create(AParent: TSprite; ALifes: integer);
796
begin
796
begin
797
  inherited Create(AParent, ALifes);
797
  inherited Create(AParent, ALifes);
798
  FState := pesNormal;
798
  FState := pesNormal;
799
  Image := MainForm.GetSpriteGraphic(smgEnemyDisk2);
799
  Image := MainForm.GetSpriteGraphic(smgEnemyDisk2);
800
  Width := Image.Width;
800
  Width := Image.Width;
801
  Height := Image.Height;
801
  Height := Image.Height;
802
  AnimCount := Image.PatternCount;
802
  AnimCount := Image.PatternCount;
803
  AnimLooped := True;
803
  AnimLooped := True;
804
  AnimSpeed := DEFAULT_ANIMSPEED;
804
  AnimSpeed := DEFAULT_ANIMSPEED;
805
end;
805
end;
806
 
806
 
807
procedure TEnemyUFO2.HitEnemy(ADead: Boolean);
807
procedure TEnemyUFO2.HitEnemy(ADead: Boolean);
808
begin
808
begin
809
  inherited HitEnemy(ADead);
809
  inherited HitEnemy(ADead);
810
 
810
 
811
  if ADead then
811
  if ADead then
812
  begin
812
  begin
813
    FState := pesDead;
813
    FState := pesDead;
814
    FCounter := 0;
814
    FCounter := 0;
815
    Inc(MainForm.FScore, 1000);
815
    Inc(MainForm.FScore, 1000);
816
    Image := MainForm.GetSpriteGraphic(smgExplosion);
816
    Image := MainForm.GetSpriteGraphic(smgExplosion);
817
    Width := Image.Width;
817
    Width := Image.Width;
818
    Height := Image.Height;
818
    Height := Image.Height;
819
    AnimCount := Image.PatternCount;
819
    AnimCount := Image.PatternCount;
820
    AnimLooped := False;
820
    AnimLooped := False;
821
    AnimSpeed := DEFAULT_ANIMSPEED;
821
    AnimSpeed := DEFAULT_ANIMSPEED;
822
    AnimPos := 0;
822
    AnimPos := 0;
823
  end
823
  end
824
  else
824
  else
825
  begin
825
  begin
826
    Inc(MainForm.FScore, 100);
826
    Inc(MainForm.FScore, 100);
827
  end;
827
  end;
828
end;
828
end;
829
 
829
 
830
procedure TEnemyUFO2.DoMove(MoveCount: Integer);
830
procedure TEnemyUFO2.DoMove(MoveCount: Integer);
831
begin
831
begin
832
  inherited DoMove(MoveCount);
832
  inherited DoMove(MoveCount);
833
  if State = pesNormal then
833
  if State = pesNormal then
834
  begin
834
  begin
835
    X := X - MoveCount*(300/1000);
835
    X := X - MoveCount*(300/1000);
836
    Y := Y + Cos256(FCounter div 15)*2;
836
    Y := Y + Cos256(FCounter div 15)*2;
837
    if X < -Width then Dead;
837
    if X < -Width then Dead;
838
    if FCounter-FOldTamaTime>=100 then
838
    if FCounter-FOldTamaTime>=100 then
839
    begin
839
    begin
840
      Inc(FTamaCount);
840
      Inc(FTamaCount);
841
      with TEnemyTama.Create(Engine, Self) do
841
      with TEnemyTama.Create(Engine, Self) do
842
      begin
842
      begin
843
        X := Self.X;
843
        X := Self.X;
844
        Y := Self.Y+Self.Height div 2-Height div 2;
844
        Y := Self.Y+Self.Height div 2-Height div 2;
845
        Z := 10;
845
        Z := 10;
846
      end;
846
      end;
847
      FOldTamaTime := FCounter;
847
      FOldTamaTime := FCounter;
848
    end;
848
    end;
849
  end
849
  end
850
  else if State = pesDead then
850
  else if State = pesDead then
851
  begin
851
  begin
852
    X := X - MoveCount*(300/1000);
852
    X := X - MoveCount*(300/1000);
853
    if FCounter>200 then
853
    if FCounter>200 then
854
    begin
854
    begin
855
      FState := pesDeadVanished;
855
      FState := pesDeadVanished;
856
      Dead;
856
      Dead;
857
    end;
857
    end;
858
  end;
858
  end;
859
  inc(FCounter, MoveCount);
859
  inc(FCounter, MoveCount);
860
end;
860
end;
861
 
861
 
862
{ TEnemyAttacker }
862
{ TEnemyAttacker }
863
 
863
 
864
constructor TEnemyAttacker.Create(AParent: TSprite; ALifes: integer);
864
constructor TEnemyAttacker.Create(AParent: TSprite; ALifes: integer);
865
begin
865
begin
866
  inherited Create(AParent, ALifes);
866
  inherited Create(AParent, ALifes);
867
  FState := pesNormal;
867
  FState := pesNormal;
868
  Image := MainForm.GetSpriteGraphic(smgEnemyAttacker);
868
  Image := MainForm.GetSpriteGraphic(smgEnemyAttacker);
869
  Width := Image.Width;
869
  Width := Image.Width;
870
  Height := Image.Height;
870
  Height := Image.Height;
871
  AnimCount := Image.PatternCount;
871
  AnimCount := Image.PatternCount;
872
  AnimLooped := True;
872
  AnimLooped := True;
873
  AnimSpeed := DEFAULT_ANIMSPEED;
873
  AnimSpeed := DEFAULT_ANIMSPEED;
874
  PixelCheck := True;
874
  PixelCheck := True;
875
end;
875
end;
876
 
876
 
877
procedure TEnemyAttacker.HitEnemy(ADead: Boolean);
877
procedure TEnemyAttacker.HitEnemy(ADead: Boolean);
878
begin
878
begin
879
  inherited HitEnemy(ADead);
879
  inherited HitEnemy(ADead);
880
 
880
 
881
  if ADead then
881
  if ADead then
882
  begin
882
  begin
883
    FState := pesDead;
883
    FState := pesDead;
884
    FCounter := 0;
884
    FCounter := 0;
885
    Inc(MainForm.FScore, 1000);
885
    Inc(MainForm.FScore, 1000);
886
    Image := MainForm.GetSpriteGraphic(smgExplosion);
886
    Image := MainForm.GetSpriteGraphic(smgExplosion);
887
    Width := Image.Width;
887
    Width := Image.Width;
888
    Height := Image.Height;
888
    Height := Image.Height;
889
    AnimCount := Image.PatternCount;
889
    AnimCount := Image.PatternCount;
890
    AnimLooped := False;
890
    AnimLooped := False;
891
    AnimSpeed := DEFAULT_ANIMSPEED;
891
    AnimSpeed := DEFAULT_ANIMSPEED;
892
    AnimPos := 0;
892
    AnimPos := 0;
893
  end
893
  end
894
  else
894
  else
895
  begin
895
  begin
896
    Inc(MainForm.FScore, 100);
896
    Inc(MainForm.FScore, 100);
897
  end;
897
  end;
898
end;
898
end;
899
 
899
 
900
procedure TEnemyAttacker.DoMove(MoveCount: Integer);
900
procedure TEnemyAttacker.DoMove(MoveCount: Integer);
901
begin
901
begin
902
  inherited DoMove(MoveCount);
902
  inherited DoMove(MoveCount);
903
  if State = pesNormal then
903
  if State = pesNormal then
904
  begin
904
  begin
905
    X := X - MoveCount*(300/1000)-FCounter div 128;
905
    X := X - MoveCount*(300/1000)-FCounter div 128;
906
    if X < -Width then Dead;
906
    if X < -Width then Dead;
907
  end
907
  end
908
  else if State = pesDead then
908
  else if State = pesDead then
909
  begin
909
  begin
910
    X := X - MoveCount*(300/1000);
910
    X := X - MoveCount*(300/1000);
911
    if FCounter>200 then
911
    if FCounter>200 then
912
    begin
912
    begin
913
      FState := pesDeadVanished;
913
      FState := pesDeadVanished;
914
      Dead;
914
      Dead;
915
    end;
915
    end;
916
  end;
916
  end;
917
  inc(FCounter, MoveCount);
917
  inc(FCounter, MoveCount);
918
end;
918
end;
919
 
919
 
920
{ TEnemyAttacker2 }
920
{ TEnemyAttacker2 }
921
 
921
 
922
constructor TEnemyAttacker2.Create(AParent: TSprite; ALifes: integer);
922
constructor TEnemyAttacker2.Create(AParent: TSprite; ALifes: integer);
923
begin
923
begin
924
  inherited Create(AParent, ALifes);
924
  inherited Create(AParent, ALifes);
925
  FState := pesEntering;
925
  FState := pesEntering;
926
  Image := MainForm.GetSpriteGraphic(smgEnemyAttacker2);
926
  Image := MainForm.GetSpriteGraphic(smgEnemyAttacker2);
927
  Width := Image.Width;
927
  Width := Image.Width;
928
  Height := Image.Height;
928
  Height := Image.Height;
929
  AnimCount := Image.PatternCount;
929
  AnimCount := Image.PatternCount;
930
  AnimLooped := True;
930
  AnimLooped := True;
931
  AnimSpeed := DEFAULT_ANIMSPEED;
931
  AnimSpeed := DEFAULT_ANIMSPEED;
932
  PixelCheck := True;
932
  PixelCheck := True;
933
end;
933
end;
934
 
934
 
935
procedure TEnemyAttacker2.HitEnemy(ADead: Boolean);
935
procedure TEnemyAttacker2.HitEnemy(ADead: Boolean);
936
begin
936
begin
937
  inherited HitEnemy(ADead);
937
  inherited HitEnemy(ADead);
938
 
938
 
939
  if ADead then
939
  if ADead then
940
  begin
940
  begin
941
    FState := pesDead;
941
    FState := pesDead;
942
    FCounter := 0;
942
    FCounter := 0;
943
    Inc(MainForm.FScore, 5000);
943
    Inc(MainForm.FScore, 5000);
944
    Image := MainForm.GetSpriteGraphic(smgExplosion);
944
    Image := MainForm.GetSpriteGraphic(smgExplosion);
945
    Width := Image.Width;
945
    Width := Image.Width;
946
    Height := Image.Height;
946
    Height := Image.Height;
947
    AnimCount := Image.PatternCount;
947
    AnimCount := Image.PatternCount;
948
    AnimLooped := False;
948
    AnimLooped := False;
949
    AnimSpeed := DEFAULT_ANIMSPEED;
949
    AnimSpeed := DEFAULT_ANIMSPEED;
950
    AnimPos := 0;
950
    AnimPos := 0;
951
  end
951
  end
952
  else
952
  else
953
  begin
953
  begin
954
    Inc(MainForm.FScore, 100);
954
    Inc(MainForm.FScore, 100);
955
  end;
955
  end;
956
end;
956
end;
957
 
957
 
958
procedure TEnemyAttacker2.DoMove(MoveCount: Integer);
958
procedure TEnemyAttacker2.DoMove(MoveCount: Integer);
959
begin
959
begin
960
  inherited DoMove(MoveCount);
960
  inherited DoMove(MoveCount);
961
  if State = pesEntering then
961
  if State = pesEntering then
962
  begin
962
  begin
963
    if X>((mainform.dxdraw.width/4) + (mainform.dxdraw.width/2) - (width/2)){450} then
963
    if X>((mainform.dxdraw.width/4) + (mainform.dxdraw.width/2) - (width/2)){450} then
964
      X := X - MoveCount*(300/1000)
964
      X := X - MoveCount*(300/1000)
965
    else
965
    else
966
    begin
966
    begin
967
      Collisioned := True;
967
      Collisioned := True;
968
      FState := pesHovering;
968
      FState := pesHovering;
969
      FPutTama := True;
969
      FPutTama := True;
970
    end;
970
    end;
971
    Y := Y + Cos256(FCounter div 15)*5;
971
    Y := Y + Cos256(FCounter div 15)*5;
972
  end
972
  end
973
  else if State = pesHovering then
973
  else if State = pesHovering then
974
  begin
974
  begin
975
    Y := Y + Cos256(FCounter div 15)*5;
975
    Y := Y + Cos256(FCounter div 15)*5;
976
    if FPutTama then
976
    if FPutTama then
977
    begin
977
    begin
978
      if FTamaT>100 then
978
      if FTamaT>100 then
979
      begin
979
      begin
980
        with TEnemyTama.Create(Engine, Self) do
980
        with TEnemyTama.Create(Engine, Self) do
981
        begin
981
        begin
982
          Z := 1;
982
          Z := 1;
983
          X := Self.X-Width;
983
          X := Self.X-Width;
984
          Y := Self.Y+Self.Height div 2-Height div 2;
984
          Y := Self.Y+Self.Height div 2-Height div 2;
985
        end;
985
        end;
986
        Inc(FTamaF);
986
        Inc(FTamaF);
987
        if FTamaF>Random(30) then FPutTama := False;
987
        if FTamaF>Random(30) then FPutTama := False;
988
        FTamaT := 0;
988
        FTamaT := 0;
989
      end;
989
      end;
990
      FTamaT := FTamaT + MoveCount;
990
      FTamaT := FTamaT + MoveCount;
991
    end
991
    end
992
    else
992
    else
993
    begin
993
    begin
994
      FTamaT := FTamaT + MoveCount;
994
      FTamaT := FTamaT + MoveCount;
995
      if FTamaT>2000+Random(500) then
995
      if FTamaT>2000+Random(500) then
996
      begin
996
      begin
997
        FPutTama := True;
997
        FPutTama := True;
998
        FTamaF := 0;
998
        FTamaF := 0;
999
        FTamaT := 0;
999
        FTamaT := 0;
1000
      end;
1000
      end;
1001
    end;
1001
    end;
1002
  end
1002
  end
1003
  else if State = pesDead then
1003
  else if State = pesDead then
1004
  begin
1004
  begin
1005
    if FCounter>200 then
1005
    if FCounter>200 then
1006
    begin
1006
    begin
1007
      FState := pesDeadVanished;
1007
      FState := pesDeadVanished;
1008
      Dead;
1008
      Dead;
1009
    end;
1009
    end;
1010
  end;
1010
  end;
1011
  inc(FCounter, MoveCount);
1011
  inc(FCounter, MoveCount);
1012
end;
1012
end;
1013
 
1013
 
1014
{ TEnemyAttacker3 }
1014
{ TEnemyAttacker3 }
1015
 
1015
 
1016
constructor TEnemyAttacker3.Create(AParent: TSprite; ALifes: integer);
1016
constructor TEnemyAttacker3.Create(AParent: TSprite; ALifes: integer);
1017
begin
1017
begin
1018
  inherited Create(AParent, ALifes);
1018
  inherited Create(AParent, ALifes);
1019
  FState := pesNormal;
1019
  FState := pesNormal;
1020
  Image := MainForm.GetSpriteGraphic(smgEnemyAttacker3);
1020
  Image := MainForm.GetSpriteGraphic(smgEnemyAttacker3);
1021
  Width := Image.Width;
1021
  Width := Image.Width;
1022
  Height := Image.Height;
1022
  Height := Image.Height;
1023
  AnimCount := Image.PatternCount;
1023
  AnimCount := Image.PatternCount;
1024
  AnimLooped := True;
1024
  AnimLooped := True;
1025
  AnimSpeed := DEFAULT_ANIMSPEED;
1025
  AnimSpeed := DEFAULT_ANIMSPEED;
1026
  PixelCheck := True;
1026
  PixelCheck := True;
1027
end;
1027
end;
1028
 
1028
 
1029
procedure TEnemyAttacker3.HitEnemy(ADead: Boolean);
1029
procedure TEnemyAttacker3.HitEnemy(ADead: Boolean);
1030
begin
1030
begin
1031
  inherited HitEnemy(ADead);
1031
  inherited HitEnemy(ADead);
1032
 
1032
 
1033
  if ADead then
1033
  if ADead then
1034
  begin
1034
  begin
1035
    FState := pesDead;
1035
    FState := pesDead;
1036
    FCounter := 0;
1036
    FCounter := 0;
1037
    Inc(MainForm.FScore, 5000);
1037
    Inc(MainForm.FScore, 5000);
1038
    Image := MainForm.GetSpriteGraphic(smgExplosion);
1038
    Image := MainForm.GetSpriteGraphic(smgExplosion);
1039
    Width := Image.Width;
1039
    Width := Image.Width;
1040
    Height := Image.Height;
1040
    Height := Image.Height;
1041
    AnimCount := Image.PatternCount;
1041
    AnimCount := Image.PatternCount;
1042
    AnimLooped := False;
1042
    AnimLooped := False;
1043
    AnimSpeed := DEFAULT_ANIMSPEED;
1043
    AnimSpeed := DEFAULT_ANIMSPEED;
1044
    AnimPos := 0;
1044
    AnimPos := 0;
1045
  end
1045
  end
1046
  else
1046
  else
1047
  begin
1047
  begin
1048
    Inc(MainForm.FScore, 100);
1048
    Inc(MainForm.FScore, 100);
1049
  end;
1049
  end;
1050
end;
1050
end;
1051
 
1051
 
1052
procedure TEnemyAttacker3.DoMove(MoveCount: Integer);
1052
procedure TEnemyAttacker3.DoMove(MoveCount: Integer);
1053
begin
1053
begin
1054
  inherited DoMove(MoveCount);
1054
  inherited DoMove(MoveCount);
1055
  if State = pesNormal then
1055
  if State = pesNormal then
1056
  begin
1056
  begin
1057
    X := X - (250/1000)*MoveCount;
1057
    X := X - (250/1000)*MoveCount;
1058
    if X < -Width then Dead;
1058
    if X < -Width then Dead;
1059
    if FCounter-FOldTamaTime>=100 then
1059
    if FCounter-FOldTamaTime>=100 then
1060
    begin
1060
    begin
1061
      Inc(FTamaCount);
1061
      Inc(FTamaCount);
1062
      with TEnemyTama.Create(Engine, Self) do
1062
      with TEnemyTama.Create(Engine, Self) do
1063
      begin
1063
      begin
1064
        X := Self.X;
1064
        X := Self.X;
1065
        Y := Self.Y+Self.Height div 2-Height div 2;
1065
        Y := Self.Y+Self.Height div 2-Height div 2;
1066
        Z := 10;
1066
        Z := 10;
1067
      end;
1067
      end;
1068
      FOldTamaTime := FCounter;
1068
      FOldTamaTime := FCounter;
1069
     end;
1069
     end;
1070
  end
1070
  end
1071
  else if State = pesDead then
1071
  else if State = pesDead then
1072
  begin
1072
  begin
1073
    if FCounter>200 then
1073
    if FCounter>200 then
1074
    begin
1074
    begin
1075
      FState := pesDeadVanished;
1075
      FState := pesDeadVanished;
1076
      Dead;
1076
      Dead;
1077
    end;
1077
    end;
1078
  end;
1078
  end;
1079
  inc(FCounter, MoveCount);
1079
  inc(FCounter, MoveCount);
1080
end;
1080
end;
1081
 
1081
 
1082
{ TEnemyBoss }
1082
{ TEnemyBoss }
1083
 
1083
 
1084
constructor TEnemyBoss.Create(AParent: TSprite; ALifes: integer);
1084
constructor TEnemyBoss.Create(AParent: TSprite; ALifes: integer);
1085
begin
1085
begin
1086
  inherited Create(AParent, ALifes);
1086
  inherited Create(AParent, ALifes);
1087
  FState := pesEntering;
1087
  FState := pesEntering;
1088
  Image := MainForm.GetSpriteGraphic(smgEnemyBoss);
1088
  Image := MainForm.GetSpriteGraphic(smgEnemyBoss);
1089
  Width := Image.Width;
1089
  Width := Image.Width;
1090
  Height := Image.Height;
1090
  Height := Image.Height;
1091
  MainForm.MusicSwitchTrack(smmBoss);
1091
  MainForm.MusicSwitchTrack(smmBoss);
1092
  AnimCount := Image.PatternCount;
1092
  AnimCount := Image.PatternCount;
1093
  AnimLooped := True;
1093
  AnimLooped := True;
1094
  AnimSpeed := DEFAULT_ANIMSPEED;
1094
  AnimSpeed := DEFAULT_ANIMSPEED;
1095
  PixelCheck := True;
1095
  PixelCheck := True;
1096
  Collisioned := False;
1096
  Collisioned := False;
1097
  MainForm.FBoss := Self;
1097
  MainForm.FBoss := Self;
1098
  waiter1 := 0;
1098
  waiter1 := 0;
1099
  waiter2 := 0;
1099
  waiter2 := 0;
1100
end;
1100
end;
1101
 
1101
 
1102
procedure TEnemyBoss.HitEnemy(ADead: Boolean);
1102
procedure TEnemyBoss.HitEnemy(ADead: Boolean);
1103
begin
1103
begin
1104
  inherited HitEnemy(ADead);
1104
  inherited HitEnemy(ADead);
1105
 
1105
 
1106
  if ADead then
1106
  if ADead then
1107
  begin
1107
  begin
1108
    FState := pesExploding; // not pesDead for the boss!
1108
    FState := pesExploding; // not pesDead for the boss!
1109
    FCounter := 0;
1109
    FCounter := 0;
1110
    Inc(MainForm.FScore, 100000);
1110
    Inc(MainForm.FScore, 100000);
1111
  end
1111
  end
1112
  else
1112
  else
1113
  begin
1113
  begin
1114
    Inc(MainForm.FScore, 100);
1114
    Inc(MainForm.FScore, 100);
1115
  end;
1115
  end;
1116
end;
1116
end;
1117
 
1117
 
1118
destructor TEnemyBoss.Destroy;
1118
destructor TEnemyBoss.Destroy;
1119
begin
1119
begin
1120
  MainForm.FBoss := nil;
1120
  MainForm.FBoss := nil;
1121
  inherited;
1121
  inherited;
1122
end;
1122
end;
1123
 
1123
 
1124
procedure TEnemyBoss.DoMove(MoveCount: Integer);
1124
procedure TEnemyBoss.DoMove(MoveCount: Integer);
1125
begin
1125
begin
1126
  inherited DoMove(MoveCount);
1126
  inherited DoMove(MoveCount);
1127
  if State = pesEntering then
1127
  if State = pesEntering then
1128
  begin
1128
  begin
1129
    if X>((mainform.dxdraw.width/4) + (mainform.dxdraw.width/2) - (width/4)){450} then
1129
    if X>((mainform.dxdraw.width/4) + (mainform.dxdraw.width/2) - (width/4)){450} then
1130
      X := X - MoveCount*(300/1000)
1130
      X := X - MoveCount*(300/1000)
1131
    else
1131
    else
1132
    begin
1132
    begin
1133
      Collisioned := True;
1133
      Collisioned := True;
1134
      FState := pesHovering;
1134
      FState := pesHovering;
1135
      FPutTama := True;
1135
      FPutTama := True;
1136
    end;
1136
    end;
1137
    Y := Y + Cos256(FCounter div 15)*5;
1137
    Y := Y + Cos256(FCounter div 15)*5;
1138
  end
1138
  end
1139
  else if State = pesHovering then
1139
  else if State = pesHovering then
1140
  begin
1140
  begin
1141
    Y := Y + Cos256(FCounter div 15)*5;
1141
    Y := Y + Cos256(FCounter div 15)*5;
1142
    if FPutTama then
1142
    if FPutTama then
1143
    begin
1143
    begin
1144
      if FTamaT>100 then
1144
      if FTamaT>100 then
1145
      begin
1145
      begin
1146
        with TEnemyTama.Create(Engine, Self) do
1146
        with TEnemyTama.Create(Engine, Self) do
1147
        begin
1147
        begin
1148
          Z := 1;
1148
          Z := 1;
1149
          X := Self.X-Width;
1149
          X := Self.X-Width;
1150
          Y := Self.Y+Self.Height div 2-Height div 2;
1150
          Y := Self.Y+Self.Height div 2-Height div 2;
1151
        end;
1151
        end;
1152
        Inc(FTamaF);
1152
        Inc(FTamaF);
1153
        if FTamaF>Random(30) then FPutTama := False;
1153
        if FTamaF>Random(30) then FPutTama := False;
1154
        FTamaT := 0;
1154
        FTamaT := 0;
1155
      end;
1155
      end;
1156
      FTamaT := FTamaT + MoveCount;
1156
      FTamaT := FTamaT + MoveCount;
1157
    end
1157
    end
1158
    else
1158
    else
1159
    begin
1159
    begin
1160
      FTamaT := FTamaT + MoveCount;
1160
      FTamaT := FTamaT + MoveCount;
1161
      if FTamaT>2000+Random(500) then
1161
      if FTamaT>2000+Random(500) then
1162
      begin
1162
      begin
1163
        FPutTama := True;
1163
        FPutTama := True;
1164
        FTamaF := 0;
1164
        FTamaF := 0;
1165
        FTamaT := 0;
1165
        FTamaT := 0;
1166
      end;
1166
      end;
1167
    end;
1167
    end;
1168
  end
1168
  end
1169
  else if State = pesExploding then
1169
  else if State = pesExploding then
1170
  begin
1170
  begin
1171
    inc(waiter1);
1171
    inc(waiter1);
1172
    if waiter1 = 3 then
1172
    if waiter1 = 3 then
1173
    begin
1173
    begin
1174
      waiter1 := 0;
1174
      waiter1 := 0;
1175
      inc(waiter2);
1175
      inc(waiter2);
1176
      if waiter2 <= 20 then
1176
      if waiter2 <= 20 then
1177
      begin
1177
      begin
1178
        with TExplosion.Create(Engine) do
1178
        with TExplosion.Create(Engine) do
1179
        begin
1179
        begin
1180
          Z := 10;
1180
          Z := 10;
1181
          X := Self.X+Random(Self.Width)-16;
1181
          X := Self.X+Random(Self.Width)-16;
1182
          Y := Self.Y+Random(Self.Height)-16;
1182
          Y := Self.Y+Random(Self.Height)-16;
1183
        end;
1183
        end;
1184
      end
1184
      end
1185
      else
1185
      else
1186
      begin
1186
      begin
1187
        Inc(MainForm.FScore, 10000);
1187
        Inc(MainForm.FScore, 10000);
1188
        FState := pesDead;
1188
        FState := pesDead;
1189
      end;
1189
      end;
1190
    end;
1190
    end;
1191
  end
1191
  end
1192
  else if State = pesDead then
1192
  else if State = pesDead then
1193
  begin
1193
  begin
1194
    if FCounter>4000 then
1194
    if FCounter>4000 then
1195
    begin
1195
    begin
1196
      FState := pesDeadVanished;
1196
      FState := pesDeadVanished;
1197
      Dead;
1197
      Dead;
1198
    end;
1198
    end;
1199
  end;
1199
  end;
1200
  inc(FCounter, MoveCount);
1200
  inc(FCounter, MoveCount);
1201
end;
1201
end;
1202
 
1202
 
1203
{ TItem }
1203
{ TItem }
1204
 
1204
 
1205
procedure TItem.Collected;
1205
procedure TItem.Collected;
1206
begin
1206
begin
1207
  MainForm.PlaySound(smsItemCollected, false);
1207
  MainForm.PlaySound(smsItemCollected, false);
1208
  Dead;
1208
  Dead;
1209
end;
1209
end;
1210
 
1210
 
1211
procedure TItem.DoMove(MoveCount: Integer);
1211
procedure TItem.DoMove(MoveCount: Integer);
1212
begin
1212
begin
1213
  X := X - MoveCount*(250/1000);
1213
  X := X - MoveCount*(250/1000);
1214
  if X < -Width then Dead;
1214
  if X < -Width then Dead;
1215
end;
1215
end;
1216
 
1216
 
1217
{ TItemMedikit }
1217
{ TItemMedikit }
1218
 
1218
 
1219
procedure TItemMedikit.Collected;
1219
procedure TItemMedikit.Collected;
1220
begin
1220
begin
1221
  Inc(MainForm.FLife);
1221
  Inc(MainForm.FLife);
1222
  inherited;
1222
  inherited;
1223
end;
1223
end;
1224
 
1224
 
1225
constructor TItemMedikit.Create(AParent: TSprite);
1225
constructor TItemMedikit.Create(AParent: TSprite);
1226
begin
1226
begin
1227
  inherited Create(AParent);
1227
  inherited Create(AParent);
1228
  FState := pesNormal;
1228
  FState := pesNormal;
1229
  Image := MainForm.GetSpriteGraphic(smgItemMedikit);
1229
  Image := MainForm.GetSpriteGraphic(smgItemMedikit);
1230
  Width := Image.Width;
1230
  Width := Image.Width;
1231
  Height := Image.Height;
1231
  Height := Image.Height;
1232
  AnimCount := Image.PatternCount;
1232
  AnimCount := Image.PatternCount;
1233
  AnimLooped := True;
1233
  AnimLooped := True;
1234
  AnimSpeed := DEFAULT_ANIMSPEED;
1234
  AnimSpeed := DEFAULT_ANIMSPEED;
1235
  PixelCheck := True;
1235
  PixelCheck := True;
1236
end;
1236
end;
1237
 
1237
 
1238
{ TMainForm }
1238
{ TMainForm }
1239
 
1239
 
1240
procedure TMainForm.FormCreate(Sender: TObject);
1240
procedure TMainForm.FormCreate(Sender: TObject);
1241
resourcestring
1241
resourcestring
1242
  SAppTitle = 'SpaceMission %s';
1242
  SAppTitle = 'SpaceMission %s';
1243
begin
1243
begin
1244
  Randomize;
1244
  Randomize;
1245
 
1245
 
1246
  LevelData := TLevelData.Create;
1246
  LevelData := TLevelData.Create;
1247
 
1247
 
1248
  { Beginne VCL-Ersatz }
1248
  { Beginne VCL-Ersatz }
1249
  dxtimer := tdxtimer.Create(self);
1249
  dxtimer := tdxtimer.Create(self);
1250
  dxtimer.Interval := 33;
1250
  dxtimer.Interval := 33;
1251
  dxtimer.OnActivate := DXTimerActivate;
1251
  dxtimer.OnActivate := DXTimerActivate;
1252
  dxtimer.OnDeactivate := DXTimerDeactivate;
1252
  dxtimer.OnDeactivate := DXTimerDeactivate;
1253
  dxtimer.OnTimer := DXTimerTimer;
1253
  dxtimer.OnTimer := DXTimerTimer;
1254
  dxtimer.ActiveOnly := false;
1254
  dxtimer.ActiveOnly := false;
1255
  dxtimer.Enabled := false;
1255
  dxtimer.Enabled := false;
1256
 
1256
 
1257
  dxdraw := tdxdraw.Create(self);
1257
  dxdraw := tdxdraw.Create(self);
1258
  dxdraw.Parent := self;
1258
  dxdraw.Parent := self;
1259
  dxdraw.Align := alClient;
1259
  dxdraw.Align := alClient;
1260
  dxdraw.Left := 0;
1260
  dxdraw.Left := 0;
1261
  dxdraw.Top := 0;
1261
  dxdraw.Top := 0;
1262
  dxdraw.Width := ClientWidth;
1262
  dxdraw.Width := ClientWidth;
1263
  dxdraw.Height := ClientHeight;
1263
  dxdraw.Height := ClientHeight;
1264
  dxdraw.AutoInitialize := False;
1264
  dxdraw.AutoInitialize := False;
1265
  dxdraw.AutoSize := False;
1265
  dxdraw.AutoSize := False;
1266
  dxdraw.Color := clBlack;
1266
  dxdraw.Color := clBlack;
1267
  (*
1267
  (*
1268
  dxdraw.Display.BitCount := 24;
1268
  dxdraw.Display.BitCount := 24;
1269
  dxdraw.Display.FixedBitCount := False;
1269
  dxdraw.Display.FixedBitCount := False;
1270
  dxdraw.Display.FixedRatio := False;
1270
  dxdraw.Display.FixedRatio := False;
1271
  dxdraw.Display.FixedSize := False;
1271
  dxdraw.Display.FixedSize := False;
1272
  dxdraw.Display.Height := 600;
1272
  dxdraw.Display.Height := 600;
1273
  dxdraw.Display.Width := 800;
1273
  dxdraw.Display.Width := 800;
1274
  *)
1274
  *)
1275
  dxdraw.Options := [doAllowReboot, doWaitVBlank, doAllowPalette256, doCenter, {doRetainedMode,} doHardware, doSelectDriver];
1275
  dxdraw.Options := [doAllowReboot, doWaitVBlank, doAllowPalette256, doCenter, {doRetainedMode,} doHardware, doSelectDriver];
1276
  dxdraw.TabOrder := 0;
1276
  dxdraw.TabOrder := 0;
1277
  dxdraw.Visible := true;
1277
  dxdraw.Visible := true;
1278
  dxdraw.OnFinalize := DXDrawFinalize;
1278
  dxdraw.OnFinalize := DXDrawFinalize;
1279
  dxdraw.OnInitialize := DXDrawInitialize;
1279
  dxdraw.OnInitialize := DXDrawInitialize;
1280
  dxdraw.OnInitializing := DXDrawInitializing;
1280
  dxdraw.OnInitializing := DXDrawInitializing;
1281
 
1281
 
1282
  dxsound := tdxsound.Create(self);
1282
  dxsound := tdxsound.Create(self);
1283
  dxsound.AutoInitialize := false;
1283
  dxsound.AutoInitialize := false;
1284
 
1284
 
1285
  dxmusic := TDXMusic.Create(self);
1285
  dxmusic := TDXMusic.Create(self);
1286
  dxmusic.DXSound := dxsound;
1286
  dxmusic.DXSound := dxsound;
1287
 
1287
 
1288
  dxinput := tdxinput.Create(self);
1288
  dxinput := tdxinput.Create(self);
1289
  dxinput.Joystick.ForceFeedback := true;
1289
  dxinput.Joystick.ForceFeedback := true;
1290
  dxinput.Keyboard.ForceFeedback := true;
1290
  dxinput.Keyboard.ForceFeedback := true;
1291
 
1291
 
1292
  wavelist := tdxwavelist.Create(self);
1292
  wavelist := tdxwavelist.Create(self);
1293
  wavelist.DXSound := dxsound;
1293
  wavelist.DXSound := dxsound;
1294
 
1294
 
1295
  imagelist := tdximagelist.create(self);
1295
  imagelist := tdximagelist.create(self);
1296
  imagelist.DXDraw := dxdraw;
1296
  imagelist.DXDraw := dxdraw;
1297
 
1297
 
1298
  spriteengine := tdxspriteengine.create(self);
1298
  spriteengine := tdxspriteengine.create(self);
1299
  spriteengine.DXDraw := dxdraw;
1299
  spriteengine.DXDraw := dxdraw;
1300
 
1300
 
1301
  InitializeCriticalSection(TimerCS);
1301
  InitializeCriticalSection(TimerCS);
1302
 
1302
 
1303
  { Ende VCL-Ersatz }
1303
  { Ende VCL-Ersatz }
1304
 
1304
 
1305
  Application.Title := Format(SAppTitle, [ProgramVersion]);
1305
  Application.Title := Format(SAppTitle, [ProgramVersion]);
1306
  LoadOptions;
1306
  LoadOptions;
1307
  DXInit;
1307
  DXInit;
1308
  SoundInit;
1308
  SoundInit;
1309
  MusicInit;
1309
  MusicInit;
1310
 
1310
 
1311
  GameStartClick(GameStart);
1311
  GameStartClick(GameStart);
1312
end;
1312
end;
1313
 
1313
 
1314
procedure TMainForm.GameStartClick(Sender: TObject);
1314
procedure TMainForm.GameStartClick(Sender: TObject);
1315
begin
1315
begin
1316
  StartScene(gsTitle);
1316
  StartScene(gsTitle);
1317
end;
1317
end;
1318
 
1318
 
1319
function TMainForm.GetSpriteGraphic(
1319
function TMainForm.GetSpriteGraphic(
1320
  Sprite: TSpaceMissionGraphicSprite): TPictureCollectionItem;
1320
  Sprite: TSpaceMissionGraphicSprite): TPictureCollectionItem;
1321
begin
1321
begin
1322
  if (Sprite<>smgNone) and (imagelist.Items.Count >= Ord(Sprite)) then
1322
  if (Sprite<>smgNone) and (imagelist.Items.Count >= Ord(Sprite)) then
1323
    result := imagelist.Items.Items[Ord(Sprite)-1]
1323
    result := imagelist.Items.Items[Ord(Sprite)-1]
1324
  else
1324
  else
1325
    result := nil;
1325
    result := nil;
1326
end;
1326
end;
1327
 
1327
 
1328
procedure TMainForm.HilfeTopicClick(Sender: TObject);
1328
procedure TMainForm.HilfeTopicClick(Sender: TObject);
1329
// Please keep this code in-sync with LevMain.pas
1329
// Please keep this code in-sync with LevMain.pas
1330
var
1330
var
1331
  bakTimerEnabled: boolean;
1331
  bakTimerEnabled: boolean;
1332
begin
1332
begin
1333
  bakTimerEnabled := dxtimer.Enabled;
1333
  bakTimerEnabled := dxtimer.Enabled;
1334
  try
1334
  try
1335
    dxtimer.Enabled := false;
1335
    dxtimer.Enabled := false;
1336
    HilfeForm.Caption := TMenuItem(Sender).Caption;
1336
    HilfeForm.Caption := TMenuItem(Sender).Caption;
1337
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, '&&', #1, [rfReplaceAll]);
1337
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, '&&', #1, [rfReplaceAll]);
1338
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, '&', '', [rfReplaceAll]);
1338
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, '&', '', [rfReplaceAll]);
1339
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, #1, '&', [rfReplaceAll]);
1339
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, #1, '&', [rfReplaceAll]);
1340
    HilfeForm.ShowMarkDownHelp(OwnDirectory+TMenuItem(Sender).Hint);
1340
    HilfeForm.ShowMarkDownHelp(OwnDirectory+TMenuItem(Sender).Hint);
1341
    HilfeForm.ShowModal;
1341
    HilfeForm.ShowModal;
1342
  finally
1342
  finally
1343
    dxtimer.Enabled := bakTimerEnabled;
1343
    dxtimer.Enabled := bakTimerEnabled;
1344
  end;
1344
  end;
1345
end;
1345
end;
1346
 
1346
 
1347
procedure TMainForm.GamePauseClick(Sender: TObject);
1347
procedure TMainForm.GamePauseClick(Sender: TObject);
1348
begin
1348
begin
1349
  GamePause.Checked := not GamePause.Checked;
1349
  GamePause.Checked := not GamePause.Checked;
1350
  DXTimer.Enabled := not GamePause.Checked;
1350
  DXTimer.Enabled := not GamePause.Checked;
1351
  if GamePause.Checked then
1351
  if GamePause.Checked then
1352
  begin
1352
  begin
1353
    if Assigned(DXTimer.OnDeactivate) then
1353
    if Assigned(DXTimer.OnDeactivate) then
1354
      DXTimer.OnDeactivate(DXTimer);
1354
      DXTimer.OnDeactivate(DXTimer);
1355
  end
1355
  end
1356
  else
1356
  else
1357
  begin
1357
  begin
1358
    if Assigned(DXTimer.OnActivate) then
1358
    if Assigned(DXTimer.OnActivate) then
1359
      DXTimer.OnActivate(DXTimer);
1359
      DXTimer.OnActivate(DXTimer);
1360
  end;
1360
  end;
1361
end;
1361
end;
1362
 
1362
 
1363
procedure TMainForm.DXInit;
1363
procedure TMainForm.DXInit;
1364
begin
1364
begin
1365
  try
1365
  try
1366
    Imagelist.Items.LoadFromFile(OwnDirectory+DxgFile);
1366
    Imagelist.Items.LoadFromFile(OwnDirectory+DxgFile);
1367
    ImageList.Items.MakeColorTable;
1367
    ImageList.Items.MakeColorTable;
1368
    DXDraw.ColorTable := ImageList.Items.ColorTable;
1368
    DXDraw.ColorTable := ImageList.Items.ColorTable;
1369
    DXDraw.DefColorTable := ImageList.Items.ColorTable;
1369
    DXDraw.DefColorTable := ImageList.Items.ColorTable;
1370
    DXDraw.UpdatePalette;
1370
    DXDraw.UpdatePalette;
1371
    DXDraw.Finalize;
1371
    DXDraw.Finalize;
1372
    DXDraw.Options := DXDraw.Options - [doFullScreen];
1372
    DXDraw.Options := DXDraw.Options - [doFullScreen];
1373
    DXDraw.autosize := true;
1373
    DXDraw.autosize := true;
1374
    DXDraw.Initialize;
1374
    DXDraw.Initialize;
1375
  except
1375
  except
1376
    //Imagelist.Items.clear;
1376
    //Imagelist.Items.clear;
1377
    //application.terminate;
1377
    //application.terminate;
1378
  end;
1378
  end;
1379
end;
1379
end;
1380
 
1380
 
1381
procedure TMainForm.CheckUpdatesClick(Sender: TObject);
1381
procedure TMainForm.CheckUpdatesClick(Sender: TObject);
1382
begin
1382
begin
1383
  CheckForUpdates('spacemission', ProgramVersion); // do not localize
1383
  CheckForUpdates('spacemission', ProgramVersion); // do not localize
1384
end;
1384
end;
1385
 
1385
 
1386
procedure TMainForm.BeendenClick(Sender: TObject);
1386
procedure TMainForm.BeendenClick(Sender: TObject);
1387
begin
1387
begin
1388
  close;
1388
  close;
1389
end;
1389
end;
1390
 
1390
 
1391
procedure TMainForm.OptionSoundClick(Sender: TObject);
1391
procedure TMainForm.OptionSoundClick(Sender: TObject);
1392
begin
1392
begin
1393
  OptionSound.Checked := not OptionSound.Checked;
1393
  OptionSound.Checked := not OptionSound.Checked;
1394
  SoundInit;
1394
  SoundInit;
1395
  WriteOptions;
1395
  WriteOptions;
1396
end;
1396
end;
1397
 
1397
 
1398
procedure TMainForm.SoundInit;
1398
procedure TMainForm.SoundInit;
1399
begin
1399
begin
1400
  if (WaveOutGetNumDevs < 1) or not FileExists(OwnDirectory+DxwFile) then
1400
  if (WaveOutGetNumDevs < 1) or not FileExists(OwnDirectory+DxwFile) then
1401
  begin
1401
  begin
1402
    OptionSound.Checked := false;
1402
    OptionSound.Checked := false;
1403
    OptionSound.Enabled := False;
1403
    OptionSound.Enabled := False;
1404
    exit;
1404
    exit;
1405
  end;
1405
  end;
1406
 
1406
 
1407
  if OptionSound.Checked then
1407
  if OptionSound.Checked then
1408
  begin
1408
  begin
1409
    if not DXSound.Initialized then
1409
    if not DXSound.Initialized then
1410
    begin
1410
    begin
1411
      try
1411
      try
1412
        DXSound.Initialize;
1412
        DXSound.Initialize;
1413
        WaveList.Items.LoadFromFile(OwnDirectory+DxwFile);
1413
        WaveList.Items.LoadFromFile(OwnDirectory+DxwFile);
1414
      except
1414
      except
1415
        OptionSound.enabled := False;
1415
        OptionSound.enabled := False;
1416
        WaveList.items.clear;
1416
        WaveList.items.clear;
1417
      end;
1417
      end;
1418
    end;
1418
    end;
1419
  end
1419
  end
1420
  else DXSound.Finalize;
1420
  else DXSound.Finalize;
1421
end;
1421
end;
1422
 
1422
 
1423
procedure TMainForm.MusicInit;
1423
procedure TMainForm.MusicInit;
1424
var
1424
var
1425
  i: integer;
1425
  i: integer;
1426
begin
1426
begin
1427
  if (WaveOutGetNumDevs < 1) or not FileExists(OwnDirectory+DxmFile) then
1427
  if (WaveOutGetNumDevs < 1) or not FileExists(OwnDirectory+DxmFile) then
1428
  begin
1428
  begin
1429
    optionmusic.Checked := false;
1429
    optionmusic.Checked := false;
1430
    optionmusic.Enabled := False;
1430
    optionmusic.Enabled := False;
1431
    exit;
1431
    exit;
1432
  end;
1432
  end;
1433
 
1433
 
1434
  try
1434
  try
1435
    dxmusic.Midis.LoadFromFile(OwnDirectory+DxmFile);
1435
    dxmusic.Midis.LoadFromFile(OwnDirectory+DxmFile);
1436
    for i := 0 to dxmusic.Midis.Count-1 do
1436
    for i := 0 to dxmusic.Midis.Count-1 do
1437
    begin
1437
    begin
1438
      if not dxmusic.Midis.Items[i].IsInitialized then
1438
      if not dxmusic.Midis.Items[i].IsInitialized then
1439
      begin
1439
      begin
1440
        dxmusic.Midis.Items[i].Init;
1440
        dxmusic.Midis.Items[i].Init; // TODO: for some reason, AddPort is very slow!
1441
        dxmusic.Midis.Items[i].Load;
1441
        dxmusic.Midis.Items[i].Load;
1442
      end;
1442
      end;
1443
    end;
1443
    end;
1444
  except
1444
  except
1445
    optionmusic.enabled := false;
1445
    optionmusic.enabled := false;
1446
  end;
1446
  end;
1447
end;
1447
end;
1448
 
1448
 
1449
procedure TMainForm.DXDrawInitializing(Sender: TObject);
1449
procedure TMainForm.DXDrawInitializing(Sender: TObject);
1450
begin
1450
begin
1451
  if doFullScreen in DXDraw.Options then
1451
  if doFullScreen in DXDraw.Options then
1452
  begin
1452
  begin
1453
    BorderStyle := bsNone;
1453
    BorderStyle := bsNone;
1454
    DXDraw.Cursor := crNone;
1454
    DXDraw.Cursor := crNone;
1455
  end
1455
  end
1456
  else
1456
  else
1457
  begin
1457
  begin
1458
    BorderStyle := bsSingle;
1458
    BorderStyle := bsSingle;
1459
    DXDraw.Cursor := crDefault;
1459
    DXDraw.Cursor := crDefault;
1460
  end;
1460
  end;
1461
end;
1461
end;
1462
 
1462
 
1463
procedure TMainForm.DXDrawInitialize(Sender: TObject);
1463
procedure TMainForm.DXDrawInitialize(Sender: TObject);
1464
begin
1464
begin
1465
  if Assigned(DXTimer) then DXTimer.Enabled := True;
1465
  if Assigned(DXTimer) then DXTimer.Enabled := True;
1466
end;
1466
end;
1467
 
1467
 
1468
procedure TMainForm.DXDrawFinalize(Sender: TObject);
1468
procedure TMainForm.DXDrawFinalize(Sender: TObject);
1469
begin
1469
begin
1470
  if Assigned(DXTimer) then DXTimer.Enabled := False;
1470
  if Assigned(DXTimer) then DXTimer.Enabled := False;
1471
end;
1471
end;
1472
 
1472
 
1473
procedure TMainForm.DXTimerActivate(Sender: TObject);
1473
procedure TMainForm.DXTimerActivate(Sender: TObject);
1474
begin
1474
begin
1475
  if TDxTimer(Sender).Tag > 0 then
1475
  if TDxTimer(Sender).Tag > 0 then
1476
    TDxTimer(Sender).Tag := TDxTimer(Sender).Tag - 1; // es können mehrere activate/deactivate vorkommen, wegen dem Pause-Button
1476
    TDxTimer(Sender).Tag := TDxTimer(Sender).Tag - 1; // es können mehrere activate/deactivate vorkommen, wegen dem Pause-Button
1477
  if TDxTimer(Sender).Tag > 0 then
1477
  if TDxTimer(Sender).Tag > 0 then
1478
    exit;
1478
    exit;
1479
  Caption := Application.Title;
1479
  Caption := Application.Title;
1480
  if not ProgrammGestartet then
1480
  if not ProgrammGestartet then
1481
  begin
1481
  begin
1482
    Programmgestartet := true;
1482
    Programmgestartet := true;
1483
    exit;
1483
    exit;
1484
  end;
1484
  end;
1485
  ResumeMusic(FMusic);
1485
  ResumeMusic(FMusic);
1486
end;
1486
end;
1487
 
1487
 
1488
procedure TMainForm.DXTimerDeactivate(Sender: TObject);
1488
procedure TMainForm.DXTimerDeactivate(Sender: TObject);
1489
resourcestring
1489
resourcestring
1490
  SPauseTitle = '%s [Pause]';
1490
  SPauseTitle = '%s [Pause]';
1491
begin
1491
begin
1492
  TDxTimer(Sender).Tag := TDxTimer(Sender).Tag + 1;
1492
  TDxTimer(Sender).Tag := TDxTimer(Sender).Tag + 1;
1493
  Caption := Format(SPauseTitle, [Application.Title]);
1493
  Caption := Format(SPauseTitle, [Application.Title]);
1494
  PauseMusic(FMusic);
1494
  PauseMusic(FMusic);
1495
end;
1495
end;
1496
 
1496
 
1497
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
1497
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
1498
begin
1498
begin
1499
  EnterCriticalSection(TimerCS);
1499
  EnterCriticalSection(TimerCS);
1500
  try
1500
  try
1501
    if crash then
1501
    if crash then
1502
    begin
1502
    begin
1503
      inc(Crash2);
1503
      inc(Crash2);
1504
      if crash2 = 30 then
1504
      if crash2 = 30 then
1505
      begin
1505
      begin
1506
        Crash2 := 0;
1506
        Crash2 := 0;
1507
        crash := false;
1507
        crash := false;
1508
        crashsound := false;
1508
        crashsound := false;
1509
      end;
1509
      end;
1510
    end;
1510
    end;
1511
    if not DXDraw.CanDraw then exit;
1511
    if not DXDraw.CanDraw then exit;
1512
    DXInput.Update;
1512
    DXInput.Update;
1513
    case FScene of
1513
    case FScene of
1514
      gsTitle   : SceneTitle;
1514
      gsTitle   : SceneTitle;
1515
      gsMain    : SceneMain;
1515
      gsMain    : SceneMain;
1516
      gsGameOver: SceneGameOver;
1516
      gsGameOver: SceneGameOver;
1517
      gsWin     : SceneWin;
1517
      gsWin     : SceneWin;
1518
      gsNewLevel: SceneNewLevel;
1518
      gsNewLevel: SceneNewLevel;
1519
    end;
1519
    end;
1520
    if FNextScene<>gsNone then
1520
    if FNextScene<>gsNone then
1521
    begin
1521
    begin
1522
      StartScene(FNextScene);
1522
      StartScene(FNextScene);
1523
      FNextScene := gsNone;
1523
      FNextScene := gsNone;
1524
    end;
1524
    end;
1525
    DXDraw.Flip;
1525
    DXDraw.Flip;
1526
  finally
1526
  finally
1527
    LeaveCriticalSection(TimerCS);
1527
    LeaveCriticalSection(TimerCS);
1528
  end;
1528
  end;
1529
end;
1529
end;
1530
 
1530
 
1531
procedure TMainForm.BlinkStart;
1531
procedure TMainForm.BlinkStart;
1532
begin
1532
begin
1533
  FBlink := 0;
1533
  FBlink := 0;
1534
  FBlinkTime := GetTickCount;
1534
  FBlinkTime := GetTickCount;
1535
end;
1535
end;
1536
 
1536
 
1537
procedure TMainForm.WriteOptions;
1537
procedure TMainForm.WriteOptions;
1538
var
1538
var
1539
  Reg: TRegistry;
1539
  Reg: TRegistry;
1540
begin
1540
begin
1541
  Reg := TRegistry.Create;
1541
  Reg := TRegistry.Create;
1542
  try
1542
  try
1543
    Reg.RootKey := HKEY_CURRENT_USER;
1543
    Reg.RootKey := HKEY_CURRENT_USER;
1544
    if Reg.OpenKey(RegistrySettingsKey, true) then
1544
    if Reg.OpenKey(RegistrySettingsKey, true) then
1545
    begin
1545
    begin
1546
      Reg.WriteBool(MusicSettingKey, OptionMusic.checked);
1546
      Reg.WriteBool(MusicSettingKey, OptionMusic.checked);
1547
      Reg.WriteBool(SoundSettingKey, OptionSound.checked);
1547
      Reg.WriteBool(SoundSettingKey, OptionSound.checked);
1548
      Reg.WriteInteger(SpeedSettingKey, Ord(FSpeed));
1548
      Reg.WriteInteger(SpeedSettingKey, Ord(FSpeed));
1549
      Reg.DeleteValue('Speed'); // deprecated. Replaced by GameSpeed
1549
      Reg.DeleteValue('Speed'); // deprecated. Replaced by GameSpeed
1550
      Reg.CloseKey;
1550
      Reg.CloseKey;
1551
    end;
1551
    end;
1552
  finally
1552
  finally
1553
    FreeAndNil(Reg);
1553
    FreeAndNil(Reg);
1554
  end;
1554
  end;
1555
end;
1555
end;
1556
 
1556
 
1557
procedure TMainForm.LoadOptions;
1557
procedure TMainForm.LoadOptions;
1558
var
1558
var
1559
  Reg: TRegistry;
1559
  Reg: TRegistry;
1560
begin
1560
begin
1561
  Reg := TRegistry.Create;
1561
  Reg := TRegistry.Create;
1562
  try
1562
  try
1563
    Reg.RootKey := HKEY_CURRENT_USER;
1563
    Reg.RootKey := HKEY_CURRENT_USER;
1564
    if Reg.OpenKey(RegistrySettingsKey, true) then
1564
    if Reg.OpenKey(RegistrySettingsKey, true) then
1565
    begin
1565
    begin
1566
      if Reg.ValueExists(MusicSettingKey) then
1566
      if Reg.ValueExists(MusicSettingKey) then
1567
        optionmusic.checked := Reg.ReadBool(MusicSettingKey)
1567
        optionmusic.checked := Reg.ReadBool(MusicSettingKey)
1568
      else
1568
      else
1569
        optionmusic.checked := true; // default
1569
        optionmusic.checked := true; // default
1570
 
1570
 
1571
      if Reg.ValueExists(SoundSettingKey) then
1571
      if Reg.ValueExists(SoundSettingKey) then
1572
        optionsound.checked := Reg.ReadBool(SoundSettingKey)
1572
        optionsound.checked := Reg.ReadBool(SoundSettingKey)
1573
      else
1573
      else
1574
        optionsound.checked := true; // default
1574
        optionsound.checked := true; // default
1575
 
1575
 
1576
      if Reg.ValueExists(SpeedSettingKey) then
1576
      if Reg.ValueExists(SpeedSettingKey) then
1577
        FSpeed := Reg.ReadInteger(SpeedSettingKey)
1577
        FSpeed := Reg.ReadInteger(SpeedSettingKey)
1578
      else
1578
      else
1579
        FSpeed := SpeedMedium; // default
1579
        FSpeed := SpeedMedium; // default
1580
 
1580
 
1581
      Leicht.Checked := FSpeed = SpeedEasy;
1581
      Leicht.Checked := FSpeed = SpeedEasy;
1582
      Mittel.Checked := FSpeed = SpeedMedium;
1582
      Mittel.Checked := FSpeed = SpeedMedium;
1583
      Schwer.Checked := FSpeed = SpeedHard;
1583
      Schwer.Checked := FSpeed = SpeedHard;
1584
      Master.Checked := FSpeed = SpeedMaster;
1584
      Master.Checked := FSpeed = SpeedMaster;
1585
 
1585
 
1586
      Reg.CloseKey;
1586
      Reg.CloseKey;
1587
    end;
1587
    end;
1588
  finally
1588
  finally
1589
    FreeAndNil(Reg);
1589
    FreeAndNil(Reg);
1590
  end;
1590
  end;
1591
  WriteOptions;
1591
  WriteOptions;
1592
end;
1592
end;
1593
 
1593
 
1594
procedure TMainForm.BlinkUpdate;
1594
procedure TMainForm.BlinkUpdate;
1595
begin
1595
begin
1596
  if GetTickCount<>FBlinkTime then
1596
  if GetTickCount<>FBlinkTime then
1597
  begin
1597
  begin
1598
    FBlink := FBlink + (GetTickCount-FBlinkTime);
1598
    FBlink := FBlink + (GetTickCount-FBlinkTime);
1599
    FBlinkTime := GetTickCount;
1599
    FBlinkTime := GetTickCount;
1600
  end;
1600
  end;
1601
end;
1601
end;
1602
 
1602
 
1603
procedure TMainForm.PlaySound(Sound: TSpaceMissionSound; Wait: Boolean);
1603
procedure TMainForm.PlaySound(Sound: TSpaceMissionSound; Wait: Boolean);
1604
begin
1604
begin
1605
  if (Sound<>smsNone) and (OptionSound.Checked) and (OptionSound.Enabled) and (WaveList.Items.Count >= Ord(Sound)) then
1605
  if (Sound<>smsNone) and (OptionSound.Checked) and (OptionSound.Enabled) and (WaveList.Items.Count >= Ord(Sound)) then
1606
    WaveList.Items.Items[Ord(Sound)-1].Play(Wait);
1606
    WaveList.Items.Items[Ord(Sound)-1].Play(Wait);
1607
end;
1607
end;
1608
 
1608
 
1609
procedure TMainForm.MusicSwitchTrack(Name: TSpaceMissionMusicTrack);
1609
procedure TMainForm.MusicSwitchTrack(Name: TSpaceMissionMusicTrack);
1610
begin
1610
begin
1611
  if (not mainform.active) and (mainform.visible) then //1st Programmstart
1611
  if (not mainform.active) and (mainform.visible) then //1st Programmstart
1612
    exit;
1612
    exit;
1613
  if (OptionMusic.checked) and (OptionMusic.enabled) then
1613
  if (OptionMusic.checked) and (OptionMusic.enabled) then
1614
  begin
1614
  begin
1615
    StopMusic(FMusic);
1615
    StopMusic(FMusic);
1616
    PlayMusic(Name);
1616
    PlayMusic(Name);
1617
  end;
1617
  end;
1618
  FMusic := Name;
1618
  FMusic := Name;
1619
end;
1619
end;
1620
 
1620
 
1621
function TMainForm.ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
1621
function TMainForm.ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
1622
begin
1622
begin
1623
  with Result do
1623
  with Result do
1624
  begin
1624
  begin
1625
    rgbRed := Src.rgbRed+((Dest.rgbRed-Src.rgbRed)*Percent div 256);
1625
    rgbRed := Src.rgbRed+((Dest.rgbRed-Src.rgbRed)*Percent div 256);
1626
    rgbGreen := Src.rgbGreen+((Dest.rgbGreen-Src.rgbGreen)*Percent div 256);
1626
    rgbGreen := Src.rgbGreen+((Dest.rgbGreen-Src.rgbGreen)*Percent div 256);
1627
    rgbBlue := Src.rgbBlue+((Dest.rgbBlue-Src.rgbBlue)*Percent div 256);
1627
    rgbBlue := Src.rgbBlue+((Dest.rgbBlue-Src.rgbBlue)*Percent div 256);
1628
    rgbReserved := 0;
1628
    rgbReserved := 0;
1629
  end;
1629
  end;
1630
end;
1630
end;
1631
 
1631
 
1632
procedure TMainForm.PalleteAnim(Col: TRGBQuad; Time: Integer);
1632
procedure TMainForm.PalleteAnim(Col: TRGBQuad; Time: Integer);
1633
var
1633
var
1634
  i: Integer;
1634
  i: Integer;
1635
  t, t2: DWORD;
1635
  t, t2: DWORD;
1636
  ChangePalette: Boolean;
1636
  ChangePalette: Boolean;
1637
  c: Integer;
1637
  c: Integer;
1638
begin
1638
begin
1639
  if DXDraw.Initialized then
1639
  if DXDraw.Initialized then
1640
  begin
1640
  begin
1641
    c := DXDraw.Surface.ColorMatch(RGB(Col.rgbRed, Col.rgbGreen, Col.rgbBlue));
1641
    c := DXDraw.Surface.ColorMatch(RGB(Col.rgbRed, Col.rgbGreen, Col.rgbBlue));
1642
    ChangePalette := False;
1642
    ChangePalette := False;
1643
    if DXDraw.CanPaletteAnimation then
1643
    if DXDraw.CanPaletteAnimation then
1644
    begin
1644
    begin
1645
      t := GetTickCount;
1645
      t := GetTickCount;
1646
      while Abs(GetTickCount-t)<Time do
1646
      while Abs(GetTickCount-t)<Time do
1647
      begin
1647
      begin
1648
        t2 := Trunc(Abs(GetTickCount-t)/Time*255);
1648
        t2 := Trunc(Abs(GetTickCount-t)/Time*255);
1649
        for i := 0 to 255 do
1649
        for i := 0 to 255 do
1650
          DXDraw.ColorTable[i] := ComposeColor(Col, DXDraw.DefColorTable[i], t2);
1650
          DXDraw.ColorTable[i] := ComposeColor(Col, DXDraw.DefColorTable[i], t2);
1651
        DXDraw.UpdatePalette;
1651
        DXDraw.UpdatePalette;
1652
        ChangePalette := True;
1652
        ChangePalette := True;
1653
      end;
1653
      end;
1654
    end
1654
    end
1655
    else
1655
    else
1656
    begin
1656
    begin
1657
      Sleep(Time);
1657
      Sleep(Time);
1658
    end;
1658
    end;
1659
    for i := 0 to 4 do
1659
    for i := 0 to 4 do
1660
    begin
1660
    begin
1661
      DXDraw.Surface.Fill(c);
1661
      DXDraw.Surface.Fill(c);
1662
      DXDraw.Flip;
1662
      DXDraw.Flip;
1663
    end;
1663
    end;
1664
    if ChangePalette then
1664
    if ChangePalette then
1665
    begin
1665
    begin
1666
      DXDraw.ColorTable := DXDraw.DefColorTable;
1666
      DXDraw.ColorTable := DXDraw.DefColorTable;
1667
      DXDraw.UpdatePalette;
1667
      DXDraw.UpdatePalette;
1668
    end;
1668
    end;
1669
    DXDraw.Surface.Fill(c);
1669
    DXDraw.Surface.Fill(c);
1670
    DXDraw.Flip;
1670
    DXDraw.Flip;
1671
  end;
1671
  end;
1672
end;
1672
end;
1673
 
1673
 
1674
procedure TMainForm.StartScene(Scene: TGameScene);
1674
procedure TMainForm.StartScene(Scene: TGameScene);
1675
begin
1675
begin
1676
  EndScene;
1676
  EndScene;
1677
  DXInput.States := DXInput.States - DXInputButton;
1677
  DXInput.States := DXInput.States - DXInputButton;
1678
  FScene := Scene;
1678
  FScene := Scene;
1679
  BlinkStart;
1679
  BlinkStart;
1680
  case FScene of
1680
  case FScene of
1681
    gsTitle   : StartSceneTitle;
1681
    gsTitle   : StartSceneTitle;
1682
    gsMain    : StartSceneMain;
1682
    gsMain    : StartSceneMain;
1683
    gsGameOver: StartSceneGameOver;
1683
    gsGameOver: StartSceneGameOver;
1684
    gsWin     : StartSceneWin;
1684
    gsWin     : StartSceneWin;
1685
    gsNewLevel: StartSceneNewLevel;
1685
    gsNewLevel: StartSceneNewLevel;
1686
  end;
1686
  end;
1687
end;
1687
end;
1688
 
1688
 
1689
procedure TMainForm.StartSceneTitle;
1689
procedure TMainForm.StartSceneTitle;
1690
begin
1690
begin
1691
  sleep(500);
1691
  sleep(500);
1692
  FCheats := [];
1692
  FCheats := [];
1693
  FLife := StartLives;
1693
  FLife := StartLives;
1694
  FLevel := 0;
1694
  FLevel := 0;
1695
  FScore := 0;
1695
  FScore := 0;
1696
  FLevelDataAlreadyLoaded := false; // do allow NewLevel() to work again
1696
  FLevelDataAlreadyLoaded := false; // do allow NewLevel() to work again
1697
  FNotSave := true;
1697
  FNotSave := true;
1698
  Cheat.enabled := false;
1698
  Cheat.enabled := false;
1699
  Neustart.enabled := false;
1699
  Neustart.enabled := false;
1700
  GamePause.enabled := false;
1700
  GamePause.enabled := false;
1701
  GameStart.enabled := false;
1701
  GameStart.enabled := false;
1702
  Spielgeschwindigkeit.enabled := false;
1702
  Spielgeschwindigkeit.enabled := false;
1703
  mainform.Visible := true;
1703
  mainform.Visible := true;
1704
  MusicSwitchTrack(smmTitle);
1704
  MusicSwitchTrack(smmTitle);
1705
end;
1705
end;
1706
 
1706
 
1707
procedure TMainForm.StartSceneMain;
1707
procedure TMainForm.StartSceneMain;
1708
{var
1708
{var
1709
  i, j: Integer;}
1709
  i, j: Integer;}
1710
begin
1710
begin
1711
  sleep(500);
1711
  sleep(500);
1712
  FCounter := 0;
1712
  FCounter := 0;
1713
  if not FLevelDataAlreadyLoaded then NewLevel(FLevel);
1713
  if not FLevelDataAlreadyLoaded then NewLevel(FLevel);
1714
  FRestEnemies := Length(LevelData.EnemyAdventTable);
1714
  FRestEnemies := Length(LevelData.EnemyAdventTable);
1715
  FLifeAtLevelStart := FLife;     // Das ist wichtig, wenn man neu starten möchte
1715
  FLifeAtLevelStart := FLife;     // Das ist wichtig, wenn man neu starten möchte
1716
  FScoreAtLevelStart := FScore;   //
1716
  FScoreAtLevelStart := FScore;   //
1717
  MusicSwitchTrack(smmGame);
1717
  MusicSwitchTrack(smmGame);
1718
  FEnemyAdventPos := 0;
1718
  FEnemyAdventPos := 0;
1719
  FFrame := -4;
1719
  FFrame := -4;
1720
  PlayerSprite := TPlayerSprite.Create(SpriteEngine.Engine);
1720
  PlayerSprite := TPlayerSprite.Create(SpriteEngine.Engine);
1721
  with TBackground.Create(SpriteEngine.Engine) do
1721
  with TBackground.Create(SpriteEngine.Engine) do
1722
  begin
1722
  begin
1723
    SetMapSize(1, 1);
1723
    SetMapSize(1, 1);
1724
    Image := MainForm.GetSpriteGraphic(smgStar3);
1724
    Image := MainForm.GetSpriteGraphic(smgStar3);
1725
    Z := -13;
1725
    Z := -13;
1726
    Y := 40;
1726
    Y := 40;
1727
    Speed := 1 / 2;
1727
    Speed := 1 / 2;
1728
    Tile := True;
1728
    Tile := True;
1729
  end;
1729
  end;
1730
  with TBackground.Create(SpriteEngine.Engine) do
1730
  with TBackground.Create(SpriteEngine.Engine) do
1731
  begin
1731
  begin
1732
    SetMapSize(1, 1);
1732
    SetMapSize(1, 1);
1733
    Image := MainForm.GetSpriteGraphic(smgStar2);
1733
    Image := MainForm.GetSpriteGraphic(smgStar2);
1734
    Z := -12;
1734
    Z := -12;
1735
    Y := 30;
1735
    Y := 30;
1736
    Speed := 1;
1736
    Speed := 1;
1737
    Tile := True;
1737
    Tile := True;
1738
  end;
1738
  end;
1739
  with TBackground.Create(SpriteEngine.Engine) do
1739
  with TBackground.Create(SpriteEngine.Engine) do
1740
  begin
1740
  begin
1741
    SetMapSize(1, 1);
1741
    SetMapSize(1, 1);
1742
    Image := MainForm.GetSpriteGraphic(smgStar1);
1742
    Image := MainForm.GetSpriteGraphic(smgStar1);
1743
    Z := -11;
1743
    Z := -11;
1744
    Y := 10;
1744
    Y := 10;
1745
    Speed := 2;
1745
    Speed := 2;
1746
    Tile := True;
1746
    Tile := True;
1747
  end;
1747
  end;
1748
  {with TBackground.Create(SpriteEngine.Engine) do
1748
  {with TBackground.Create(SpriteEngine.Engine) do
1749
  begin
1749
  begin
1750
    SetMapSize(200, 10);
1750
    SetMapSize(200, 10);
1751
    Y := 10;
1751
    Y := 10;
1752
    Z := -13;
1752
    Z := -13;
1753
    Speed := 1 / 2;
1753
    Speed := 1 / 2;
1754
    Tile := True;
1754
    Tile := True;
1755
    for i := 0 to MapHeight-1 do
1755
    for i := 0 to MapHeight-1 do
1756
    begin
1756
    begin
1757
      for j := 0 to MapWidth-1 do
1757
      for j := 0 to MapWidth-1 do
1758
      begin
1758
      begin
1759
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 8);
1759
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 8);
1760
        if Random(100)<95 then Chips[j, i] := -1;
1760
        if Random(100)<95 then Chips[j, i] := -1;
1761
      end;
1761
      end;
1762
    end;
1762
    end;
1763
  end;
1763
  end;
1764
  with TBackground.Create(SpriteEngine.Engine) do
1764
  with TBackground.Create(SpriteEngine.Engine) do
1765
  begin
1765
  begin
1766
    SetMapSize(200, 10);
1766
    SetMapSize(200, 10);
1767
    Y := 30;
1767
    Y := 30;
1768
    Z := -12;
1768
    Z := -12;
1769
    Speed := 1;
1769
    Speed := 1;
1770
    Tile := True;
1770
    Tile := True;
1771
    for i := 0 to MapHeight-1 do
1771
    for i := 0 to MapHeight-1 do
1772
    begin
1772
    begin
1773
      for j := 0 to MapWidth-1 do
1773
      for j := 0 to MapWidth-1 do
1774
      begin
1774
      begin
1775
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 4);
1775
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 4);
1776
        if Random(100)<95 then Chips[j, i] := -1;
1776
        if Random(100)<95 then Chips[j, i] := -1;
1777
      end;
1777
      end;
1778
    end;
1778
    end;
1779
  end;
1779
  end;
1780
  with TBackground.Create(SpriteEngine.Engine) do
1780
  with TBackground.Create(SpriteEngine.Engine) do
1781
  begin
1781
  begin
1782
    SetMapSize(200, 10);
1782
    SetMapSize(200, 10);
1783
    Y := 40;
1783
    Y := 40;
1784
    Z := -11;
1784
    Z := -11;
1785
    Speed := 2;
1785
    Speed := 2;
1786
    Tile := True;
1786
    Tile := True;
1787
    for i := 0 to MapHeight-1 do
1787
    for i := 0 to MapHeight-1 do
1788
    begin
1788
    begin
1789
      for j := 0 to MapWidth-1 do
1789
      for j := 0 to MapWidth-1 do
1790
      begin
1790
      begin
1791
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 2);
1791
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 2);
1792
        if Random(100)<95 then Chips[j, i] := -1;
1792
        if Random(100)<95 then Chips[j, i] := -1;
1793
      end;
1793
      end;
1794
    end;
1794
    end;
1795
  end;}
1795
  end;}
1796
  FNotSave := false;
1796
  FNotSave := false;
1797
  Cheat.enabled := true;
1797
  Cheat.enabled := true;
1798
  Neustart.enabled := true;
1798
  Neustart.enabled := true;
1799
  GamePause.enabled := true;
1799
  GamePause.enabled := true;
1800
  GameStart.enabled := true;
1800
  GameStart.enabled := true;
1801
  Spielgeschwindigkeit.enabled := true;
1801
  Spielgeschwindigkeit.enabled := true;
1802
end;
1802
end;
1803
 
1803
 
1804
procedure TMainForm.StartSceneGameOver;
1804
procedure TMainForm.StartSceneGameOver;
1805
begin
1805
begin
1806
  sleep(500);
1806
  sleep(500);
1807
  FNotSave := true; // Wenn man speichert, würde man LevelAdventTable vom vorherigen Level machen, das wär müll!
1807
  FNotSave := true; // Wenn man speichert, würde man LevelAdventTable vom vorherigen Level machen, das wär müll!
1808
  Cheat.enabled := false;
1808
  Cheat.enabled := false;
1809
  Spielgeschwindigkeit.enabled := false;
1809
  Spielgeschwindigkeit.enabled := false;
1810
  Neustart.enabled := false;
1810
  Neustart.enabled := false;
1811
  GamePause.enabled := false;
1811
  GamePause.enabled := false;
1812
  MusicSwitchTrack(smmScene);
1812
  MusicSwitchTrack(smmScene);
1813
end;
1813
end;
1814
 
1814
 
1815
procedure TMainForm.StartSceneWin;
1815
procedure TMainForm.StartSceneWin;
1816
begin
1816
begin
1817
  sleep(500);
1817
  sleep(500);
1818
  FNotSave := true; // Wenn man speichert, würde man LevelAdventTable vom vorherigen Level machen, das wär müll!
1818
  FNotSave := true; // Wenn man speichert, würde man LevelAdventTable vom vorherigen Level machen, das wär müll!
1819
  Cheat.enabled := false;
1819
  Cheat.enabled := false;
1820
  Spielgeschwindigkeit.enabled := false;
1820
  Spielgeschwindigkeit.enabled := false;
1821
  Neustart.enabled := false;
1821
  Neustart.enabled := false;
1822
  GamePause.enabled := false;
1822
  GamePause.enabled := false;
1823
  MusicSwitchTrack(smmScene);
1823
  MusicSwitchTrack(smmScene);
1824
end;
1824
end;
1825
 
1825
 
1826
procedure TMainForm.EndScene;
1826
procedure TMainForm.EndScene;
1827
begin
1827
begin
1828
  case FScene of
1828
  case FScene of
1829
    gsTitle   : EndSceneTitle;
1829
    gsTitle   : EndSceneTitle;
1830
    gsMain    : EndSceneMain;
1830
    gsMain    : EndSceneMain;
1831
    gsGameOver: EndSceneGameOver;
1831
    gsGameOver: EndSceneGameOver;
1832
    gsWin     : EndSceneWin;
1832
    gsWin     : EndSceneWin;
1833
    gsNewLevel: EndSceneNewLevel;
1833
    gsNewLevel: EndSceneNewLevel;
1834
  end;
1834
  end;
1835
end;
1835
end;
1836
 
1836
 
1837
procedure TMainForm.EndSceneTitle;
1837
procedure TMainForm.EndSceneTitle;
1838
begin
1838
begin
1839
  {  Ende Title  }
1839
  {  Ende Title  }
1840
end;
1840
end;
1841
 
1841
 
1842
procedure TMainForm.EndSceneMain;
1842
procedure TMainForm.EndSceneMain;
1843
begin
1843
begin
1844
  SpriteEngine.Engine.Clear;
1844
  SpriteEngine.Engine.Clear;
1845
end;
1845
end;
1846
 
1846
 
1847
procedure TMainForm.EndSceneGameOver;
1847
procedure TMainForm.EndSceneGameOver;
1848
begin
1848
begin
1849
  {  Ende GameOver  }
1849
  {  Ende GameOver  }
1850
end;
1850
end;
1851
 
1851
 
1852
procedure TMainForm.EndSceneWin;
1852
procedure TMainForm.EndSceneWin;
1853
begin
1853
begin
1854
  {  Ende Win  }
1854
  {  Ende Win  }
1855
end;
1855
end;
1856
 
1856
 
1857
procedure TMainForm.ResetLevelData;
1857
procedure TMainForm.ResetLevelData;
1858
begin
1858
begin
1859
  LevelData.Clear;
1859
  LevelData.Clear;
1860
  FRestEnemies := 0;
1860
  FRestEnemies := 0;
1861
end;
1861
end;
1862
 
1862
 
1863
procedure TMainForm.NewLevel(lev: integer);
1863
procedure TMainForm.NewLevel(lev: integer);
1864
resourcestring
1864
resourcestring
1865
  SLevelInvalid = 'Die Datei für Level %d ist ungültig. Level wird übersprungen!';
1865
  SLevelInvalid = 'Die Datei für Level %d ist ungültig. Level wird übersprungen!';
1866
var
1866
var
1867
  act: integer;
1867
  act: integer;
1868
  Enemies: array[1..32] of TEnemyType;
1868
  Enemies: array[1..32] of TEnemyType;
1869
  numEnemies: integer;
1869
  numEnemies: integer;
1870
  e: TEnemyAdvent;
1870
  e: TEnemyAdvent;
1871
  bossPosition: integer;
1871
  bossPosition: integer;
1872
  levFile: TLevelFile;
1872
  levFile: TLevelFile;
1873
begin
1873
begin
1874
  ResetLevelData;
1874
  ResetLevelData;
1875
  if FGameMode = gmRandom then
1875
  if FGameMode = gmRandom then
1876
  begin
1876
  begin
1877
    {$REGION 'Random game'}
1877
    {$REGION 'Random game'}
1878
    Enemies[1] := etEnemyAttacker;     // ab Lev 1
1878
    Enemies[1] := etEnemyAttacker;     // ab Lev 1
1879
    Enemies[2] := etEnemyMeteor;       // ab Lev 1
1879
    Enemies[2] := etEnemyMeteor;       // ab Lev 1
1880
    Enemies[3] := etEnemyUFO;          // ab Lev 1
1880
    Enemies[3] := etEnemyUFO;          // ab Lev 1
1881
    Enemies[4] := etEnemyAttacker;     // ab Lev 2
1881
    Enemies[4] := etEnemyAttacker;     // ab Lev 2
1882
    Enemies[5] := etEnemyMeteor;       // ab Lev 3
1882
    Enemies[5] := etEnemyMeteor;       // ab Lev 3
1883
    Enemies[6] := etEnemyUFO;          // ab Lev 4
1883
    Enemies[6] := etEnemyUFO;          // ab Lev 4
1884
    Enemies[7] := etEnemyAttacker;     // ab Lev 5
1884
    Enemies[7] := etEnemyAttacker;     // ab Lev 5
1885
    Enemies[8] := etEnemyMeteor;       // ab Lev 6
1885
    Enemies[8] := etEnemyMeteor;       // ab Lev 6
1886
    Enemies[9] := etEnemyUFO;          // ab Lev 7
1886
    Enemies[9] := etEnemyUFO;          // ab Lev 7
1887
    Enemies[10] := etEnemyAttacker;    // ab Lev 8
1887
    Enemies[10] := etEnemyAttacker;    // ab Lev 8
1888
    Enemies[11] := etEnemyMeteor;      // ab Lev 9
1888
    Enemies[11] := etEnemyMeteor;      // ab Lev 9
1889
    Enemies[12] := etEnemyUFO;         // ab Lev 10
1889
    Enemies[12] := etEnemyUFO;         // ab Lev 10
1890
    Enemies[13] := etEnemyAttacker;    // ab Lev 11
1890
    Enemies[13] := etEnemyAttacker;    // ab Lev 11
1891
    Enemies[14] := etEnemyMeteor;      // ab Lev 12
1891
    Enemies[14] := etEnemyMeteor;      // ab Lev 12
1892
    Enemies[15] := etEnemyUFO;         // ab Lev 13
1892
    Enemies[15] := etEnemyUFO;         // ab Lev 13
1893
    Enemies[16] := etEnemyAttacker3;   // ab Lev 14
1893
    Enemies[16] := etEnemyAttacker3;   // ab Lev 14
1894
    Enemies[17] := etEnemyAttacker;    // ab Lev 15
1894
    Enemies[17] := etEnemyAttacker;    // ab Lev 15
1895
    Enemies[18] := etEnemyMeteor;      // ab Lev 16
1895
    Enemies[18] := etEnemyMeteor;      // ab Lev 16
1896
    Enemies[19] := etEnemyUFO;         // ab Lev 17
1896
    Enemies[19] := etEnemyUFO;         // ab Lev 17
1897
    Enemies[20] := etEnemyUFO2;        // ab Lev 18
1897
    Enemies[20] := etEnemyUFO2;        // ab Lev 18
1898
    Enemies[21] := etEnemyAttacker;    // ab Lev 19
1898
    Enemies[21] := etEnemyAttacker;    // ab Lev 19
1899
    Enemies[22] := etEnemyMeteor;      // ab Lev 20
1899
    Enemies[22] := etEnemyMeteor;      // ab Lev 20
1900
    Enemies[23] := etEnemyUFO;         // ab Lev 21
1900
    Enemies[23] := etEnemyUFO;         // ab Lev 21
1901
    Enemies[24] := etEnemyAttacker2;   // ab Lev 22
1901
    Enemies[24] := etEnemyAttacker2;   // ab Lev 22
1902
    Enemies[25] := etEnemyMeteor;      // ab Lev 23
1902
    Enemies[25] := etEnemyMeteor;      // ab Lev 23
1903
    Enemies[26] := etEnemyUFO;         // ab Lev 24
1903
    Enemies[26] := etEnemyUFO;         // ab Lev 24
1904
    Enemies[27] := etEnemyAttacker;    // ab Lev 25
1904
    Enemies[27] := etEnemyAttacker;    // ab Lev 25
1905
    Enemies[28] := etEnemyAttacker;    // ab Lev 26
1905
    Enemies[28] := etEnemyAttacker;    // ab Lev 26
1906
    Enemies[29] := etEnemyAttacker2;   // ab Lev 27
1906
    Enemies[29] := etEnemyAttacker2;   // ab Lev 27
1907
    Enemies[30] := etEnemyAttacker3;   // ab Lev 28
1907
    Enemies[30] := etEnemyAttacker3;   // ab Lev 28
1908
    Enemies[31] := etEnemyUFO;         // ab Lev 29
1908
    Enemies[31] := etEnemyUFO;         // ab Lev 29
1909
    Enemies[32] := etEnemyUFO2;        // ab Lev 30
1909
    Enemies[32] := etEnemyUFO2;        // ab Lev 30
1910
    numEnemies := lev*RandomLevelAdditionalEnemiesPerLevel;
1910
    numEnemies := lev*RandomLevelAdditionalEnemiesPerLevel;
1911
    SetLength(LevelData.EnemyAdventTable, numEnemies);
1911
    SetLength(LevelData.EnemyAdventTable, numEnemies);
1912
    for act := 0 to numEnemies-1 do
1912
    for act := 0 to numEnemies-1 do
1913
    begin
1913
    begin
1914
      e.enemyType := Enemies[min(random(lev+2)+1, High(Enemies))];
1914
      e.enemyType := Enemies[min(random(lev+2)+1, High(Enemies))];
1915
      if e.enemyType = etEnemyAttacker2 then
1915
      if e.enemyType = etEnemyAttacker2 then
1916
      begin
1916
      begin
1917
        //e.enemyType := Enemies[min(random(lev+2)+1, High(Enemies))];
1917
        //e.enemyType := Enemies[min(random(lev+2)+1, High(Enemies))];
1918
        if Random(2) = 0 then e.enemyType := etEnemyAttacker3;
1918
        if Random(2) = 0 then e.enemyType := etEnemyAttacker3;
1919
      end;
1919
      end;
1920
      e.x := 85-(lev+(random(lev))*2){O_o};
1920
      e.x := 85-(lev+(random(lev))*2){O_o};
1921
      if e.x < 1 then e.x := 1; // passiert bei großen Levels
1921
      if e.x < 1 then e.x := 1; // passiert bei großen Levels
1922
      e.x := act*30 + random(e.x);
1922
      e.x := act*30 + random(e.x);
1923
      e.y := random((LevEditRows-1)*LevEditRasterH);
1923
      e.y := random((LevEditRows-1)*LevEditRasterH);
1924
      if e.enemyType = etEnemyAttacker2 then
1924
      if e.enemyType = etEnemyAttacker2 then
1925
      begin
1925
      begin
1926
        e.lifes := random(6)+1{O_o};
1926
        e.lifes := random(6)+1{O_o};
1927
      end
1927
      end
1928
      else
1928
      else
1929
      begin
1929
      begin
1930
        if lev > RandomLevelMaxEnemyLives then
1930
        if lev > RandomLevelMaxEnemyLives then
1931
        begin
1931
        begin
1932
          e.lifes := random(RandomLevelMaxEnemyLives)+1;
1932
          e.lifes := random(RandomLevelMaxEnemyLives)+1;
1933
        end
1933
        end
1934
        else
1934
        else
1935
        begin
1935
        begin
1936
          e.lifes := random(lev)+1;
1936
          e.lifes := random(lev)+1;
1937
        end;
1937
        end;
1938
      end;
1938
      end;
1939
 
1939
 
1940
      if (act-1) mod RandomLevelMedikitEveryX = 0 then
1940
      if (act-1) mod RandomLevelMedikitEveryX = 0 then
1941
      begin
1941
      begin
1942
        e.enemyType := etItemMedikit;
1942
        e.enemyType := etItemMedikit;
1943
        e.lifes := 0;
1943
        e.lifes := 0;
1944
      end;
1944
      end;
1945
 
1945
 
1946
      LevelData.EnemyAdventTable[act] := e;
1946
      LevelData.EnemyAdventTable[act] := e;
1947
    end;
1947
    end;
1948
 
1948
 
1949
    if lev < 5 then
1949
    if lev < 5 then
1950
    begin
1950
    begin
1951
      // Level 1-4: No boss
1951
      // Level 1-4: No boss
1952
      bossPosition := -1;
1952
      bossPosition := -1;
1953
    end
1953
    end
1954
    else if lev < 10 then
1954
    else if lev < 10 then
1955
    begin
1955
    begin
1956
      // Level 5-9: Boss is at the end of the level
1956
      // Level 5-9: Boss is at the end of the level
1957
      bossPosition := numEnemies-1;
1957
      bossPosition := numEnemies-1;
1958
    end
1958
    end
1959
    else
1959
    else
1960
    begin
1960
    begin
1961
      // Starting with Level 10: Boss at 75% of the level
1961
      // Starting with Level 10: Boss at 75% of the level
1962
      bossPosition := round(0.75 * numEnemies);
1962
      bossPosition := round(0.75 * numEnemies);
1963
    end;
1963
    end;
1964
 
1964
 
1965
    if LevelData.EnemyAdventTable[bossPosition].enemyType = etItemMedikit then
1965
    if LevelData.EnemyAdventTable[bossPosition].enemyType = etItemMedikit then
1966
      Inc(bossPosition);
1966
      Inc(bossPosition);
1967
 
1967
 
1968
    if bossPosition >= 0 then
1968
    if bossPosition >= 0 then
1969
    begin
1969
    begin
1970
      e.enemyType := etEnemyBoss;
1970
      e.enemyType := etEnemyBoss;
1971
      //e.x := lev*75*30{O_o} div lev;
1971
      //e.x := lev*75*30{O_o} div lev;
1972
      e.x := LevelData.EnemyAdventTable[bossPosition-1].x;
1972
      e.x := LevelData.EnemyAdventTable[bossPosition-1].x;
1973
      e.y := (dxdraw.surfaceheight div 2) - (MainForm.GetSpriteGraphic(smgEnemyBoss).height div 2);
1973
      e.y := (dxdraw.surfaceheight div 2) - (MainForm.GetSpriteGraphic(smgEnemyBoss).height div 2);
1974
      e.lifes := lev*5;
1974
      e.lifes := lev*5;
1975
      LevelData.EnemyAdventTable[bossPosition] := e;
1975
      LevelData.EnemyAdventTable[bossPosition] := e;
1976
    end;
1976
    end;
1977
 
1977
 
1978
    {$ENDREGION}
1978
    {$ENDREGION}
1979
  end
1979
  end
1980
  else
1980
  else
1981
  begin
1981
  begin
1982
    {$REGION 'Normal game'}
1982
    {$REGION 'Normal game'}
1983
    levFile := GetLevelFileName(lev,false);
1983
    levFile := GetLevelFileName(lev,false);
1984
    if levFile.found then
1984
    if levFile.found then
1985
    begin
1985
    begin
1986
      try
1986
      try
1987
        LevelData.RasterErzwingen := false;
1987
        LevelData.RasterErzwingen := false;
1988
        LevelData.LoadFromFile(levFile.fileLocation);
1988
        LevelData.LoadFromFile(levFile.fileLocation);
1989
      except
1989
      except
1990
        showmessage(Format(SLevelInvalid, [lev]));
1990
        showmessage(Format(SLevelInvalid, [lev]));
1991
        ResetLevelData; // empty level = the player will continue with the next level
1991
        ResetLevelData; // empty level = the player will continue with the next level
1992
      end;
1992
      end;
1993
    end;
1993
    end;
1994
    {$ENDREGION}
1994
    {$ENDREGION}
1995
  end;
1995
  end;
1996
  FLevelDataAlreadyLoaded := true; // nicht nochmal NewLevel() aufrufen. Erst wieder wenn man gewonnen hat.
1996
  FLevelDataAlreadyLoaded := true; // nicht nochmal NewLevel() aufrufen. Erst wieder wenn man gewonnen hat.
1997
end;
1997
end;
1998
 
1998
 
1999
var
1999
var
2000
  TitleWasPressed: TDxInputState = isButton32;
2000
  TitleWasPressed: TDxInputState = isButton32;
2001
 
2001
 
2002
procedure TMainForm.SceneTitle;
2002
procedure TMainForm.SceneTitle;
2003
resourcestring
2003
resourcestring
2004
  SNormalGame = 'Normales Spiel';
2004
  SNormalGame = 'Normales Spiel';
2005
  SRandomGame = 'Zufalls-Level';
2005
  SRandomGame = 'Zufalls-Level';
2006
  SLevelEditor = 'Level-Editor';
2006
  SLevelEditor = 'Level-Editor';
2007
var
2007
var
2008
  Logo: TPictureCollectionItem;
2008
  Logo: TPictureCollectionItem;
2009
  colo1, colo2: TColor;
2009
  colo1, colo2: TColor;
2010
begin
2010
begin
2011
  DXDraw.Surface.Fill(0);
2011
  DXDraw.Surface.Fill(0);
2012
  Logo := GetSpriteGraphic(smgLogo);
2012
  Logo := GetSpriteGraphic(smgLogo);
2013
  {Logo.DrawWaveX(DXDraw.Surface, (dxdraw.surfaceWidth div 2) - 181, 65, Logo.Width, Logo.Height, 0,
2013
  {Logo.DrawWaveX(DXDraw.Surface, (dxdraw.surfaceWidth div 2) - 181, 65, Logo.Width, Logo.Height, 0,
2014
    Trunc(16 - Cos256(FBlink div 60) * 16), 32, -FBlink div 5);}
2014
    Trunc(16 - Cos256(FBlink div 60) * 16), 32, -FBlink div 5);}
2015
  Logo.DrawWaveX(DXDraw.Surface, trunc((dxdraw.surfaceWidth / 2) - (Logo.Width / 2)), 65, Logo.Width, Logo.Height, 0,
2015
  Logo.DrawWaveX(DXDraw.Surface, trunc((dxdraw.surfaceWidth / 2) - (Logo.Width / 2)), 65, Logo.Width, Logo.Height, 0,
2016
    2, 80, Fangle * 4);
2016
    2, 80, Fangle * 4);
2017
  inc(Fangle);
2017
  inc(Fangle);
2018
 
2018
 
2019
  if FGameMode = gmUnknown then FGameMode := gmLevels;
2019
  if FGameMode = gmUnknown then FGameMode := gmLevels;
2020
 
2020
 
2021
  if (isUp in MainForm.DXInput.States) then TitleWasPressed := isUp;
2021
  if (isUp in MainForm.DXInput.States) then TitleWasPressed := isUp;
2022
  if (TitleWasPressed=isUp) and not (isUp in MainForm.DXInput.States) then
2022
  if (TitleWasPressed=isUp) and not (isUp in MainForm.DXInput.States) then
2023
  begin
2023
  begin
2024
    TitleWasPressed := isButton32;
2024
    TitleWasPressed := isButton32;
2025
    if (Ord(FGameMode) <> 1) then
2025
    if (Ord(FGameMode) <> 1) then
2026
      FGameMode := TGameMode(Ord(FGameMode)-1);
2026
      FGameMode := TGameMode(Ord(FGameMode)-1);
2027
  end;
2027
  end;
2028
 
2028
 
2029
  if (isDown in MainForm.DXInput.States) then TitleWasPressed := isDown;
2029
  if (isDown in MainForm.DXInput.States) then TitleWasPressed := isDown;
2030
  if (TitleWasPressed=isDown) and not (isDown in MainForm.DXInput.States) then
2030
  if (TitleWasPressed=isDown) and not (isDown in MainForm.DXInput.States) then
2031
  begin
2031
  begin
2032
    TitleWasPressed := isButton32;
2032
    TitleWasPressed := isButton32;
2033
    if (FGameMode <> High(TGameMode)) then
2033
    if (FGameMode <> High(TGameMode)) then
2034
      FGameMode := TGameMode(Ord(FGameMode)+1);
2034
      FGameMode := TGameMode(Ord(FGameMode)+1);
2035
  end;
2035
  end;
2036
 
2036
 
2037
  DXDraw.Surface.Canvas.Brush.Style := bsClear;
2037
  DXDraw.Surface.Canvas.Brush.Style := bsClear;
2038
  DXDraw.Surface.Canvas.Font.Size := 30;
2038
  DXDraw.Surface.Canvas.Font.Size := 30;
2039
 
2039
 
2040
  {$REGION 'Menu point: Normal Level'}
2040
  {$REGION 'Menu point: Normal Level'}
2041
  if FGameMode = gmLevels then
2041
  if FGameMode = gmLevels then
2042
  begin
2042
  begin
2043
    colo1 := clMaroon;
2043
    colo1 := clMaroon;
2044
    colo2 := clRed;
2044
    colo2 := clRed;
2045
  end
2045
  end
2046
  else
2046
  else
2047
  begin
2047
  begin
2048
    colo1 := clOlive;
2048
    colo1 := clOlive;
2049
    colo2 := clYellow;
2049
    colo2 := clYellow;
2050
  end;
2050
  end;
2051
  DXDraw.Surface.Canvas.Font.Color := colo1;
2051
  DXDraw.Surface.Canvas.Font.Color := colo1;
2052
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-52, SNormalGame);
2052
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-52, SNormalGame);
2053
  if FGameMode = gmLevels then
2053
  if FGameMode = gmLevels then
2054
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)-52, '>');
2054
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)-52, '>');
2055
  DXDraw.Surface.Canvas.Font.Color := colo2;
2055
  DXDraw.Surface.Canvas.Font.Color := colo2;
2056
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)-50, SNormalGame);
2056
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)-50, SNormalGame);
2057
  if FGameMode = gmLevels then
2057
  if FGameMode = gmLevels then
2058
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)-50, '>');
2058
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)-50, '>');
2059
  {$ENDREGION}
2059
  {$ENDREGION}
2060
 
2060
 
2061
  {$REGION 'Menu point: Random Level'}
2061
  {$REGION 'Menu point: Random Level'}
2062
  if FGameMode = gmRandom then
2062
  if FGameMode = gmRandom then
2063
  begin
2063
  begin
2064
    colo1 := clMaroon;
2064
    colo1 := clMaroon;
2065
    colo2 := clRed;
2065
    colo2 := clRed;
2066
  end
2066
  end
2067
  else
2067
  else
2068
  begin
2068
  begin
2069
    colo1 := clOlive;
2069
    colo1 := clOlive;
2070
    colo2 := clYellow;
2070
    colo2 := clYellow;
2071
  end;
2071
  end;
2072
  DXDraw.Surface.Canvas.Font.Color := colo1;
2072
  DXDraw.Surface.Canvas.Font.Color := colo1;
2073
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-2, SRandomGame);
2073
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-2, SRandomGame);
2074
  if FGameMode = gmRandom then
2074
  if FGameMode = gmRandom then
2075
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-187, (dxdraw.surfaceheight div 2)-2, '>');
2075
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-187, (dxdraw.surfaceheight div 2)-2, '>');
2076
  DXDraw.Surface.Canvas.Font.Color := colo2;
2076
  DXDraw.Surface.Canvas.Font.Color := colo2;
2077
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2), SRandomGame);
2077
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2), SRandomGame);
2078
  if FGameMode = gmRandom then
2078
  if FGameMode = gmRandom then
2079
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2), '>');
2079
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2), '>');
2080
  {$ENDREGION}
2080
  {$ENDREGION}
2081
 
2081
 
2082
  {$REGION 'Menu point: Level Editor'}
2082
  {$REGION 'Menu point: Level Editor'}
2083
  if FGameMode = gmEditor then
2083
  if FGameMode = gmEditor then
2084
  begin
2084
  begin
2085
    colo1 := clMaroon;
2085
    colo1 := clMaroon;
2086
    colo2 := clRed;
2086
    colo2 := clRed;
2087
  end
2087
  end
2088
  else
2088
  else
2089
  begin
2089
  begin
2090
    colo1 := clOlive;
2090
    colo1 := clOlive;
2091
    colo2 := clYellow;
2091
    colo2 := clYellow;
2092
  end;
2092
  end;
2093
  DXDraw.Surface.Canvas.Font.Color := colo1;
2093
  DXDraw.Surface.Canvas.Font.Color := colo1;
2094
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)+48, SLevelEditor);
2094
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)+48, SLevelEditor);
2095
  if FGameMode = gmEditor then
2095
  if FGameMode = gmEditor then
2096
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)+48, '>');
2096
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)+48, '>');
2097
  DXDraw.Surface.Canvas.Font.Color := colo2;
2097
  DXDraw.Surface.Canvas.Font.Color := colo2;
2098
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)+50, SLevelEditor);
2098
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)+50, SLevelEditor);
2099
  if FGameMode = gmEditor then
2099
  if FGameMode = gmEditor then
2100
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)+50, '>');
2100
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)+50, '>');
2101
  {$ENDREGION}
2101
  {$ENDREGION}
2102
 
2102
 
2103
  { if (FBlink div 300) mod 2=0 then
2103
  { if (FBlink div 300) mod 2=0 then
2104
  begin
2104
  begin
2105
    DXDraw.Surface.Canvas.Font.Color := clGreen;
2105
    DXDraw.Surface.Canvas.Font.Color := clGreen;
2106
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, SWeiterMitLeertaste);
2106
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, SWeiterMitLeertaste);
2107
    DXDraw.Surface.Canvas.Font.Color := clLime;
2107
    DXDraw.Surface.Canvas.Font.Color := clLime;
2108
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, SWeiterMitLeertaste);
2108
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, SWeiterMitLeertaste);
2109
  end; }
2109
  end; }
2110
  BlinkUpdate;
2110
  BlinkUpdate;
2111
  DXDraw.Surface.Canvas.Release;
2111
  DXDraw.Surface.Canvas.Release;
2112
 
2112
 
2113
  // Weiter mit Leertaste oder Enter
2113
  // Weiter mit Leertaste oder Enter
2114
  if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
2114
  if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
2115
  begin
2115
  begin
2116
    FLevel := 1;
2116
    FLevel := 1;
2117
    if FGameMode = gmEditor then
2117
    if FGameMode = gmEditor then
2118
    begin
2118
    begin
2119
      ShellExecute(0, 'open', PChar(OwnDirectory+LevEditExe), '', PChar(OwnDirectory), SW_NORMAL); // do not localize
2119
      ShellExecute(0, 'open', PChar(OwnDirectory+LevEditExe), '', PChar(OwnDirectory), SW_NORMAL); // do not localize
2120
      Close;
2120
      Close;
2121
      exit;
2121
      exit;
2122
    end;
2122
    end;
2123
    if ((FGameMode=gmLevels) and not GetLevelFileName(FLevel,false).found) or
2123
    if ((FGameMode=gmLevels) and not GetLevelFileName(FLevel,false).found) or
2124
       ((FGameMode=gmRandom) and (FLevel > MaxPossibleLevels)) then
2124
       ((FGameMode=gmRandom) and (FLevel > MaxPossibleLevels)) then
2125
    begin
2125
    begin
2126
      //PlaySound('Frage', False);
2126
      //PlaySound('Frage', False);
2127
      exit;
2127
      exit;
2128
    end;
2128
    end;
2129
    PlaySound(smsSceneMov, False);
2129
    PlaySound(smsSceneMov, False);
2130
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2130
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2131
    Sleep(200);
2131
    Sleep(200);
2132
    StartScene(gsMain);
2132
    StartScene(gsMain);
2133
  end;
2133
  end;
2134
end;
2134
end;
2135
 
2135
 
2136
procedure TMainForm.SceneMain;
2136
procedure TMainForm.SceneMain;
2137
resourcestring
2137
resourcestring
2138
  SMissionSuccessful = 'Mission erfolgreich!';
2138
  SMissionSuccessful = 'Mission erfolgreich!';
2139
  SMissionFailed = 'Mission gescheitert!';
2139
  SMissionFailed = 'Mission gescheitert!';
2140
  SPunkte = 'Punkte: %s';
2140
  SPunkte = 'Punkte: %s';
2141
  SLevel = 'Level: %d';
2141
  SLevel = 'Level: %d';
2142
  SLifes = 'Leben: %d';
2142
  SLifes = 'Leben: %d';
2143
  SInfLifes = '';
2143
  SInfLifes = '';
2144
  SBossLifes = 'Boss: %d';
2144
  SBossLifes = 'Boss: %d';
2145
  SEinheiten = 'Einheiten: %d';
2145
  SEinheiten = 'Einheiten: %d';
2146
var
2146
var
2147
  Enemy: TSprite;
2147
  Enemy: TSprite;
2148
  spriteClass: TClass;
2148
  spriteClass: TClass;
2149
  tmpEnemyAnzeige: integer;
2149
  tmpEnemyAnzeige: integer;
2150
begin
2150
begin
2151
  SpriteEngine.Move(FSpeed);
2151
  SpriteEngine.Move(FSpeed);
2152
  SpriteEngine.Dead;
2152
  SpriteEngine.Dead;
2153
  while (FEnemyAdventPos >= Low(LevelData.EnemyAdventTable)) and
2153
  while (FEnemyAdventPos >= Low(LevelData.EnemyAdventTable)) and
2154
    (FEnemyAdventPos <= High(LevelData.EnemyAdventTable)) and
2154
    (FEnemyAdventPos <= High(LevelData.EnemyAdventTable)) and
2155
    ((LevelData.EnemyAdventTable[FEnemyAdventPos].x / 4) <= FFrame) and
2155
    ((LevelData.EnemyAdventTable[FEnemyAdventPos].x / 4) <= FFrame) and
2156
    (FRestEnemies > 0) do
2156
    (FRestEnemies > 0) do
2157
  begin
2157
  begin
2158
    Dec(FRestEnemies);
2158
    Dec(FRestEnemies);
2159
    with LevelData.EnemyAdventTable[FEnemyAdventPos] do
2159
    with LevelData.EnemyAdventTable[FEnemyAdventPos] do
2160
    begin
2160
    begin
2161
      spriteClass := nil;
2161
      spriteClass := nil;
2162
      case enemyType of
2162
      case enemyType of
2163
        //etUnknown: ;
2163
        //etUnknown: ;
2164
        etEnemyAttacker:  spriteClass := TEnemyAttacker;
2164
        etEnemyAttacker:  spriteClass := TEnemyAttacker;
2165
        etEnemyAttacker2: spriteClass := TEnemyAttacker2;
2165
        etEnemyAttacker2: spriteClass := TEnemyAttacker2;
2166
        etEnemyAttacker3: spriteClass := TEnemyAttacker3;
2166
        etEnemyAttacker3: spriteClass := TEnemyAttacker3;
2167
        etEnemyMeteor:    spriteClass := TEnemyMeteor;
2167
        etEnemyMeteor:    spriteClass := TEnemyMeteor;
2168
        etEnemyUFO:       spriteClass := TEnemyUFO;
2168
        etEnemyUFO:       spriteClass := TEnemyUFO;
2169
        etEnemyUFO2:      spriteClass := TEnemyUFO2;
2169
        etEnemyUFO2:      spriteClass := TEnemyUFO2;
2170
        etEnemyBoss:      spriteClass := TEnemyBoss;
2170
        etEnemyBoss:      spriteClass := TEnemyBoss;
2171
        etItemMedikit:    spriteClass := TItemMedikit;
2171
        etItemMedikit:    spriteClass := TItemMedikit;
2172
      end;
2172
      end;
2173
      if spriteClass <> nil then
2173
      if spriteClass <> nil then
2174
      begin
2174
      begin
2175
        Enemy := nil;
2175
        Enemy := nil;
2176
        if spriteClass.InheritsFrom(TEnemy) then
2176
        if spriteClass.InheritsFrom(TEnemy) then
2177
          Enemy := TEnemyClass(spriteClass).Create(SpriteEngine.Engine, lifes)
2177
          Enemy := TEnemyClass(spriteClass).Create(SpriteEngine.Engine, lifes)
2178
        else if spriteClass.InheritsFrom(TItem) then
2178
        else if spriteClass.InheritsFrom(TItem) then
2179
          Enemy := TItemClass(spriteClass).Create(SpriteEngine.Engine)
2179
          Enemy := TItemClass(spriteClass).Create(SpriteEngine.Engine)
2180
        else
2180
        else
2181
          Assert(False);
2181
          Assert(False);
2182
        Enemy.x := dxdraw.surfacewidth;
2182
        Enemy.x := dxdraw.surfacewidth;
2183
        //Enemy.y := y;
2183
        //Enemy.y := y;
2184
        if y <> 0 then
2184
        if y <> 0 then
2185
          Enemy.y := dxdraw.surfaceheight / ((LevEditRows*LevEditRasterH) / y)
2185
          Enemy.y := dxdraw.surfaceheight / ((LevEditRows*LevEditRasterH) / y)
2186
        else
2186
        else
2187
          Enemy.y := 0;
2187
          Enemy.y := 0;
2188
      end;
2188
      end;
2189
    end;
2189
    end;
2190
    Inc(FEnemyAdventPos);
2190
    Inc(FEnemyAdventPos);
2191
  end;
2191
  end;
2192
  Inc(FFrame);
2192
  Inc(FFrame);
2193
  DXDraw.Surface.Fill(0);
2193
  DXDraw.Surface.Fill(0);
2194
  if FNextScene=gsNone then
2194
  if FNextScene=gsNone then
2195
  begin
2195
  begin
2196
    SpriteEngine.Draw;
2196
    SpriteEngine.Draw;
2197
    DXDraw.Surface.Canvas.Brush.Style := bsClear;
2197
    DXDraw.Surface.Canvas.Brush.Style := bsClear;
2198
    DXDraw.Surface.Canvas.Font.Size := 20;
2198
    DXDraw.Surface.Canvas.Font.Size := 20;
2199
    if flife > 0 then
2199
    if flife > 0 then
2200
    begin
2200
    begin
2201
      {$REGION 'Anzeige Punkte'}
2201
      {$REGION 'Anzeige Punkte'}
2202
      DXDraw.Surface.Canvas.Font.Color := clOlive;
2202
      DXDraw.Surface.Canvas.Font.Color := clOlive;
2203
      DXDraw.Surface.Canvas.Textout(9, 9, Format(SPunkte, [FloatToStrF(FScore,ffNumber,14,0)]));
2203
      DXDraw.Surface.Canvas.Textout(9, 9, Format(SPunkte, [FloatToStrF(FScore,ffNumber,14,0)]));
2204
      DXDraw.Surface.Canvas.Font.Color := clYellow;
2204
      DXDraw.Surface.Canvas.Font.Color := clYellow;
2205
      DXDraw.Surface.Canvas.Textout(10, 10, Format(SPunkte, [FloatToStrF(FScore,ffNumber,14,0)]));
2205
      DXDraw.Surface.Canvas.Textout(10, 10, Format(SPunkte, [FloatToStrF(FScore,ffNumber,14,0)]));
2206
      {$ENDREGION}
2206
      {$ENDREGION}
2207
 
2207
 
2208
      {$REGION 'Anzeige Level'}
2208
      {$REGION 'Anzeige Level'}
2209
      DXDraw.Surface.Canvas.Font.Color := clMaroon;
2209
      DXDraw.Surface.Canvas.Font.Color := clMaroon;
2210
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-141, 9, Format(SLevel, [flevel]));
2210
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-141, 9, Format(SLevel, [flevel]));
2211
      DXDraw.Surface.Canvas.Font.Color := clRed;
2211
      DXDraw.Surface.Canvas.Font.Color := clRed;
2212
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-140, 10, Format(SLevel, [flevel]));
2212
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-140, 10, Format(SLevel, [flevel]));
2213
      {$ENDREGION}
2213
      {$ENDREGION}
2214
 
2214
 
2215
      {$REGION 'Lebensanzeige'}
2215
      {$REGION 'Lebensanzeige'}
2216
      if FLife<0 then FLife := 0;
2216
      if FLife<0 then FLife := 0;
2217
      if ctInfiniteLives in FCheats then
2217
      if ctInfiniteLives in FCheats then
2218
      begin
2218
      begin
2219
        DXDraw.Surface.Canvas.Font.Color := clPurple;
2219
        DXDraw.Surface.Canvas.Font.Color := clPurple;
2220
        DXDraw.Surface.Canvas.Textout(9, dxdraw.surfaceheight-41, SInfLifes);
2220
        DXDraw.Surface.Canvas.Textout(9, dxdraw.surfaceheight-41, SInfLifes);
2221
        DXDraw.Surface.Canvas.Font.Color := clFuchsia;
2221
        DXDraw.Surface.Canvas.Font.Color := clFuchsia;
2222
        DXDraw.Surface.Canvas.Textout(10, dxdraw.surfaceheight-40, SInfLifes);
2222
        DXDraw.Surface.Canvas.Textout(10, dxdraw.surfaceheight-40, SInfLifes);
2223
      end
2223
      end
2224
      else
2224
      else
2225
      begin
2225
      begin
2226
        if ((Flife = 1) and ((FBlink div 300) mod 2=0)) or (Flife <> 1) then
2226
        if ((Flife = 1) and ((FBlink div 300) mod 2=0)) or (Flife <> 1) then
2227
        begin
2227
        begin
2228
          DXDraw.Surface.Canvas.Font.Color := clPurple;
2228
          DXDraw.Surface.Canvas.Font.Color := clPurple;
2229
          DXDraw.Surface.Canvas.Textout(9, dxdraw.surfaceheight-41, Format(SLifes, [flife]));
2229
          DXDraw.Surface.Canvas.Textout(9, dxdraw.surfaceheight-41, Format(SLifes, [flife]));
2230
          DXDraw.Surface.Canvas.Font.Color := clFuchsia;
2230
          DXDraw.Surface.Canvas.Font.Color := clFuchsia;
2231
          DXDraw.Surface.Canvas.Textout(10, dxdraw.surfaceheight-40, Format(SLifes, [flife]));
2231
          DXDraw.Surface.Canvas.Textout(10, dxdraw.surfaceheight-40, Format(SLifes, [flife]));
2232
        end;
2232
        end;
2233
        if Flife = 1 then BlinkUpdate;
2233
        if Flife = 1 then BlinkUpdate;
2234
      end;
2234
      end;
2235
      {$ENDREGION}
2235
      {$ENDREGION}
2236
 
2236
 
2237
      {$REGION 'Anzeige Einheiten und Boss Leben'}
2237
      {$REGION 'Anzeige Einheiten und Boss Leben'}
2238
 
2238
 
2239
      tmpEnemyAnzeige := EnemyCounter{Auf Bildschirm} + FRestEnemies{In der Warteschlange};
2239
      tmpEnemyAnzeige := EnemyCounter{Auf Bildschirm} + FRestEnemies{In der Warteschlange};
2240
      if Assigned(FBoss) and (FBoss.State<>pesDeadVanished) then Dec(tmpEnemyAnzeige);
2240
      if Assigned(FBoss) and (FBoss.State<>pesDeadVanished) then Dec(tmpEnemyAnzeige);
2241
 
2241
 
2242
      if Assigned(FBoss) and (FBoss.Life>0) then
2242
      if Assigned(FBoss) and (FBoss.Life>0) then
2243
      begin
2243
      begin
2244
        if (tmpEnemyAnzeige>0) then
2244
        if (tmpEnemyAnzeige>0) then
2245
        begin
2245
        begin
2246
          DXDraw.Surface.Canvas.Font.Color := clGreen;
2246
          DXDraw.Surface.Canvas.Font.Color := clGreen;
2247
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-81, Format(SBossLifes, [FBoss.Life]));
2247
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-81, Format(SBossLifes, [FBoss.Life]));
2248
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, Format(SEinheiten, [tmpEnemyAnzeige]));
2248
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, Format(SEinheiten, [tmpEnemyAnzeige]));
2249
          DXDraw.Surface.Canvas.Font.Color := clLime;
2249
          DXDraw.Surface.Canvas.Font.Color := clLime;
2250
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-80, Format(SBossLifes, [FBoss.Life]));
2250
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-80, Format(SBossLifes, [FBoss.Life]));
2251
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, Format(SEinheiten, [tmpEnemyAnzeige]));
2251
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, Format(SEinheiten, [tmpEnemyAnzeige]));
2252
        end
2252
        end
2253
        else
2253
        else
2254
        begin
2254
        begin
2255
          DXDraw.Surface.Canvas.Font.Color := clGreen;
2255
          DXDraw.Surface.Canvas.Font.Color := clGreen;
2256
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, Format(SBossLifes, [FBoss.Life]));
2256
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, Format(SBossLifes, [FBoss.Life]));
2257
          DXDraw.Surface.Canvas.Font.Color := clLime;
2257
          DXDraw.Surface.Canvas.Font.Color := clLime;
2258
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, Format(SBossLifes, [FBoss.Life]));
2258
          DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, Format(SBossLifes, [FBoss.Life]));
2259
        end;
2259
        end;
2260
      end
2260
      end
2261
      else if tmpEnemyAnzeige>0 then
2261
      else if tmpEnemyAnzeige>0 then
2262
      begin
2262
      begin
2263
        DXDraw.Surface.Canvas.Font.Color := clGreen;
2263
        DXDraw.Surface.Canvas.Font.Color := clGreen;
2264
        DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, Format(SEinheiten, [tmpEnemyAnzeige]));
2264
        DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, Format(SEinheiten, [tmpEnemyAnzeige]));
2265
        DXDraw.Surface.Canvas.Font.Color := clLime;
2265
        DXDraw.Surface.Canvas.Font.Color := clLime;
2266
        DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, Format(SEinheiten, [tmpEnemyAnzeige]));
2266
        DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, Format(SEinheiten, [tmpEnemyAnzeige]));
2267
      end;
2267
      end;
2268
      {$ENDREGION}
2268
      {$ENDREGION}
2269
 
2269
 
2270
      {$REGION 'Anzeige Mission erfolgreich/gescheitert'}
2270
      {$REGION 'Anzeige Mission erfolgreich/gescheitert'}
2271
      if (EnemyCounter=0) and (FRestEnemies=0) then
2271
      if (EnemyCounter=0) and (FRestEnemies=0) then
2272
      begin
2272
      begin
2273
        DXDraw.Surface.Canvas.Font.Color := clGreen;
2273
        DXDraw.Surface.Canvas.Font.Color := clGreen;
2274
        DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, SMissionSuccessful);
2274
        DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, SMissionSuccessful);
2275
        DXDraw.Surface.Canvas.Font.Color := clLime;
2275
        DXDraw.Surface.Canvas.Font.Color := clLime;
2276
        DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, SMissionSuccessful);
2276
        DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, SMissionSuccessful);
2277
        DXDraw.Surface.Canvas.Release;
2277
        DXDraw.Surface.Canvas.Release;
2278
        Sleep(1);
2278
        Sleep(1);
2279
        inc(FCounter);
2279
        inc(FCounter);
2280
        if FCounter>150{200} then PlayerSprite.FlyAway;
2280
        if FCounter>150{200} then PlayerSprite.FlyAway;
2281
      end;
2281
      end;
2282
      {$ENDREGION}
2282
      {$ENDREGION}
2283
    end
2283
    end
2284
    else
2284
    else
2285
    begin
2285
    begin
2286
      DXDraw.Surface.Canvas.Font.Color := clMaroon;
2286
      DXDraw.Surface.Canvas.Font.Color := clMaroon;
2287
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, SMissionFailed);
2287
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, SMissionFailed);
2288
      DXDraw.Surface.Canvas.Font.Color := clRed;
2288
      DXDraw.Surface.Canvas.Font.Color := clRed;
2289
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, SMissionFailed);
2289
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, SMissionFailed);
2290
    end;
2290
    end;
2291
    DXDraw.Surface.Canvas.Release;
2291
    DXDraw.Surface.Canvas.Release;
2292
  end;
2292
  end;
2293
end;
2293
end;
2294
 
2294
 
2295
procedure TMainForm.SceneGameOver;
2295
procedure TMainForm.SceneGameOver;
2296
resourcestring
2296
resourcestring
2297
  SGameOver = 'Game Over!';
2297
  SGameOver = 'Game Over!';
2298
begin
2298
begin
2299
  DXDraw.Surface.Fill(0);
2299
  DXDraw.Surface.Fill(0);
2300
 
2300
 
2301
  FNotSave := true;
2301
  FNotSave := true;
2302
  Cheat.enabled := false;
2302
  Cheat.enabled := false;
2303
  GamePause.enabled := false;
2303
  GamePause.enabled := false;
2304
  Neustart.enabled := false;
2304
  Neustart.enabled := false;
2305
  Brush.Style := bsClear;
2305
  Brush.Style := bsClear;
2306
  DXDraw.Surface.Canvas.Font.Size := 35;
2306
  DXDraw.Surface.Canvas.Font.Size := 35;
2307
  DXDraw.Surface.Canvas.Font.Color := clMaroon;
2307
  DXDraw.Surface.Canvas.Font.Color := clMaroon;
2308
  DXDraw.Surface.Canvas.Textout((dxdraw.surfacewidth div 2)-127, 98, SGameOver);
2308
  DXDraw.Surface.Canvas.Textout((dxdraw.surfacewidth div 2)-127, 98, SGameOver);
2309
  DXDraw.Surface.Canvas.Font.Color := clRed;
2309
  DXDraw.Surface.Canvas.Font.Color := clRed;
2310
  DXDraw.Surface.Canvas.Textout((dxdraw.surfacewidth div 2)-125, 100, SGameOver);
2310
  DXDraw.Surface.Canvas.Textout((dxdraw.surfacewidth div 2)-125, 100, SGameOver);
2311
  if (FBlink div 300) mod 2=0 then
2311
  if (FBlink div 300) mod 2=0 then
2312
  begin
2312
  begin
2313
    DXDraw.Surface.Canvas.Font.Size := 30;
2313
    DXDraw.Surface.Canvas.Font.Size := 30;
2314
    DXDraw.Surface.Canvas.Font.Color := clOlive;
2314
    DXDraw.Surface.Canvas.Font.Color := clOlive;
2315
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, SWeiterMitLeertaste);
2315
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, SWeiterMitLeertaste);
2316
    DXDraw.Surface.Canvas.Font.Color := clYellow;
2316
    DXDraw.Surface.Canvas.Font.Color := clYellow;
2317
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, SWeiterMitLeertaste);
2317
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, SWeiterMitLeertaste);
2318
  end;
2318
  end;
2319
  BlinkUpdate;
2319
  BlinkUpdate;
2320
  DXDraw.Surface.Canvas.Release;
2320
  DXDraw.Surface.Canvas.Release;
2321
 
2321
 
2322
  // Weiter mit Leertaste oder Enter
2322
  // Weiter mit Leertaste oder Enter
2323
  if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
2323
  if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
2324
  begin
2324
  begin
2325
    PlaySound(smsSceneMov, False);
2325
    PlaySound(smsSceneMov, False);
2326
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2326
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2327
    Sleep(200);
2327
    Sleep(200);
2328
    StartScene(gsTitle);
2328
    StartScene(gsTitle);
2329
  end;
2329
  end;
2330
end;
2330
end;
2331
 
2331
 
2332
procedure TMainForm.SceneWin;
2332
procedure TMainForm.SceneWin;
2333
resourcestring
2333
resourcestring
2334
  SGewonnen = 'Gewonnen!';
2334
  SGewonnen = 'Gewonnen!';
2335
begin
2335
begin
2336
  DXDraw.Surface.Fill(0);
2336
  DXDraw.Surface.Fill(0);
2337
 
2337
 
2338
  FNotSave := true;
2338
  FNotSave := true;
2339
  Cheat.enabled := false;
2339
  Cheat.enabled := false;
2340
  GamePause.enabled := false;
2340
  GamePause.enabled := false;
2341
  Neustart.enabled := false;
2341
  Neustart.enabled := false;
2342
 
2342
 
2343
  DXDraw.Surface.Canvas.Brush.Style := bsClear;
2343
  DXDraw.Surface.Canvas.Brush.Style := bsClear;
2344
  DXDraw.Surface.Canvas.Font.Size := 35;
2344
  DXDraw.Surface.Canvas.Font.Size := 35;
2345
  DXDraw.Surface.Canvas.Font.Color := clMaroon;
2345
  DXDraw.Surface.Canvas.Font.Color := clMaroon;
2346
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-127, 98, SGewonnen);
2346
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-127, 98, SGewonnen);
2347
  DXDraw.Surface.Canvas.Font.Color := clRed;
2347
  DXDraw.Surface.Canvas.Font.Color := clRed;
2348
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-125, 100, SGewonnen);
2348
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-125, 100, SGewonnen);
2349
  if (FBlink div 300) mod 2=0 then
2349
  if (FBlink div 300) mod 2=0 then
2350
  begin
2350
  begin
2351
    DXDraw.Surface.Canvas.Font.Size := 30;
2351
    DXDraw.Surface.Canvas.Font.Size := 30;
2352
    DXDraw.Surface.Canvas.Font.Color := clOlive;
2352
    DXDraw.Surface.Canvas.Font.Color := clOlive;
2353
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, SWeiterMitLeertaste);
2353
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, SWeiterMitLeertaste);
2354
    DXDraw.Surface.Canvas.Font.Color := clYellow;
2354
    DXDraw.Surface.Canvas.Font.Color := clYellow;
2355
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, SWeiterMitLeertaste);
2355
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, SWeiterMitLeertaste);
2356
  end;
2356
  end;
2357
  BlinkUpdate;
2357
  BlinkUpdate;
2358
  DXDraw.Surface.Canvas.Release;
2358
  DXDraw.Surface.Canvas.Release;
2359
 
2359
 
2360
  // Weiter mit Leertaste oder Enter
2360
  // Weiter mit Leertaste oder Enter
2361
  if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
2361
  if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
2362
  begin
2362
  begin
2363
    PlaySound(smsSceneMov, False);
2363
    PlaySound(smsSceneMov, False);
2364
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2364
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2365
    Sleep(200);
2365
    Sleep(200);
2366
    StartScene(gsTitle);
2366
    StartScene(gsTitle);
2367
  end;
2367
  end;
2368
end;
2368
end;
2369
 
2369
 
2370
procedure TMainForm.StartSceneNewLevel;
2370
procedure TMainForm.StartSceneNewLevel;
2371
begin
2371
begin
2372
  sleep(500);
2372
  sleep(500);
2373
  FNotSave := true; // Wenn man speichert, würde man LevelAdventTable vom vorherigen Level machen, das wär müll!
2373
  FNotSave := true; // Wenn man speichert, würde man LevelAdventTable vom vorherigen Level machen, das wär müll!
2374
  Cheat.enabled := false;
2374
  Cheat.enabled := false;
2375
  Neustart.enabled := false;
2375
  Neustart.enabled := false;
2376
  GamePause.enabled := false;
2376
  GamePause.enabled := false;
2377
  GameStart.enabled := true;
2377
  GameStart.enabled := true;
2378
  Spielgeschwindigkeit.enabled := false;
2378
  Spielgeschwindigkeit.enabled := false;
2379
  Spielgeschwindigkeit.enabled := false;
2379
  Spielgeschwindigkeit.enabled := false;
2380
  if ((FGameMode=gmLevels) and not GetLevelFileName(FLevel,false).found)
2380
  if ((FGameMode=gmLevels) and not GetLevelFileName(FLevel,false).found)
2381
     // or ((FGameMode=gmRandom) and (FLevel > 25))
2381
     // or ((FGameMode=gmRandom) and (FLevel > 25))
2382
     or (FLevel > MaxPossibleLevels) then
2382
     or (FLevel > MaxPossibleLevels) then
2383
  begin
2383
  begin
2384
    //PlaySound('SceneMov', False);
2384
    //PlaySound('SceneMov', False);
2385
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2385
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2386
    Sleep(200);
2386
    Sleep(200);
2387
    StartScene(gsWin);
2387
    StartScene(gsWin);
2388
    exit;
2388
    exit;
2389
  end;
2389
  end;
2390
  MusicSwitchTrack(smmScene);
2390
  MusicSwitchTrack(smmScene);
2391
end;
2391
end;
2392
 
2392
 
2393
procedure TMainForm.EndSceneNewLevel;
2393
procedure TMainForm.EndSceneNewLevel;
2394
begin
2394
begin
2395
  {  Ende NewLevel  }
2395
  {  Ende NewLevel  }
2396
end;
2396
end;
2397
 
2397
 
2398
procedure TMainForm.SceneNewLevel;
2398
procedure TMainForm.SceneNewLevel;
2399
resourcestring
2399
resourcestring
2400
  SLevelScene = 'Level %d';
2400
  SLevelScene = 'Level %d';
2401
begin
2401
begin
2402
  DXDraw.Surface.Fill(0);
2402
  DXDraw.Surface.Fill(0);
2403
 
2403
 
2404
  DXDraw.Surface.Canvas.Brush.Style := bsClear;
2404
  DXDraw.Surface.Canvas.Brush.Style := bsClear;
2405
  DXDraw.Surface.Canvas.Font.Size := 40;
2405
  DXDraw.Surface.Canvas.Font.Size := 40;
2406
  DXDraw.Surface.Canvas.Font.Color := clMaroon;
2406
  DXDraw.Surface.Canvas.Font.Color := clMaroon;
2407
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-(83+(length(inttostr(flevel))*22)), 98, Format(SLevelScene, [flevel]));
2407
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-(83+(length(inttostr(flevel))*22)), 98, Format(SLevelScene, [flevel]));
2408
  DXDraw.Surface.Canvas.Font.Color := clRed;
2408
  DXDraw.Surface.Canvas.Font.Color := clRed;
2409
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-(81+(length(inttostr(flevel))*22)), 100, Format(SLevelScene, [flevel]));
2409
  DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-(81+(length(inttostr(flevel))*22)), 100, Format(SLevelScene, [flevel]));
2410
  if (FBlink div 300) mod 2=0 then
2410
  if (FBlink div 300) mod 2=0 then
2411
  begin
2411
  begin
2412
    DXDraw.Surface.Canvas.Font.Size := 30;
2412
    DXDraw.Surface.Canvas.Font.Size := 30;
2413
    DXDraw.Surface.Canvas.Font.Color := clOlive;
2413
    DXDraw.Surface.Canvas.Font.Color := clOlive;
2414
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, SWeiterMitLeertaste);
2414
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, SWeiterMitLeertaste);
2415
    DXDraw.Surface.Canvas.Font.Color := clYellow;
2415
    DXDraw.Surface.Canvas.Font.Color := clYellow;
2416
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, SWeiterMitLeertaste);
2416
    DXDraw.Surface.Canvas.Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, SWeiterMitLeertaste);
2417
  end;
2417
  end;
2418
  BlinkUpdate;
2418
  BlinkUpdate;
2419
  DXDraw.Surface.Canvas.Release;
2419
  DXDraw.Surface.Canvas.Release;
2420
 
2420
 
2421
  // Weiter mit Leertaste oder Enter
2421
  // Weiter mit Leertaste oder Enter
2422
  if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
2422
  if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
2423
  begin
2423
  begin
2424
    PlaySound(smsSceneMov, False);
2424
    PlaySound(smsSceneMov, False);
2425
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2425
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2426
    Sleep(200);
2426
    Sleep(200);
2427
    StartScene(gsMain);
2427
    StartScene(gsMain);
2428
  end;
2428
  end;
2429
end;
2429
end;
2430
 
2430
 
2431
procedure TMainForm.OptionMusicClick(Sender: TObject);
2431
procedure TMainForm.OptionMusicClick(Sender: TObject);
2432
begin
2432
begin
2433
  OptionMusic.Checked := not OptionMusic.Checked;
2433
  OptionMusic.Checked := not OptionMusic.Checked;
2434
  if OptionMusic.Checked then
2434
  if OptionMusic.Checked then
2435
  begin
2435
  begin
2436
    MusicSwitchTrack(FMusic)
2436
    MusicSwitchTrack(FMusic)
2437
  end
2437
  end
2438
  else
2438
  else
2439
  begin
2439
  begin
2440
    StopMusic(FMusic);
2440
    StopMusic(FMusic);
2441
  end;
2441
  end;
2442
  WriteOptions;
2442
  WriteOptions;
2443
end;
2443
end;
2444
 
2444
 
2445
procedure TMainForm.PlayMusic(Name: TSpaceMissionMusicTrack);
2445
procedure TMainForm.PlayMusic(Name: TSpaceMissionMusicTrack);
2446
begin
2446
begin
2447
  if not OptionMusic.checked then exit;
2447
  if not OptionMusic.checked then exit;
2448
  if Ord(Name) > dxmusic.Midis.Count then exit;
2448
  if Ord(Name) > dxmusic.Midis.Count then exit;
2449
  dxmusic.Midis.Items[Ord(Name)-1].Play;
2449
  dxmusic.Midis.Items[Ord(Name)-1].Play;
2450
end;
2450
end;
2451
 
2451
 
2452
procedure TMainForm.StopMusic(Name: TSpaceMissionMusicTrack);
2452
procedure TMainForm.StopMusic(Name: TSpaceMissionMusicTrack);
2453
begin
2453
begin
2454
  if Name = smmNone then exit;
2454
  if Name = smmNone then exit;
2455
  if Ord(Name) > dxmusic.Midis.Count then exit;
2455
  if Ord(Name) > dxmusic.Midis.Count then exit;
2456
  dxmusic.Midis.Items[Ord(Name)-1].Stop;
2456
  dxmusic.Midis.Items[Ord(Name)-1].Stop;
2457
end;
2457
end;
2458
 
2458
 
2459
procedure TMainForm.ResumeMusic(Name: TSpaceMissionMusicTrack);
2459
procedure TMainForm.ResumeMusic(Name: TSpaceMissionMusicTrack);
2460
begin
2460
begin
2461
  if not OptionMusic.checked then exit;
2461
  if not OptionMusic.checked then exit;
2462
  if Ord(Name) > dxmusic.Midis.Count then exit;
2462
  if Ord(Name) > dxmusic.Midis.Count then exit;
2463
  dxmusic.Midis.Items[Ord(Name)-1].Play; // TODO: how to pause/resume instead play/stop
2463
  dxmusic.Midis.Items[Ord(Name)-1].Play; // TODO: how to pause/resume instead play/stop
2464
end;
2464
end;
2465
 
2465
 
2466
procedure TMainForm.PauseMusic(Name: TSpaceMissionMusicTrack);
2466
procedure TMainForm.PauseMusic(Name: TSpaceMissionMusicTrack);
2467
begin
2467
begin
2468
  if Name = smmNone then exit;
2468
  if Name = smmNone then exit;
2469
  if Ord(Name) > dxmusic.Midis.Count then exit;
2469
  if Ord(Name) > dxmusic.Midis.Count then exit;
2470
  dxmusic.Midis.Items[Ord(Name)-1].Stop; // TODO: how to pause/resume instead play/stop
2470
  dxmusic.Midis.Items[Ord(Name)-1].Stop; // TODO: how to pause/resume instead play/stop
2471
end;
2471
end;
2472
 
2472
 
2473
procedure TMainForm.SpielstandClick(Sender: TObject);
2473
procedure TMainForm.SpielstandClick(Sender: TObject);
2474
begin
2474
begin
2475
  speicherungform.showmodal;
2475
  speicherungform.showmodal;
2476
end;
2476
end;
2477
 
2477
 
2478
procedure TMainForm.LevelNeuStarten;
2478
procedure TMainForm.LevelNeuStarten;
2479
begin
2479
begin
2480
  FNextScene := gsNewLevel;
2480
  FNextScene := gsNewLevel;
2481
  FLife := FLifeAtLevelStart;
2481
  FLife := FLifeAtLevelStart;
2482
  FScore := FScoreAtLevelStart;
2482
  FScore := FScoreAtLevelStart;
2483
end;
2483
end;
2484
 
2484
 
2485
procedure TMainForm.NeustartClick(Sender: TObject);
2485
procedure TMainForm.NeustartClick(Sender: TObject);
2486
begin
2486
begin
2487
  LevelNeuStarten;
2487
  LevelNeuStarten;
2488
end;
2488
end;
2489
 
2489
 
2490
procedure TMainForm.LeichtClick(Sender: TObject);
2490
procedure TMainForm.LeichtClick(Sender: TObject);
2491
begin
2491
begin
2492
  leicht.checked := true;
2492
  leicht.checked := true;
2493
  FSpeed := SpeedEasy;
2493
  FSpeed := SpeedEasy;
2494
  writeoptions;
2494
  writeoptions;
2495
end;
2495
end;
2496
 
2496
 
2497
procedure TMainForm.MittelClick(Sender: TObject);
2497
procedure TMainForm.MittelClick(Sender: TObject);
2498
begin
2498
begin
2499
  mittel.checked := true;
2499
  mittel.checked := true;
2500
  FSpeed := SpeedMedium;
2500
  FSpeed := SpeedMedium;
2501
  writeoptions;
2501
  writeoptions;
2502
end;
2502
end;
2503
 
2503
 
2504
procedure TMainForm.SchwerClick(Sender: TObject);
2504
procedure TMainForm.SchwerClick(Sender: TObject);
2505
begin
2505
begin
2506
  schwer.checked := true;
2506
  schwer.checked := true;
2507
  FSpeed := SpeedHard;
2507
  FSpeed := SpeedHard;
2508
  writeoptions;
2508
  writeoptions;
2509
end;
2509
end;
2510
 
2510
 
2511
procedure TMainForm.MasterClick(Sender: TObject);
2511
procedure TMainForm.MasterClick(Sender: TObject);
2512
begin
2512
begin
2513
  master.checked := true;
2513
  master.checked := true;
2514
  FSpeed := SpeedMaster;
2514
  FSpeed := SpeedMaster;
2515
  writeoptions;
2515
  writeoptions;
2516
end;
2516
end;
2517
 
2517
 
2518
procedure TMainForm.FormShow(Sender: TObject);
2518
procedure TMainForm.FormShow(Sender: TObject);
2519
resourcestring
2519
resourcestring
2520
  SFileError = 'Die Datei kann von SpaceMission nicht geöffnet werden!';
2520
  SFileError = 'Die Datei kann von SpaceMission nicht geöffnet werden!';
2521
var
2521
var
2522
  SavGame: TSaveData;
2522
  SavGame: TSaveData;
2523
begin
2523
begin
2524
  if Assigned(SplashForm) then
2524
  if Assigned(SplashForm) then
2525
  begin
2525
  begin
2526
    SplashForm.Hide;
2526
    SplashForm.Hide;
2527
    FreeAndNil(SplashForm);
2527
    FreeAndNil(SplashForm);
2528
  end;
2528
  end;
2529
 
2529
 
2530
  dxtimer.Enabled := true;
2530
  dxtimer.Enabled := true;
2531
  dxtimer.ActiveOnly := true;
2531
  dxtimer.ActiveOnly := true;
2532
 
2532
 
2533
  ResetLevelData;
2533
  ResetLevelData;
2534
  if (paramcount > 0) and (fileexists(paramstr(1))) and (ExtractFileExt(paramstr(1)).ToLower = '.sav') then
2534
  if (paramcount > 0) and (fileexists(paramstr(1))) and (ExtractFileExt(paramstr(1)).ToLower = '.sav') then
2535
  begin
2535
  begin
2536
    SavGame := TSaveData.Create;
2536
    SavGame := TSaveData.Create;
2537
    try
2537
    try
2538
      try
2538
      try
2539
        SavGame.LoadFromFile(paramstr(1));
2539
        SavGame.LoadFromFile(paramstr(1));
2540
        FScore := SavGame.Score;
2540
        FScore := SavGame.Score;
2541
        FLife := SavGame.Life;
2541
        FLife := SavGame.Life;
2542
        FLevel := SavGame.Level;
2542
        FLevel := SavGame.Level;
2543
        FGameMode := SavGame.GameMode;
2543
        FGameMode := SavGame.GameMode;
2544
        FLevelDataAlreadyLoaded := true; // do not call NewLevel() in StartSceneMain
2544
        FLevelDataAlreadyLoaded := true; // do not call NewLevel() in StartSceneMain
2545
        if Assigned(SavGame.LevelData) then
2545
        if Assigned(SavGame.LevelData) then
2546
        begin
2546
        begin
2547
          LevelData.Assign(SavGame.LevelData);
2547
          LevelData.Assign(SavGame.LevelData);
2548
        end;
2548
        end;
2549
      except
2549
      except
2550
        on E: Exception do
2550
        on E: Exception do
2551
        begin
2551
        begin
2552
          showmessage(SFileError + ' ' +E.Message);
2552
          showmessage(SFileError + ' ' +E.Message);
2553
          GameStartClick(GameStart);
2553
          GameStartClick(GameStart);
2554
          exit;
2554
          exit;
2555
        end;
2555
        end;
2556
      end;
2556
      end;
2557
    finally
2557
    finally
2558
      FreeAndNil(SavGame);
2558
      FreeAndNil(SavGame);
2559
    end;
2559
    end;
2560
    //FNextScene := gsNewLevel;
2560
    //FNextScene := gsNewLevel;
2561
    StartScene(gsNewLevel);
2561
    StartScene(gsNewLevel);
2562
    exit;
2562
    exit;
2563
  end;
2563
  end;
2564
end;
2564
end;
2565
 
2565
 
2566
procedure TMainForm.InformationenClick(Sender: TObject);
2566
procedure TMainForm.InformationenClick(Sender: TObject);
2567
begin
2567
begin
2568
  dxtimer.enabled := false;
2568
  dxtimer.enabled := false;
2569
  InfoForm.showmodal;
2569
  InfoForm.showmodal;
2570
  if not mainform.gamepause.checked then mainform.dxtimer.enabled := true;
2570
  if not mainform.gamepause.checked then mainform.dxtimer.enabled := true;
2571
end;
2571
end;
2572
 
2572
 
2573
procedure TMainForm.CheatClick(Sender: TObject);
2573
procedure TMainForm.CheatClick(Sender: TObject);
2574
begin
2574
begin
2575
  CheatForm.showmodal;
2575
  CheatForm.showmodal;
2576
end;
2576
end;
2577
 
2577
 
2578
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
2578
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
2579
begin
2579
begin
2580
  if optionMusic.checked then StopMusic(FMusic);
2580
  if optionMusic.checked then StopMusic(FMusic);
2581
  SpriteEngine.Engine.Clear;
2581
  SpriteEngine.Engine.Clear;
2582
  dxsound.Finalize;
2582
  dxsound.Finalize;
2583
  dxinput.Destroy;
2583
  dxinput.Destroy;
2584
  DXTimer.Enabled := False;
2584
  DXTimer.Enabled := False;
2585
end;
2585
end;
2586
 
2586
 
2587
procedure TMainForm.FormDestroy(Sender: TObject);
2587
procedure TMainForm.FormDestroy(Sender: TObject);
2588
begin
2588
begin
2589
  FreeAndNil(imagelist);
2589
  FreeAndNil(imagelist);
2590
  FreeAndNil(spriteengine);
2590
  FreeAndNil(spriteengine);
2591
  FreeAndNil(dxdraw);
2591
  FreeAndNil(dxdraw);
2592
  FreeAndNil(wavelist);
2592
  FreeAndNil(wavelist);
2593
  FreeAndNil(dxmusic);
2593
  FreeAndNil(dxmusic);
2594
  FreeAndNil(dxsound);
2594
  FreeAndNil(dxsound);
2595
  //FreeAndNil(dxinput);
2595
  //FreeAndNil(dxinput);
2596
  FreeAndNil(dxtimer);
2596
  FreeAndNil(dxtimer);
2597
  DeleteCriticalSection(TimerCS);
2597
  DeleteCriticalSection(TimerCS);
2598
  FreeAndNil(LevelData);
2598
  FreeAndNil(LevelData);
2599
end;
2599
end;
2600
 
2600
 
2601
procedure PostKeyEx32(key: Word; const shift: TShiftState; specialkey: Boolean);
2601
procedure PostKeyEx32(key: Word; const shift: TShiftState; specialkey: Boolean);
2602
{************************************************************
2602
{************************************************************
2603
* Procedure PostKeyEx32
2603
* Procedure PostKeyEx32
2604
*
2604
*
2605
* Parameters:
2605
* Parameters:
2606
*  key    : virtual keycode of the key to send. For printable
2606
*  key    : virtual keycode of the key to send. For printable
2607
*           keys this is simply the ANSI code (Ord(character)).
2607
*           keys this is simply the ANSI code (Ord(character)).
2608
*  shift  : state of the modifier keys. This is a set, so you
2608
*  shift  : state of the modifier keys. This is a set, so you
2609
*           can set several of these keys (shift, control, alt,
2609
*           can set several of these keys (shift, control, alt,
2610
*           mouse buttons) in tandem. The TShiftState type is
2610
*           mouse buttons) in tandem. The TShiftState type is
2611
*           declared in the Classes Unit.
2611
*           declared in the Classes Unit.
2612
*  specialkey: normally this should be False. Set it to True to
2612
*  specialkey: normally this should be False. Set it to True to
2613
*           specify a key on the numeric keypad, for example.
2613
*           specify a key on the numeric keypad, for example.
2614
* Description:
2614
* Description:
2615
*  Uses keybd_event to manufacture a series of key events matching
2615
*  Uses keybd_event to manufacture a series of key events matching
2616
*  the passed parameters. The events go to the control with focus.
2616
*  the passed parameters. The events go to the control with focus.
2617
*  Note that for characters key is always the upper-case version of
2617
*  Note that for characters key is always the upper-case version of
2618
*  the character. Sending without any modifier keys will result in
2618
*  the character. Sending without any modifier keys will result in
2619
*  a lower-case character, sending it with [ssShift] will result
2619
*  a lower-case character, sending it with [ssShift] will result
2620
*  in an upper-case character!
2620
*  in an upper-case character!
2621
// Code by P. Below
2621
// Code by P. Below
2622
************************************************************}
2622
************************************************************}
2623
type
2623
type
2624
  TShiftKeyInfo = record
2624
  TShiftKeyInfo = record
2625
    shift: Byte;
2625
    shift: Byte;
2626
    vkey: Byte;
2626
    vkey: Byte;
2627
  end;
2627
  end;
2628
  byteset = set of 0..7;
2628
  byteset = set of 0..7;
2629
const
2629
const
2630
  shiftkeys: array [1..3] of TShiftKeyInfo =
2630
  shiftkeys: array [1..3] of TShiftKeyInfo =
2631
    ((shift: Ord(ssCtrl); vkey: VK_CONTROL),
2631
    ((shift: Ord(ssCtrl); vkey: VK_CONTROL),
2632
    (shift: Ord(ssShift); vkey: VK_SHIFT),
2632
    (shift: Ord(ssShift); vkey: VK_SHIFT),
2633
    (shift: Ord(ssAlt); vkey: VK_MENU));
2633
    (shift: Ord(ssAlt); vkey: VK_MENU));
2634
var
2634
var
2635
  flag: DWORD;
2635
  flag: DWORD;
2636
  bShift: ByteSet absolute shift;
2636
  bShift: ByteSet absolute shift;
2637
  i: Integer;
2637
  i: Integer;
2638
begin
2638
begin
2639
  for i := 1 to 3 do
2639
  for i := 1 to 3 do
2640
  begin
2640
  begin
2641
    if shiftkeys[i].shift in bShift then
2641
    if shiftkeys[i].shift in bShift then
2642
      keybd_event(shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0), 0, 0);
2642
      keybd_event(shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0), 0, 0);
2643
  end; { For }
2643
  end; { For }
2644
  if specialkey then
2644
  if specialkey then
2645
    flag := KEYEVENTF_EXTENDEDKEY
2645
    flag := KEYEVENTF_EXTENDEDKEY
2646
  else
2646
  else
2647
    flag := 0;
2647
    flag := 0;
2648
 
2648
 
2649
  keybd_event(key, MapvirtualKey(key, 0), flag, 0);
2649
  keybd_event(key, MapvirtualKey(key, 0), flag, 0);
2650
  flag := flag or KEYEVENTF_KEYUP;
2650
  flag := flag or KEYEVENTF_KEYUP;
2651
  keybd_event(key, MapvirtualKey(key, 0), flag, 0);
2651
  keybd_event(key, MapvirtualKey(key, 0), flag, 0);
2652
 
2652
 
2653
  for i := 3 downto 1 do
2653
  for i := 3 downto 1 do
2654
  begin
2654
  begin
2655
    if shiftkeys[i].shift in bShift then
2655
    if shiftkeys[i].shift in bShift then
2656
      keybd_event(shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0),
2656
      keybd_event(shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0),
2657
        KEYEVENTF_KEYUP, 0);
2657
        KEYEVENTF_KEYUP, 0);
2658
  end; { For }
2658
  end; { For }
2659
end; { PostKeyEx32 }
2659
end; { PostKeyEx32 }
2660
 
2660
 
2661
procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
2661
procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
2662
  Shift: TShiftState);
2662
  Shift: TShiftState);
2663
begin
2663
begin
2664
  if Key = VK_ESCAPE then
2664
  if Key = VK_ESCAPE then
2665
  begin
2665
  begin
2666
    // TODO: Unfortunately, you cannot see if it is already popup. It would be great if ESC closes the main menu...
2666
    // TODO: Unfortunately, you cannot see if it is already popup. It would be great if ESC closes the main menu...
2667
    Key := 0;
2667
    Key := 0;
2668
    PostKeyEx32(Ord('S'), [ssAlt], False);
2668
    PostKeyEx32(Ord('S'), [ssAlt], False);
2669
  end;
2669
  end;
2670
end;
2670
end;
2671
 
2671
 
2672
end.
2672
end.
2673
 
2673
 
2674
 
2674