SDLSnow.cc 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #include "SDLSnow.hh"
  2. #include "SDLOutputSurface.hh"
  3. #include "Display.hh"
  4. #include "build-info.hh"
  5. #include "checked_cast.hh"
  6. #include "random.hh"
  7. #include <cstring>
  8. #include <cstdint>
  9. namespace openmsx {
  10. template <class Pixel>
  11. SDLSnow<Pixel>::SDLSnow(OutputSurface& output, Display& display_)
  12. : Layer(COVER_FULL, Z_BACKGROUND)
  13. , display(display_)
  14. {
  15. // Precalc gray values for noise
  16. for (int i = 0; i < 256; ++i) {
  17. gray[i] = output.mapRGB255(gl::ivec3(i));
  18. }
  19. }
  20. template <class Pixel>
  21. void SDLSnow<Pixel>::paint(OutputSurface& output_)
  22. {
  23. auto& generator = global_urng(); // fast (non-cryptographic) random numbers
  24. std::uniform_int_distribution<int> distribution(0, 255);
  25. auto& output = checked_cast<SDLOutputSurface&>(output_);
  26. {
  27. auto pixelAccess = output.getDirectPixelAccess();
  28. auto [width, height] = output.getLogicalSize();
  29. for (int y = 0; y < height; y += 2) {
  30. auto* p0 = pixelAccess.getLinePtr<Pixel>(y + 0);
  31. auto* p1 = pixelAccess.getLinePtr<Pixel>(y + 1);
  32. for (int x = 0; x < width; x += 2) {
  33. p0[x + 0] = p0[x + 1] = gray[distribution(generator)];
  34. }
  35. memcpy(p1, p0, width * sizeof(Pixel));
  36. }
  37. }
  38. output.flushFrameBuffer();
  39. display.repaintDelayed(100 * 1000); // 10fps
  40. }
  41. // Force template instantiation.
  42. #if HAVE_16BPP
  43. template class SDLSnow<uint16_t>;
  44. #endif
  45. #if HAVE_32BPP
  46. template class SDLSnow<uint32_t>;
  47. #endif
  48. } // namespace openmsx