Subversion Repositories spacemission

Rev

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

Rev Author Line No. Line
2 daniel-mar 1
unit Global;
2
 
3
interface
4
 
5
const
90 daniel-mar 6
  ProgramVersion = '1.2.2';
79 daniel-mar 7
  LevEditRasterW = 48;
8
  LevEditRasterH = 32;
81 daniel-mar 9
  LevEditRows = 15; // Attention: if you change this, you also need to change the LevEditor GUI!
10
  LevEditCols = 13; // Attention: if you change this, you also need to change the LevEditor GUI!
40 daniel-mar 11
  MaxPossibleEnemyLives = 999;
61 daniel-mar 12
  MaxPossibleLevels = 999;
79 daniel-mar 13
  RegistrySettingsKey = 'SOFTWARE\ViaThinkSoft\SpaceMission\Settings'; // do not localize
14
  MusicSettingKey = 'Music'; // do not localize
15
  SoundSettingKey = 'Sound'; // do not localize
80 daniel-mar 16
  SpeedSettingKey = 'GameSpeed'; // do not localize
51 daniel-mar 17
  DefaultLevelLength = 1200;
54 daniel-mar 18
  StartLives = 6;
81 daniel-mar 19
  SpeedEasy = 650 div 60; // 10
20
  SpeedMedium = 1000 div 60; // 16
21
  SpeedHard = 1350 div 60; // 22
22
  SpeedMaster = 2000 div 60; // 33
54 daniel-mar 23
  DEFAULT_ANIMSPEED = 15/1000;
79 daniel-mar 24
  BossWidth = 4;
25
  BossHeight = 2;
26
  SpaceMissionExe = 'SpaceMission.exe'; // do not localize
27
  LevEditExe = 'LevEdit.exe'; // do not localize
80 daniel-mar 28
  DxgFile = 'DirectX\Graphics.dxg'; // do not localize
29
  DxwFile = 'DirectX\Sound.dxw'; // do not localize
30
  DxmFile = 'DirectX\Music.dxm'; // do not localize
81 daniel-mar 31
  RandomLevelMaxEnemyLives = 10;
32
  RandomLevelMedikitEveryX = 250;
33
  RandomLevelAdditionalEnemiesPerLevel = 75; // Zufalls-Level
2 daniel-mar 34
 
89 daniel-mar 35
const
36
  // Cheat1 = 'Kmkjk'+#39+'Khyc';
37
  Cheat1 = #75+#109+#107+#106+#107+#127+#39+#75+#104+#121+#99; {Johnny Cash}
38
 
39
resourcestring
40
  Cheat1Text = 'Unendlich Leben!';
41
 
31 daniel-mar 42
type
89 daniel-mar 43
  TCheat = (ctUnknown, ctInfiniteLives);
44
  TCheatSet = set of TCheat;
45
 
31 daniel-mar 46
  // DirectX\Music.dxm
47
  TSpaceMissionMusicTrack = (
48
    smmNone,
49
    smmBoss,   // dxmusic.Midis[0]
50
    smmGame,   // dxmusic.Midis[1]
51
    smmScene,  // dxmusic.Midis[2]
52
    smmTitle   // dxmusic.Midis[3]
53
  );
54
 
55
  // DirectX\Graphics.dxg
56
  TSpaceMissionGraphicSprite = (
34 daniel-mar 57
    smgNone,
58
    smgEnemyDisk,         // ImageList.Items.Item[0]
59
    smgEnemyAttacker,     // ImageList.Items.Item[1]
60
    smgEnemyBoss,         // ImageList.Items.Item[2]
61
    smgBounce,            // ImageList.Items.Item[3]
62
    smgMachine,           // ImageList.Items.Item[4]
63
    smgEnemyAttacker2,    // ImageList.Items.Item[5]
64
    smgEnemyAttacker3,    // ImageList.Items.Item[6]
65
    smgEnemyMeteor,       // ImageList.Items.Item[7]
66
    smgBounce2,           // ImageList.Items.Item[8]
67
    smgEnemyDisk2,        // ImageList.Items.Item[9]
68
    smgLogo,              // ImageList.Items.Item[10]
69
    smgExplosion,         // ImageList.Items.Item[11]
70
    smgBackgroundPlanet1, // ImageList.Items.Item[12]
71
    smgMatrix,            // ImageList.Items.Item[13]
72
    smgStar1,             // ImageList.Items.Item[14]
73
    smgStar2,             // ImageList.Items.Item[15]
74
    smgStar3,             // ImageList.Items.Item[16]
75
    smgBackgroundBlue,    // ImageList.Items.Item[17]
76
    smgBackgroundRed,     // ImageList.Items.Item[18]
77
    smgBackgroundYellow,  // ImageList.Items.Item[19]
72 daniel-mar 78
    smgHintergrundRot,    // ImageList.Items.Item[20]
79
    smgItemMedikit        // ImageList.Items.Item[21]
31 daniel-mar 80
  );
