OSDN Git Service

Musicの追加
authorangeart <angeart@git.sourceforge.jp>
Sat, 22 Sep 2012 06:56:45 +0000 (15:56 +0900)
committerangeart <angeart@git.sourceforge.jp>
Sat, 22 Sep 2012 06:56:45 +0000 (15:56 +0900)
13 files changed:
client/Card.cpp
client/Card.hpp
client/GenerateJSON.cpp
client/MiniMap.cpp
client/Music.cpp [new file with mode: 0644]
client/Music.hpp [new file with mode: 0644]
client/PlayerManager.cpp
client/ResourceManager.cpp
client/ResourceManager.hpp
client/bin/cards/bgmlist/main.js [new file with mode: 0644]
client/scene/Init.cpp
client/scene/MainLoop.cpp
client/version.hpp

index ddbc973..d42c976 100644 (file)
@@ -21,6 +21,8 @@
 #include "../common/database/AccountProperty.hpp"\r
 #include "Profiler.hpp"\r
 #include "GenerateJSON.hpp"\r
+#include "Music.hpp"\r
+\r
 \r
 char Card::STORAGE_DIR[] = "storage";\r
 char Card::SCRIPT_PATH[] = "resources/js";\r
@@ -77,6 +79,7 @@ Card::Card(
         context->Global()->Set(String::New("Network"),  script_object->Clone());\r
         context->Global()->Set(String::New("Player"),  script_object->Clone());\r
         context->Global()->Set(String::New("Account"), script_object->Clone());\r
+        context->Global()->Set(String::New("Music"),  script_object->Clone());\r
         context->Global()->Set(String::New("InputBox"),   script_object->Clone());\r
         context->Global()->Set(String::New("Card"),    script_object->Clone());\r
         context->Global()->Set(String::New("Screen"),  script_object->Clone());\r
@@ -221,6 +224,78 @@ Handle<Value> Card::Function_Player_stopMotion(const Arguments& args)
     return Undefined();\r
 }\r
 \r
