/// <summary> /// mpegファイルを読み込む /// </summary> /// <param name="filename">ファイル名</param> public YanesdkResult Load(string filename) { lock (lockObject) { Release(); tmpFile = FileSys.GetTmpFile(filename); if (tmpFile == null || tmpFile.FileName == null) { return(YanesdkResult.FileNotFound); } // 読み込み。 //mpeg = SMPEG.SMPEG_new(tmpFile.FileName, ref info, SDL.SDL_WasInit(SDL.SDL_INIT_AUDIO) == 0 ? 1 : 0); mpeg = SMPEG.SMPEG_new(tmpFile.FileName, ref info, 0); if (SMPEG.SMPEG_error(mpeg) != null) { Debug.Fail(SMPEG.SMPEG_error(mpeg)); return(YanesdkResult.SdlError); // …SDL? } // 初期設定 // loop = false; // ループ設定はここでは変更しないほうが良い。 paused = false; SMPEG.SMPEG_enablevideo(mpeg, 1); SMPEG.SMPEG_enableaudio(mpeg, 0); if (info.has_audio != 0) { SDL.SDL_AudioSpec audiofmt = new SDL.SDL_AudioSpec(); audiofmt.format = (ushort)Sound.Sound.SoundConfig.AudioFormat; audiofmt.freq = (ushort)Sound.Sound.SoundConfig.AudioRate; audiofmt.channels = (byte)Sound.Sound.SoundConfig.AudioChannels; audiofmt.samples = (ushort)Sound.Sound.SoundConfig.AudioBuffers; SMPEG.SMPEG_actualSpec(mpeg, ref audiofmt); SDL.Mix_HookMusic(mix_hook, mpeg); SMPEG.SMPEG_enableaudio(mpeg, 1); } SMPEG.SMPEG_enableaudio(mpeg, 1); Volume = volume; // 描画先サーフェスのsmpegへの登録など。 if (window != null) { // SDLWindowに直に描画する if (surface != null) { surface.Dispose(); surface = null; } uint flags = (uint)window.Option; flags &= ~SDL.SDL_OPENGL; // OPENGLはダメ。 IntPtr s = SDL.SDL_SetVideoMode(window.Width, window.Height, window.Bpp, flags); if (s == IntPtr.Zero) { return(YanesdkResult.SdlError); } SMPEG.SMPEG_setdisplay(mpeg, s, IntPtr.Zero, null); SMPEG.SMPEG_move(mpeg, (int)windowRect.Left, (int)windowRect.Top); SMPEG.SMPEG_scaleXY(mpeg, (int)windowRect.Width, (int)windowRect.Height); } else if ( Yanesdk.System.Platform.PlatformID == Yanesdk.System.PlatformID.Windows && hwnd != IntPtr.Zero) { // SDLWindowを貼り付けてそれに描画する if (surface != null) { surface.Dispose(); surface = null; } // 親ウィンドウの位置・サイズを取得 POINT parentPos = new POINT(); ClientToScreen(hwnd, ref parentPos); RECT parentRect = new RECT(); GetClientRect(hwnd, out parentRect); int w = parentRect.right - parentRect.left, h = parentRect.bottom - parentRect.top; // SDLウィンドウの位置を合わせる IntPtr sdlHwnd = GetSDLWindowHandle(); //SetParent(sdlHwnd, hwnd); // これするとどうもバグる… SetWindowPos(sdlHwnd, IntPtr.Zero, parentPos.x, parentPos.y, w, h, SWP_NOZORDER); // SDLウィンドウの作成 uint flags = SDL.SDL_HWSURFACE | SDL.SDL_NOFRAME; IntPtr s = SDL.SDL_SetVideoMode(w, h, 0, flags); if (s == IntPtr.Zero) { return(YanesdkResult.SdlError); } sdlWindowCreated = true; sdlHwnd = GetSDLWindowHandle(); // 変わらないと思うが、一応再取得 if (sdlHwnd == IntPtr.Zero) { return(YanesdkResult.SdlError); } SetParent(sdlHwnd, hwnd); SetWindowPos(sdlHwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE); SMPEG.SMPEG_setdisplay(mpeg, s, IntPtr.Zero, null); SMPEG.SMPEG_move(mpeg, 0, 0); SMPEG.SMPEG_scaleXY(mpeg, w, h); } else { // surfaceに描画する if (surface != null && (!surface.CheckRGB888() || surface.Width != Width || surface.Height != Height)) { surface.Dispose(); surface = null; } if (surface == null) { surface = new Surface(); // 拡大・縮小はSMPEG側にやらせると重いので、原寸大で。 YanesdkResult result = surface.CreateDIB(Width, Height, false); if (result != YanesdkResult.NoError) { return(result); } } SMPEG.SMPEG_setdisplay(mpeg, surface.SDL_Surface, mutex, callback); SMPEG.SMPEG_move(mpeg, 0, 0); SMPEG.SMPEG_scaleXY(mpeg, surface.Width, surface.Height); //SetFilter(SMPEG.SMPEGfilter_null()); } this.fileName = filename; // おしまい。 return(YanesdkResult.NoError); } }
/// <summary> /// ファイル(wav,ogg,mid)の読み込み。 /// ここで読み込んだものは、bgmとして再生される /// </summary> /// <param name="filename"></param> /// <returns></returns> private YanesdkResult LoadMusic(string filename) { if (NoSound) { return(YanesdkResult.PreconditionError); } tmpFile = FileSys.GetTmpFile(filename); string f = tmpFile.FileName; YanesdkResult result; if (f != null) { music = SDL.Mix_LoadMUS(f); // Debug.Fail(SDL.Mix_GetError()); // ここでmusic == 0が返ってくるのは明らかにおかしい。 // smpeg.dllがないのに mp3を再生しようとしただとか? if (music == IntPtr.Zero) { result = YanesdkResult.HappenSomeError; } else { result = YanesdkResult.NoError; } } else { result = YanesdkResult.FileNotFound; // file not found } // music = Mix_LoadMUS_RW(rwops,1); // この関数なんでないかなーヽ(´Д`)ノ // ↑については↓と教えていただきました。 // この関数は SDL_mixer をコンパイルするときに // "USE_RWOPS" プリプロセッサ定義を追加すると使えるようです。 // http://ilaliart.sourceforge.jp/tips/mix_rwops.html // 最新のSDL_mixerならばあるらしい。 // ここで、注意して欲しいのは、Mix_LoadMUS_RW関数でMix_Musicオブジェクトを生成しても // すぐにSDL_RWclose関数でSDL_RWopsオブジェクトを開放していないことである。 // Mix_Musicオブジェクトはストリーミング再生されるため、常にファイルを開いた状態でなければならない。 // そのため、SDL_RWcloseでロード後にすぐにファイルを閉じてしまった場合、Mix_PlayMusic関数で再生に失敗してしまう。 // そのため、再生に用いるSDL_RWopsオブジェクトは再生停止後に破棄する必要がある。 /* * SDL_RWopsH rwops = FileSys.ReadRW(filename); * if (rwops.Handle != IntPtr.Zero) * { * music = SDL.Mix_LoadMUS_RW(rwops.Handle); * // ↑このときrwopsをどこかで解放する必要あり * * } * else * { * return YanesdkResult.FileNotFound; // file not found * } * * if (music == IntPtr.Zero) { * return YanesdkResult.SdlError; * } */ // MacOSやmp3再生だと対応してないっぽいので、やっぱりこれ使うのやめ if (result == YanesdkResult.NoError) { this.fileName = filename; CacheSystem.OnResourceChanged(this); } return(result); }