81
 
82
  // DirectX\Sound.dxw
83
  TSpaceMissionSound = (
84
    smsNone,
85
    smsSceneMov,      // WaveList.Items.Item[0]
86
    smsExplosion,     // WaveList.Items.Item[1]
87
    smsHit,           // WaveList.Items.Item[2]
88
    smsShoot,         // WaveList.Items.Item[3]
72 daniel-mar 89
    smsItemCollected  // WaveList.Items.Item[4]
31 daniel-mar 90
  );
91
 
92
function OwnDirectory: string;
93
 
51 daniel-mar 94
const
79 daniel-mar 95
  FOLDERID_SavedGames: TGuid = '{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}'; // do not localize
51 daniel-mar 96
 
54 daniel-mar 97
// Useful functions
51 daniel-mar 98
function GetKnownFolderPath(const rfid: TGUID): string;
54 daniel-mar 99
function KillTask(ExeFileName: string): Integer;
74 daniel-mar 100
procedure CheckForUpdates(ViaThinkSoftProjectName: string; AVersion: string);
51 daniel-mar 101
 
2 daniel-mar 102
implementation
103
 
104
uses
79 daniel-mar 105
  Windows, SysUtils, Dialogs, ActiveX, ShlObj, TlHelp32, wininet, Forms, ShellAPI,
106
  System.UITypes;
2 daniel-mar 107
 
51 daniel-mar 108
function GetKnownFolderPath(const rfid: TGUID): string;
109
var
110
  OutPath: PWideChar;
111
begin
112
  // https://www.delphipraxis.net/135471-unit-zur-verwendung-von-shgetknownfolderpath.html
113
  if ShGetKnownFolderPath(rfid, 0, 0, OutPath) {>= 0} = S_OK then
114
  begin
115
    Result := OutPath;
116
    // From MSDN
117
    // ppszPath [out]
118
    // Type: PWSTR*
119
    // When this method returns, contains the address of a pointer to a null-terminated Unicode string that specifies the path of the known folder
120
    // The calling process is responsible for freeing this resource once it is no longer needed by calling CoTaskMemFree.
121
    // The returned path does not include a trailing backslash. For example, "C:\Users" is returned rather than "C:\Users\".
122
    CoTaskMemFree(OutPath);
123
  end
124
  else
125
  begin
126
    Result := '';
127
  end;
128
end;
129
 
54 daniel-mar 130
// https://stackoverflow.com/questions/43774320/how-to-kill-a-process-by-name
131
function KillTask(ExeFileName: string): Integer;
132
const
133
  PROCESS_TERMINATE = $0001;
134
var
135
  ContinueLoop: BOOL;
136
  FSnapshotHandle: THandle;
137
  FProcessEntry32: TProcessEntry32;
138
begin
139
  Result := 0;
140
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
141
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
142
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
143
 
144
  while Integer(ContinueLoop) <> 0 do
145
  begin
146
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
147
      UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
148
      UpperCase(ExeFileName))) then
149
      Result := Integer(TerminateProcess(
150
                        OpenProcess(PROCESS_TERMINATE,
151
                                    BOOL(0),
152
                                    FProcessEntry32.th32ProcessID),
153
                                    0));
154
     ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
155
  end;
156
  CloseHandle(FSnapshotHandle);
157
end;
158
 
31 daniel-mar 159
function OwnDirectory: string;
2 daniel-mar 160
begin
161
  result := extractfilepath(paramstr(0));
162
end;
163
 
74 daniel-mar 164
// https://www.delphipraxis.net/post43515.html , fixed , works for Delphi 12 Athens
165
function GetHTML(AUrl: string): RawByteString;
63 daniel-mar 166
var
74 daniel-mar 167
  databuffer : array[0..4095] of ansichar; // SIC! ansichar!
168
  ResStr : ansistring; // SIC! ansistring
63 daniel-mar 169
  hSession, hfile: hInternet;
170
  dwindex,dwcodelen,dwread,dwNumber: cardinal;
171
  dwcode : array[1..20] of char;
172
  res    : pchar;
74 daniel-mar 173
  Str    : pansichar; // SIC! pansichar
