Briefing menu music (fixes #574)

This commit is contained in:
Cong Xu
2019-06-22 21:40:22 +10:00
parent 7b46eabf64
commit 7adc769b5b
20 changed files with 159 additions and 145 deletions

Binary file not shown.

View File

@@ -0,0 +1,6 @@
Dynamic Action Music Pack
ViRiX
soundcloud.com/virix
https://opengameart.org/content/dynamic-action-music-pack
http://creativecommons.org/licenses/by/3.0/

Binary file not shown.

View File

@@ -0,0 +1,6 @@
Futuristic_junk
Alexandr Zhelanov
https://soundcloud.com/alexandr-zhelanov
https://opengameart.org/content/futuristicjunk
http://creativecommons.org/licenses/by/3.0/

View File

@@ -0,0 +1 @@
Add music here to have them play in briefing menus

Binary file not shown.

View File

@@ -0,0 +1,5 @@
The 9th Circle
Joth
https://opengameart.org/content/the-9th-circle
http://creativecommons.org/publicdomain/zero/1.0/

BIN
music/menu/Battle_2.ogg Normal file

Binary file not shown.

5
music/menu/Battle_2.txt Normal file
View File

@@ -0,0 +1,5 @@
Reencoded from Post Apocalyptic and CyberPunk Melodies by Alexandr Zhelanov
Alexandr Zhelanov https://soundcloud.com/alexandr-zhelanov
https://opengameart.org/content/post-apocalyptic-and-cyberpunk-melodies
https://creativecommons.org/licenses/by/4.0/

View File

@@ -31,6 +31,7 @@
#include <cdogs/files.h>
#include <cdogs/font.h>
#include <cdogs/grafx_bg.h>
#include <cdogs/music.h>
#include <cdogs/objective.h>
#include "animated_counter.h"
@@ -51,6 +52,7 @@ typedef struct
const CampaignSetting *c;
} ScreenCampaignIntroData;
static void CampaignIntroTerminate(GameLoopData *data);
static void CampaignIntroOnEnter(GameLoopData *data);
static void CampaignIntroOnExit(GameLoopData *data);
static void CampaignIntroInput(GameLoopData *data);
static GameLoopResult CampaignIntroUpdate(GameLoopData *data, LoopRunner *l);
@@ -61,7 +63,7 @@ GameLoopData *ScreenCampaignIntro(CampaignSetting *c)
CMALLOC(data, sizeof *data);
data->c = c;
return GameLoopDataNew(
data, CampaignIntroTerminate, NULL, CampaignIntroOnExit,
data, CampaignIntroTerminate, CampaignIntroOnEnter, CampaignIntroOnExit,
CampaignIntroInput, CampaignIntroUpdate, CampaignIntroDraw);
}
static void CampaignIntroTerminate(GameLoopData *data)
@@ -69,6 +71,11 @@ static void CampaignIntroTerminate(GameLoopData *data)
ScreenCampaignIntroData *mData = data->Data;
CFREE(mData);
}
static void CampaignIntroOnEnter(GameLoopData *data)
{
UNUSED(data);
MusicPlay(&gSoundDevice, MUSIC_BRIEFING, NULL, NULL);
}
static void CampaignIntroOnExit(GameLoopData *data)
{
const ScreenCampaignIntroData *sData = data->Data;
@@ -432,6 +439,8 @@ static void MissionSummaryOnEnter(GameLoopData *data)
{
MissionSummaryData *mData = data->Data;
MusicPlay(&gSoundDevice, MUSIC_BRIEFING, NULL, NULL);
if (mData->completed)
{
// Save password

View File

@@ -195,10 +195,6 @@ int main(int argc, char *argv[])
LOG(LM_MAIN, LL_ERROR, "Sound initialization failed!");
}
LoadSongs();
MusicPlayMenu(&gSoundDevice);
EventInit(&gEventHandlers, NULL, NULL, true);
NetServerInit(&gNetServer);
PicManagerInit(&gPicManager);
@@ -296,8 +292,6 @@ bail:
AutosaveSave(&gAutosave, GetConfigFilePath(AUTOSAVE_FILE));
AutosaveTerminate(&gAutosave);
PlayerTemplatesTerminate(&gPlayerTemplates);
FreeSongs(&gMenuSongs);
FreeSongs(&gGameSongs);
SoundTerminate(&gSoundDevice, true);
ConfigDestroy(&gConfig);
LogTerminate();

View File

@@ -145,91 +145,6 @@ void MissionOptionsTerminate(struct MissionOptions *mo)
}
void LoadSongList(struct SongDef **songList, const char *dirPath);
void AddSong(struct SongDef **songList, const char *path)
{
struct SongDef *s;
CMALLOC(s, sizeof(struct SongDef));
strcpy(s->path, path);
s->next = *songList;
*songList = s;
}
void ShiftSongs(struct SongDef **songList)
{
struct SongDef **h;
if (!*songList || !(*songList)->next)
return;
h = songList;
while (*h)
h = &(*h)->next;
*h = *songList;
*songList = (*songList)->next;
(*h)->next = NULL;
}
void FreeSongs(struct SongDef **songList)
{
struct SongDef *s;
while (*songList) {
s = *songList;
*songList = s->next;
CFREE(s);
}
}
void LoadSongs(void)
{
LoadSongList(&gGameSongs, "music/game");
LoadSongList(&gMenuSongs, "music/menu");
}
void LoadSongList(struct SongDef **songList, const char *dirPath)
{
tinydir_dir dir;
char buf[CDOGS_PATH_MAX];
GetDataFilePath(buf, dirPath);
if (tinydir_open(&dir, buf) == -1)
{
LOG(LM_MAIN, LL_ERROR, "Cannot open music dir %s: %s",
buf, strerror(errno));
goto bail;
}
for (; dir.has_next; tinydir_next(&dir))
{
Mix_Music *m;
tinydir_file file;
if (tinydir_readfile(&dir, &file) == -1)
{
goto bail;
}
if (!file.is_reg)
{
continue;
}
m = MusicLoad(file.path);
if (m == NULL)
{
continue;
}
Mix_FreeMusic(m);
AddSong(songList, file.path);
}
bail:
tinydir_close(&dir);
}
bool GameIsMouseUsed(void)
{
CA_FOREACH(const PlayerData, p, gPlayerDatas)

View File

@@ -67,19 +67,6 @@
extern struct MissionOptions gMission;
struct SongDef {
char path[255];
struct SongDef *next;
};
extern struct SongDef *gGameSongs;
extern struct SongDef *gMenuSongs;
void AddSong(struct SongDef **songList, const char *path);
void ShiftSongs(struct SongDef **songList);
void FreeSongs(struct SongDef **songList);
void LoadSongs(void);
bool CampaignLoad(CampaignOptions *co, CampaignEntry *entry);
void CampaignUnload(CampaignOptions *co);

View File

@@ -427,7 +427,8 @@ void MissionBegin(struct MissionOptions *m, const NGameBegin gb)
{
m->HasBegun = true;
m->state = MISSION_STATE_PLAY;
MusicPlayGame(&gSoundDevice, gCampaign.Entry.Path, m->missionData->Song);
MusicPlay(
&gSoundDevice, MUSIC_GAME, gCampaign.Entry.Path, m->missionData->Song);
if (MusicGetStatus(&gSoundDevice) == MUSIC_NOLOAD)
{
// Display music error message for 2 seconds

View File

@@ -2,7 +2,7 @@
C-Dogs SDL
A port of the legendary (and fun) action/arcade cdogs.
Copyright (c) 2013-2016, Cong Xu
Copyright (c) 2013-2016, 2019 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -60,20 +60,8 @@ Mix_Music *MusicLoad(const char *path)
return Mix_LoadMUS(path);
}
static bool MusicPlay(SoundDevice *device, const char *path)
static bool PlayMusic(SoundDevice *device)
{
if (!device->isInitialised)
{
return true;
}
if (path == NULL || strlen(path) == 0)
{
LOG(LM_SOUND, LL_WARN, "Attempting to play song with empty name");
return false;
}
device->music = MusicLoad(path);
if (device->music == NULL)
{
strcpy(device->musicErrorMessage, SDL_GetError());
@@ -94,13 +82,32 @@ static bool MusicPlay(SoundDevice *device, const char *path)
return true;
}
void MusicPlayGame(
SoundDevice *device, const char *missionPath, const char *music)
static bool Play(SoundDevice *device, const char *path)
{
if (!device->isInitialised)
{
return true;
}
if (path == NULL || strlen(path) == 0)
{
LOG(LM_SOUND, LL_WARN, "Attempting to play song with empty name");
return false;
}
device->music = MusicLoad(path);
return PlayMusic(device);
}
void MusicPlay(
SoundDevice *device, const MusicType type,
const char *missionPath, const char *music)
{
// Play a tune
// Start by trying to play a mission specific song,
// otherwise pick one from the general collection...
MusicStop(device);
device->musicIsDynamic = false;
bool played = false;
if (music != NULL && strlen(music) != 0)
{
@@ -110,29 +117,37 @@ void MusicPlayGame(
GetDataFilePath(buf, missionPath);
strcat(buf, "/");
strcat(buf, music);
played = MusicPlay(device, buf);
played = Play(device, buf);
if (!played)
{
char buf2[CDOGS_PATH_MAX];
GetDataFilePath(buf2, missionPath);
PathGetDirname(buf, buf2);
strcat(buf, music);
played = MusicPlay(device, buf);
played = Play(device, buf);
}
if (played)
{
device->musicIsDynamic = true;
}
}
if (!played && gGameSongs != NULL)
if (!played)
{
MusicPlay(device, gGameSongs->path);
ShiftSongs(&gGameSongs);
}
}
void MusicPlayMenu(SoundDevice *device)
{
MusicStop(device);
if (gMenuSongs)
{
MusicPlay(device, gMenuSongs->path);
ShiftSongs(&gMenuSongs);
CArray *tracks = &device->musicTracks[type];
if (tracks->size == 0)
{
return;
}
device->music = *(Mix_Music **)CArrayGet(tracks, 0);
// Shuffle tracks
if (tracks->size > 1)
{
while (device->music == *(Mix_Music **)CArrayGet(tracks, 0))
{
CArrayShuffle(tracks);
}
}
PlayMusic(device);
}
}
@@ -141,7 +156,10 @@ void MusicStop(SoundDevice *device)
if (device->music != NULL)
{
Mix_HaltMusic();
Mix_FreeMusic(device->music);
if (device->musicIsDynamic)
{
Mix_FreeMusic(device->music);
}
device->music = NULL;
}
}

View File

@@ -22,7 +22,7 @@
This file incorporates work covered by the following copyright and
permission notice:
Copyright (c) 2013, 2016-2017 Cong Xu
Copyright (c) 2013, 2016-2017, 2019 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -52,9 +52,9 @@
Mix_Music *MusicLoad(const char *path);
void MusicPlayGame(
SoundDevice *device, const char *missionPath, const char *music);
void MusicPlayMenu(SoundDevice *device);
void MusicPlay(
SoundDevice *device, const MusicType type,
const char *missionPath, const char *music);
void MusicStop(SoundDevice *device);
void MusicPause(SoundDevice *device);
void MusicResume(SoundDevice *device);

View File

@@ -22,7 +22,7 @@
This file incorporates work covered by the following copyright and
permission notice:
Copyright (c) 2013-2017 Cong Xu
Copyright (c) 2013-2017, 2019 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -182,6 +182,7 @@ static void AddSound(map_t sounds, const char *name, SoundData *sound)
}
}
static void SoundLoadMusic(CArray *tracks, const char *path);
void SoundInitialize(SoundDevice *device, const char *path)
{
memset(device, 0, sizeof *device);
@@ -198,6 +199,11 @@ void SoundInitialize(SoundDevice *device, const char *path)
char buf[CDOGS_PATH_MAX];
GetDataFilePath(buf, path);
SoundLoadDir(device->sounds, buf, NULL);
// Load music
SoundLoadMusic(&device->musicTracks[MUSIC_MENU], "music/menu");
SoundLoadMusic(&device->musicTracks[MUSIC_BRIEFING], "music/briefing");
SoundLoadMusic(&device->musicTracks[MUSIC_GAME], "music/game");
}
void SoundLoadDir(map_t sounds, const char *path, const char *prefix)
{
@@ -242,6 +248,43 @@ void SoundLoadDir(map_t sounds, const char *path, const char *prefix)
}
}
bail:
tinydir_close(&dir);
}
static void SoundLoadMusic(CArray *tracks, const char *path)
{
CArrayInit(tracks, sizeof(Mix_Music *));
tinydir_dir dir;
char buf[CDOGS_PATH_MAX];
GetDataFilePath(buf, path);
if (tinydir_open(&dir, buf) == -1)
{
LOG(LM_MAIN, LL_ERROR, "Cannot open music dir %s: %s",
buf, strerror(errno));
goto bail;
}
for (; dir.has_next; tinydir_next(&dir))
{
Mix_Music *m;
tinydir_file file;
if (tinydir_readfile(&dir, &file) == -1)
{
goto bail;
}
if (!file.is_reg)
{
continue;
}
m = MusicLoad(file.path);
if (m == NULL)
{
continue;
}
CArrayPushBack(tracks, &m);
}
bail:
tinydir_close(&dir);
}
@@ -274,6 +317,7 @@ void SoundClear(map_t sounds)
{
hashmap_clear(sounds, SoundDataTerminate);
}
static void SoundUnloadMusic(CArray *tracks);
void SoundTerminate(SoundDevice *device, const bool waitForSoundsComplete)
{
if (!device->isInitialised)
@@ -296,6 +340,11 @@ void SoundTerminate(SoundDevice *device, const bool waitForSoundsComplete)
hashmap_destroy(device->sounds, SoundDataTerminate);
hashmap_destroy(device->customSounds, SoundDataTerminate);
for (MusicType type = MUSIC_MENU; type < MUSIC_COUNT; type++)
{
SoundUnloadMusic(&device->musicTracks[type]);
}
}
static void SoundDataTerminate(any_t data)
{
@@ -317,6 +366,13 @@ static void SoundDataTerminate(any_t data)
}
CFREE(s);
}
static void SoundUnloadMusic(CArray *tracks)
{
CA_FOREACH(Mix_Music *, m, *tracks)
Mix_FreeMusic(*m);
CA_FOREACH_END()
CArrayTerminate(tracks);
}
#define OUT_OF_SIGHT_DISTANCE_PLUS 100
static int GetChannel(SoundDevice *s, Mix_Chunk *data);

