Subversion Repositories spacemission

Rev

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

Rev 90 Rev 94
1
unit LevMain;
1
unit LevMain;
2
 
2
 
3
interface
3
interface
4
 
4
 
5
uses
5
uses
6
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, MMSystem,
6
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, MMSystem,
7
  Dialogs, StdCtrls, ExtCtrls, Menus, DIB, DXClass, DXSprite, DXDraws,
7
  Dialogs, StdCtrls, ExtCtrls, Menus, DIB, DXClass, DXSprite, DXDraws,
8
  DXSounds, Spin, ComCtrls{$IF CompilerVersion >= 23.0}, System.UITypes,
8
  DXSounds, Spin, ComCtrls{$IF CompilerVersion >= 23.0}, System.UITypes,
9
  WinAPI.DirectDraw{$ENDIF}, DirectX, ComLevelReader, Global, IOUtils;
9
  WinAPI.DirectDraw{$ENDIF}, DirectX, ComLevelReader, Global, IOUtils;
10
 
10
 
11
type
11
type
12
  TMainForm = class(TDXForm)
12
  TMainForm = class(TDXForm)
13
    MainMenu: TMainMenu;
13
    MainMenu: TMainMenu;
14
    Spiel: TMenuItem;
14
    Spiel: TMenuItem;
15
    Beenden: TMenuItem;
15
    Beenden: TMenuItem;
16
    Hilfe: TMenuItem;
16
    Hilfe: TMenuItem;
17
    Leer1: TMenuItem;
17
    Leer1: TMenuItem;
18
    Level: TMenuItem;
18
    Level: TMenuItem;
19
    Informationen: TMenuItem;
19
    Informationen: TMenuItem;
20
    Enemy1: TRadioButton;
20
    Enemy1: TRadioButton;
21
    Enemy2: TRadioButton;
21
    Enemy2: TRadioButton;
22
    Enemy3: TRadioButton;
22
    Enemy3: TRadioButton;
23
    Enemy4: TRadioButton;
23
    Enemy4: TRadioButton;
24
    Enemy5: TRadioButton;
24
    Enemy5: TRadioButton;
25
    Enemy6: TRadioButton;
25
    Enemy6: TRadioButton;
26
    Enemy7: TRadioButton;
26
    Enemy7: TRadioButton;
27
    ScrollBar: TScrollBar;
27
    ScrollBar: TScrollBar;
28
    Bevel1: TBevel;
28
    Bevel1: TBevel;
29
    Bevel2: TBevel;
29
    Bevel2: TBevel;
30
    SelLabel: TLabel;
30
    SelLabel: TLabel;
31
    SelPanel: TPanel;
31
    SelPanel: TPanel;
32
    Bevel3: TBevel;
32
    Bevel3: TBevel;
33
    SLabel1a: TLabel;
33
    SLabel1a: TLabel;
34
    SLabel2a: TLabel;
34
    SLabel2a: TLabel;
35
    SLabel1b: TLabel;
35
    SLabel1b: TLabel;
36
    SLabel2b: TLabel;
36
    SLabel2b: TLabel;
37
    SLabel0: TLabel;
37
    SLabel0: TLabel;
38
    Neu: TMenuItem;
38
    Neu: TMenuItem;
39
    Image1: TImage;
39
    Image1: TImage;
40
    SLabel3a: TLabel;
40
    SLabel3a: TLabel;
41
    SLabel3b: TLabel;
41
    SLabel3b: TLabel;
42
    SLabel4a: TLabel;
42
    SLabel4a: TLabel;
43
    SLabel4b: TLabel;
43
    SLabel4b: TLabel;
44
    LivesLabel: TLabel;
44
    LivesLabel: TLabel;
45
    StatusBar: TStatusBar;
45
    StatusBar: TStatusBar;
46
    N1: TMenuItem;
46
    N1: TMenuItem;
47
    Spielfelderweitern1: TMenuItem;
47
    Spielfelderweitern1: TMenuItem;
48
    SidePanel: TPanel;
48
    SidePanel: TPanel;
49
    LivesEdit: TSpinEdit;
49
    LivesEdit: TSpinEdit;
50
    AlleLeveldateienaktualisieren1: TMenuItem;
50
    AlleLeveldateienaktualisieren1: TMenuItem;
51
    N2: TMenuItem;
51
    N2: TMenuItem;
52
    Leveltesten1: TMenuItem;
52
    Leveltesten1: TMenuItem;
53
    Hilfe1: TMenuItem;
53
    Hilfe1: TMenuItem;
54
    N3: TMenuItem;
54
    N3: TMenuItem;
55
    AufUpdatesprfen1: TMenuItem;
55
    AufUpdatesprfen1: TMenuItem;
56
    N4: TMenuItem;
56
    N4: TMenuItem;
57
    WasgibtesNeues1: TMenuItem;
57
    WasgibtesNeues1: TMenuItem;
58
    Enemy8: TRadioButton;
58
    Enemy8: TRadioButton;
59
    procedure DXDrawFinalize(Sender: TObject);
59
    procedure DXDrawFinalize(Sender: TObject);
60
    procedure DXDrawInitialize(Sender: TObject);
60
    procedure DXDrawInitialize(Sender: TObject);
61
    procedure FormCreate(Sender: TObject);
61
    procedure FormCreate(Sender: TObject);
62
    procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
62
    procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
63
    procedure BeendenClick(Sender: TObject);
63
    procedure BeendenClick(Sender: TObject);
64
    procedure FormDestroy(Sender: TObject);
64
    procedure FormDestroy(Sender: TObject);
65
    procedure LevelClick(Sender: TObject);
65
    procedure LevelClick(Sender: TObject);
66
    procedure FormShow(Sender: TObject);
66
    procedure FormShow(Sender: TObject);
67
    procedure InformationenClick(Sender: TObject);
67
    procedure InformationenClick(Sender: TObject);
68
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
68
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
69
    procedure DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
69
    procedure DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
70
      Shift: TShiftState; X, Y: Integer);
70
      Shift: TShiftState; X, Y: Integer);
71
    procedure EnemyClick(Sender: TObject);
71
    procedure EnemyClick(Sender: TObject);
72
    procedure NeuClick(Sender: TObject);
72
    procedure NeuClick(Sender: TObject);
73
    procedure DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
73
    procedure DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
74
      Y: Integer);
74
      Y: Integer);
75
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
75
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
76
    procedure Spielfelderweitern1Click(Sender: TObject);
76
    procedure Spielfelderweitern1Click(Sender: TObject);
77
    procedure ScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode;
77
    procedure ScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode;
78
      var ScrollPos: Integer);
78
      var ScrollPos: Integer);
79
    procedure AlleLeveldateienaktualisieren1Click(Sender: TObject);
79
    procedure AlleLeveldateienaktualisieren1Click(Sender: TObject);
80
    procedure Leveltesten1Click(Sender: TObject);
80
    procedure Leveltesten1Click(Sender: TObject);
81
    procedure HilfeTopicClick(Sender: TObject);
81
    procedure HilfeTopicClick(Sender: TObject);
82
    procedure AufUpdatesprfen1Click(Sender: TObject);
82
    procedure AufUpdatesprfen1Click(Sender: TObject);
83
  private
83
  private
84
    function GetTestlevelFilename: string;
84
    function GetTestlevelFilename: string;
85
  public
85
  public
86
    { VCL-Ersatz }
86
    { VCL-Ersatz }
87
    spriteengine: tdxspriteengine;
87
    spriteengine: tdxspriteengine;
88
    dxtimer: tdxtimer;
88
    dxtimer: tdxtimer;
89
    imagelist: tdximagelist;
89
    imagelist: tdximagelist;
90
    dxdraw: tdxdraw;
90
    dxdraw: tdxdraw;
91
    { Variablen }
91
    { Variablen }
92
    FMenuItem: integer;
92
    FMenuItem: integer;
93
    LevData: TLevelData;
93
    LevData: TLevelData;
94
    ScrollP: integer;
94
    ScrollP: integer;
95
    AltScrollPos: integer;
95
    AltScrollPos: integer;
96
    Boss: boolean;
96
    Boss: boolean;
97
    LevChanged: boolean;
97
    LevChanged: boolean;
98
    NumEnemys: integer;
98
    NumEnemys: integer;
99
    function SelectedEnemyType: TEnemyType;
99
    function SelectedEnemyType: TEnemyType;
