The master and develop branches track hengband.
OS X development happens on the macos-1-6-2, macos-2-2-1, and macos-develop branches.
Revision | 1188a98071fd61303a5dae801724ee2237f54343 (tree) |
---|---|
Time | 2021-06-13 21:47:30 |
Author | Deskull <61610939+sikabane-works@user...> |
Commiter | GitHub |
Merge pull request #1207 from sikabane-works/release/3.0.0Alpha27
Release/3.0.0 alpha27
@@ -271,6 +271,7 @@ | ||
271 | 271 | <ClCompile Include="..\..\src\main-win\commandline-win.cpp" /> |
272 | 272 | <ClCompile Include="..\..\src\main-win\graphics-win.cpp" /> |
273 | 273 | <ClCompile Include="..\..\src\main-win\main-win-term.cpp" /> |
274 | + <ClCompile Include="..\..\src\main-win\wav-reader.cpp" /> | |
274 | 275 | <ClCompile Include="..\..\src\object-enchant\apply-magic-amulet.cpp" /> |
275 | 276 | <ClCompile Include="..\..\src\object-enchant\apply-magic-ring.cpp" /> |
276 | 277 | <ClCompile Include="..\..\src\object\object-index-list.cpp" /> |
@@ -949,6 +950,7 @@ | ||
949 | 950 | <ClInclude Include="..\..\src\main-win\commandline-win.h" /> |
950 | 951 | <ClInclude Include="..\..\src\main-win\graphics-win.h" /> |
951 | 952 | <ClInclude Include="..\..\src\main-win\main-win-term.h" /> |
953 | + <ClInclude Include="..\..\src\main-win\wav-reader.h" /> | |
952 | 954 | <ClInclude Include="..\..\src\object-enchant\apply-magic-amulet.h" /> |
953 | 955 | <ClInclude Include="..\..\src\object-enchant\apply-magic-ring.h" /> |
954 | 956 | <ClInclude Include="..\..\src\object\object-index-list.h" /> |
@@ -2292,6 +2292,9 @@ | ||
2292 | 2292 | <ClCompile Include="..\..\src\main-win\main-win-term.cpp"> |
2293 | 2293 | <Filter>main-win</Filter> |
2294 | 2294 | </ClCompile> |
2295 | + <ClCompile Include="..\..\src\main-win\wav-reader.cpp"> | |
2296 | + <Filter>main-win</Filter> | |
2297 | + </ClCompile> | |
2295 | 2298 | </ItemGroup> |
2296 | 2299 | <ItemGroup> |
2297 | 2300 | <ClInclude Include="..\..\src\combat\shoot.h"> |
@@ -4929,6 +4932,9 @@ | ||
4929 | 4932 | <ClInclude Include="..\..\src\main-win\main-win-term.h"> |
4930 | 4933 | <Filter>main-win</Filter> |
4931 | 4934 | </ClInclude> |
4935 | + <ClInclude Include="..\..\src\main-win\wav-reader.h"> | |
4936 | + <Filter>main-win</Filter> | |
4937 | + </ClInclude> | |
4932 | 4938 | </ItemGroup> |
4933 | 4939 | <ItemGroup> |
4934 | 4940 | <None Include="..\..\src\wall.bmp" /> |
@@ -939,6 +939,7 @@ EXTRA_hengband_SOURCES = \ | ||
939 | 939 | main-win/main-win-term.cpp main-win/main-win-term.h \ |
940 | 940 | main-win/main-win-tokenizer.cpp main-win/main-win-tokenizer.h \ |
941 | 941 | main-win/main-win-utils.cpp main-win/main-win-utils.h \ |
942 | + main-win/wav-reader.cpp main-win/wav-reader.h \ | |
942 | 943 | wall.bmp \ |
943 | 944 | stdafx.cpp stdafx.h |
944 | 945 |
@@ -146,8 +146,8 @@ errr parse_d_info(std::string_view buf, angband_header *head) | ||
146 | 146 | info_set_value(d_ptr->max_m_alloc_chance, tokens[6]); |
147 | 147 | info_set_value(d_ptr->obj_good, tokens[7]); |
148 | 148 | info_set_value(d_ptr->obj_great, tokens[8]); |
149 | - info_set_value(d_ptr->pit, tokens[9]); | |
150 | - info_set_value(d_ptr->nest, tokens[10]); | |
149 | + info_set_value(d_ptr->pit, tokens[9], 16); | |
150 | + info_set_value(d_ptr->nest, tokens[10], 16); | |
151 | 151 | } else if (tokens[0] == "P") { |
152 | 152 | // P:wild_y:wild_x |
153 | 153 | if (tokens.size() < 3) |
@@ -2497,6 +2497,7 @@ static void hook_quit(concptr str) | ||
2497 | 2497 | DeleteObject(hbrYellow); |
2498 | 2498 | finalize_bg(); |
2499 | 2499 | graphic.finalize(); |
2500 | + finalize_sound(); | |
2500 | 2501 | |
2501 | 2502 | UnregisterClassW(AppName, hInstance); |
2502 | 2503 | if (hIcon) |
@@ -7,12 +7,16 @@ | ||
7 | 7 | #include "main-win/main-win-cfg-reader.h" |
8 | 8 | #include "main-win/main-win-define.h" |
9 | 9 | #include "main-win/main-win-file-utils.h" |
10 | -#include "main-win/main-win-mmsystem.h" | |
11 | 10 | #include "main-win/main-win-utils.h" |
11 | +#include "main-win/wav-reader.h" | |
12 | 12 | #include "util/angband-files.h" |
13 | 13 | |
14 | 14 | #include "main/sound-definitions-table.h" |
15 | 15 | |
16 | +#include <memory> | |
17 | + | |
18 | +#include <mmsystem.h> | |
19 | + | |
16 | 20 | /* |
17 | 21 | * Directory name |
18 | 22 | */ |
@@ -24,6 +28,103 @@ concptr ANGBAND_DIR_XTRA_SOUND; | ||
24 | 28 | CfgData *sound_cfg_data; |
25 | 29 | |
26 | 30 | /*! |
31 | + * 効果音データ | |
32 | + */ | |
33 | +struct sound_res { | |
34 | + sound_res(BYTE* _buf) | |
35 | + { | |
36 | + buf.reset(_buf); | |
37 | + } | |
38 | + ~sound_res() | |
39 | + { | |
40 | + dispose(); | |
41 | + } | |
42 | + | |
43 | + HWAVEOUT hwo = NULL; | |
44 | + /*! | |
45 | + * PCMデータバッファ | |
46 | + */ | |
47 | + std::unique_ptr<BYTE[]> buf; | |
48 | + WAVEHDR wh = { 0 }; | |
49 | + | |
50 | + void dispose() | |
51 | + { | |
52 | + if (hwo != NULL) { | |
53 | + ::waveOutReset(hwo); | |
54 | + ::waveOutUnprepareHeader(hwo, &wh, sizeof(WAVEHDR)); | |
55 | + ::waveOutClose(hwo); | |
56 | + hwo = NULL; | |
57 | + wh.lpData = nullptr; | |
58 | + } | |
59 | + } | |
60 | +}; | |
61 | +/*! | |
62 | + * 効果音リソースの管理キュー | |
63 | + */ | |
64 | +std::queue<sound_res *> sound_queue; | |
65 | + | |
66 | +/*! | |
67 | + * 効果音の再生と管理キューへの追加. | |
68 | + * | |
69 | + * @param wf WAVEFORMATEXへのポインタ | |
70 | + * @param buf PCMデータバッファ | |
71 | + * @param bufsize バッファサイズ | |
72 | + * @retval true 正常に処理された | |
73 | + * @retval false 処理エラー | |
74 | + */ | |
75 | +static bool add_sound_queue(const WAVEFORMATEX *wf, BYTE *buf, DWORD bufsize) | |
76 | +{ | |
77 | + while (!sound_queue.empty()) { | |
78 | + auto res = sound_queue.front(); | |
79 | + if (res->hwo == NULL || (res->wh.dwFlags & WHDR_DONE)) { | |
80 | + delete res; | |
81 | + sound_queue.pop(); | |
82 | + continue; | |
83 | + } | |
84 | + break; | |
85 | + } | |
86 | + | |
87 | + auto res = new sound_res(buf); | |
88 | + sound_queue.push(res); | |
89 | + | |
90 | + MMRESULT mr = ::waveOutOpen(&res->hwo, WAVE_MAPPER, wf, NULL, NULL, CALLBACK_NULL); | |
91 | + if (mr != MMSYSERR_NOERROR) { | |
92 | + return false; | |
93 | + } | |
94 | + | |
95 | + WAVEHDR *wh = &res->wh; | |
96 | + wh->lpData = (LPSTR)buf; | |
97 | + wh->dwBufferLength = bufsize; | |
98 | + wh->dwFlags = 0; | |
99 | + | |
100 | + ::waveOutPrepareHeader(res->hwo, wh, sizeof(WAVEHDR)); | |
101 | + ::waveOutWrite(res->hwo, wh, sizeof(WAVEHDR)); | |
102 | + | |
103 | + return true; | |
104 | +} | |
105 | + | |
106 | +/*! | |
107 | + * 指定ファイルを再生する | |
108 | + * | |
109 | + * @param buf ファイル名 | |
110 | + * @retval true 正常に処理された | |
111 | + * @retval false 処理エラー | |
112 | + */ | |
113 | +static bool play_sound_impl(char *filename) | |
114 | +{ | |
115 | + wav_reader reader; | |
116 | + if (!reader.open(filename)) | |
117 | + return false; | |
118 | + auto wf = reader.get_waveformat(); | |
119 | + | |
120 | + auto data_buffer = reader.read_data(); | |
121 | + if (data_buffer == nullptr) | |
122 | + return false; | |
123 | + | |
124 | + return add_sound_queue(wf, data_buffer, reader.get_data_chunk()->cksize); | |
125 | +} | |
126 | + | |
127 | +/*! | |
27 | 128 | * @brief action-valに対応する[Sound]セクションのキー名を取得する |
28 | 129 | * @param index "term_xtra()"の第2引数action-valに対応する値 |
29 | 130 | * @param buf 使用しない |
@@ -52,6 +153,18 @@ void load_sound_prefs(void) | ||
52 | 153 | } |
53 | 154 | |
54 | 155 | /*! |
156 | + * @brief 効果音の終了処理 | |
157 | + */ | |
158 | +void finalize_sound(void) | |
159 | +{ | |
160 | + while (!sound_queue.empty()) { | |
161 | + auto res = sound_queue.front(); | |
162 | + delete res; | |
163 | + sound_queue.pop(); | |
164 | + } | |
165 | +} | |
166 | + | |
167 | +/*! | |
55 | 168 | * @brief 指定の効果音を鳴らす。 |
56 | 169 | * @param val see sound_type |
57 | 170 | * @retval 0 正常終了 |
@@ -68,8 +181,9 @@ errr play_sound(int val) | ||
68 | 181 | char buf[MAIN_WIN_MAX_PATH]; |
69 | 182 | path_build(buf, MAIN_WIN_MAX_PATH, ANGBAND_DIR_XTRA_SOUND, filename); |
70 | 183 | |
71 | - if (::PlaySoundW(to_wchar(buf).wc_str(), 0, SND_FILENAME | SND_ASYNC)) { | |
184 | + if (play_sound_impl(buf)) { | |
72 | 185 | return 0; |
73 | 186 | } |
187 | + | |
74 | 188 | return -1; |
75 | 189 | } |
@@ -7,4 +7,5 @@ extern concptr ANGBAND_DIR_XTRA_SOUND; | ||
7 | 7 | extern CfgData *sound_cfg_data; |
8 | 8 | |
9 | 9 | void load_sound_prefs(void); |
10 | +void finalize_sound(void); | |
10 | 11 | errr play_sound(int val); |
@@ -50,7 +50,7 @@ protected: | ||
50 | 50 | |
51 | 51 | void kill() |
52 | 52 | { |
53 | - if (!buf) { | |
53 | + if (buf) { | |
54 | 54 | C_KILL(buf, buf_size, WCHAR); |
55 | 55 | buf = NULL; |
56 | 56 | } |
@@ -100,7 +100,7 @@ protected: | ||
100 | 100 | |
101 | 101 | void kill() |
102 | 102 | { |
103 | - if (!buf) { | |
103 | + if (buf) { | |
104 | 104 | C_KILL(buf, buf_size, char); |
105 | 105 | buf = NULL; |
106 | 106 | } |
@@ -0,0 +1,69 @@ | ||
1 | +/*! | |
2 | + * @file wav-reader.cpp | |
3 | + * @brief Windows版固有実装(WAVファイル読込) | |
4 | + */ | |
5 | + | |
6 | +#include "main-win/wav-reader.h" | |
7 | +#include "main-win/main-win-utils.h" | |
8 | + | |
9 | +bool wav_reader::open(char *filename) | |
10 | +{ | |
11 | + close(); | |
12 | + | |
13 | + this->hmmio = ::mmioOpenW(to_wchar(filename).wc_str(), NULL, MMIO_READ); | |
14 | + if (this->hmmio == NULL) | |
15 | + return false; | |
16 | + | |
17 | + MMRESULT mmresult; | |
18 | + LONG read_size; | |
19 | + LONG readed_size; | |
20 | + | |
21 | + this->riff_chunk.fccType = mmioFOURCC('W', 'A', 'V', 'E'); | |
22 | + mmresult = ::mmioDescend(this->hmmio, &this->riff_chunk, NULL, MMIO_FINDRIFF); | |
23 | + if (mmresult != MMSYSERR_NOERROR) | |
24 | + return false; | |
25 | + | |
26 | + this->fmt_chunk.ckid = mmioFOURCC('f', 'm', 't', ' '); | |
27 | + mmresult = ::mmioDescend(this->hmmio, &this->fmt_chunk, &this->riff_chunk, MMIO_FINDCHUNK); | |
28 | + if (mmresult != MMSYSERR_NOERROR) | |
29 | + return false; | |
30 | + | |
31 | + if (this->fmt_chunk.cksize > sizeof(this->waveformatex)) | |
32 | + return false; | |
33 | + read_size = this->fmt_chunk.cksize; | |
34 | + readed_size = ::mmioRead(this->hmmio, (HPSTR) & this->waveformatex, read_size); | |
35 | + if (readed_size != read_size) | |
36 | + return false; | |
37 | + if (this->waveformatex.wFormatTag != WAVE_FORMAT_PCM) | |
38 | + return false; | |
39 | + mmresult = ::mmioAscend(this->hmmio, &this->fmt_chunk, 0); | |
40 | + if (mmresult != MMSYSERR_NOERROR) | |
41 | + return false; | |
42 | + | |
43 | + this->data_chunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); | |
44 | + mmresult = ::mmioDescend(this->hmmio, &this->data_chunk, &riff_chunk, MMIO_FINDCHUNK); | |
45 | + if (mmresult != MMSYSERR_NOERROR) | |
46 | + return false; | |
47 | + | |
48 | + this->buffer.reset(new BYTE[data_chunk.cksize]); | |
49 | + read_size = this->data_chunk.cksize; | |
50 | + readed_size = ::mmioRead(this->hmmio, (HPSTR)this->buffer.get(), read_size); | |
51 | + if (readed_size != read_size) { | |
52 | + return false; | |
53 | + } | |
54 | + | |
55 | + return true; | |
56 | +} | |
57 | + | |
58 | +BYTE *wav_reader::read_data() | |
59 | +{ | |
60 | + return this->buffer.release(); | |
61 | +} | |
62 | + | |
63 | +void wav_reader::close() | |
64 | +{ | |
65 | + if (this->hmmio != NULL) { | |
66 | + ::mmioClose(this->hmmio, 0); | |
67 | + this->hmmio = NULL; | |
68 | + } | |
69 | +} |
@@ -0,0 +1,57 @@ | ||
1 | +#pragma once | |
2 | +/*! | |
3 | + * @file wav-reader.h | |
4 | + * @brief Windows版固有実装(WAVファイル読込)ヘッダ | |
5 | + */ | |
6 | + | |
7 | +#include <memory> | |
8 | + | |
9 | +#include <windows.h> | |
10 | +#include <mmsystem.h> | |
11 | + | |
12 | +/*! | |
13 | + * WAVファイルの読み込み | |
14 | + */ | |
15 | +class wav_reader { | |
16 | +public: | |
17 | + wav_reader() | |
18 | + : hmmio(NULL) | |
19 | + { | |
20 | + } | |
21 | + ~wav_reader() | |
22 | + { | |
23 | + close(); | |
24 | + } | |
25 | + | |
26 | + /*! | |
27 | + * WAVファイルを開く | |
28 | + * | |
29 | + * @param filename | |
30 | + * @retval true 正常に処理された | |
31 | + * @retval false 処理エラー | |
32 | + */ | |
33 | + bool open(char *filename); | |
34 | + /*! | |
35 | + * PCMデータ取得 | |
36 | + * @details 呼び出し元でdelete[]すること | |
37 | + * @return PCMデータ | |
38 | + */ | |
39 | + BYTE* read_data(); | |
40 | + const WAVEFORMATEX *get_waveformat() | |
41 | + { | |
42 | + return &waveformatex; | |
43 | + } | |
44 | + const MMCKINFO *get_data_chunk() | |
45 | + { | |
46 | + return &data_chunk; | |
47 | + } | |
48 | + void close(); | |
49 | + | |
50 | +protected: | |
51 | + HMMIO hmmio; | |
52 | + MMCKINFO riff_chunk{}; | |
53 | + MMCKINFO fmt_chunk{}; | |
54 | + WAVEFORMATEX waveformatex{}; | |
55 | + MMCKINFO data_chunk{}; | |
56 | + std::unique_ptr<BYTE[]> buffer; | |
57 | +}; |
@@ -17,7 +17,7 @@ | ||
17 | 17 | #define H_VER_MAJOR 3 //!< ゲームのバージョン定義(メジャー番号) |
18 | 18 | #define H_VER_MINOR 0 //!< ゲームのバージョン定義(マイナー番号) |
19 | 19 | #define H_VER_PATCH 0 //!< ゲームのバージョン定義(パッチ番号) |
20 | -#define H_VER_EXTRA 26 //!< ゲームのバージョン定義(エクストラ番号) | |
20 | +#define H_VER_EXTRA 27 //!< ゲームのバージョン定義(エクストラ番号) | |
21 | 21 | |
22 | 22 | /*! |
23 | 23 | * @brief セーブファイルのバージョン(3.0.0から導入) |