Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - devkitSMS tip: how to prioritize SFXs

Reply to topic
Author Message
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
devkitSMS tip: how to prioritize SFXs
Post Posted: Fri Dec 09, 2016 1:23 pm
It is known that PSGlib audio library includes support for replaying an SFX on top of the background music but it does a very basic job when it comes to start a new SFX when one is already playing: the library will simply stop the currently playing SFX to reproduce the newly requested one. Sometimes this might not be the desired behavior as in some cases the already playing SFX is of importance and we might prefer not to give way to a less important SFX.

So here follows a possible approach to a simple solution for this problem: we’re going to create a priority system that implements a way for an SFX to interrupt an already playing SFX only if the latter isn’t more important.
First, we define a few priority levels, according to our needs. In this example I’ll create only 3 of them:

#define PRIORITY_HIGH                70
#define PRIORITY_NORMAL              50
#define PRIORITY_LOW                 30

note that the specific values aren’t important, as long as they fit in a single byte and they’re decreasing with the decreasing priority. Also, you can leave some unused values in between in case you need to create some intermediate priority levels.

[Note: I tend not to use C enumerations because of the inconsistent behavior among compilers, so I choose to use a few #defines instead]

Then, we need a variable to keep track of the priority of the currently playing SFX. Also, I’d expect a game using music and SFXs to require ROM paging, so we also need two variables to keep track of the bank locations of the currently playing SFX and of the currently playing background tune:

unsigned char current_SFX_priority;
unsigned char current_SFX_ROM_bank;
unsigned char current_tune_ROM_bank;

Finally, we need a short macro that will start a SFX only when appropriate, which means either when there isn’t any other SFX playing or when the SFX currently playing isn’t of higher priority. It will also store the SFX bank location, if it’s started.

#define FIRESFX(which,bank,how,prio)                          \
   if((!PSGSFXGetStatus())||((prio)>=current_SFX_priority)){  \
     PSGSFXPlay ((which),(how));                              \
     current_SFX_ROM_bank=bank;                               \
     current_SFX_priority=prio;                               \
   }

So we’re now ready to use our newly created macro. The parameters needed for the macro invocation are:
* A pointer to the SFX we want to play
* The bank where the said SFX resides
* The channels the SFX will use (SFX_CHANNEL2, SFX_CHANNEL3, SFX_CHANNELS2AND3 – this value will be passed untouched to PSGSFXPlay function)
* The priority for this effect

For example, say we’ve got an explosion SFX and some other important SFX; we might want to start the important SFX using:

FIRESFX(important_SFX_psg, important_SFX_psg _bank, SFX_CHANNELS2AND3, PRIORITY_HIGH);

so that when it will happen that we need to fire the explosion SFX:

FIRESFX(explosion_SFX_psg, explosion_SFX_psg_bank, SFX_CHANNEL3, PRIORITY_NORMAL);

this will or won’t actually be fired, as appropriate.

We shouldn’t forget anyway that to make music and SFX work correctly, somewhere in our main game loop we need to constantly execute this, once per frame:

SMS_mapROMBank(current_tune_ROM_bank);
PSGFrame();
SMS_mapROMBank(current_SFX_ROM_bank);
PSGSFXFrame();

…but that was already a PSGlib requirement, anyway.

I hope you found this small tip clear, interesting an useful. Feedback and comments welcome!
  View user's profile Send private message Visit poster's website
Reply to topic



Back to the top of this page

Back to SMS Power!