mirror of
https://gitlab.com/drummyfish/anarch.git
synced 2024-11-25 10:22:23 -05:00
Continue music
This commit is contained in:
parent
443adbe950
commit
2a58188ee0
95
main.c
95
main.c
@ -101,6 +101,14 @@ static inline void SFG_setPixel(uint16_t x, uint16_t y, uint8_t colorIndex);
|
|||||||
*/
|
*/
|
||||||
void SFG_playSound(uint8_t soundIndex, uint8_t volume);
|
void SFG_playSound(uint8_t soundIndex, uint8_t volume);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Informs the frontend whether music should get enabled/disabled. Playing music
|
||||||
|
is optional and the frontend can ignore it. If a frontend wants to implement
|
||||||
|
music, it can use the one provided in sounds.h or use its own.
|
||||||
|
*/
|
||||||
|
void SFG_enableMusic(uint8_t enable);
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -285,6 +293,9 @@ struct
|
|||||||
uint8_t selectedMenuItem;
|
uint8_t selectedMenuItem;
|
||||||
uint8_t selectedLevel; ///< Level to play selected in the main menu.
|
uint8_t selectedLevel; ///< Level to play selected in the main menu.
|
||||||
uint8_t antiSpam; ///< Prevents log message spamming.
|
uint8_t antiSpam; ///< Prevents log message spamming.
|
||||||
|
|
||||||
|
uint8_t soundSettings; /**< Sound settings: LSB says whether SFX is on,
|
||||||
|
second LSB says whether music is on. */
|
||||||
} SFG_game;
|
} SFG_game;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -442,8 +453,11 @@ uint8_t SFG_random()
|
|||||||
return SFG_game.currentRandom;
|
return SFG_game.currentRandom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SFG_playSoundSafe(uint8_t soundIndex, uint8_t volume)
|
void SFG_playGameSound(uint8_t soundIndex, uint8_t volume)
|
||||||
{
|
{
|
||||||
|
if (!(SFG_game.soundSettings & 0x01))
|
||||||
|
return;
|
||||||
|
|
||||||
uint8_t mask = 0x01 << soundIndex;
|
uint8_t mask = 0x01 << soundIndex;
|
||||||
|
|
||||||
if (!(SFG_game.soundsPlayedThisFrame & mask))
|
if (!(SFG_game.soundsPlayedThisFrame & mask))
|
||||||
@ -1418,6 +1432,9 @@ void SFG_init()
|
|||||||
|
|
||||||
SFG_game.antiSpam = 0;
|
SFG_game.antiSpam = 0;
|
||||||
|
|
||||||
|
SFG_game.soundSettings = 0xff;
|
||||||
|
SFG_enableMusic(1);
|
||||||
|
|
||||||
SFG_LOG("computing average texture colors")
|
SFG_LOG("computing average texture colors")
|
||||||
|
|
||||||
for (uint8_t i = 0; i < SFG_WALL_TEXTURE_COUNT; ++i)
|
for (uint8_t i = 0; i < SFG_WALL_TEXTURE_COUNT; ++i)
|
||||||
@ -1693,10 +1710,10 @@ void SFG_monsterChangeHealth(SFG_MonsterRecord *monster, int8_t healthAdd)
|
|||||||
SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]),
|
SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]),
|
||||||
SFG_MONSTER_COORD_TO_SQUARES(monster->coords[1])));
|
SFG_MONSTER_COORD_TO_SQUARES(monster->coords[1])));
|
||||||
|
|
||||||
SFG_playSoundSafe(5,volume);
|
SFG_playGameSound(5,volume);
|
||||||
|
|
||||||
if (monster->health == 0)
|
if (monster->health == 0)
|
||||||
SFG_playSoundSafe(2,volume);
|
SFG_playGameSound(2,volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1748,7 +1765,7 @@ void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z)
|
|||||||
{
|
{
|
||||||
SFG_ProjectileRecord explosion;
|
SFG_ProjectileRecord explosion;
|
||||||
|
|
||||||
SFG_playSound(2,SFG_distantSoundVolume(x,y,z));
|
SFG_playGameSound(2,SFG_distantSoundVolume(x,y,z));
|
||||||
|
|
||||||
explosion.type = SFG_PROJECTILE_EXPLOSION;
|
explosion.type = SFG_PROJECTILE_EXPLOSION;
|
||||||
|
|
||||||
@ -1926,7 +1943,7 @@ void SFG_monsterPerformAI(SFG_MonsterRecord *monster)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (projectile == SFG_PROJECTILE_BULLET)
|
if (projectile == SFG_PROJECTILE_BULLET)
|
||||||
SFG_playSoundSafe(0,
|
SFG_playGameSound(0,
|
||||||
SFG_distantSoundVolume(
|
SFG_distantSoundVolume(
|
||||||
SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]),
|
SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]),
|
||||||
SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]),
|
SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]),
|
||||||
@ -2014,7 +2031,7 @@ void SFG_monsterPerformAI(SFG_MonsterRecord *monster)
|
|||||||
SFG_playerChangeHealth(
|
SFG_playerChangeHealth(
|
||||||
-1 * SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_MELEE));
|
-1 * SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_MELEE));
|
||||||
|
|
||||||
SFG_playSoundSafe(3,255);
|
SFG_playGameSound(3,255);
|
||||||
}
|
}
|
||||||
else // SFG_MONSTER_ATTACK_EXPLODE
|
else // SFG_MONSTER_ATTACK_EXPLODE
|
||||||
{
|
{
|
||||||
@ -2085,7 +2102,7 @@ void SFG_monsterPerformAI(SFG_MonsterRecord *monster)
|
|||||||
|
|
||||||
if ((coordAdd[0] != 0 || coordAdd[1] != 0) && SFG_random() <
|
if ((coordAdd[0] != 0 || coordAdd[1] != 0) && SFG_random() <
|
||||||
SFG_MONSTER_SOUND_PROBABILITY)
|
SFG_MONSTER_SOUND_PROBABILITY)
|
||||||
SFG_playSoundSafe(5,
|
SFG_playGameSound(5,
|
||||||
SFG_distantSoundVolume(
|
SFG_distantSoundVolume(
|
||||||
SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]),
|
SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]),
|
||||||
SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]),
|
SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]),
|
||||||
@ -2309,7 +2326,7 @@ void SFG_updateLevel()
|
|||||||
else if (p->type == SFG_PROJECTILE_BULLET)
|
else if (p->type == SFG_PROJECTILE_BULLET)
|
||||||
SFG_createDust(p->position[0],p->position[1],p->position[2]);
|
SFG_createDust(p->position[0],p->position[1],p->position[2]);
|
||||||
else if (p->type == SFG_PROJECTILE_PLASMA)
|
else if (p->type == SFG_PROJECTILE_PLASMA)
|
||||||
SFG_playSoundSafe(4,SFG_distantSoundVolume(pos[0],pos[1],pos[2]));
|
SFG_playGameSound(4,SFG_distantSoundVolume(pos[0],pos[1],pos[2]));
|
||||||
|
|
||||||
// remove the projectile
|
// remove the projectile
|
||||||
|
|
||||||
@ -2360,7 +2377,7 @@ void SFG_updateLevel()
|
|||||||
) ? SFG_DOOR_UP_DOWN_MASK : 0x00;
|
) ? SFG_DOOR_UP_DOWN_MASK : 0x00;
|
||||||
|
|
||||||
if (upDownState != newUpDownState)
|
if (upDownState != newUpDownState)
|
||||||
SFG_playSoundSafe(1,255);
|
SFG_playGameSound(1,255);
|
||||||
|
|
||||||
door->state = (door->state & ~SFG_DOOR_UP_DOWN_MASK) | newUpDownState;
|
door->state = (door->state & ~SFG_DOOR_UP_DOWN_MASK) | newUpDownState;
|
||||||
|
|
||||||
@ -2567,7 +2584,7 @@ void SFG_gameStepPlaying()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sound != 255)
|
if (sound != 255)
|
||||||
SFG_playSoundSafe(sound,255);
|
SFG_playGameSound(sound,255);
|
||||||
|
|
||||||
if (ammo != SFG_AMMO_NONE)
|
if (ammo != SFG_AMMO_NONE)
|
||||||
SFG_player.ammo[ammo] -= projectileCount;
|
SFG_player.ammo[ammo] -= projectileCount;
|
||||||
@ -2970,7 +2987,7 @@ void SFG_gameStepPlaying()
|
|||||||
SFG_removeItem(i);
|
SFG_removeItem(i);
|
||||||
SFG_player.lastItemTakenFrame = SFG_game.frame;
|
SFG_player.lastItemTakenFrame = SFG_game.frame;
|
||||||
i--;
|
i--;
|
||||||
SFG_playSoundSafe(3,255);
|
SFG_playGameSound(3,255);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
@ -3011,7 +3028,7 @@ void SFG_gameStepPlaying()
|
|||||||
|
|
||||||
SFG_player.justTeleported = 1;
|
SFG_player.justTeleported = 1;
|
||||||
|
|
||||||
SFG_playSoundSafe(4,255);
|
SFG_playGameSound(4,255);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3104,12 +3121,12 @@ void SFG_gameStepMenu()
|
|||||||
(SFG_game.selectedMenuItem < menuItems - 1))
|
(SFG_game.selectedMenuItem < menuItems - 1))
|
||||||
{
|
{
|
||||||
SFG_game.selectedMenuItem++;
|
SFG_game.selectedMenuItem++;
|
||||||
SFG_playSoundSafe(3,64);
|
SFG_playGameSound(3,64);
|
||||||
}
|
}
|
||||||
else if (SFG_keyRegisters(SFG_KEY_UP) && (SFG_game.selectedMenuItem > 0))
|
else if (SFG_keyRegisters(SFG_KEY_UP) && (SFG_game.selectedMenuItem > 0))
|
||||||
{
|
{
|
||||||
SFG_game.selectedMenuItem--;
|
SFG_game.selectedMenuItem--;
|
||||||
SFG_playSoundSafe(3,64);
|
SFG_playGameSound(3,64);
|
||||||
}
|
}
|
||||||
else if (SFG_keyJustPressed(SFG_KEY_A))
|
else if (SFG_keyJustPressed(SFG_KEY_A))
|
||||||
{
|
{
|
||||||
@ -3135,6 +3152,23 @@ void SFG_gameStepMenu()
|
|||||||
SFG_setGameState(SFG_GAME_STATE_MAP);
|
SFG_setGameState(SFG_GAME_STATE_MAP);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SFG_MENU_ITEM_SOUND:
|
||||||
|
SFG_LOG("sound changed");
|
||||||
|
|
||||||
|
SFG_game.soundSettings++;
|
||||||
|
SFG_playGameSound(3,64);
|
||||||
|
|
||||||
|
if ((SFG_game.soundSettings & 0x02) !=
|
||||||
|
((SFG_game.soundSettings - 1) & 0x02))
|
||||||
|
{
|
||||||
|
if (SFG_game.soundSettings & 0x02)
|
||||||
|
SFG_enableMusic(1);
|
||||||
|
else
|
||||||
|
SFG_enableMusic(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3145,12 +3179,12 @@ void SFG_gameStepMenu()
|
|||||||
(SFG_game.selectedLevel < SFG_NUMBER_OF_LEVELS - 1))
|
(SFG_game.selectedLevel < SFG_NUMBER_OF_LEVELS - 1))
|
||||||
{
|
{
|
||||||
SFG_game.selectedLevel++;
|
SFG_game.selectedLevel++;
|
||||||
SFG_playSoundSafe(3,64);
|
SFG_playGameSound(3,64);
|
||||||
}
|
}
|
||||||
else if (SFG_keyRegisters(SFG_KEY_LEFT) && SFG_game.selectedLevel > 0)
|
else if (SFG_keyRegisters(SFG_KEY_LEFT) && SFG_game.selectedLevel > 0)
|
||||||
{
|
{
|
||||||
SFG_game.selectedLevel--;
|
SFG_game.selectedLevel--;
|
||||||
SFG_playSoundSafe(3,64);
|
SFG_playGameSound(3,64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3625,12 +3659,29 @@ void SFG_drawMenu()
|
|||||||
|
|
||||||
SFG_drawText(text,drawX,y,SFG_FONT_SIZE_MEDIUM,textColor,0,0);
|
SFG_drawText(text,drawX,y,SFG_FONT_SIZE_MEDIUM,textColor,0,0);
|
||||||
|
|
||||||
if (item == SFG_MENU_ITEM_PLAY &&
|
if ((item == SFG_MENU_ITEM_PLAY || item == SFG_MENU_ITEM_SOUND) &&
|
||||||
(((i != SFG_game.selectedMenuItem) ||
|
((i != SFG_game.selectedMenuItem) ||
|
||||||
(SFG_game.frame / SFG_BLINK_PERIOD_FRAMES) % 2)))
|
((SFG_game.frame / SFG_BLINK_PERIOD_FRAMES) % 2)))
|
||||||
SFG_drawNumber((SFG_game.selectedLevel + 1),
|
{
|
||||||
drawX + SFG_characterSize(SFG_FONT_SIZE_MEDIUM) * (textLen + 1),
|
//uint8_t blink = (SFG_game.frame / SFG_BLINK_PERIOD_FRAMES) % 2;
|
||||||
y,SFG_FONT_SIZE_MEDIUM,93);
|
|
||||||
|
uint32_t x =
|
||||||
|
drawX + SFG_characterSize(SFG_FONT_SIZE_MEDIUM) * (textLen + 1);
|
||||||
|
|
||||||
|
uint8_t c = 93;
|
||||||
|
|
||||||
|
if (item == SFG_MENU_ITEM_PLAY)
|
||||||
|
SFG_drawNumber((SFG_game.selectedLevel + 1),x,y,SFG_FONT_SIZE_MEDIUM,c);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char settingText[3] = " ";
|
||||||
|
|
||||||
|
settingText[0] = (SFG_game.soundSettings & 0x01) ? 'S' : ' ';
|
||||||
|
settingText[1] = (SFG_game.soundSettings & 0x02) ? 'M' : ' ';
|
||||||
|
|
||||||
|
SFG_drawText(settingText,x,y,SFG_FONT_SIZE_MEDIUM,c,0,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
y += SFG_characterSize(SFG_FONT_SIZE_MEDIUM) + SFG_FONT_SIZE_MEDIUM;
|
y += SFG_characterSize(SFG_FONT_SIZE_MEDIUM) + SFG_FONT_SIZE_MEDIUM;
|
||||||
i++;
|
i++;
|
||||||
|
@ -188,16 +188,26 @@ static inline uint8_t addSamples(uint8_t sample1, uint8_t sample2)
|
|||||||
return mixed;
|
return mixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t musicOn = 1;
|
||||||
|
|
||||||
void audioFillCallback(void *userdata, uint8_t *s, int l)
|
void audioFillCallback(void *userdata, uint8_t *s, int l)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < l; ++i)
|
for (int i = 0; i < l; ++i)
|
||||||
{
|
{
|
||||||
s[i] = addSamples(audioBuff[audioPos],SFG_getNextMusicSample());
|
s[i] = musicOn ?
|
||||||
|
addSamples(audioBuff[audioPos],SFG_getNextMusicSample()) :
|
||||||
|
audioBuff[audioPos];
|
||||||
|
|
||||||
audioBuff[audioPos] = 127;
|
audioBuff[audioPos] = 127;
|
||||||
audioPos = (audioPos < SFG_SFX_SAMPLE_COUNT - 1) ? (audioPos + 1) : 0;
|
audioPos = (audioPos < SFG_SFX_SAMPLE_COUNT - 1) ? (audioPos + 1) : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SFG_enableMusic(uint8_t enable)
|
||||||
|
{
|
||||||
|
musicOn = enable;
|
||||||
|
}
|
||||||
|
|
||||||
void SFG_playSound(uint8_t soundIndex, uint8_t volume)
|
void SFG_playSound(uint8_t soundIndex, uint8_t volume)
|
||||||
{
|
{
|
||||||
uint8_t volumeStep = volume / 16;
|
uint8_t volumeStep = volume / 16;
|
||||||
|
19
sounds.h
19
sounds.h
@ -10,6 +10,9 @@
|
|||||||
|
|
||||||
by Miloslav Ciz (drummyfish), 2019
|
by Miloslav Ciz (drummyfish), 2019
|
||||||
|
|
||||||
|
Music is based on bytebeat (procedural waveforms generated by short bitwise
|
||||||
|
operation formulas).
|
||||||
|
|
||||||
Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/)
|
Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/)
|
||||||
plus a waiver of all other intellectual property. The goal of this work is
|
plus a waiver of all other intellectual property. The goal of this work is
|
||||||
be and remain completely in the public domain forever, available for any use
|
be and remain completely in the public domain forever, available for any use
|
||||||
@ -34,6 +37,7 @@
|
|||||||
|
|
||||||
struct
|
struct
|
||||||
{ // all should be initialized to 0
|
{ // all should be initialized to 0
|
||||||
|
// TODO: leave only those needed here
|
||||||
uint8_t track;
|
uint8_t track;
|
||||||
uint32_t t;
|
uint32_t t;
|
||||||
uint32_t t2;
|
uint32_t t2;
|
||||||
@ -42,13 +46,17 @@ struct
|
|||||||
uint32_t n7t;
|
uint32_t n7t;
|
||||||
} SFG_MusicState;
|
} SFG_MusicState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the next 8bit 8KHz music sample for the bytebeat soundtrack. This
|
||||||
|
function is to be used by the frontend that plays music.
|
||||||
|
*/
|
||||||
uint8_t SFG_getNextMusicSample()
|
uint8_t SFG_getNextMusicSample()
|
||||||
{
|
{
|
||||||
if (SFG_MusicState.t >= SFG_TRACK_SAMPLES)
|
if (SFG_MusicState.t >= SFG_TRACK_SAMPLES)
|
||||||
{
|
{
|
||||||
SFG_MusicState.track++;
|
SFG_MusicState.track++;
|
||||||
|
|
||||||
if (SFG_MusicState.track >= 3)
|
if (SFG_MusicState.track >= 4)
|
||||||
SFG_MusicState.track = 0;
|
SFG_MusicState.track = 0;
|
||||||
|
|
||||||
SFG_MusicState.t = 0;
|
SFG_MusicState.t = 0;
|
||||||
@ -64,7 +72,7 @@ uint8_t SFG_getNextMusicSample()
|
|||||||
#define t2 SFG_MusicState.t2
|
#define t2 SFG_MusicState.t2
|
||||||
#define n3t SFG_MusicState.n3t
|
#define n3t SFG_MusicState.n3t
|
||||||
|
|
||||||
switch (SFG_MusicState.track)
|
switch (SFG_MusicState.track) // individual music tracks
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
@ -82,6 +90,13 @@ uint8_t SFG_getNextMusicSample()
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
{
|
||||||
|
result =
|
||||||
|
~((((t >> (t >> 2)) | (t >> (t >> 5))) & 0x12) << 1) | (t >> 11);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3:
|
||||||
{
|
{
|
||||||
result =
|
result =
|
||||||
((((t >> (t >> 2)) + (t >> (t >> 7)))) & 0x3f | (t >> 5) | (t >> 11))
|
((((t >> (t >> 2)) + (t >> (t >> 7)))) & 0x3f | (t >> 5) | (t >> 11))
|
||||||
|
Loading…
Reference in New Issue
Block a user