View File

@@ -22,7 +22,7 @@
This file incorporates work covered by the following copyright and
permission notice:
Copyright (c) 2013-2017 Cong Xu
Copyright (c) 2013-2017, 2019 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -93,10 +93,20 @@ typedef enum
MUSIC_PAUSED
} music_status_e;
typedef enum
{
MUSIC_MENU,
MUSIC_BRIEFING,
MUSIC_GAME,
MUSIC_COUNT
} MusicType;
typedef struct
{
int isInitialised;
Mix_Music *music;
bool musicIsDynamic;
CArray musicTracks[MUSIC_COUNT]; // of Mix_Music *
music_status_e musicStatus;
char musicErrorMessage[128];
int channels;

View File

@@ -321,8 +321,6 @@ static void RunGameOnExit(GameLoopData *data)
p->hp = player->health;
}
CA_FOREACH_END()
MusicPlayMenu(&gSoundDevice);
}
static void RunGameInput(GameLoopData *data)
{

View File

@@ -32,6 +32,7 @@
#include <cdogs/font.h>
#include <cdogs/grafx_bg.h>
#include <cdogs/log.h>
#include <cdogs/music.h>
#include <cdogs/net_client.h>
#include <cdogs/net_server.h>
@@ -103,6 +104,8 @@ static void MainMenuOnEnter(GameLoopData *data)
return;
}
MusicPlay(&gSoundDevice, MUSIC_MENU, NULL, NULL);
MainMenuReset(&mData->ms);
NetClientDisconnect(&gNetClient);
NetServerClose(&gNetServer);