100
    { Grafik-Routinen }
100
    { Grafik-Routinen }
101
    function GetSpriteGraphic(Sprite: TSpaceMissionGraphicSprite): TPictureCollectionItem;
101
    function GetSpriteGraphic(Sprite: TSpaceMissionGraphicSprite): TPictureCollectionItem;
102
    { Level-Routinen }
102
    { Level-Routinen }
103
    procedure EnemyCreateSprite(x, y: integer; AEnemyType: TEnemyType; ALives: integer);
103
    procedure EnemyCreateSprite(x, y: integer; AEnemyType: TEnemyType; ALives: integer);
104
    procedure DestroyLevel;
104
    procedure DestroyLevel;
105
    procedure RefreshFromLevData;
105
    procedure RefreshFromLevData;
106
    procedure AnzeigeAct;
106
    procedure AnzeigeAct;
107
    { Initialisiations-Routinen }
107
    { Initialisiations-Routinen }
108
    procedure DXInit;
108
    procedure DXInit;
109
    procedure ProgramInit;
109
    procedure ProgramInit;
110
    { Farb-Routinen }
110
    { Farb-Routinen }
111
    function ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
111
    function ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
112
    procedure PalleteAnim(Col: TRGBQuad; Time: Integer);
112
    procedure PalleteAnim(Col: TRGBQuad; Time: Integer);
113
  end;
113
  end;
114
 
114
 
115
var
115
var
116
  MainForm: TMainForm;
116
  MainForm: TMainForm;
117
 
117
 
118
implementation
118
implementation
119
 
119
 
120
uses
120
uses
121
  LevSplash, LevSpeicherung, ComInfo, LevOptions, ShellAPI, ComHilfe;
121
  LevSplash, LevSpeicherung, ComInfo, LevOptions, ShellAPI, ComHilfe;
122
 
122
 
123
{$R *.DFM}
123
{$R *.DFM}
124
 
124
 
125
resourcestring
125
resourcestring
126
  status_info = 'Zeigen Sie mit dem Mauszeiger auf eine Einheit, um deren Eigenschaften anzuzeigen...';
126
  status_info = 'Zeigen Sie mit dem Mauszeiger auf eine Einheit, um deren Eigenschaften anzuzeigen...';
127
 
127
 
128
type
128
type
129
  TBackground = class(TBackgroundSprite)
129
  TBackground = class(TBackgroundSprite)
130
  strict protected
130
  strict protected
131
    procedure DoMove(MoveCount: Integer); override;
131
    procedure DoMove(MoveCount: Integer); override;
132
  end;
132
  end;
133
 
133
 
134
  TEnemyOrItem = class(TImageSprite)
134
  TEnemyOrItem = class(TImageSprite)
135
  strict private
135
  strict private
136
    FLives: integer;
136
    FLives: integer;
137
    FEnemyType: TEnemyType;
137
    FEnemyType: TEnemyType;
138
    FXCor: integer;
138
    FXCor: integer;
139
    FCorInit: boolean;
139
    FCorInit: boolean;
140
  strict protected
140
  strict protected
141
    procedure DoMove(MoveCount: Integer); override;
141
    procedure DoMove(MoveCount: Integer); override;
142
  public
142
  public
143
    constructor Create(AParent: TSprite; AEnemyType: TEnemyType; ALives: Integer); reintroduce;
143
    constructor Create(AParent: TSprite; AEnemyType: TEnemyType; ALives: Integer); reintroduce;
144
  end;
144
  end;
145
 
145
 
146
{ TBackground }
146
{ TBackground }
147
 
147
 
148
procedure TBackground.DoMove(MoveCount: Integer);
148
procedure TBackground.DoMove(MoveCount: Integer);
149
begin
149
begin
150
  X := -(MainForm.ScrollP * LevEditRasterW);
150
  X := -(MainForm.ScrollP * LevEditRasterW);
151
end;
151
end;
152
 
152
 
153
{ TEnemy }
153
{ TEnemy }
154
 
154
 
155
procedure TEnemyOrItem.DoMove(MoveCount: Integer);
155
procedure TEnemyOrItem.DoMove(MoveCount: Integer);
156
begin
156
begin
157
  if not FCorInit then
157
  if not FCorInit then
158
  begin
158
  begin
159
    FXCor := trunc(x) + (MainForm.ScrollP * LevEditRasterW);
159
    FXCor := trunc(x) + (MainForm.ScrollP * LevEditRasterW);
160
    FCorInit := true;
160
    FCorInit := true;
161
  end;
161
  end;
162
  if MainForm.LevData.IndexOfEnemy(FXCor, integer(round(Y)), FEnemyType, FLives) = -1 then dead;
162
  if MainForm.LevData.IndexOfEnemy(FXCor, integer(round(Y)), FEnemyType, FLives) = -1 then dead;
163
  X := FXCor - (MainForm.ScrollP * LevEditRasterW);
163
  X := FXCor - (MainForm.ScrollP * LevEditRasterW);
164
end;
164
end;
165
 
165
 
166
constructor TEnemyOrItem.Create(AParent: TSprite; AEnemyType: TEnemyType; ALives: Integer);
166
constructor TEnemyOrItem.Create(AParent: TSprite; AEnemyType: TEnemyType; ALives: Integer);
167
begin
167
begin
168
  inherited Create(AParent);
168
  inherited Create(AParent);
169
  if AEnemyType = etEnemyAttacker  then Image := MainForm.GetSpriteGraphic(smgEnemyAttacker);
169
  if AEnemyType = etEnemyAttacker  then Image := MainForm.GetSpriteGraphic(smgEnemyAttacker);
170
  if AEnemyType = etEnemyAttacker2 then Image := MainForm.GetSpriteGraphic(smgEnemyAttacker2);
170
  if AEnemyType = etEnemyAttacker2 then Image := MainForm.GetSpriteGraphic(smgEnemyAttacker2);
171
  if AEnemyType = etEnemyAttacker3 then Image := MainForm.GetSpriteGraphic(smgEnemyAttacker3);
171
  if AEnemyType = etEnemyAttacker3 then Image := MainForm.GetSpriteGraphic(smgEnemyAttacker3);
172
  if AEnemyType = etEnemyMeteor    then Image := MainForm.GetSpriteGraphic(smgEnemyMeteor);
172
  if AEnemyType = etEnemyMeteor    then Image := MainForm.GetSpriteGraphic(smgEnemyMeteor);
173
  if AEnemyType = etEnemyUFO       then Image := MainForm.GetSpriteGraphic(smgEnemyDisk);
173
  if AEnemyType = etEnemyUFO       then Image := MainForm.GetSpriteGraphic(smgEnemyDisk);
174
  if AEnemyType = etEnemyUFO2      then Image := MainForm.GetSpriteGraphic(smgEnemyDisk2);
174
  if AEnemyType = etEnemyUFO2      then Image := MainForm.GetSpriteGraphic(smgEnemyDisk2);
175
  if AEnemyType = etEnemyBoss      then Image := MainForm.GetSpriteGraphic(smgEnemyBoss);
175
  if AEnemyType = etEnemyBoss      then Image := MainForm.GetSpriteGraphic(smgEnemyBoss);
176
  if AEnemyType = etItemMedikit    then Image := MainForm.GetSpriteGraphic(smgItemMedikit);
176
  if AEnemyType = etItemMedikit    then Image := MainForm.GetSpriteGraphic(smgItemMedikit);
177
 
177
 
178
  if not EnemyTypeHasLives(AEnemyType) then
178
  if not EnemyTypeHasLives(AEnemyType) then
179
    FLives := 0
179
    FLives := 0
180
  else
180
  else
181
    FLives := ALives;
181
    FLives := ALives;
182
  FEnemyType := AEnemyType;
182
  FEnemyType := AEnemyType;
183
  Width := Image.Width;
183
  Width := Image.Width;
184
  Height := Image.Height;
184
  Height := Image.Height;
185
  PixelCheck := True;
185
  PixelCheck := True;
186
end;
186
end;
187
 
187
 
188
{ TMainForm }
188
{ TMainForm }
189
 
189
 
190
procedure TMainForm.DXInit;
190
procedure TMainForm.DXInit;
191
begin
191
begin
192
  Imagelist.Items.LoadFromFile(OwnDirectory+DxgFile);
192
  Imagelist.Items.LoadFromFile(OwnDirectory+DxgFile);
