| 148 | } |
| 149 | |
| 150 | void Game_System::SePlay(const lcf::rpg::Sound& se, bool stop_sounds) { |
| 151 | if (se.name.empty()) { |
| 152 | return; |
| 153 | } else if (se.name == "(OFF)") { |
| 154 | if (stop_sounds) { |
| 155 | Audio().SE_Stop(); |
| 156 | } |
| 157 | return; |
| 158 | } |
| 159 | |
| 160 | // NOTE: Yume Nikki plays hundreds of sound effects at 0% volume on startup, |
| 161 | // probably for caching. This avoids "No free channels" warnings. |
| 162 | if (se.volume == 0) |
| 163 | return; |
| 164 | |
| 165 | int32_t volume = se.volume; |
| 166 | int32_t tempo = se.tempo; |
| 167 | |
| 168 | // Validate |
| 169 | if (volume < 0 || volume > 100) { |
| 170 | Output::Debug("SE {} has invalid volume {}", se.name, volume); |
| 171 | volume = Utils::Clamp<int32_t>(volume, 0, 100); |
| 172 | } |
| 173 | |
| 174 | // Normal pitch is 50 to 200 but Yume2kki uses out of range values |
| 175 | if (tempo < 10 || tempo > 400) { |
| 176 | Output::Debug("SE {} has invalid tempo {}", se.name, tempo); |
| 177 | tempo = Utils::Clamp<int32_t>(se.tempo, 10, 400); |
| 178 | } |
| 179 | |
| 180 | FileRequestAsync* request = AsyncHandler::RequestFile("Sound", se.name); |
| 181 | lcf::rpg::Sound se_adj = se; |
| 182 | se_adj.volume = volume; |
| 183 | se_adj.tempo = tempo; |
| 184 | se_request_ids[se.name] = request->Bind(&Game_System::OnSeReady, this, se_adj, stop_sounds); |
| 185 | if (EndsWith(se.name, ".script")) { |
| 186 | // Is a Ineluki Script File |
| 187 | request->SetImportantFile(true); |
| 188 | } |
| 189 | request->Start(); |
| 190 | } |
| 191 | |
| 192 | void Game_System::SePlay(const lcf::rpg::Animation &animation) { |
| 193 | Filesystem_Stream::InputStream stream; |
no test coverage detected