Subversion Repositories spacemission

Rev

Rev 79 | Rev 81 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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