193
  ImageList.Items.MakeColorTable;
193
  ImageList.Items.MakeColorTable;
194
  DXDraw.ColorTable := ImageList.Items.ColorTable;
194
  DXDraw.ColorTable := ImageList.Items.ColorTable;
195
  DXDraw.DefColorTable := ImageList.Items.ColorTable;
195
  DXDraw.DefColorTable := ImageList.Items.ColorTable;
196
  DXDraw.UpdatePalette;
196
  DXDraw.UpdatePalette;
197
  DXDraw.Initialize;
197
  DXDraw.Initialize;
198
end;
198
end;
199
 
199
 
200
procedure TMainForm.FormCreate(Sender: TObject);
200
procedure TMainForm.FormCreate(Sender: TObject);
201
resourcestring
201
resourcestring
202
  SFileError = 'Die Datei kann von SpaceMission nicht geöffnet werden!';
202
  SFileError = 'Die Datei kann von SpaceMission nicht geöffnet werden!';
203
  SCaption = 'SpaceMission %s - Leveleditor';
203
  SCaption = 'SpaceMission %s - Level-Editor';
204
begin
204
begin
205
  { VCL-Ersatz start }
205
  { VCL-Ersatz start }
206
  dxtimer := tdxtimer.create(self);
206
  dxtimer := tdxtimer.create(self);
207
  dxtimer.Interval := 100;
207
  dxtimer.Interval := 100;
208
  dxtimer.ActiveOnly := false;
208
  dxtimer.ActiveOnly := false;
209
  dxtimer.Enabled := false;
209
  dxtimer.Enabled := false;
210
  dxtimer.OnTimer := DxTimerTimer;
210
  dxtimer.OnTimer := DxTimerTimer;
211
 
211
 
212
  dxdraw := tdxdraw.Create(self);
212
  dxdraw := tdxdraw.Create(self);
213
  dxdraw.Parent := self;
213
  dxdraw.Parent := self;
214
  dxdraw.Left := 0;
214
  dxdraw.Left := 0;
215
  dxdraw.Top := 0;
215
  dxdraw.Top := 0;
216
  dxdraw.Width := SidePanel.Left;
216
  dxdraw.Width := SidePanel.Left;
217
  dxdraw.Height := ScrollBar.Top;
217
  dxdraw.Height := ScrollBar.Top;
218
  dxdraw.AutoInitialize := False;
218
  dxdraw.AutoInitialize := False;
219
  dxdraw.AutoSize := False;
219
  dxdraw.AutoSize := False;
220
  dxdraw.Color := clBlack;
220
  dxdraw.Color := clBlack;
221
  (*
221
  (*
222
  dxdraw.Display.BitCount := 24;
222
  dxdraw.Display.BitCount := 24;
223
  dxdraw.Display.FixedBitCount := False;
223
  dxdraw.Display.FixedBitCount := False;
224
  dxdraw.Display.FixedRatio := False;
224
  dxdraw.Display.FixedRatio := False;
225
  dxdraw.Display.FixedSize := False;
225
  dxdraw.Display.FixedSize := False;
226
  dxdraw.Display.Height := 600;
226
  dxdraw.Display.Height := 600;
227
  dxdraw.Display.Width := 800;
227
  dxdraw.Display.Width := 800;
228
  *)
228
  *)
229
  dxdraw.Options := [doAllowReboot, doWaitVBlank, doAllowPalette256, doCenter, {doRetainedMode,} doHardware, doSelectDriver];
229
  dxdraw.Options := [doAllowReboot, doWaitVBlank, doAllowPalette256, doCenter, {doRetainedMode,} doHardware, doSelectDriver];
230
  dxdraw.OnFinalize := DXDrawFinalize;
230
  dxdraw.OnFinalize := DXDrawFinalize;
231
  dxdraw.OnInitialize := DXDrawInitialize;
231
  dxdraw.OnInitialize := DXDrawInitialize;
232
  dxdraw.ParentShowHint := False;
232
  dxdraw.ParentShowHint := False;
233
  dxdraw.ShowHint := False;
233
  dxdraw.ShowHint := False;
234
  dxdraw.TabOrder := 0;
234
  dxdraw.TabOrder := 0;
235
  dxdraw.OnMouseDown := DXDrawMouseDown;
235
  dxdraw.OnMouseDown := DXDrawMouseDown;
236
  dxdraw.OnMouseMove := DXDrawMouseMove;
236
  dxdraw.OnMouseMove := DXDrawMouseMove;
237
 
237
 
238
  spriteengine := tdxspriteengine.create(self);
238
  spriteengine := tdxspriteengine.create(self);
239
  spriteengine.DXDraw := dxdraw;
239
  spriteengine.DXDraw := dxdraw;
240
 
240
 
241
  imagelist := tdximagelist.create(self);
241
  imagelist := tdximagelist.create(self);
242
  imagelist.DXDraw := dxdraw;
242
  imagelist.DXDraw := dxdraw;
243
 
243
 
244
  { VCL-Ersatz ende }
244
  { VCL-Ersatz ende }
245
 
245
 
246
  StatusBar.SimpleText := ' ' + status_info;
246
  StatusBar.SimpleText := ' ' + status_info;
247
 
247
 
248
  LivesEdit.MinValue := 1;
248
  LivesEdit.MinValue := 1;
249
  LivesEdit.MaxValue := MaxPossibleEnemyLives;
249
  LivesEdit.MaxValue := MaxPossibleEnemyLives;
250
  LivesEdit.Value := 1;
250
  LivesEdit.Value := 1;
251
 
251
 
252
  Enemy1.Checked := true;
252
  Enemy1.Checked := true;
253
  EnemyClick(Enemy1);
253
  EnemyClick(Enemy1);
254
  // Leeres Level am Anfang braucht keine Beenden-Bestätigung.
254
  // Leeres Level am Anfang braucht keine Beenden-Bestätigung.
255
  // LevChanged := true;
255
  // LevChanged := true;
256
 
256
 
257
  //Application.Title := Format(SCaption, [ProgramVersion]);
257
  //Application.Title := Format(SCaption, [ProgramVersion]);
258
  Caption := Format(SCaption, [ProgramVersion]);
258
  Caption := Format(SCaption, [ProgramVersion]);
259
  DXInit;
259
  DXInit;
260
  LevData := TLevelData.create;
260
  LevData := TLevelData.create;
261
  ProgramInit;
261
  ProgramInit;
262
  DestroyLevel;
262
  DestroyLevel;
263
  if (paramcount > 0) and (fileexists(paramstr(1))) and (ExtractFileExt(paramstr(1)).ToLower = '.lev') then
263
  if (paramcount > 0) and (fileexists(paramstr(1))) and (ExtractFileExt(paramstr(1)).ToLower = '.lev') then
264
  begin
264
  begin
265
    try
265
    try
266
      LevData.RasterErzwingen := true;
266
      LevData.RasterErzwingen := true;
267
      LevData.LoadFromFile(paramstr(1));
267
      LevData.LoadFromFile(paramstr(1));
268
    except
268
    except
269
      on E: Exception do
269
      on E: Exception do
270
      begin
270
      begin
271
        showmessage(SFileError + ' ' +E.Message);
271
        showmessage(SFileError + ' ' +E.Message);
272
        DestroyLevel;
272
        DestroyLevel;
273
      end;
273
      end;
274
    end;
274
    end;
275
    RefreshFromLevData;
275
    RefreshFromLevData;
276
    LevChanged := false;
276
    LevChanged := false;
277
    AnzeigeAct;
277
    AnzeigeAct;
278
  end;
278
  end;
279
end;
279
end;
280
 
280
 
281
procedure TMainForm.FormDestroy(Sender: TObject);
281
procedure TMainForm.FormDestroy(Sender: TObject);
282
var
282
var
283
  tmp: string;
283
  tmp: string;
284
begin
284
begin
285
  FreeAndNil(dxdraw);
285
  FreeAndNil(dxdraw);
286
  FreeAndNil(LevData);
286
  FreeAndNil(LevData);
287
  //FreeAndNil(spriteengine);
287
  //FreeAndNil(spriteengine);
288
  FreeAndNil(dxtimer);
288
  FreeAndNil(dxtimer);
289
  FreeAndNil(imagelist);
289
  FreeAndNil(imagelist);
290
  tmp := GetTestlevelFilename;
290
  tmp := GetTestlevelFilename;
291
 
291
 
292
  // SpaceMission.exe only loads a file once, so we can delete any test level
292
  // SpaceMission.exe only loads a file once, so we can delete any test level
293
  if FileExists(tmp) then DeleteFile(GetTestlevelFilename);
293
  if FileExists(tmp) then DeleteFile(GetTestlevelFilename);
294
end;
294
end;
295
 
295
 
296
procedure TMainForm.BeendenClick(Sender: TObject);
296
procedure TMainForm.BeendenClick(Sender: TObject);
297
begin
297
begin
298
  close;
298
  close;
299
end;
299
end;
300
 
300
 
301
procedure TMainForm.DXDrawInitialize(Sender: TObject);
301
procedure TMainForm.DXDrawInitialize(Sender: TObject);
302
begin
302
begin
303
  if Assigned(DXTimer) then DXTimer.Enabled := True;
303
  if Assigned(DXTimer) then DXTimer.Enabled := True;
304
end;
304
end;
305
 
305
 
306
procedure TMainForm.DXDrawFinalize(Sender: TObject);
306
procedure TMainForm.DXDrawFinalize(Sender: TObject);
307
begin
307
begin
308
  if Assigned(DXTimer) then DXTimer.Enabled := False;
308
  if Assigned(DXTimer) then DXTimer.Enabled := False;
309
end;
309
end;
310
 
310
 
311
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
311
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
312
begin
312
begin
313
  if not DXDraw.CanDraw then exit;
313
  if not DXDraw.CanDraw then exit;
314
  LagCount := 1000 div 60;
314
  LagCount := 1000 div 60;
315
  SpriteEngine.Move(LagCount);
315
  SpriteEngine.Move(LagCount);
316
  SpriteEngine.Dead;
316
  SpriteEngine.Dead;
317
  DxDraw.Surface.Fill(0);
317
  DxDraw.Surface.Fill(0);
318
  SpriteEngine.Draw;
318
  SpriteEngine.Draw;
319
  DXDraw.Flip;
319
  DXDraw.Flip;
320
end;
320
end;
321
 
321
 
322
function TMainForm.ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
322
function TMainForm.ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
323
begin
323
begin
324
  with Result do
324
  with Result do
325
  begin
325
  begin
326
    rgbRed := Src.rgbRed+((Dest.rgbRed-Src.rgbRed)*Percent div 256);
326
    rgbRed := Src.rgbRed+((Dest.rgbRed-Src.rgbRed)*Percent div 256);
327
    rgbGreen := Src.rgbGreen+((Dest.rgbGreen-Src.rgbGreen)*Percent div 256);
327
    rgbGreen := Src.rgbGreen+((Dest.rgbGreen-Src.rgbGreen)*Percent div 256);
328
    rgbBlue := Src.rgbBlue+((Dest.rgbBlue-Src.rgbBlue)*Percent div 256);
328
    rgbBlue := Src.rgbBlue+((Dest.rgbBlue-Src.rgbBlue)*Percent div 256);
329
    rgbReserved := 0;
329
    rgbReserved := 0;
330
  end;
330
  end;
331
end;
331
end;
332
 
332
 
333
procedure TMainForm.PalleteAnim(Col: TRGBQuad; Time: Integer);
333
procedure TMainForm.PalleteAnim(Col: TRGBQuad; Time: Integer);
334
var
334
var
335
  i: Integer;
335
  i: Integer;
336
  t, t2: DWORD;
336
  t, t2: DWORD;
337
  ChangePalette: Boolean;
337
  ChangePalette: Boolean;
338
  c: Integer;
338
  c: Integer;
339
begin
339
begin
340
  if DXDraw.Initialized then
340
  if DXDraw.Initialized then
341
  begin
341
  begin
342
    c := DXDraw.Surface.ColorMatch(RGB(Col.rgbRed, Col.rgbGreen, Col.rgbBlue));
342
    c := DXDraw.Surface.ColorMatch(RGB(Col.rgbRed, Col.rgbGreen, Col.rgbBlue));
343
    ChangePalette := False;
343
    ChangePalette := False;
344
    if DXDraw.CanPaletteAnimation then
344
    if DXDraw.CanPaletteAnimation then
345
    begin
345
    begin
346
      t := GetTickCount;
346
      t := GetTickCount;
347
      while Abs(GetTickCount-t)<Time do
347
      while Abs(GetTickCount-t)<Time do
348
      begin
348
      begin
349
        t2 := Trunc(Abs(GetTickCount-t)/Time*255);
349
        t2 := Trunc(Abs(GetTickCount-t)/Time*255);
350
        for i := 0 to 255 do
350
        for i := 0 to 255 do
351
          DXDraw.ColorTable[i] := ComposeColor(Col, DXDraw.DefColorTable[i], t2);
351
          DXDraw.ColorTable[i] := ComposeColor(Col, DXDraw.DefColorTable[i], t2);
352
        DXDraw.UpdatePalette;
352
        DXDraw.UpdatePalette;
353
        ChangePalette := True;
353
        ChangePalette := True;
354
      end;
354
      end;
355
    end else
355
    end else
356
      Sleep(Time);
356
      Sleep(Time);
357
    for i := 0 to 4 do
357
    for i := 0 to 4 do
358
    begin
358
    begin
359
      DXDraw.Surface.Fill(c);
359
      DXDraw.Surface.Fill(c);
360
      DXDraw.Flip;
360
      DXDraw.Flip;
361
    end;
361
    end;
362
    if ChangePalette then
362
    if ChangePalette then
363
    begin
363
    begin
364
      DXDraw.ColorTable := DXDraw.DefColorTable;
364
      DXDraw.ColorTable := DXDraw.DefColorTable;
365
      DXDraw.UpdatePalette;
365
      DXDraw.UpdatePalette;
366
    end;
366
    end;
367
    DXDraw.Surface.Fill(c);
367
    DXDraw.Surface.Fill(c);
368
    DXDraw.Flip;
368
    DXDraw.Flip;
369
  end;
369
  end;
370
end;
370
end;
371
 
371
 
372
procedure TMainForm.ProgramInit;
372
procedure TMainForm.ProgramInit;
373
{var
373
{var
374
  i, j: Integer;}
374
  i, j: Integer;}
375
begin
375
begin
376
  sleep(500);
376
  sleep(500);
377
  //PlayerSprite
377
  //PlayerSprite
378
  with TBackground.Create(SpriteEngine.Engine) do
378
  with TBackground.Create(SpriteEngine.Engine) do
379
  begin
379
  begin
380
    SetMapSize(1, 1);
380
    SetMapSize(1, 1);
381
    Image := MainForm.GetSpriteGraphic(smgStar3);
381
    Image := MainForm.GetSpriteGraphic(smgStar3);
382
    Z := -13;
382
    Z := -13;
383
    Y := 40;
383
    Y := 40;
384
    Tile := True;
384
    Tile := True;
385
  end;
385
  end;
386
  with TBackground.Create(SpriteEngine.Engine) do
386
  with TBackground.Create(SpriteEngine.Engine) do
387
  begin
387
  begin
388
    SetMapSize(1, 1);
388
    SetMapSize(1, 1);
389
    Image := MainForm.GetSpriteGraphic(smgStar2);
389
    Image := MainForm.GetSpriteGraphic(smgStar2);
390
    Z := -12;
390
    Z := -12;
391
    Y := 30;
391
    Y := 30;
392
    Tile := True;
392
    Tile := True;
393
  end;
393
  end;
394
  with TBackground.Create(SpriteEngine.Engine) do
394
  with TBackground.Create(SpriteEngine.Engine) do
395
  begin
395
  begin
396
    SetMapSize(1, 1);
396
    SetMapSize(1, 1);
397
    Image := MainForm.GetSpriteGraphic(smgStar1);
397
    Image := MainForm.GetSpriteGraphic(smgStar1);
398
    Z := -11;
398
    Z := -11;
399
    Y := 10;
399
    Y := 10;
400
    Tile := True;
400
    Tile := True;
401
  end;
401
  end;
402
  with TBackground.Create(SpriteEngine.Engine) do
402
  with TBackground.Create(SpriteEngine.Engine) do
403
  begin
403
  begin
404
    SetMapSize(1, 1);
404
    SetMapSize(1, 1);
405
    Image := MainForm.GetSpriteGraphic(smgMatrix);
405
    Image := MainForm.GetSpriteGraphic(smgMatrix);
406
    Z := -10;
406
    Z := -10;
407
    Tile := True;
407
    Tile := True;
408
  end;
408
  end;
409
  {with TBackground.Create(SpriteEngine.Engine) do
409
  {with TBackground.Create(SpriteEngine.Engine) do
410
  begin
410
  begin
411
    SetMapSize(200, 10);
411
    SetMapSize(200, 10);
412
    Y := 10;
412
    Y := 10;
413
    Z := -13;
413
    Z := -13;
414
    FSpeed := 1 / 2;
414
    FSpeed := 1 / 2;
415
    Tile := True;
415
    Tile := True;
416
    for i := 0 to MapHeight-1 do
416
    for i := 0 to MapHeight-1 do
417
    begin
417
    begin
418
      for j := 0 to MapWidth-1 do
418
      for j := 0 to MapWidth-1 do
419
      begin
419
      begin
420
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 8);
420
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 8);
421
        if Random(100)<95 then Chips[j, i] := -1;
421
        if Random(100)<95 then Chips[j, i] := -1;
422
      end;
422
      end;
423
    end;
423
    end;
424
  end;
424
  end;
425
  with TBackground.Create(SpriteEngine.Engine) do
425
  with TBackground.Create(SpriteEngine.Engine) do
426
  begin
426
  begin
427
    SetMapSize(200, 10);
427
    SetMapSize(200, 10);
428
    Y := 30;
428
    Y := 30;
429
    Z := -12;
429
    Z := -12;
430
    FSpeed := 1;
430
    FSpeed := 1;
431
    Tile := True;
431
    Tile := True;
432
    for i := 0 to MapHeight-1 do
432
    for i := 0 to MapHeight-1 do
433
    begin
433
    begin
434
      for j := 0 to MapWidth-1 do
434
      for j := 0 to MapWidth-1 do
435
      begin
435
      begin
436
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 4);
436
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 4);
437
        if Random(100)<95 then Chips[j, i] := -1;
437
        if Random(100)<95 then Chips[j, i] := -1;
438
      end;
438
      end;
439
    end;
439
    end;
440
  end;
440
  end;
441
  with TBackground.Create(SpriteEngine.Engine) do
441
  with TBackground.Create(SpriteEngine.Engine) do
442
  begin
442
  begin
443
    SetMapSize(200, 10);
443
    SetMapSize(200, 10);
444
    Y := 40;
444
    Y := 40;
445
    Z := -11;
445
    Z := -11;
446
    FSpeed := 2;
446
    FSpeed := 2;
447
    Tile := True;
447
    Tile := True;
448
    for i := 0 to MapHeight-1 do
448
    for i := 0 to MapHeight-1 do
449
    begin
449
    begin
450
      for j := 0 to MapWidth-1 do
450
      for j := 0 to MapWidth-1 do
451
      begin
451
      begin
452
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 2);
452
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 2);
453
        if Random(100)<95 then Chips[j, i] := -1;
453
        if Random(100)<95 then Chips[j, i] := -1;
454
      end;
454
      end;
455
    end;
455
    end;
456
  end;}
456
  end;}
457
  PalleteAnim(RGBQuad(0, 0, 0), 300);
457
  PalleteAnim(RGBQuad(0, 0, 0), 300);
458
  mainform.Visible := true;
458
  mainform.Visible := true;
459
end;
459
end;
460
 
460
 
461
procedure TMainForm.RefreshFromLevData;
461
procedure TMainForm.RefreshFromLevData;
462
var
462
var
463
  i: integer;
463
  i: integer;
464
begin
464
begin
465
  MainForm.ScrollBar.Max := MainForm.LevData.LevelEditorLength;
465
  MainForm.ScrollBar.Max := MainForm.LevData.LevelEditorLength;
466
  for i := 0 to MainForm.LevData.CountEnemies - 1 do
466
  for i := 0 to MainForm.LevData.CountEnemies - 1 do
467
  begin
467
  begin
468
    MainForm.EnemyCreateSprite(
468
    MainForm.EnemyCreateSprite(
469
      MainForm.LevData.EnemyAdventTable[i].x,
469
      MainForm.LevData.EnemyAdventTable[i].x,
470
      MainForm.LevData.EnemyAdventTable[i].y,
470
      MainForm.LevData.EnemyAdventTable[i].y,
471
      MainForm.LevData.EnemyAdventTable[i].enemyType,
471
      MainForm.LevData.EnemyAdventTable[i].enemyType,
472
      MainForm.LevData.EnemyAdventTable[i].lifes
472
      MainForm.LevData.EnemyAdventTable[i].lifes
473
    );
473
    );
474
  end;
474
  end;
475
  MainForm.NumEnemys := MainForm.LevData.CountEnemies;
475
  MainForm.NumEnemys := MainForm.LevData.CountEnemies;
476
  MainForm.Boss := MainForm.LevData.HasBoss;
476
  MainForm.Boss := MainForm.LevData.HasBoss;
477
  AnzeigeAct;
477
  AnzeigeAct;
478
end;
478
end;
479
 
479
 
480
procedure TMainForm.LevelClick(Sender: TObject);
480
procedure TMainForm.LevelClick(Sender: TObject);
481
begin
481
begin
482
  speicherungform.showmodal;
482
  speicherungform.showmodal;
483
end;
483
end;
484
 
484
 
485
procedure TMainForm.Leveltesten1Click(Sender: TObject);
485
procedure TMainForm.Leveltesten1Click(Sender: TObject);
486
var
486
var
487
  sav: TSaveData;
487
  sav: TSaveData;
488
  tmp: string;
488
  tmp: string;
489
begin
489
begin
490
  KillTask(SpaceMissionExe);
490
  KillTask(SpaceMissionExe);
491
 
491
 
492
  sav := TSaveData.Create;
492
  sav := TSaveData.Create;
493
  try
493
  try
494
    sav.Score := 0;
494
    sav.Score := 0;
495
    sav.Life := 6;
495
    sav.Life := 6;
496
    if Assigned(SpeicherungForm) then
496
    if Assigned(SpeicherungForm) then
497
      sav.Level := SpeicherungForm.LevelNumber.Value
497
      sav.Level := SpeicherungForm.LevelNumber.Value
498
    else
498
    else
499
      sav.Level := 1;
499
      sav.Level := 1;
500
    sav.GameMode := gmLevels;
500
    sav.GameMode := gmLevels;
501
    sav.LevelData := TlevelData.Create;
501
    sav.LevelData := TlevelData.Create;
502
    sav.LevelData.Assign(LevData);
502
    sav.LevelData.Assign(LevData);
503
    tmp := GetTestlevelFilename;
503
    tmp := GetTestlevelFilename;
504
    sav.SaveToFile(tmp);
504
    sav.SaveToFile(tmp);
505
    ShellExecute(Handle, 'open', PChar(OwnDirectory+SpaceMissionExe), PChar('"'+tmp+'"'), PChar(OwnDirectory), SW_NORMAL); // do not localize
505
    ShellExecute(Handle, 'open', PChar(OwnDirectory+SpaceMissionExe), PChar('"'+tmp+'"'), PChar(OwnDirectory), SW_NORMAL); // do not localize
506
  finally
506
  finally
507
    FreeAndNil(sav);
507
    FreeAndNil(sav);
508
  end;
508
  end;
509
end;
509
end;
510
 
510
 
511
procedure TMainForm.FormShow(Sender: TObject);
511
procedure TMainForm.FormShow(Sender: TObject);
512
begin
512
begin
513
  if Assigned(SplashForm) then
513
  if Assigned(SplashForm) then
514
  begin
514
  begin
515
    SplashForm.Hide;
515
    SplashForm.Hide;
516
    FreeAndNil(SplashForm);
516
    FreeAndNil(SplashForm);
517
  end;
517
  end;
518
 
518
 
519
  dxtimer.Enabled := true;
519
  dxtimer.Enabled := true;
520
  dxtimer.ActiveOnly := true;
520
  dxtimer.ActiveOnly := true;
521
end;
521
end;
522
 
522
 
523
function TMainForm.GetSpriteGraphic(
523
function TMainForm.GetSpriteGraphic(
524
  Sprite: TSpaceMissionGraphicSprite): TPictureCollectionItem;
524
  Sprite: TSpaceMissionGraphicSprite): TPictureCollectionItem;
525
begin
525
begin
526
  if (Sprite<>smgNone) and (imagelist.Items.Count >= Ord(Sprite)) then
