workaround for the "no digital sound" crash

Started by StillInThe90s, Mon 18/05/2015 16:41:47

Previous topic - Next topic

StillInThe90s

Without starting another discussion about what AGS should and should not do, I'm trying to find a workaround for the sound issue discussed in this thread. I.e. if "no digital sound" option is chosen in the setup, the code below will make your game crash.
Code: ags
AudioChannel *audio = aMusic.Play();
audio.Volume = 70;

...unless you wrap everything in a "if(audio){}" which is too much work for me at this point.

I suppose there is no way of checking if this option is chosen, from within an ags-application? Could I do this by raw reading acetup.cfg? (been unsuccessful so far) Changing the name of audio.vox with a custom setup could do the trick, since ags can check for files. Any obvious dangers there? (such as windows security)

Thanks.

Wyz

#1
Without making any changes to the engine the best I can come up with is a wrapper object. This is structure that you assign an AudioChannel object and implements all functionality that AudioChannel objects already have but with the added null check.

For this example it would contain the following:
Code: ags

struct SafeAudioChannel
{
  AudioChannel *audio;

  void SetVolume(int volume)
  {
    if (audio)
      audio.Volume = volume;
  }

  int GetVolume(int volume)
  {
    if (audio)
      return audio.Volume;
    return -1;
  }
  
  // ... many more potentially
};


Which you can use like this:
Code: ags

SafeAudioChannel channel;
channel.audio = aMusic.Play();
channel.SetVolume(70);


Would be nice to have this as a module I guess. :)
Life is like an adventure without the pixel hunts.

Snarky

Should be AudioChannel* audio; â€" but yeah.

StillInThe90s

Interesting.
Could this be done with already defined global AudioChannels as well?

Wyz

I believe so yes. It would need the usual im/exporting and setting up like other global variables but I can't think of a reason why not.
Life is like an adventure without the pixel hunts.

StillInThe90s

Thanks Wyz.
Unfortunately, it seems that this solution was horrible to implement in retrospect. I will have to go for bracket wrapping this time, but any new project will have safe audio structs for sure. ...that is, if nobody makes it even easier and writes a module -COUGH!-

Snarky

Quote from: StillInThe90s on Tue 19/05/2015 17:29:07
Unfortunately, it seems that this solution was horrible to implement in retrospect.

How so? Seems to me that there should only be two or three steps to it:

1. Create the struct type like Wyz outlines, wrapping all the API methods you need.
2. If you have any AudioChannel* globalvars, change them to regular variables exported by a script and imported in the header.
3. Change every AudioChannel* declaration to a SafeAudioChannel declaration.

The only possible problem I can see is if you've been passing AudioChannel* variables as arguments to functions, or had them as members of other structs.

StillInThe90s

It's hard because my script is a mess, but I think I got it. :)
QuoteThe only possible problem I can see is if you've been passing AudioChannel* variables as arguments to functions...
Well, sort of. At least now I know this is bad practice.

Snarky

No, not necessarily. It's just that it interferes with this particular workaround because of one of the most frustrating limitations in the AGS scripting language.

Crimson Wizard

You can also use helper functions like
Code: ags

AudioChannel *SafePlayAtVolume(AudioClip *clip, int volume)
{
    AudioChannel *ch = clip.Play();
    if (ch)
        ch.Volume = volume;
    return ch;
}

StillInThe90s

Well that looks simple enough.
Will definitely try it out.

SMF spam blocked by CleanTalk