Subversion Repositories spacemission

Rev

Rev 89 | Rev 94 | 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.2';
  7.   LevEditRasterW = 48;
  8.   LevEditRasterH = 32;
  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!
  11.   MaxPossibleEnemyLives = 999;
  12.   MaxPossibleLevels = 999;
  13.   RegistrySettingsKey = 'SOFTWARE\ViaThinkSoft\SpaceMission\Settings'; // do not localize
  14.   MusicSettingKey = 'Music'; // do not localize
  15.   SoundSettingKey = 'Sound'; // do not localize
  16.   SpeedSettingKey = 'GameSpeed'; // do not localize
  17.   DefaultLevelLength = 1200;
  18.   StartLives = 6;
  19.   SpeedEasy = 650 div 60; // 10
  20.   SpeedMedium = 1000 div 60; // 16
  21.   SpeedHard = 1350 div 60; // 22
  22.   SpeedMaster = 2000 div 60; // 33
  23.   DEFAULT_ANIMSPEED = 15/1000;
  24.   BossWidth = 4;
  25.   BossHeight = 2;
  26.   SpaceMissionExe = 'SpaceMission.exe'; // do not localize
  27.   LevEditExe = 'LevEdit.exe'; // do not localize
  28.   DxgFile = 'DirectX\Graphics.dxg'; // do not localize
  29.   DxwFile = 'DirectX\Sound.dxw'; // do not localize
  30.   DxmFile = 'DirectX\Music.dxm'; // do not localize
  31.   RandomLevelMaxEnemyLives = 10;
  32.   RandomLevelMedikitEveryX = 250;
  33.   RandomLevelAdditionalEnemiesPerLevel = 75; // Zufalls-Level
  34.  
  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.  
  42. type
  43.   TCheat = (ctUnknown, ctInfiniteLives);
  44.   TCheatSet = set of TCheat;
  45.  
  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 = (
  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]
  78.     smgHintergrundRot,    // ImageList.Items.Item[20]
  79.     smgItemMedikit        // ImageList.Items.Item[21]
  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]
  89.     smsItemCollected  // WaveList.Items.Item[4]
  90.   );
  91.  
  92. function OwnDirectory: string;
  93.  
  94. const
  95.   FOLDERID_SavedGames: TGuid = '{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}'; // do not localize
  96.  
  97. // Useful functions
  98. function GetKnownFolderPath(const rfid: TGUID): string;
  99. function KillTask(ExeFileName: string): Integer;
  100. procedure CheckForUpdates(ViaThinkSoftProjectName: string; AVersion: string);
  101.  
  102. implementation
  103.  
  104. uses
  105.   Windows, SysUtils, Dialogs, ActiveX, ShlObj, TlHelp32, wininet, Forms, ShellAPI,
  106.   System.UITypes;
  107.  
  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.  
  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.  
  159. function OwnDirectory: string;
  160. begin
  161.   result := extractfilepath(paramstr(0));
  162. end;
  163.  
  164. // https://www.delphipraxis.net/post43515.html , fixed , works for Delphi 12 Athens
  165. function GetHTML(AUrl: string): RawByteString;
  166. var
  167.   databuffer : array[0..4095] of ansichar; // SIC! ansichar!
  168.   ResStr : ansistring; // SIC! ansistring
  169.   hSession, hfile: hInternet;
  170.   dwindex,dwcodelen,dwread,dwNumber: cardinal;
  171.   dwcode : array[1..20] of char;
  172.   res    : pchar;
  173.   Str    : pansichar; // SIC! pansichar
  174. begin
  175.   ResStr:='';
  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
  179.  
  180.   // Hinzugefügt
  181.   if Assigned(Application) then Application.ProcessMessages;
  182.  
  183.   hSession:=InternetOpen('InetURL:/1.0', // do not localize
  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;
  213.     if (res ='200') or (res = '302') then // do not localize
  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;
  227.         Str := pansichar(@databuffer);
  228.         resStr := resStr + Str;
  229.       end;
  230.     end
  231.     else
  232.       ResStr := 'Status:'+AnsiString(res); // do not localize
  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.  
  244. procedure CheckForUpdates(ViaThinkSoftProjectName: string; AVersion: string);
  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.';
  249. var
  250.   cont: RawByteString;
  251. begin
  252.   cont := GetHTML('https://www.viathinksoft.de/update/?id='+ViaThinkSoftProjectName); // do not localize
  253.   if copy(cont, 0, 7) = 'Status:' then
  254.   begin
  255.     MessageDlg(SDownloadError, mtError, [mbOk], 0);
  256.   end
  257.   else
  258.   begin
  259.     if string(cont) <> AVersion then
  260.     begin
  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
  263.     end
  264.     else
  265.     begin
  266.       MessageDlg(SNoUpdateAvailable, mtInformation, [mbOk], 0);
  267.     end;
  268.   end;
  269. end;
  270.  
  271. end.
  272.