526
  if (Sprite<>smgNone) and (imagelist.Items.Count >= Ord(Sprite)) then
527
    result := imagelist.Items.Items[Ord(Sprite)-1]
527
    result := imagelist.Items.Items[Ord(Sprite)-1]
528
  else
528
  else
529
    result := nil;
529
    result := nil;
530
end;
530
end;
531
 
531
 
532
function TMainForm.GetTestlevelFilename: string;
532
function TMainForm.GetTestlevelFilename: string;
533
begin
533
begin
534
  result := IncludeTrailingPathDelimiter(TPath.GetTempPath) + 'SpaceMissionTest.sav'; // do not localize
534
  result := IncludeTrailingPathDelimiter(TPath.GetTempPath) + 'SpaceMissionTest.sav'; // do not localize
535
end;
535
end;
536
 
536
 
537
procedure TMainForm.HilfeTopicClick(Sender: TObject);
537
procedure TMainForm.HilfeTopicClick(Sender: TObject);
538
// Please keep this code in-sync with GamMain.pas
538
// Please keep this code in-sync with GamMain.pas
539
var
539
var
540
  bakTimerEnabled: boolean;
540
  bakTimerEnabled: boolean;
541
begin
541
begin
542
  bakTimerEnabled := dxtimer.Enabled;
542
  bakTimerEnabled := dxtimer.Enabled;
543
  try
543
  try
544
    dxtimer.Enabled := false;
544
    dxtimer.Enabled := false;
545
    HilfeForm.Caption := TMenuItem(Sender).Caption;
545
    HilfeForm.Caption := TMenuItem(Sender).Caption;
546
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, '&&', #1, [rfReplaceAll]);
546
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, '&&', #1, [rfReplaceAll]);
547
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, '&', '', [rfReplaceAll]);
547
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, '&', '', [rfReplaceAll]);
548
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, #1, '&', [rfReplaceAll]);
548
    HilfeForm.Caption := StringReplace(HilfeForm.Caption, #1, '&', [rfReplaceAll]);
549
    HilfeForm.ShowMarkDownHelp(OwnDirectory+TMenuItem(Sender).Hint);
549
    HilfeForm.ShowMarkDownHelp(OwnDirectory+TMenuItem(Sender).Hint);
550
    HilfeForm.ShowModal;
550
    HilfeForm.ShowModal;
551
  finally
551
  finally
552
    dxtimer.Enabled := bakTimerEnabled;
552
    dxtimer.Enabled := bakTimerEnabled;
553
  end;
553
  end;
554
end;
554
end;
555
 
555
 
556
procedure TMainForm.InformationenClick(Sender: TObject);
556
procedure TMainForm.InformationenClick(Sender: TObject);
557
begin
557
begin
558
  mainform.dxtimer.enabled := false;
558
  mainform.dxtimer.enabled := false;
559
  InfoForm.showmodal;
559
  InfoForm.showmodal;
560
  mainform.dxtimer.enabled := true;
560
  mainform.dxtimer.enabled := true;
561
end;
561
end;
562
 
562
 
563
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
563
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
564
begin
564
begin
565
  SpriteEngine.Engine.Clear;
565
  SpriteEngine.Engine.Clear;
566
  DXTimer.Enabled := False;
566
  DXTimer.Enabled := False;
567
end;
567
end;
568
 
568
 
569
procedure TMainForm.DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
569
procedure TMainForm.DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
570
  Shift: TShiftState; X, Y: Integer);
570
  Shift: TShiftState; X, Y: Integer);
571
var
571
var
572
  i: TEnemyType;
572
  i: TEnemyType;
573
  j, k, l, ex, ey: integer;
573
  j, k, l, ex, ey: integer;
574
  ok, breaked: boolean;
574
  ok, breaked: boolean;
575
begin
575
begin
576
  ex := trunc(x/LevEditRasterW) * LevEditRasterW;
576
  ex := trunc(x/LevEditRasterW) * LevEditRasterW;
577
  ey := trunc(y/LevEditRasterH) * LevEditRasterH;
577
  ey := trunc(y/LevEditRasterH) * LevEditRasterH;
578
  EnemyCreateSprite(ex, ey, SelectedEnemyType, LivesEdit.Value);
578
  EnemyCreateSprite(ex, ey, SelectedEnemyType, LivesEdit.Value);
579
  breaked := false;
579
  breaked := false;
580
  { Setzen }
580
  { Setzen }
581
  if Button = mbLeft then
581
  if Button = mbLeft then
582
  begin
582
  begin
583
    ok := true;
583
    ok := true;
584
    if (SelectedEnemyType = etEnemyBoss) and boss then
584
    if (SelectedEnemyType = etEnemyBoss) and boss then
585
      ok := false // boss already exists
585
      ok := false // boss already exists
586
    else
586
    else
587
    begin
587
    begin
588
      for i := Low(TEnemyType) to High(TEnemyType) do
588
      for i := Low(TEnemyType) to High(TEnemyType) do
589
      begin
589
      begin
590
        for j := 0 to MaxPossibleEnemyLives do
590
        for j := 0 to MaxPossibleEnemyLives do
591
        begin
591
        begin
592
          if boss then
592
          if boss then
593
          begin
593
          begin
594
            for k := 0 to BossWidth-1 do
594
            for k := 0 to BossWidth-1 do
595
            begin
595
            begin
596
              for l := 0 to BossHeight-2 do
596
              for l := 0 to BossHeight-2 do
597
              begin
597
              begin
598
                if LevData.IndexOfEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), etEnemyBoss, j) <> -1 then
598
                if LevData.IndexOfEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), etEnemyBoss, j) <> -1 then
599
                begin
599
                begin
600
                  ok := false;
600
                  ok := false;
601
                  break;
601
                  break;
602
                end;
602
                end;
603
              end;
603
              end;
604
              if not ok then break;
604
              if not ok then break;
605
            end;
605
            end;
606
            if not ok then break;
606
            if not ok then break;
607
          end;
607
          end;
608
          if LevData.IndexOfEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j) <> -1 then
608
          if LevData.IndexOfEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j) <> -1 then
609
          begin
609
          begin
610
            ok := false;
610
            ok := false;
611
            break;
611
            break;
612
          end;
612
          end;
613
        end;
613
        end;
614
        if not ok then break;
614
        if not ok then break;
615
      end;
615
      end;
616
    end;
616
    end;
617
    if ok then
617
    if ok then
618
    begin
618
    begin
619
      if EnemyTypeHasLives(SelectedEnemyType) then
619
      if EnemyTypeHasLives(SelectedEnemyType) then
620
        LevData.AddEnemy(ex + (ScrollP * LevEditRasterW), ey, SelectedEnemyType, LivesEdit.Value)
620
        LevData.AddEnemy(ex + (ScrollP * LevEditRasterW), ey, SelectedEnemyType, LivesEdit.Value)
621
      else
621
      else
622
        LevData.AddEnemy(ex + (ScrollP * LevEditRasterW), ey, SelectedEnemyType, 0);
622
        LevData.AddEnemy(ex + (ScrollP * LevEditRasterW), ey, SelectedEnemyType, 0);
623
      inc(NumEnemys);
623
      inc(NumEnemys);
624
      if SelectedEnemyType = etEnemyBoss then boss := true;
624
      if SelectedEnemyType = etEnemyBoss then boss := true;
625
    end
625
    end
626
    else beep;
626
    else beep;
627
  end
627
  end
628
  { Löschen }
628
  { Löschen }
629
  else if Button = mbRight then
629
  else if Button = mbRight then
630
  begin
630
  begin
631
    for i := Low(TEnemyType) to High(TEnemyType) do
631
    for i := Low(TEnemyType) to High(TEnemyType) do
632
    begin
632
    begin
633
      for j := 0 to MaxPossibleEnemyLives do
633
      for j := 0 to MaxPossibleEnemyLives do
634
      begin
634
      begin
635
        if boss and (i = etEnemyBoss) then
635
        if boss and (i = etEnemyBoss) then
636
        begin
636
        begin
637
          for k := 0 to BossWidth - 1 do
637
          for k := 0 to BossWidth - 1 do
638
          begin
638
          begin
639
            for l := 0 to BossHeight - 1 do
639
            for l := 0 to BossHeight - 1 do
640
            begin
640
            begin
641
              if LevData.IndexOfEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), i, j) <> -1 then
