Skip to content

Instantly share code, notes, and snippets.

@jmcd
Last active January 14, 2019 08:30
Show Gist options
  • Save jmcd/6513d16742c90be040f250e548778142 to your computer and use it in GitHub Desktop.
Save jmcd/6513d16742c90be040f250e548778142 to your computer and use it in GitHub Desktop.
A Morié pattern generator that compiles to native desktop application and wasm
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<canvas id="canvas" oncontextmenu="event.preventDefault()"></canvas>
<script type='text/javascript'>
var Module = {
canvas: (function () { return document.getElementById("canvas"); })()
};
</script>
<script src="index.js"></script>
</body>
</html>
#include <time.h>
#include <stdlib.h>
#ifdef emcc
#include <emscripten.h>
#endif
#include <SDL2/SDL.h>
#define rand_speed() (rand()%10 + 1)
#define WINDOW_WIDTH 512
#define FPS 60
#define LINE_COUNT 100
#define NUMBER_OF_POINTS_PER_LINE 4
struct context {
int lsLen;
int *ls;
int lp;
int *v;
SDL_Renderer *renderer;
};
void render(struct context *ctx) {
SDL_Renderer *renderer = ctx->renderer;
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
for (int i = 0; i < LINE_COUNT; i++) {
int ilp = (ctx->lp + (i + 1) * 4)%ctx->lsLen;
int r = i/(float)LINE_COUNT * 0xff;
SDL_SetRenderDrawColor(renderer, r, r, r, 255);
SDL_RenderDrawLine(renderer, ctx->ls[ilp+0], ctx->ls[ilp+1], ctx->ls[ilp+2], ctx->ls[ilp+3]);
}
SDL_RenderPresent(renderer);
int nlp = (ctx->lp + 4) % ctx->lsLen;
for (int i = 0; i < 4; i++) {
int tmp = ctx->ls[ctx->lp+i] + ctx->v[i];
if (tmp < 0) {
ctx->v[i] = rand_speed();
}
if (tmp >= WINDOW_WIDTH) {
ctx->v[i] = -1 * rand_speed();
}
ctx->ls[nlp+i] = ctx->ls[ctx->lp+i] + ctx->v[i];
}
ctx->lp = nlp;
}
int main(void) {
srand((uint)time(NULL));
SDL_Event event;
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Init(SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_WIDTH, 0, &window, &renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
int lsLen = NUMBER_OF_POINTS_PER_LINE * LINE_COUNT;
int ls[lsLen];
for (int i = 0; i < lsLen; i++) {
ls[i] = i < 4 ? rand()%WINDOW_WIDTH : 0;
}
int lp = 0;
int v[4] = {1, 1, 1, 1};
struct context ctx;
ctx.lp = lp;
ctx.ls = &ls;
ctx.lsLen = lsLen;
ctx.renderer = renderer;
ctx.v = &v;
Uint32 waittime = 1000.0f/FPS;
Uint32 framestarttime = 0;
Sint32 delaytime;
#ifdef emcc
// The browser render loop
emscripten_set_main_loop_arg(render, &ctx, -1, 1);
#else
// The desktop render loop
while(1)
{
if (SDL_PollEvent(&event) && event.type == SDL_QUIT) {
break;
}
render(&ctx);
delaytime = waittime - (SDL_GetTicks() - framestarttime);
if(delaytime > 0) {
SDL_Delay((Uint32)delaytime);
}
framestarttime = SDL_GetTicks();
}
#endif
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
emcc main.c -s WASM=1 -s USE_SDL=2 -O3 -Demcc -o index.js
the -Demcc flag defines "emcc", so the pre-processor can conditionally include blocks of code (#ifdef emcc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment