mirror of
https://github.com/kichikuou/system3-sdl2.git
synced 2026-10-03 20:38:13 +03:00
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.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
#include <jni.h>
|
||||
#include "mako.h"
|
||||
|
||||
MAKO::MAKO(NACT* parent)
|
||||
MAKO::MAKO(NACT* parent, const char* playlist)
|
||||
: current_music(0)
|
||||
, next_loop(0)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <emscripten.h>
|
||||
#include "mako.h"
|
||||
|
||||
MAKO::MAKO(NACT* parent)
|
||||
MAKO::MAKO(NACT* parent, const char* playlist)
|
||||
: current_music(0)
|
||||
, next_loop(0)
|
||||
{
|
||||
|
||||
+4
-1
@@ -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__
|
||||
|
||||
+55
-68
@@ -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")); // 実際には使わない
|
||||
|
||||
// 再生状況
|
||||
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) {
|
||||
// 再生に失敗
|
||||
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)
|
||||
|
||||
+8
-16
@@ -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<const char*> playlist;
|
||||
Mix_Music *mix_music;
|
||||
std::vector<uint8> 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() {}
|
||||
|
||||
+2
-7
@@ -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)
|
||||
|
||||
// 各種クラス生成
|
||||
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();
|
||||
|
||||
+1
-2
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user