#include #include #include #include #include namespace { template struct sdl_wrapper_t : std::unique_ptr { explicit sdl_wrapper_t(SDLT* p) : std::unique_ptr{p, deletef} {} operator SDLT*() { return std::unique_ptr::get(); } }; using window_t = sdl_wrapper_t; using surface_t = sdl_wrapper_t; using renderer_t = sdl_wrapper_t; auto operator+(SDL_Point a, SDL_Point b) { return SDL_Point{.x = a.x + b.x, .y = a.y + b.y}; } auto operator<=>(const SDL_Point& a, const SDL_Point& b) { auto y_comp = a.x <=> b.x; if (y_comp != std::strong_ordering::equal) { return y_comp; } return a.y <=> b.y; } auto operator==(const SDL_Point& a, const SDL_Point& b) { return a.x == b.x && a.y == b.y; } // constexpr int width = 1000; // constexpr int height = 1000; constexpr int width = 3440; constexpr int height = 1300; template struct [[nodiscard("give this a name so SDL_Quit is called at the end" )]] Defer { Defer() = default; Defer(const Defer&) = delete; Defer(Defer&&) = delete; auto operator=(Defer&&) = delete; auto operator=(const Defer&) = delete; ~Defer() { EF(); } }; using clock = std::chrono::steady_clock; auto poll_events(bool& continu) { for (SDL_Event e; SDL_PollEvent(&e);) { if (e.type == SDL_QUIT) { continu = false; } } } } // namespace int main() { if (SDL_Init(SDL_INIT_VIDEO) < 0) { std::println("fuck"); return EXIT_FAILURE; } Defer defer_SDL_Quit; window_t window{SDL_CreateWindow( "random walk", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, 0 )}; if (!window) { std::println( "Window could not be created! SDL_Error: {}", SDL_GetError() ); return EXIT_FAILURE; } // owned by window auto* window_surface = SDL_GetWindowSurface(window); if (!window_surface) { return EXIT_FAILURE; } if (window_surface->format->palette) { return EXIT_FAILURE; } std::println( "got surface with {} bits per pixel", window_surface->format->BitsPerPixel ); if (!(window_surface->format->format & SDL_PIXELFORMAT_RGBA32)) { return EXIT_FAILURE; } SDL_Point pos{.x = width / 2, .y = height / 2}; const SDL_Point directions[] = { {.x = -1, .y = 0}, {.x = 1, .y = 0}, {.x = 0, .y = -1}, {.x = 0, .y = 1} }; std::mt19937_64 rne(std::random_device{}()); std::uniform_int_distribution dist(0, 3); // aarrggbb?? constexpr Uint32 bg_color = 0xffdbd7c0; constexpr Uint32 walk_color = 0xff0d0f14; constexpr auto batchsize = 1000; SDL_LockSurface(window_surface); for (int i = 0; i < window_surface->w * window_surface->h; ++i) { static_cast(window_surface->pixels)[i] = bg_color; } SDL_UnlockSurface(window_surface); const auto start_time = clock::now(); auto next_poll_events_time = start_time; auto frame_start = start_time; clock::duration frame_time; for (bool continu = true; continu;) { // measure frame_time const auto now = clock::now(); frame_time = now - frame_start; frame_start = now; if (now >= next_poll_events_time) { next_poll_events_time = now + std::chrono::milliseconds{200}; poll_events(continu); std::println( "last frame_time={} batchsize={}", frame_time, batchsize ); } SDL_LockSurface(window_surface); for (auto step = 0z; step < batchsize; ++step) { SDL_Point newpoint; do { newpoint = pos + directions[dist(rne)]; } while (newpoint.x < 0 or newpoint.x >= width or newpoint.y < 0 or newpoint.y >= height); pos = newpoint; static_cast(window_surface->pixels )[pos.x + pos.y * window_surface->w] = walk_color; } SDL_UnlockSurface(window_surface); SDL_UpdateWindowSurface(window); } // leaking memory, nothing I can do }