641
              if LevData.IndexOfEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), i, j) <> -1 then
642
              begin
642
              begin
643
                LevData.DeleteEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), i, j);
643
                LevData.DeleteEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), i, j);
644
                Boss := false;
644
                Boss := false;
645
                dec(NumEnemys);
645
                dec(NumEnemys);
646
                breaked := true;
646
                breaked := true;
647
                break;
647
                break;
648
              end;
648
              end;
649
            end;
649
            end;
650
            if breaked then break;
650
            if breaked then break;
651
          end;
651
          end;
652
        end;
652
        end;
653
        if LevData.IndexOfEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j) <> -1 then
653
        if LevData.IndexOfEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j) <> -1 then
654
        begin
654
        begin
655
          LevData.DeleteEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j);
655
          LevData.DeleteEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j);
656
          if i = etEnemyBoss then Boss := false;
656
          if i = etEnemyBoss then Boss := false;
657
          dec(NumEnemys);
657
          dec(NumEnemys);
658
          breaked := true;
658
          breaked := true;
659
          break;
659
          break;
660
        end;
660
        end;
661
      end;
661
      end;
662
      if breaked then break;
662
      if breaked then break;
663
    end;
663
    end;
664
  end;
664
  end;
665
  LevChanged := true;
665
  LevChanged := true;
666
  AnzeigeAct;
666
  AnzeigeAct;
667
end;
667
end;
668
 
668
 
669
procedure TMainForm.EnemyClick(Sender: TObject);
669
procedure TMainForm.EnemyClick(Sender: TObject);
670
var
670
var
671
  et: TEnemyType;
671
  et: TEnemyType;
672
begin
672
begin
673
  et := SelectedEnemyType;
673
  et := SelectedEnemyType;
674
  Image1.Left := -(87 * (Ord(et) - 1)) + 1;
674
  Image1.Left := -(87 * (Ord(et) - 1)) + 1;
675
  LivesEdit.Enabled := EnemyTypeHasLives(et);
675
  LivesEdit.Enabled := EnemyTypeHasLives(et);
676
  LivesLabel.Enabled := EnemyTypeHasLives(et);
676
  LivesLabel.Enabled := EnemyTypeHasLives(et);
677
end;
677
end;
678
 
678
 
679
procedure TMainForm.EnemyCreateSprite(x, y: integer; AEnemyType: TEnemyType; ALives: integer);
679
procedure TMainForm.EnemyCreateSprite(x, y: integer; AEnemyType: TEnemyType; ALives: integer);
680
var
680
var
681
  Enemy: TSprite;
681
  Enemy: TSprite;
682
begin
682
begin
683
  Enemy := TEnemyOrItem.Create(SpriteEngine.Engine, AEnemyType, ALives);
683
  Enemy := TEnemyOrItem.Create(SpriteEngine.Engine, AEnemyType, ALives);
684
  Enemy.x := x;
684
  Enemy.x := x;
685
  Enemy.y := y;
685
  Enemy.y := y;
686
end;
686
end;
687
 
687
 
688
procedure TMainForm.DestroyLevel;
688
procedure TMainForm.DestroyLevel;
689
begin
689
begin
690
  ScrollBar.Position := 0; // this doesn't call ScrollBarScroll()
690
  ScrollBar.Position := 0; // this doesn't call ScrollBarScroll()
691
  ScrollP := 0;
691
  ScrollP := 0;
692
  LevData.Clear;
692
  LevData.Clear;
693
  ScrollBar.Max := LevData.LevelEditorLength;
693
  ScrollBar.Max := LevData.LevelEditorLength;
694
  NumEnemys := 0;
694
  NumEnemys := 0;
695
  Boss := false;
695
  Boss := false;
696
  LevChanged := true;
696
  LevChanged := true;
697
  LivesEdit.Value := 1;
697
  LivesEdit.Value := 1;
698
  Enemy1.Checked := true;
698
  Enemy1.Checked := true;
699
  EnemyClick(Enemy1);
699
  EnemyClick(Enemy1);
700
  AnzeigeAct;
700
  AnzeigeAct;
701
end;
701
end;
702
 
702
 
703
procedure TMainForm.AlleLeveldateienaktualisieren1Click(Sender: TObject);
703
procedure TMainForm.AlleLeveldateienaktualisieren1Click(Sender: TObject);
704
var
704
var
705
  i: integer;
705
  i: integer;
706
begin
706
begin
707
  // Just for internal/development purposes
707
  // Just for internal/development purposes
708
  for i := 1 to MaxPossibleLevels do
708
  for i := 1 to MaxPossibleLevels do
709
  begin
709
  begin
710
    if FileExists('Levels\Level '+IntToStr(i)+'.lev') then
710
    if FileExists('Levels\Level '+IntToStr(i)+'.lev') then
711
    begin
711
    begin
712
      LevData.RasterErzwingen := true;
712
      LevData.RasterErzwingen := true;
713
      LevData.LoadFromFile('Levels\Level '+IntToStr(i)+'.lev');
713
      LevData.LoadFromFile('Levels\Level '+IntToStr(i)+'.lev');
714
      LevData.SaveToFile('Levels\Level '+IntToStr(i)+'.lev');
714
      LevData.SaveToFile('Levels\Level '+IntToStr(i)+'.lev');
715
    end;
715
    end;
716
  end;
716
  end;
717
end;
717
end;
718
 
718
 
719
procedure TMainForm.AnzeigeAct;
719
procedure TMainForm.AnzeigeAct;
720
resourcestring
720
resourcestring
721
  SYes = 'Ja';
721
  SYes = 'Ja';
722
  SNo = 'Nein';
722
  SNo = 'Nein';
723
begin
723
begin
724
  SLabel1b.Caption := inttostr(NumEnemys);
724
  SLabel1b.Caption := inttostr(NumEnemys);
725
  if Boss then SLabel2b.Caption := SYes else SLabel2b.Caption := SNo;
725
  if Boss then SLabel2b.Caption := SYes else SLabel2b.Caption := SNo;
726
  SLabel3b.Caption := inttostr(ScrollBar.Max);
726
  SLabel3b.Caption := inttostr(ScrollBar.Max);
727
  if LevChanged then
727
  if LevChanged then
728
  begin
728
  begin
729
    SLabel4a.Font.Color := $00000096;
729
    SLabel4a.Font.Color := $00000096;
730
    SLabel4b.Font.Color := $00000096;
730
    SLabel4b.Font.Color := $00000096;
731
    SLabel4b.Caption := SNo;
731
    SLabel4b.Caption := SNo;
732
  end
732
  end
733
  else
733
  else
734
  begin
734
  begin
735
    SLabel4a.Font.Color := $00009600;
735
    SLabel4a.Font.Color := $00009600;
736
    SLabel4b.Font.Color := $00009600;
736
    SLabel4b.Font.Color := $00009600;
737
    SLabel4b.Caption := SYes;
737
    SLabel4b.Caption := SYes;
738
  end;
738
  end;
739
end;
739
end;
740
 
740
 
741
procedure TMainForm.AufUpdatesprfen1Click(Sender: TObject);
741
procedure TMainForm.AufUpdatesprfen1Click(Sender: TObject);
742
begin
742
begin
743
  CheckForUpdates('spacemission', ProgramVersion); // do not localize
743
  CheckForUpdates('spacemission', ProgramVersion); // do not localize
744
end;
744
end;
745
 
745
 
746
procedure TMainForm.NeuClick(Sender: TObject);
746
procedure TMainForm.NeuClick(Sender: TObject);
747
resourcestring
747
resourcestring
748
  SReallyDeleteLevel = 'Level wirklich löschen?';
748
  SReallyDeleteLevel = 'Level wirklich löschen?';
749
begin
749
begin
750
  if MessageDlg(SReallyDeleteLevel, mtConfirmation, mbYesNoCancel, 0) = mrYes then
750
  if MessageDlg(SReallyDeleteLevel, mtConfirmation, mbYesNoCancel, 0) = mrYes then
751
    DestroyLevel;
751
    DestroyLevel;
752
end;
752
end;
753
 
753
 
754
procedure TMainForm.DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
754
procedure TMainForm.DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
755
  Y: Integer);
755
  Y: Integer);
756
resourcestring
756
resourcestring
757
  status_lives = 'Leben: ';
757
  status_lives = 'Leben: ';
758
  status_nolives = 'Einheit hat keine Lebensangabe';
