* * *

Author Topic: Strange behaviour ("seeing" files)  (Read 1966 times)

justnewbie

  • Full Member
  • ***
  • Posts: 129
Strange behaviour ("seeing" files)
« on: May 02, 2018, 01:03:49 pm »
Something strange for me.
I have a program that uses an INI file, which can be found in the root folder of the program (ie. the executable and the INI file are in the same folder).
When I run the program from the Lazarus IDE, then it "sees" this INI file and works well.
But, when I run the program outside the IDE, it cannot "see" the INI file.
(I found the same problem with my tennis game https://forum.lazarus.freepascal.org/index.php/topic,41089.msg284619.html#msg284619, from the IDE the sound files are working, but "in itself" don't.)
Why?

Bram71

  • New member
  • *
  • Posts: 13
Re: Strange behaviour ("seeing" files)
« Reply #1 on: May 02, 2018, 01:25:31 pm »
Problem is the working directory normally specified in the shortcut to start your program. The IDE does it automagically for you...

See "SetCurrentDir" function.

I normally use the line below in my programs:

SetCurrentDir(ExtractFilePath(ParamStr(0)));

If you want to prepend the program path to the ini filename instead, then use the line below:

LIniFileName:=ExtractFilePath(ParamStr(0))+'TheIniFilename';
« Last Edit: May 02, 2018, 01:31:39 pm by Bram71 »

Handoko

  • Hero Member
  • *****
  • Posts: 2456
  • My goal: build my own game engine using Lazarus
Re: Strange behaviour ("seeing" files)
« Reply #2 on: May 02, 2018, 01:32:05 pm »
@justnewbie

I never got any sound when testing your Tennis Wonder.

After closer inspection, I found you forgot to put this line below on your initGame procedure:
Code: Pascal  [Select]
  1.   playsound1 := Tplaysound.Create(Self);

justnewbie

  • Full Member
  • ***
  • Posts: 129
Re: Strange behaviour ("seeing" files)
« Reply #3 on: May 02, 2018, 01:40:51 pm »
@Bram71: thank you, it works! Perfect!  :)

