| 320 | } |
| 321 | |
| 322 | void Weather::DrawFogOverlay(Bitmap& dst, const Bitmap& overlay) { |
| 323 | const auto dr = dst.GetRect(); |
| 324 | constexpr auto sr = overlay_bitmap_rect; |
| 325 | |
| 326 | auto* src = ApplyToneEffect(overlay, sr); |
| 327 | |
| 328 | auto strength = Utils::Clamp(Main_Data::game_screen->GetWeatherStrength(), 0, num_opacities - 1); |
| 329 | int back_opacity = fog_opacity[0][strength]; |
| 330 | int front_opacity = fog_opacity[1][strength]; |
| 331 | |
| 332 | const auto shake_x = Main_Data::game_screen->GetShakeOffsetX(); |
| 333 | const auto shake_y = Main_Data::game_screen->GetShakeOffsetY(); |
| 334 | |
| 335 | // RPG_RT uses the first 2 particles for fog layer graphics |
| 336 | const auto& particles = Main_Data::game_screen->GetParticles(); |
| 337 | assert(particles.size() >= num_fog_particles); |
| 338 | const auto fog_bg_frames = particles[0].x; |
| 339 | const auto fog_fg_frames = particles[1].x; |
| 340 | |
| 341 | // Front layer moves left one pixel every 8 frames. |
| 342 | const int fx = shake_x + (fog_fg_frames / 8) % sr.width; |
| 343 | // Back layer moves left one pixel every 4 frames. |
| 344 | const int bx = shake_x - (fog_bg_frames / 4) % sr.width; |
| 345 | // Front layer moves vertically up and down using this algorithm. And it uses the background frame counter! |
| 346 | // Confirmed to be matching RPG_RT |
| 347 | const int fy = shake_y - Utils::RoundTo<int>(std::sin(fog_bg_frames * M_PI / 4096.0) * (sr.height / 2)) - (sr.height / 4); |
| 348 | // Back layer never moves vertically |
| 349 | const int by = shake_y; |
| 350 | |
| 351 | dst.TiledBlit(bx, by, sr, *src, dr, back_opacity); |
| 352 | dst.TiledBlit(fx, fy, sr, *src, dr, front_opacity); |
| 353 | } |
| 354 | |
| 355 | void Weather::SetTone(Tone tone) { |
| 356 | if (tone != tone_effect) { |
nothing calls this directly
no test coverage detected