758
  status_nolives = 'Einheit hat keine Lebensangabe';
759
  SUnknownEnemyType = '???';
759
  SUnknownEnemyType = '???';
760
var
760
var
761
  i: TEnemyType;
761
  i: TEnemyType;
762
  ex, ey, j, k, l: integer;
762
  ex, ey, j, k, l: integer;
763
  lifes: integer;
763
  lifes: integer;
764
  enemyType: TEnemyType;
764
  enemyType: TEnemyType;
765
  enemyName: string;
765
  enemyName: string;
766
  breaked: boolean;
766
  breaked: boolean;
767
begin
767
begin
768
  if sender <> DxDraw then
768
  if sender <> DxDraw then
769
  begin
769
  begin
770
    StatusBar.SimpleText := ' ' + status_info;
770
    StatusBar.SimpleText := ' ' + status_info;
771
    exit;
771
    exit;
772
  end;
772
  end;
773
  ex := trunc(x/LevEditRasterW) * LevEditRasterW;
773
  ex := trunc(x/LevEditRasterW) * LevEditRasterW;
774
  ey := trunc(y/LevEditRasterH) * LevEditRasterH;
774
  ey := trunc(y/LevEditRasterH) * LevEditRasterH;
775
  lifes := -1;
775
  lifes := -1;
776
  enemyType := etUnknown;
776
  enemyType := etUnknown;
777
  breaked := false;
777
  breaked := false;
778
  for i := Low(TEnemyType) to High(TEnemyType) do
778
  for i := Low(TEnemyType) to High(TEnemyType) do
779
  begin
779
  begin
780
    for j := 0 to MaxPossibleEnemyLives do
780
    for j := 0 to MaxPossibleEnemyLives do
781
    begin
781
    begin
782
      if boss and (i = etEnemyBoss) then
782
      if boss and (i = etEnemyBoss) then
783
      begin
783
      begin
784
        for k := 0 to BossWidth - 1 do
784
        for k := 0 to BossWidth - 1 do
785
        begin
785
        begin
786
          for l := 0 to BossHeight - 1 do
786
          for l := 0 to BossHeight - 1 do
787
          begin
787
          begin
788
            if LevData.IndexOfEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), i, j) <> -1 then
788
            if LevData.IndexOfEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), i, j) <> -1 then
789
            begin
789
            begin
790
              lifes := j;
790
              lifes := j;
791
              breaked := true;
791
              breaked := true;
792
              break;
792
              break;
793
            end;
793
            end;
794
          end;
794
          end;
795
          if breaked then break;
795
          if breaked then break;
796
        end;
796
        end;
797
      end;
797
      end;
798
      if (breaked = false) and (LevData.IndexOfEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j) <> -1) then
798
      if (breaked = false) and (LevData.IndexOfEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j) <> -1) then
799
      begin
799
      begin
800
        lifes := j;
800
        lifes := j;
801
        enemyType := i;
801
        enemyType := i;
802
        breaked := true;
802
        breaked := true;
803
        break;
803
        break;
804
      end;
804
      end;
805
    end;
805
    end;
806
    if breaked then break;
806
    if breaked then break;
807
  end;
807
  end;
808
  if lifes <> -1 then
808
  if lifes <> -1 then
809
  begin
809
  begin
810
    if Ord(enemyType) = 1 then enemyName := Enemy1.Caption
810
    if Ord(enemyType) = 1 then enemyName := Enemy1.Caption
811
    else if Ord(enemyType) = 2 then enemyName := Enemy2.Caption
811
    else if Ord(enemyType) = 2 then enemyName := Enemy2.Caption
812
    else if Ord(enemyType) = 3 then enemyName := Enemy3.Caption
812
    else if Ord(enemyType) = 3 then enemyName := Enemy3.Caption
813
    else if Ord(enemyType) = 4 then enemyName := Enemy4.Caption
813
    else if Ord(enemyType) = 4 then enemyName := Enemy4.Caption
814
    else if Ord(enemyType) = 5 then enemyName := Enemy5.Caption
814
    else if Ord(enemyType) = 5 then enemyName := Enemy5.Caption
815
    else if Ord(enemyType) = 6 then enemyName := Enemy6.Caption
815
    else if Ord(enemyType) = 6 then enemyName := Enemy6.Caption
816
    else if Ord(enemyType) = 7 then enemyName := Enemy7.Caption
816
    else if Ord(enemyType) = 7 then enemyName := Enemy7.Caption
817
    else if Ord(enemyType) = 8 then enemyName := Enemy8.Caption
817
    else if Ord(enemyType) = 8 then enemyName := Enemy8.Caption
818
    else enemyName := SUnknownEnemyType;
818
    else enemyName := SUnknownEnemyType;
819
    if lifes > 0 then
819
    if lifes > 0 then
820
      StatusBar.SimpleText := ' ' + enemyName + ' - ' + status_lives + inttostr(lifes)
820
      StatusBar.SimpleText := ' ' + enemyName + ' - ' + status_lives + inttostr(lifes)
821
    else
821
    else
822
      StatusBar.SimpleText := ' ' + enemyName + ' - ' + status_nolives;
822
      StatusBar.SimpleText := ' ' + enemyName + ' - ' + status_nolives;
823
  end
823
  end
824
  else
824
  else
825
    StatusBar.SimpleText := ' ' + status_info;
825
    StatusBar.SimpleText := ' ' + status_info;
826
end;
826
end;
827
 
827
 
828
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
828
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
829
resourcestring
829
resourcestring
830
  SExitWithoutSave = 'Beenden ohne abspeichern?';
830
  SExitWithoutSave = 'Beenden ohne abspeichern?';
831
begin
831
begin
832
  if Assigned(LevData) and LevChanged and (LevData.CountEnemies>0) then
832
  if Assigned(LevData) and LevChanged and (LevData.CountEnemies>0) then
833
    CanClose := MessageDlg(SExitWithoutSave, mtConfirmation, mbYesNoCancel, 0) = mrYes;
833
    CanClose := MessageDlg(SExitWithoutSave, mtConfirmation, mbYesNoCancel, 0) = mrYes;
834
end;
834
end;
835
 
835
 
836
procedure TMainForm.Spielfelderweitern1Click(Sender: TObject);
836
procedure TMainForm.Spielfelderweitern1Click(Sender: TObject);
837
begin
837
begin
838
  LevelForm.Aktualisieren;
838
  LevelForm.Aktualisieren;
839
  LevelForm.showmodal;
839
  LevelForm.showmodal;
840
end;
840
end;
841
 
841
 
842
procedure TMainForm.ScrollBarScroll(Sender: TObject;
842
procedure TMainForm.ScrollBarScroll(Sender: TObject;
843
  ScrollCode: TScrollCode; var ScrollPos: Integer);
843
  ScrollCode: TScrollCode; var ScrollPos: Integer);
844
begin
844
begin
845
  ScrollP := ScrollPos;
845
  ScrollP := ScrollPos;
846
end;
846
end;
847
 
847
 
848
function TMainForm.SelectedEnemyType: TEnemyType;
848
function TMainForm.SelectedEnemyType: TEnemyType;
849
begin
849
begin
850
  if Enemy1.Checked then result := etEnemyAttacker
850
  if Enemy1.Checked then result := etEnemyAttacker
851
  else if Enemy2.Checked then result := etEnemyAttacker2
851
  else if Enemy2.Checked then result := etEnemyAttacker2
852
  else if Enemy3.Checked then result := etEnemyAttacker3
852
  else if Enemy3.Checked then result := etEnemyAttacker3
853
  else if Enemy4.Checked then result := etEnemyMeteor
853
  else if Enemy4.Checked then result := etEnemyMeteor
854
  else if Enemy5.Checked then result := etEnemyUFO
854
  else if Enemy5.Checked then result := etEnemyUFO
855
  else if Enemy6.Checked then result := etEnemyUFO2
855
  else if Enemy6.Checked then result := etEnemyUFO2
856
  else if Enemy7.Checked then result := etEnemyBoss
856
  else if Enemy7.Checked then result := etEnemyBoss
857
  else if Enemy8.Checked then result := etItemMedikit
857
  else if Enemy8.Checked then result := etItemMedikit
858
  else result := etUnknown;
858
  else result := etUnknown;
859
end;
859
end;
860
 
860
 
861
end.
861
end.
862
 
862
 
863
 
863