+Handle<Value> Card::Function_Music_playBGM(const Arguments& args)\r
+{\r
+\r
+       if (args.Length() >= 2 && args[0]->IsString()) {\r
+               auto name = std::string(*String::Utf8Value(args[0]->ToString()));\r
+               auto fade = args[1]->ToBoolean()->BooleanValue();\r
+               ResourceManager::music()->Play(unicode::ToTString(name),fade);\r
+       }\r
+\r
+    return Undefined();\r
+}\r
+\r
+Handle<Value> Card::Function_Music_stopBGM(const Arguments& args)\r
+{\r
+\r
+       if (args.Length() == 1 && args[0]->IsBoolean()) {\r
+               auto fade = args[1]->ToBoolean()->BooleanValue();\r
+               ResourceManager::music()->Stop(fade);\r
+       }else if(args.Length() == 0) {\r
+               ResourceManager::music()->Stop(false);\r
+       }\r
+\r
+    return Undefined();\r
+}\r
+\r
+Handle<Value> Card::Function_Music_playME(const Arguments& args)\r
+{\r
+\r
+       if (args.Length() == 1 && args[0]->IsString()) {\r
+               auto name = std::string(*String::Utf8Value(args[0]->ToString()));\r
+               ResourceManager::music()->PlayME(unicode::ToTString(name));\r
+       }\r
+\r
+    return Undefined();\r
+}\r
+\r
+\r
+Handle<Value> Card::Function_Music_playSE(const Arguments& args)\r
+{\r
+\r
+       if (args.Length() == 1 && args[0]->IsString()) {\r
+               auto name = std::string(*String::Utf8Value(args[0]->ToString()));\r
+               ResourceManager::music()->PlaySE(unicode::ToTString(name));\r
+       }\r
+\r
+    return Undefined();\r
+}\r
+\r
+Handle<Value> Card::Function_Music_all(const Arguments& args)\r
+{\r
+    HandleScope handle;\r
+    auto array = Array::New();\r
+\r
+    int i = 0;\r
+       BOOST_FOREACH(const boost::filesystem::path& music_path, ResourceManager::music()->GetMusicList()) {\r
+               array->Set(i, String::New(music_path.stem().string().c_str()));\r
+        i++;\r
+    }\r
+    return array;\r
+}\r
+\r
+\r
+Handle<Value> Card::Function_Music_IsLoadingDone(const Arguments& args)\r
+{\r
+       if (args.Length() == 1 && args[0]->IsString()) {\r
+       auto name = std::string(*String::Utf8Value(args[0]->ToString()));\r
+       auto check = ResourceManager::music()->CheckLoadedBGM(unicode::ToTString(name));\r
+       return Boolean::New(check);\r
+       }\r
+       return Boolean::New(false);\r
+}\r
+\r
 Handle<Value> Card::Function_Account_id(const Arguments& args)\r
 {\r
     auto self = static_cast<Card*>(args.Holder()->GetPointerFromInternalField(0));\r
@@ -283,6 +358,7 @@ Handle<Value> Card::Function_Account_updateModelName(const Arguments& args)
         auto name = std::string(*String::Utf8Value(args[0]->ToString()));\r
         if (auto world_manager = self->manager_accessor_->world_manager().lock()) {\r
             world_manager->myself()->LoadModel(unicode::ToTString(name));\r
+                       world_manager->myself()->ResetMotion();\r
         }\r
         auto account_manager = self->manager_accessor_->account_manager().lock();\r
         auto command_manager = self->manager_accessor_->command_manager().lock();\r
@@ -650,7 +726,62 @@ void Card::SetFunctions()
      * @static\r
      */\r
     script_.SetFunction("Player.stopMotion", Function_Player_stopMotion);\r
+\r
+    /**\r
+     * 音楽を再生します\r
+     *\r
+     * @method playMotion\r
+     * @param {String} name BGM名\r
+     * @static\r
+     */\r
+    script_.SetFunction("Music.play", Function_Music_playBGM);\r
+\r
     /**\r
+     * 音楽を停止します\r
+     *\r
+     * @method playMotion\r
+     * @param\r
+     * @static\r
+     */\r
+    script_.SetFunction("Music.stop", Function_Music_stopBGM);\r
+\r
+    /**\r
+     * MEを再生します\r
+     *\r
+     * @method playMotion\r
+     * @param {String} name ME名\r
+     * @static\r
+     */\r
+    script_.SetFunction("Music.playME", Function_Music_playME);\r
+\r
+       /**\r
+     * SEを再生します\r
+     *\r
+     * @method playMotion\r
+     * @param {String} name SE名\r
+     * @static\r
+     */\r
+    script_.SetFunction("Music.playSE", Function_Music_playSE);\r
+\r
+    /**\r
+     * BGM,MEのロードが終了しているかチェックします\r
+     *\r
+     * @method playMotion\r
+     * @param {String} name BGM、ME名\r
+     * @static\r
+     */\r
+    script_.SetFunction("Music.loadCheck", Function_Music_IsLoadingDone);\r
+\r
+    /**\r
+     * BGMのリストを返します\r
+     *\r
+     * @method playMotion\r
+     * @param\r
+     * @static\r
+     */\r
+    script_.SetFunction("Music.all", Function_Music_all);\r
+\r
+       /**\r
      * アカウント\r
      *\r
      * @class Account\r
index db15958..ede11cc 100644 (file)
Binary files a/client/Card.hpp and b/client/Card.hpp differ
index 1d4dec6..25b2f8a 100644 (file)
@@ -175,8 +175,8 @@ JsonGen::JsonGen()
        DxLib::VECTOR prePos = {0},curPos = {0},lclPos = {0};\r
        DxLib::MATRIX chglcl = {0};\r
 \r
-       char pmd_model_name_[256] = {0};\r
-       TCHAR pmd_author_name_[256] = {0};\r
+       char pmd_model_name_[MAX_PATH] = {0};\r
+       TCHAR pmd_author_name_[MAX_PATH] = {0};\r
 \r
        int exist_num_pmd_ = 0;\r
 \r
index 3a81e9c..a8d99a7 100644 (file)
@@ -196,7 +196,7 @@ void MiniMap::DrawPosAndCalc()
                if(tmp_pos_x < absolute_x() + 12)tmp_pos_x = absolute_x() + 12;
                if(tmp_pos_x > absolute_x() + absolute_width() - 12)tmp_pos_x = absolute_x() + absolute_width() - 12;
                if(tmp_pos_z < absolute_y() + 12)tmp_pos_z = absolute_y() + 12;
-               if(tmp_pos_z > absolute_y() + absolute_height() -12)tmp_pos_z = absolute_y() + absolute_height() - 12;
+               if(tmp_pos_z > absolute_y() + absolute_height() -12 - 16)tmp_pos_z = absolute_y() + absolute_height() - 12 - 16;
                DrawCircle( tmp_pos_x, tmp_pos_z, 2, GetColor(23,162,175),TRUE);
        }
        prev_myself_pos_on_map_ = player_manager->char_data_providers()[player_manager->charmgr()->my_character_id()]->position();
diff --git a/client/Music.cpp b/client/Music.cpp
new file mode 100644 (file)
index 0000000..9774b81
--- /dev/null
@@ -0,0 +1,202 @@
+//
+// Music.cpp
+//
+
+#include <boost/filesystem.hpp>
+#include "Music.hpp"
+#include "../common/Logger.hpp"
+#include "../common/unicode.hpp"
+
+extern int LoadFile(const TCHAR *FilePath, void **FileImageAddr, int *FileSize);
+
+Music::Music() :
+bgm_handle_(),
+se_handle_(),
+prev_bgm_(-1),
+present_bgm_(-1),
+requested_bgm_(-1),
+music_paths_(),
+crossfade_now_(false),
+fade_count_(0)
+{
+}
+
+void Music::Init()
+{
+    using namespace boost::filesystem;
+    using namespace std;
+
+       music_paths_.clear();
+
+       path p("./resources/musics");
+
+       try{
+               if (exists(p) && is_directory(p)) {
+                       for (auto it_dir = directory_iterator(p); it_dir != directory_iterator(); ++it_dir) {
+                               if (!is_directory(*it_dir)) {
+                                       path music_path = it_dir->path();
+                                       auto extension = music_path.extension().string();
+                                       if(     extension == ".wave" || extension == ".wav" ||
+                                               extension == ".ogg"  || extension == ".mp3")
+                                       {
+                                               music_paths_.push_back(music_path);
+                                       }
+                               }
+                       }
+               }
+       } catch (const filesystem_error& ex) {
+               Logger::Error(_T("%s"), unicode::ToTString(ex.what()));
+       }
+
+       se_paths_.clear();
+
+       p = "./resources/ses";
+
+       try{
+               if (exists(p) && is_directory(p)) {
+                       for (auto it_dir = directory_iterator(p); it_dir != directory_iterator(); ++it_dir) {
+                               if (!is_directory(*it_dir)) {
+                                       path music_path = it_dir->path();
+                                       auto extension = music_path.extension().string();
+                                       if(     extension == ".wave" || extension == ".wav" ||
+                                               extension == ".ogg"  || extension == ".mp3")
+                                       {
+                                               se_paths_.push_back(music_path);
+                                       }
+                               }
+                       }
+               }
+       } catch (const filesystem_error& ex) {
+               Logger::Error(_T("%s"), unicode::ToTString(ex.what()));
+       }
+
+}
+
+void Music::Play(tstring name,bool crossfade)
+{
+       if(bgm_handle_.find(name) == bgm_handle_.end())
+       {
+               SetUseASyncLoadFlag(FALSE);
+               auto NameFind = [&](boost::filesystem::path& src)->bool
+               {
+                       return src.stem().string() == unicode::ToString(name);
+               };
+               auto bgm_it_ = std::find_if(music_paths_.begin(),music_paths_.end(),NameFind);
+               void *fileaddr;
+               int filesize;
+               LoadFile(unicode::ToTString(bgm_it_->string()).c_str(),&fileaddr,&filesize);
+               auto softhandle_ = LoadSoftSoundFromMemImage(fileaddr,filesize);
+               auto handle_ = LoadSoundMemByMemImage(fileaddr,filesize);
+               if(handle_ == -1)return;
+               bgm_handle_.insert(std::make_pair<tstring,int>(unicode::ToTString(bgm_it_->stem().string()),handle_));
+               SetUseASyncLoadFlag(TRUE);
+       }
+       if(crossfade)
+       {
+               requested_bgm_ = bgm_handle_[name];
+       }else{
+               if(present_bgm_ != -1)StopSoundMem(present_bgm_);
+               present_bgm_ = bgm_handle_[name];
+               PlaySoundMem(present_bgm_,DX_PLAYTYPE_LOOP);
+       }
+       fade_count_ = 0;
+       crossfade_now_ = crossfade;
+}
+
+void Music::PlayME(tstring name)
+{
+       if(present_bgm_ != -1)prev_bgm_ = present_bgm_;
+       if(bgm_handle_.find(name) == bgm_handle_.end())
+       {
+               SetUseASyncLoadFlag(FALSE);
+               auto NameFind = [&](boost::filesystem::path& src)->bool
+               {
+                       return src.stem().string() == unicode::ToString(name);
+               };
+               auto bgm_it_ = std::find_if(music_paths_.begin(),music_paths_.end(),NameFind);
+               void *fileaddr;
+               int filesize;
+               LoadFile(unicode::ToTString(bgm_it_->string()).c_str(),&fileaddr,&filesize);
+               auto softhandle_ = LoadSoftSoundFromMemImage(fileaddr,filesize);
+               auto handle_ = LoadSoundMemByMemImage(fileaddr,filesize);
+               if(handle_ == -1)return;
+               bgm_handle_.insert(std::make_pair<tstring,int>(unicode::ToTString(bgm_it_->stem().string()),handle_));
+               SetUseASyncLoadFlag(TRUE);
+       }
+       if(present_bgm_ != -1)StopSoundMem(present_bgm_);
+       present_bgm_ = bgm_handle_[name];
+       PlaySoundMem(present_bgm_,DX_PLAYTYPE_BACK);
+       crossfade_now_ = false;
+       fade_count_ = 0;
+}
+
+void Music::Stop(bool fadeout)
+{
+       if(!CheckSoundMem(present_bgm_))return;
+       if(!fadeout)
+       {
+               StopSoundMem(present_bgm_);
+       }
+       crossfade_now_ = fadeout;
+       fade_count_ = 0;
+}
+
+void Music::PlaySE(tstring name)
+{
+       if(se_handle_.find(name) == se_handle_.end())
+       {
+               SetUseASyncLoadFlag(FALSE);
+               auto NameFind = [&](boost::filesystem::path& src)->bool
+               {
+                       return src.stem().string() == unicode::ToString(name);
+               };
+               auto se_it_ = std::find_if(se_paths_.begin(),se_paths_.end(),NameFind);
+               auto handle_ = LoadSoundMemToBufNumSitei(unicode::ToTString(se_it_->string()).c_str(),64);
+               if(handle_ == -1)return;
+               se_handle_.insert(std::make_pair<tstring,int>(unicode::ToTString(se_it_->stem().string()),handle_));
+       }
+       PlaySoundMem(se_handle_[name],DX_PLAYTYPE_BACK);
+}
+
+bool Music::CheckLoadedBGM(tstring name)
+{
+       if(bgm_handle_.find(name) == bgm_handle_.end())return true;
+       return CheckHandleASyncLoad(bgm_handle_[name]);
+}
+
+void Music::Update()
+{
+       if(prev_bgm_ != -1)
+       {
+               if(!CheckSoundMem(present_bgm_))
+               {
+                       present_bgm_ = -1;
+                       requested_bgm_ = prev_bgm_;
+                       fade_count_ = 0;
+                       crossfade_now_ = true;
+               }
+       }
+       if(!crossfade_now_)return;
+       if(CheckHandleASyncLoad(requested_bgm_) == false && requested_bgm_ != -1)
+       {
+               if(fade_count_ == 0)PlaySoundMem(requested_bgm_,DX_PLAYTYPE_LOOP);
+               if(fade_count_ >= 120)
+               {
+                       ChangeVolumeSoundMem(100,requested_bgm_);
+                       StopSoundMem(present_bgm_);
+                       ChangeVolumeSoundMem(100,present_bgm_);
+                       present_bgm_ = requested_bgm_;
+                       requested_bgm_ = -1;
+                       fade_count_ = 0;
+                       crossfade_now_ = false;
+               }
+               ChangeVolumeSoundMem((int)(fade_count_/1.2),requested_bgm_);
+               ChangeVolumeSoundMem((int)((120-fade_count_)/1.2),present_bgm_);
+               ++fade_count_;
+       }
+}
+
+std::vector<boost::filesystem::path>& Music::GetMusicList()
+{
+       return music_paths_;
+}
\ No newline at end of file
diff --git a/client/Music.hpp b/client/Music.hpp
new file mode 100644 (file)
index 0000000..dd7c7b4
--- /dev/null
@@ -0,0 +1,42 @@
+//\r
+// Music.hpp\r
+//\r
+#include "../common/unicode.hpp"\r
+#include <v8.h>\r
+#include <map>\r
+#include <vector>\r
+\r
+//\89ð\90Í\82·\82é\90M\8d\86\82Ì\92·\82³(\95b)\r
+#define SIGNAL_LENGTH 0.5\r
+//\83X\83y\83N\83g\83\89\83\80\82Ì\90\94\r
+#define SPECTRUM_NUM 256\r
+//\83X\83y\83N\83g\83\89\83\80\82Ì\8ag\91å\95\9d\r
+#define SPECTRUM_WIDTH 2\r
+\r
+\r
+class Music\r
+{\r
+public:\r
+       Music();\r
+       virtual ~Music(){};\r
+       void Init();\r
+       void Update();\r
+       void Play(tstring name,bool crossfade);\r
+       void Stop(bool fadeout);\r
+       void PlaySE(tstring name);\r
+       void PlayME(tstring name);\r
+       bool CheckLoadedBGM(tstring name);\r
+       std::vector<boost::filesystem::path>& GetMusicList();\r
+\r
+private:\r
+       bool crossfade_now_;\r
+       int fade_count_;\r
+       int present_bgm_;\r
+       int prev_bgm_;\r
+       int requested_bgm_;\r
+       std::map<tstring,int> bgm_handle_;\r
+       std::map<tstring,int> se_handle_;\r
+\r
+       std::vector<boost::filesystem::path> music_paths_;\r
+       std::vector<boost::filesystem::path> se_paths_;\r
+};\r
index 40a3a6d..e69e842 100644 (file)
Binary files a/client/PlayerManager.cpp and b/client/PlayerManager.cpp differ
index a1742ef..a270224 100644 (file)
Binary files a/client/ResourceManager.cpp and b/client/ResourceManager.cpp differ
index f52bd3c..3c545d0 100644 (file)
@@ -19,9 +19,11 @@ using boost::property_tree::ptree;
 
 class ImageHandle;
 class ModelHandle;
+class Music;
 
 typedef std::shared_ptr<ImageHandle> ImageHandlePtr;
 typedef std::shared_ptr<ModelHandle> ModelHandlePtr;
+typedef std::shared_ptr<Music> MusicPtr;
 
 struct ReadFuncData {
        ReadFuncData(){};
@@ -86,6 +88,9 @@ class ResourceManager {
 
                static tstring NameToFullPath(const tstring& name);
 
+               //Musics
+               static MusicPtr& music();
+
     private:
         static int default_font_handle_;
         static std::unordered_map<tstring, ImageHandlePtr> graph_handles_;
@@ -96,6 +101,8 @@ class ResourceManager {
         static std::unordered_map<tstring, ModelHandle> model_handles_;
                static std::vector<std::string> model_name_list_;
                static float model_edge_size_;
+               //Musics
+               static MusicPtr music_;
 };
 
 class ImageHandle {
diff --git a/client/bin/cards/bgmlist/main.js b/client/bin/cards/bgmlist/main.js
new file mode 100644 (file)
index 0000000..21016d0
--- /dev/null
@@ -0,0 +1,37 @@
+
+/***MetaData***
+
+{
+       "name": "BGM\83\8a\83X\83g",
+       "icon": "icon.png",
+       "api_version": 1
+}
+
+***MetaData***/
+
+var list;
+list = new UI.List({
+       docking: UI.DOCKING_TOP | UI.DOCKING_LEFT | UI.DOCKING_RIGHT | UI.DOCKING_BOTTOM
+});
+
+var even_line = false;
+var music_names = Music.all();
+for (var i = 0; i < music_names.length; i++) {
+    (function (music_name) {
+        list.addItem(
+                               new UI.Label({
+                                   docking: UI.DOCKING_TOP | UI.DOCKING_LEFT | UI.DOCKING_RIGHT,
+                                   text: music_name,
+                                   bgcolor: ((even_line = !even_line) ? "#EEAFEECC" : "#FFFFFFCC"),
+                                   onclick: function () {
+                                       Music.play(music_name,true)
+                                   }
+                               })
+                       );
+    })(music_names[i])
+}
+
+Card.board.width = 240;
+Card.board.height = 120;
+Card.board.docking = UI.DOCKING_BOTTOM | UI.DOCKING_LEFT
+Card.board.addChild(list);
\ No newline at end of file
index 345a45d..44a77ea 100644 (file)
Binary files a/client/scene/Init.cpp and b/client/scene/Init.cpp differ
index db2972a..a22e630 100644 (file)
@@ -10,6 +10,7 @@
 #include "../Core.hpp"
 #include <shlwapi.h>
 #include "ServerChange.hpp"
+#include "../Music.hpp"
 
 namespace scene {
 MainLoop::MainLoop(const ManagerAccessorPtr& manager_accessor) :
@@ -54,6 +55,7 @@ void MainLoop::Update()
     card_manager_->Update();
        minimap_.Update();
     world_manager_->Update();
+       ResourceManager::music()->Update();
 }
 
 void MainLoop::ProcessInput(InputManager* input)
index c3e8eb6..9de1226 100644 (file)
@@ -9,7 +9,7 @@
 
 #define MMO_VERSION_MAJOR 0
 #define MMO_VERSION_MINOR 3
-#define MMO_VERSION_REVISION 8
+#define MMO_VERSION_REVISION 9
 
 #define MMO_PROTOCOL_VERSION 2