63 daniel-mar 174
begin
175
  ResStr:='';
79 daniel-mar 176
  if (system.pos('http://',lowercase(AUrl))=0) and // do not localize
177
     (system.pos('https://',lowercase(AUrl))=0) then // do not localize
178
     AUrl:='http://'+AUrl; // do not localize
63 daniel-mar 179
 
180
  // Hinzugefügt
181
  if Assigned(Application) then Application.ProcessMessages;
182
 
79 daniel-mar 183
  hSession:=InternetOpen('InetURL:/1.0', // do not localize
63 daniel-mar 184
                         INTERNET_OPEN_TYPE_PRECONFIG,
185
                         nil,
186
                         nil,
187
                         0);
188
  if assigned(hsession) then
189
  begin
190
    // Hinzugefügt
191
    if Assigned(Application) then application.ProcessMessages;
192
 
193
    hfile:=InternetOpenUrl(
194
           hsession,
195
           pchar(AUrl),
196
           nil,
197
           0,
198
           INTERNET_FLAG_RELOAD,
199
           0);
200
    dwIndex  := 0;
201
    dwCodeLen := 10;
202
 
203
    // Hinzugefügt
204
    if Assigned(Application) then application.ProcessMessages;
205
 
206
    HttpQueryInfo(hfile,
207
                  HTTP_QUERY_STATUS_CODE,
208
                  @dwcode,
209
                  dwcodeLen,
210
                  dwIndex);
211
    res := pchar(@dwcode);
212
    dwNumber := sizeof(databuffer)-1;
79 daniel-mar 213
    if (res ='200') or (res = '302') then // do not localize
63 daniel-mar 214
    begin
215
      while (InternetReadfile(hfile,
216
                              @databuffer,
217
                              dwNumber,
218
                              DwRead)) do
219
      begin
220
 
221
        // Hinzugefügt
222
        if Assigned(Application) then application.ProcessMessages;
223
 
224
        if dwRead =0 then
225
          break;
226
        databuffer[dwread]:=#0;
74 daniel-mar 227
        Str := pansichar(@databuffer);
63 daniel-mar 228
        resStr := resStr + Str;
229
      end;
230
    end
231
    else
79 daniel-mar 232
      ResStr := 'Status:'+AnsiString(res); // do not localize
63 daniel-mar 233
    if assigned(hfile) then
234
      InternetCloseHandle(hfile);
235
  end;
236
 
237
  // Hinzugefügt
238
  if Assigned(Application) then application.ProcessMessages;
239
 
240
  InternetCloseHandle(hsession);
241
  Result := resStr;
242
end;
243
 
74 daniel-mar 244
procedure CheckForUpdates(ViaThinkSoftProjectName: string; AVersion: string);
79 daniel-mar 245
resourcestring
246
  SDownloadError = 'Ein Fehler ist aufgetreten. Wahrscheinlich ist keine Internetverbindung aufgebaut, oder der der ViaThinkSoft-Server vorübergehend offline.';
247
  SNewProgramVersionAvailable = 'Eine neue Programmversion ist vorhanden. Möchten Sie diese jetzt herunterladen?';
248
  SNoUpdateAvailable = 'Es ist keine neue Programmversion vorhanden.';
63 daniel-mar 249
var
74 daniel-mar 250
  cont: RawByteString;
63 daniel-mar 251
begin
79 daniel-mar 252
  cont := GetHTML('https://www.viathinksoft.de/update/?id='+ViaThinkSoftProjectName); // do not localize
63 daniel-mar 253
  if copy(cont, 0, 7) = 'Status:' then
254
  begin
79 daniel-mar 255
    MessageDlg(SDownloadError, mtError, [mbOk], 0);
63 daniel-mar 256
  end
257
  else
258
  begin
74 daniel-mar 259
    if string(cont) <> AVersion then
63 daniel-mar 260
    begin
79 daniel-mar 261
      if MessageDlg(SNewProgramVersionAvailable, mtConfirmation, mbYesNoCancel, 0) = mrYes then
262
        shellexecute(application.handle, 'open', pchar('https://www.viathinksoft.de/update/?id=@'+ViaThinkSoftProjectName), '', '', sw_normal); // do not localize
63 daniel-mar 263
    end
264
    else
265
    begin
79 daniel-mar 266
      MessageDlg(SNoUpdateAvailable, mtInformation, [mbOk], 0);
63 daniel-mar 267
    end;
268
  end;
269
end;
270
 
2 daniel-mar 271
end.