From 8a3913c74cb701c56184ecd06e92d584452c2c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20H=C3=B6rdt?= <6329417-neop_@users.noreply.gitlab.com> Date: Tue, 6 Aug 2024 00:49:10 +0200 Subject: [PATCH] complete emscripten port https://wiki.libsdl.org/SDL2/README/emscripten was still up-to-date --- .gitignore | 4 +- build-web.sh | 2 + build.sh | 2 + main.cpp | 178 +++++++++++++++++++++++++++++---------------------- 4 files changed, 110 insertions(+), 76 deletions(-) create mode 100755 build-web.sh create mode 100755 build.sh diff --git a/.gitignore b/.gitignore index a952070..061ed91 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ !.gitignore !main.cpp -!screenshot.png \ No newline at end of file +!screenshot.png +!build.sh +!build-web.sh \ No newline at end of file diff --git a/build-web.sh b/build-web.sh new file mode 100755 index 0000000..584a7ef --- /dev/null +++ b/build-web.sh @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/lib/emscripten/em++ -std=c++26 --use-port=sdl2 -O2 --emrun -sASSERTIONS -o index.html main.cpp \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..841b665 --- /dev/null +++ b/build.sh @@ -0,0 +1,2 @@ +#!/bin/bash +clang++ -Wall -std=c++26 -O2 -g -o main main.cpp -fuse-ld=mold `pkg-config --libs --cflags sdl2` \ No newline at end of file diff --git a/main.cpp b/main.cpp index 717eee0..c2bc7e4 100644 --- a/main.cpp +++ b/main.cpp @@ -9,6 +9,12 @@ #include #include #include +#include + +#ifdef __EMSCRIPTEN__ + #include + #include +#endif namespace { @@ -53,10 +59,11 @@ auto operator+(SDL_Point a, SDL_Point b) { return SDL_Point{.x = a.x + b.x, .y = a.y + b.y}; } -// constexpr int width = 1000; -// constexpr int height = 1000; -constexpr int width = 3440; -constexpr int height = 1440; +constexpr int width = 1000; +constexpr int height = 500; + +// constexpr int width = 3440; +// constexpr int height = 1440; template struct [[nodiscard("give this a name so SDL_Quit is called at the end" @@ -79,13 +86,87 @@ auto poll_events(bool& continu) { } } // namespace +template +void mainloop(void* userData) { + constexpr SDL_Point directions[] = { + {.x = -1, .y = 0}, {.x = 1, .y = 0}, {.x = 0, .y = -1}, {.x = 0, .y = 1} + }; + constexpr auto batchsize = 1000; + auto& [renderer, texture, pos, pos1, rne, dist, start_time, next_poll_events_time, next_frame_render_time, frame_start, frame_time, continu] = + *static_cast(userData); + + // 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); + } + + std::array point_batch; + 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; + point_batch[step] = newpoint; + } + + ///// Render image + sdl_check(SDL_SetRenderTarget(renderer, texture)); + sdl_check(SDL_SetRenderDrawBlendMode( + renderer, + SDL_ComposeCustomBlendMode( + SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, + SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, + SDL_BLENDOPERATION_ADD + ) + )); + sdl_check(SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 32)); + sdl_check( + SDL_RenderDrawPoints(renderer, point_batch.data(), point_batch.size()) + ); + for (auto step = 0z; step < batchsize; ++step) { + SDL_Point newpoint; + do { + newpoint = pos1 + directions[dist(rne)]; + } while (newpoint.x < 0 or newpoint.x >= width or newpoint.y < 0 or + newpoint.y >= height); + pos1 = newpoint; + point_batch[step] = newpoint; + } + sdl_check(SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 32)); + sdl_check( + SDL_RenderDrawPoints(renderer, point_batch.data(), point_batch.size()) + ); + // sdl_check(SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, + // 32)); sdl_check(SDL_RenderFillRect(renderer, nullptr)); + // SDL_RenderCopy(renderer, fade_texture, nullptr, nullptr); + + ///// Render screen + sdl_check(SDL_SetRenderTarget(renderer, nullptr)); + sdl_check( + SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE) + ); + SDL_RenderClear(renderer); + sdl_check(SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE)); + // sdl_check(SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_NONE)); + sdl_check(SDL_RenderCopy(renderer, texture, nullptr, nullptr)); + SDL_RenderPresent(renderer); +} + int main() try { sdl_check(SDL_Init(SDL_INIT_VIDEO)); Defer defer_SDL_Quit; window_t window{SDL_CreateWindow( "random walk", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, - height, SDL_WINDOW_FULLSCREEN + height, 0 // SDL_WINDOW_FULLSCREEN )}; renderer_t renderer{SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED) }; @@ -114,85 +195,32 @@ int main() try { SDL_Point pos{.x = width / 2, .y = height / 2}; SDL_Point pos1{.x = width / 2, .y = height / 2}; - constexpr 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); - constexpr auto batchsize = 10000; + bool continu = true; const auto start_time = clock::now(); auto next_poll_events_time = start_time; + auto next_frame_render_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 - ); - } - - std::array point_batch; - 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; - point_batch[step] = newpoint; - } - - ///// Render image - sdl_check(SDL_SetRenderTarget(renderer, texture)); - sdl_check(SDL_SetRenderDrawBlendMode( - renderer, - SDL_ComposeCustomBlendMode( - SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, - SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ZERO, - SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD - ) - )); - sdl_check(SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 32)); - sdl_check(SDL_RenderDrawPoints( - renderer, point_batch.data(), point_batch.size() - )); - for (auto step = 0z; step < batchsize; ++step) { - SDL_Point newpoint; - do { - newpoint = pos1 + directions[dist(rne)]; - } while (newpoint.x < 0 or newpoint.x >= width or newpoint.y < 0 or - newpoint.y >= height); - pos1 = newpoint; - point_batch[step] = newpoint; - } - sdl_check(SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 32)); - sdl_check(SDL_RenderDrawPoints( - renderer, point_batch.data(), point_batch.size() - )); - // sdl_check(SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 32)); - // sdl_check(SDL_RenderFillRect(renderer, nullptr)); - // SDL_RenderCopy(renderer, fade_texture, nullptr, nullptr); - - ///// Render screen - sdl_check(SDL_SetRenderTarget(renderer, nullptr)); - sdl_check( - SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE) - ); - SDL_RenderClear(renderer); - sdl_check(SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE)); - // sdl_check(SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_NONE)); - sdl_check(SDL_RenderCopy(renderer, texture, nullptr, nullptr)); - SDL_RenderPresent(renderer); + auto loopdata = std::tie( + renderer, texture, pos, pos1, rne, dist, start_time, + next_poll_events_time, next_frame_render_time, frame_start, frame_time, + continu + ); + std::puts("initialization complete"); +#ifdef __EMSCRIPTEN__ + // Receives a function to call and some user data to provide it. + emscripten_set_main_loop_arg(mainloop, &loopdata, 0, 1); +#else + while (continu) { + mainloop(&loopdata); + std::this_thread::sleep_until(next_frame_render_time); + next_frame_render_time += std::chrono::nanoseconds{16666666}; } +#endif // leaking memory, nothing I can do } catch (const std::exception& e) {