From 487bd497458e89aaa81cf58660a477c17b653002 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sat, 15 Feb 2020 16:28:17 +0900 Subject: [PATCH] CD-DA BGM playback support with SDL_mixer This adds -playlist command line option to specify a "playlist" file which lists music files to be played instead of CD audio tracks. The format of playlist file is the same as xsystem35's. --- src/android/mako.cpp | 2 +- src/emscripten/mako.cpp | 2 +- src/sdlmain.cpp | 5 +- src/sys/mako.cpp | 123 ++++++++++++++++++---------------------- src/sys/mako.h | 24 +++----- src/sys/nact.cpp | 9 +-- src/sys/nact.h | 3 +- 7 files changed, 72 insertions(+), 96 deletions(-) diff --git a/src/android/mako.cpp b/src/android/mako.cpp index 31124f1..82d0053 100644 --- a/src/android/mako.cpp +++ b/src/android/mako.cpp @@ -3,7 +3,7 @@ #include #include "mako.h" -MAKO::MAKO(NACT* parent) +MAKO::MAKO(NACT* parent, const char* playlist) : current_music(0) , next_loop(0) { diff --git a/src/emscripten/mako.cpp b/src/emscripten/mako.cpp index f8e1c8d..f81dc2a 100644 --- a/src/emscripten/mako.cpp +++ b/src/emscripten/mako.cpp @@ -6,7 +6,7 @@ #include #include "mako.h" -MAKO::MAKO(NACT* parent) +MAKO::MAKO(NACT* parent, const char* playlist) : current_music(0) , next_loop(0) { diff --git a/src/sdlmain.cpp b/src/sdlmain.cpp index 4ab65c0..07e1fb4 100644 --- a/src/sdlmain.cpp +++ b/src/sdlmain.cpp @@ -36,6 +36,7 @@ int main(int argc, char *argv[]) g_window = SDL_CreateWindow(buf, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 400, flags); const char* font_file = DEFAULT_FONT_PATH "MTLc3m.ttf"; + const char* playlist = NULL; const char* game_id = NULL; char save_dir[256] = ""; @@ -48,12 +49,14 @@ int main(int argc, char *argv[]) strcpy(save_dir, argv[++i]); else if (strcmp(argv[i], "-fontfile") == 0) font_file = argv[++i]; + else if (strcmp(argv[i], "-playlist") == 0) + playlist = argv[++i]; else if (strcmp(argv[i], "-game") == 0) game_id = argv[++i]; } // system3 åˆ�期化 - NACT* nact = new NACT(game_id, font_file); + NACT* nact = new NACT(game_id, font_file, playlist); if (save_dir[0]) { #ifdef __ANDROID__ diff --git a/src/sys/mako.cpp b/src/sys/mako.cpp index 5cc15aa..5c5584a 100644 --- a/src/sys/mako.cpp +++ b/src/sys/mako.cpp @@ -16,27 +16,26 @@ #define MIX_INIT_MID MIX_INIT_FLUIDSYNTH #endif -MAKO::MAKO(NACT* parent) : nact(parent) +MAKO::MAKO(NACT* parent, const char* playlist) : + current_music(0), + next_loop(0), + nact(parent) { - // AMUS.DAT, AMSE.DAT + int mix_init_flags = MIX_INIT_MID; + + if (playlist && load_playlist(playlist)) + mix_init_flags |= MIX_INIT_MP3 | MIX_INIT_OGG; + _tcscpy_s(amus, 16, _T("AMUS.DAT")); _tcscpy_s(amse, 16, _T("AMSE.DAT")); // ŽÀ�ۂɂ͎g‚í‚È‚¢ - // �Ä�¶�ó‹µ - current_music = current_loop = 0; - current_max = next_loop = 0; - - // CD-DA for(int i = 1; i <= 99; i++) { cd_track[i] = 0; } - cdda_play = false; - if (Mix_Init(MIX_INIT_MID) != MIX_INIT_MID) { - WARNING("Mix_Init failed"); - } - if (Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 4096) < 0) { + if (Mix_Init(mix_init_flags) != mix_init_flags) + WARNING("Mix_Init(0x%x) failed", mix_init_flags); + if (Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 4096) < 0) WARNING("Mix_OpenAudio failed: %s", Mix_GetError()); - } } MAKO::~MAKO() @@ -44,34 +43,55 @@ MAKO::~MAKO() Mix_CloseAudio(); Mix_Quit(); - // PCM’âŽ~ #if defined(_USE_PCM) PlaySound(NULL, NULL, SND_PURGE); #endif } +bool MAKO::load_playlist(const char* path) +{ + FILE* fp = fopen(path, "rt"); + if (!fp) { + WARNING("Cannot open %s", path); + return false; + } + char buf[256]; + while (fgets(buf, sizeof(buf) - 1, fp)) { + char *p = &buf[strlen(buf) - 1]; + if (*p == '\n') + *p = '\0'; + playlist.push_back(buf[0] ? strdup(buf) : NULL); + } + fclose(fp); + return true; +} + void MAKO::play_music(int page) { - // Šù‚É“¯‚¶‹È‚ð�Ä�¶‚µ‚Ä‚¢‚é - if(current_music == page) { + if(current_music == page) return; - } stop_music(); - current_music = page; - current_max = next_loop; - - if(page < 100 && cd_track[page]) { - // CD-DA‚Å�Ä�¶ - // TODO: fix - // PostMessage(g_hwnd, WM_USER, cd_track[page] + 1, 0); - cdda_play = true; + int track = page < 100 ? cd_track[page] : 0; + if(track) { + if (track < playlist.size() && playlist[track]) { + mix_music = Mix_LoadMUS(playlist[track]); + if (!mix_music) { + WARNING("Mix_LoadMUS failed: %s: %s", playlist[track], Mix_GetError()); + return; + } + if (Mix_PlayMusic(mix_music, next_loop ? next_loop : -1) != 0) { + WARNING("Mix_PlayMusic failed: %s", Mix_GetError()); + Mix_FreeMusic(mix_music); + return; + } + } } else { MAKOMidi midi(nact, amus); if (midi.load_mml(page)) { midi.load_mda(page); - smf = midi.generate_smf(current_max); + smf = midi.generate_smf(next_loop); SDL_RWops *rwops = SDL_RWFromConstMem(smf.data(), smf.size()); mix_music = Mix_LoadMUSType_RW(rwops, MUS_MID, SDL_TRUE /* freesrc */); if (!mix_music) { @@ -80,67 +100,34 @@ void MAKO::play_music(int page) } if (Mix_PlayMusic(mix_music, -1) != 0) { WARNING("Mix_PlayMusic failed: %s", Mix_GetError()); + Mix_FreeMusic(mix_music); return; } } - cdda_play = false; } + current_music = page; } void MAKO::stop_music() { - // Œ»�Ý�Ä�¶’†‚Ì�ê�‡‚Í’âŽ~‚·‚é - if(current_music) { - if(cdda_play) { - // TODO: fix - // PostMessage(g_hwnd, WM_USER, 0, 0); - } else { - if (mix_music) { - Mix_FreeMusic(mix_music); - mix_music = NULL; - smf.clear(); - } - } + if (mix_music) { + Mix_FreeMusic(mix_music); + mix_music = NULL; + smf.clear(); } - cdda_play = false; - current_music = current_loop = 0; + current_music = 0; } bool MAKO::check_music() { - // �Ä�¶’†‚Åtrue - if (!current_music) - return false; - if (mix_music) - return Mix_PlayingMusic(); - return true; + return Mix_PlayingMusic(); } void MAKO::get_mark(int* mark, int* loop) { // TODO: fix *mark = 0; - *loop = cdda_play ? 0 : current_loop; -} - -void MAKO::notify_mci(int status) -{ - if(status == -1) { - // �Ä�¶‚ÉŽ¸”s - current_music = current_loop = 0; - return; - } - - if(cdda_play) { - current_loop++; - if(current_loop < current_max || current_max == 0) { - // TODO: fix - // PostMessage(g_hwnd, WM_USER, cd_track[current_music] + 1, 0); - } else { - current_music = current_loop = 0; - cdda_play = false; - } - } + *loop = 0; } void MAKO::play_pcm(int page, bool loop) diff --git a/src/sys/mako.h b/src/sys/mako.h index c7278de..fa3317b 100644 --- a/src/sys/mako.h +++ b/src/sys/mako.h @@ -23,27 +23,14 @@ class MAKO { -protected: - NACT* nact; - -private: - // FM, CD-DA - bool cdda_play; - int current_loop; - int current_max; // Y19 - - // PCM - char wav[MAX_SAMPLES]; - public: - MAKO(NACT* parent); + MAKO(NACT* parent, const char* playlist); ~MAKO(); void play_music(int page); void stop_music(); bool check_music(); void get_mark(int* mark, int* loop); - void notify_mci(int status); void play_pcm(int page, bool loop); void stop_pcm(); @@ -62,22 +49,27 @@ public: int current_music; int next_loop; // Y19 int cd_track[100]; // Z + private: + bool load_playlist(const char* path); + + NACT* nact; + std::vector playlist; Mix_Music *mix_music; std::vector smf; + char wav[MAX_SAMPLES]; }; #else // Emscripten or Android class MAKO { public: - MAKO(NACT* parent); + MAKO(NACT* parent, const char* playlist); void play_music(int page); void stop_music(); bool check_music() { return current_music != 0; } void get_mark(int* mark, int* loop) {} - void notify_mci(int status) {} void play_pcm(int page, bool loop) {} void stop_pcm() {} diff --git a/src/sys/nact.cpp b/src/sys/nact.cpp index e28492a..fb1bd6f 100644 --- a/src/sys/nact.cpp +++ b/src/sys/nact.cpp @@ -16,7 +16,7 @@ extern SDL_Window* g_window; // �‰Šú‰» -NACT::NACT(const char* game_id, const char* font_file) +NACT::NACT(const char* game_id, const char* font_file, const char* playlist) { mouse_x = mouse_y = 0; @@ -114,7 +114,7 @@ NACT::NACT(const char* game_id, const char* font_file) // ŠeŽíƒNƒ‰ƒX�¶�¬ ags = new AGS(this, font_file); - mako = new MAKO(this); + mako = new MAKO(this, playlist); #ifdef USE_JOY // “ü—Í�‰Šú‰» @@ -409,11 +409,6 @@ int NACT::get_screen_height() return ags->screen_height; } -void NACT::notify_mci(int status) -{ - mako->notify_mci(status); -} - void NACT::select_cursor() { ags->select_cursor(); diff --git a/src/sys/nact.h b/src/sys/nact.h index e5985b7..df20a5c 100644 --- a/src/sys/nact.h +++ b/src/sys/nact.h @@ -231,13 +231,12 @@ private: void release_console(); public: - NACT(const char* game_id, const char* font_file); + NACT(const char* game_id, const char* font_file, const char* playlist); ~NACT(); void mainloop(); int get_screen_height(); - void notify_mci(int status); void select_cursor(); void select_sound(int dev);