@Handoko: for me - within the IDE - it worked perfectly. Now (using Bram71's method) works well outside the IDE too.  :)

Handoko

  • Hero Member
  • *****
  • Posts: 2456
  • My goal: build my own game engine using Lazarus
Re: Strange behaviour ("seeing" files)
« Reply #4 on: May 02, 2018, 01:47:07 pm »
So, you do not want to put Tplaysound.Create(Self); in the source code? Really?

Oh my gosh, something 'really' bad will happen for sure someday.

There won't be any strange behaviour nor paranormal activities may happen if the programmer understand the logic of the code (s)he is writing and (s)he follows the all rules of writing program.

One of the rules we all know is: don't use any variable that hasn't been initialized.

Without initializing playsound1 in your Tennis Wonder, I never got any audio running the game both in the IDE or outside the IDE. Simply initializing the variable, I can hear the sound effect when running the game both on the IDE and outside the IDE. I tested several times on Lazarus 1.8.0 64-bit Gtk2 Ubuntu 17.10.
« Last Edit: May 02, 2018, 02:07:03 pm by Handoko »

justnewbie

  • Full Member
  • ***
  • Posts: 129
Re: Strange behaviour ("seeing" files)
« Reply #5 on: May 02, 2018, 02:30:58 pm »
So, you do not want to put Tplaysound.Create(Self); in the source code? Really?

Oh my gosh, something 'really' bad will happen for sure someday.

There won't be any strange behaviour nor paranormal activities may happen if the programmer understand the logic of the code (s)he is writing and (s)he follows the all rules of writing program.

One of the rules we all know is: don't use any variable that hasn't been initialized.

Without initializing playsound1 in your Tennis Wonder, I never got any audio running the game both in the IDE or outside the IDE. Simply initializing the variable, I can hear the sound effect when running the game both on the IDE and outside the IDE. I tested several times on Lazarus 1.8.0 64-bit Gtk2 Ubuntu 17.10.

Now I tried that you wrote and did place playsound1 := Tplaysound.Create(Self); in the initGame procedure.
And, replaced playsound1.SoundFile := ExtractFilePath(ParamStr(0))+'hit.wav'; with playsound1.SoundFile := 'hit.wav'; (it was originally there).
There was no sound.

Changing back from playsound1.SoundFile := 'hit.wav'; to playsound1.SoundFile := ExtractFilePath(ParamStr(0))+'hit.wav';, the sound is working well (without playsound1 := Tplaysound.Create(Self);).
I really don't know, but hasn't been initialized playsound1 when I placed its component to the Form?

« Last Edit: May 02, 2018, 02:45:37 pm by justnewbie »

Handoko

  • Hero Member
  • *****
  • Posts: 2456
  • My goal: build my own game engine using Lazarus
Re: Strange behaviour ("seeing" files)
« Reply #6 on: May 02, 2018, 02:55:58 pm »
I didn't say Bram71's suggestion is wrong. I just want to let you know without initializing playsound1 you may get lots of unpredictable things to happen. What may happen are random, sometimes it works but on the other times you may get SIGSEG error.

If you ask 10 senior programmers can you use playsound1 without calling the constructor first. All of them will say no, because Tplaysound is a class, a call to the constructor is required. Where is Thaddy? He is one senior here who is very strict about rules. I frequently fails to pass all this rules.

About the sound issue, why I have no problem on my computer but you have no sound on yours. That is another story. Computer configuration, OS, environment settings, ...

I looked into uplaysound unit. It tries to find 10 programs that can be used to play sound depends on what is available on the user's computer. It then passed the audio file name as a parameter to that program. Some may require full path + filename, the other may need only filename. That's could be the reason why it behaves differently on your computer and mine.
« Last Edit: May 02, 2018, 03:02:16 pm by Handoko »

justnewbie

  • Full Member
  • ***
  • Posts: 129
Re: Strange behaviour ("seeing" files)
« Reply #7 on: May 02, 2018, 03:01:51 pm »
Playsound: good thoughts, thank you!
About initialization: it is not really clear for me. For example, I guess that you don't have to initialize a Memo1, when you place its component to the form. Why not? Why is it needed in the case of Playsound?

Handoko

  • Hero Member
  • *****
  • Posts: 2456
  • My goal: build my own game engine using Lazarus
Re: Strange behaviour ("seeing" files)
« Reply #8 on: May 02, 2018, 03:17:27 pm »
Playsound: good thoughts, thank you!
About initialization: it is not really clear for me. For example, I guess that you don't have to initialize a Memo1, when you place its component to the form. Why not? Why is it needed in the case of Playsound?

If you drop something into the form, that is auto initialized.

If you create a TMemo instance without using the IDE to drop it, you have to manually call the constructor.

Okay my fault, now I've just saw you have a TPlaysound component on the form. That's mean it is auto-initialized. Sorry, I didn't pay attention on the form.

justnewbie

  • Full Member
  • ***
  • Posts: 129
Re: Strange behaviour ("seeing" files)
« Reply #9 on: May 02, 2018, 03:23:46 pm »
Now it's clear, thank you.

Handoko

  • Hero Member
  • *****
  • Posts: 2456
  • My goal: build my own game engine using Lazarus
Re: Strange behaviour ("seeing" files)
« Reply #10 on: May 02, 2018, 03:57:10 pm »
Do you use Linux?

I need your help. On my tests, the Tplaysound.Create will never be called except I manually call the constructor.

Can you please do:
01. Open your Tennis Wonder source code (the one without Tplaysound.Create)
02. Set the project build mode to Debug
03. Lazarus main menu > Run > Build
04. Run the program from IDE

Do you get the error as what I got on the image below?

justnewbie

  • Full Member
  • ***
  • Posts: 129
Re: Strange behaviour ("seeing" files)
« Reply #11 on: May 02, 2018, 04:15:06 pm »
I did what you asked (on Linux), did not get any error (both within and outside the IDE).
Here is the code I ran:
Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  9.   StdCtrls, uplaysound, LclType, LclIntf;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     lblRestart: TLabel;
  17.     field: TImage;
  18.     lblGameOver: TLabel;
  19.     lblScore: TLabel;
  20.     playsound1: Tplaysound;
  21.     Racket: TShape;
  22.     Ball: TShape;
  23.     tmrGame: TTimer;
  24.     procedure FormCreate(Sender: TObject);
  25.     procedure lblRestartClick(Sender: TObject);
  26.     procedure lblRestartMouseEnter(Sender: TObject);
  27.     procedure lblRestartMouseLeave(Sender: TObject);
  28.     procedure tmrGameTimer(Sender: TObject);
  29.   private
  30.     procedure initGame;
  31.     procedure updateScore;
  32.     procedure gameOver;
  33.     procedure increaseSpeed;
  34.   public
  35.  
  36.   end;
  37.  
  38. type
  39.   TDirection = (dirLeft, dirRight, dirNone);
  40.  
  41. var
  42.   Form1: TForm1;
  43.   score: integer;
  44.   speedX, speedY: double;
  45.   step: byte = 6;
  46.   Direction: TDirection = dirNone;
  47.  
  48. implementation
  49.  
  50. {$R *.lfm}
  51.  
  52. { TForm1 }
  53.  
  54. procedure TForm1.FormCreate(Sender: TObject);
  55. begin
  56.   DoubleBuffered := True;
  57.   Randomize;
  58.   initGame;
  59. end;
  60.  
  61. procedure TForm1.lblRestartClick(Sender: TObject);
  62. begin
  63.   initGame;
  64. end;
  65.  
  66. procedure TForm1.lblRestartMouseEnter(Sender: TObject);
  67. begin
  68.   lblRestart.Font.Style := [fsBold, fsUnderline];
  69. end;
  70.  
  71. procedure TForm1.lblRestartMouseLeave(Sender: TObject);
  72. begin
  73.   lblRestart.Font.Style := [];
  74. end;
  75.  
  76. procedure TForm1.initGame;
  77. var
  78.   startPos: integer;
  79. begin
  80.   score := 0;
  81.   speedX := -5;
  82.   speedY := -5;
  83.  
  84.   startPos := ClientWidth div 2 + Random(2 * 200) - 200;
  85.  
  86.   Racket.Left := startPos - Racket.Width div 2;
  87.   Racket.Top := ClientHeight - Racket.Height - 2;
  88.  
  89.   Ball.Left := startPos - Ball.Width div 2;
  90.   Ball.Top := Racket.Top - Ball.Height - 2;
  91.  
  92.   lblGameOver.Visible := False;
  93.   lblRestart.Visible := False;
  94.   lblRestart.Font.Style := [];
  95.  
  96.   updateScore;
  97.   Cursor := crNone;
  98.   field.Cursor := crNone;
  99.   tmrGame.Enabled := True;
  100. end;
  101.  
  102. procedure TForm1.updateScore;
  103. begin
  104.   lblScore.Caption := IntToStr(score);
  105. end;
  106.  
  107. procedure TForm1.increaseSpeed;
  108. begin
  109.   if speedX > 0 then
  110.     //Inc(speedX)
  111.     speedX := speedX + 0.25
  112.   else
  113.     //Dec(speedX);
  114.     speedX := speedX - 0.25;
  115.   if speedY > 0 then
  116.     //Inc(speedY)
  117.     speedY := speedY + 0.25
  118.   else
  119.     //Dec(speedY);
  120.     speedY := speedY - 0.25;
  121.  
  122. end;
  123.  
  124. procedure TForm1.gameOver;
  125. begin
  126.   tmrGame.Enabled := False;
  127.   lblGameOver.Visible := True;
  128.   lblRestart.Visible := True;
  129.   Cursor := crDefault;
  130.   field.Cursor := crDefault;
  131. end;
  132.  
  133. procedure TForm1.tmrGameTimer(Sender: TObject);
  134. begin
  135.   if GetKeyState(VK_LSHIFT) < 0 then
  136.     Direction := dirLeft;
  137.   if GetKeyState(VK_RSHIFT) < 0 then
  138.     Direction := dirRight;
  139.   case Direction of
  140.     dirLeft: if Racket.Left >= step then
  141.         Racket.Left := Racket.Left - step;
  142.     dirRight: if Racket.Left + Racket.Width <= ClientWidth - step then
  143.         Racket.Left := Racket.Left + step;
  144.   end;
  145.   Direction := dirNone;
  146.  
  147.   Ball.Left := Ball.Left + Round(speedX);
  148.   Ball.Top := Ball.Top + Round(speedY);
  149.  
  150.   //Walls
  151.   if Ball.Top <= 0 then
  152.   begin
  153.     playsound1.SoundFile := ExtractFilePath(ParamStr(0)) + 'wall1.wav';
  154.     playsound1.Execute;
  155.     speedY := -speedY;
  156.   end;
  157.  
  158.   if (Ball.Left <= 0) or (Ball.Left + Ball.Width >= ClientWidth) then
  159.   begin
  160.     playsound1.SoundFile := ExtractFilePath(ParamStr(0)) + 'wall1.wav';
  161.     playsound1.Execute;
  162.     speedX := -speedX;
  163.   end;
  164.  
  165.  
  166.   //Game over
  167.   if Ball.Top + Ball.Height > Racket.Top + Racket.Height div 2 then
  168.   begin
  169.     playsound1.SoundFile := ExtractFilePath(ParamStr(0)) + 'gameover2.wav';
  170.     playsound1.Execute;
  171.     gameOver;
  172.   end;
  173.  
  174.  
  175.   //Good hit
  176.   if (Ball.Left + Ball.Width > Racket.Left) and (Ball.Left < Racket.Left + Racket.Width) and (Ball.Top + Ball.Height >= Racket.Top) then
  177.   begin
  178.     playsound1.SoundFile := ExtractFilePath(ParamStr(0)) + 'hit.wav';
  179.     playsound1.Execute;
  180.     speedY := -speedY;
  181.     increaseSpeed;
  182.     Inc(score);
  183.     updateScore;
  184.   end;
  185. end;
  186.  
  187.  
  188. end.
« Last Edit: May 02, 2018, 04:17:40 pm by justnewbie »

Handoko

  • Hero Member
  • *****
  • Posts: 2456
  • My goal: build my own game engine using Lazarus
Re: Strange behaviour ("seeing" files)
« Reply #12 on: May 02, 2018, 04:28:04 pm »
Then there is something not correct on my computer.

I added some breakpoints on the TPlaysound's procedures including the constructor. None of them were called. Unless I have to manually call the constructor, then everything will work normal. And that made me thought you need to manually call the constructor.

I will inspect it deeply.

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 797
    • Burdjia
Re: Strange behaviour ("seeing" files)
« Reply #13 on: May 02, 2018, 05:54:25 pm »
You must be careful with the directories.  It depends on the operating system.  Bram71's way is the standard for Windows but it is a no no in POSIX (including Linux and MacOS).  POSIX systems have a well defined directory hierachy for data files.  For example GNU/Linux use the FHS definition.  I'm not sure MacOS uses the same directory distribution, but many POSIX systems uses similar ones.
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

justnewbie

  • Full Member
  • ***
  • Posts: 129
Re: Strange behaviour ("seeing" files)
« Reply #14 on: May 02, 2018, 07:41:15 pm »
Thank you for the suggestions.
I did not think that it is so difficult (and it works on my Linux system).

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus