commit 0d683a0274f4701069a44daaed97cb41b5f2052e
parent 6cf93319870bf49b80b6e08951cd60581e506942
Author: Nihal Jere <nihal@nihaljere.xyz>
Date: Thu, 29 Jul 2021 17:26:03 -0500
cleanup, draw_line, split rendering and state updating
Diffstat:
M | main.c | | | 228 | +++++++++++++++++++++++-------------------------------------------------------- |
1 file changed, 66 insertions(+), 162 deletions(-)
diff --git a/main.c b/main.c
@@ -4,6 +4,7 @@
#define BALL_RADIUS 30
#define DROPRATE 2000
+#define MINLENGTH 10
const float rate = .05;
const float G = 1;
@@ -41,45 +42,6 @@ struct line *lines_last;
bool ismousedown;
SDL_Point mousedown;
-void
-draw_circle_aa(Uint32 *pixels, int w, int h, int radius)
-{
- double x, y, frac;
- int xi, yi;
- int al1, al2;
- int ffd = round(radius / sqrt(2));
- for (int i = 0; i <= ffd; i++) {
- y = sqrt(radius*radius - i*i);
- yi = y;
- frac = y - floor(y);
- al2 = 0xff*frac;
- al1 = 0xff*(1-frac);
- pixels[(yi+h/2)*w + i+w/2] = 0xFFFFFF00 + al1;
- pixels[(yi+h/2+1)*w + i+w/2] = 0xFFFFFF00 + al2;
- pixels[(h/2-yi)*w + i+w/2] = 0xFFFFFF00 + al1;
- pixels[(h/2-yi-1)*w + i+w/2] = 0xFFFFFF00 + al2;
- pixels[(h/2-yi)*w + w/2 - i] = 0xFFFFFF00 + al1;
- pixels[(h/2-yi-1)*w + w/2 - i] = 0xFFFFFF00 + al2;
- pixels[(h/2+yi)*w + w/2 - i] = 0xFFFFFF00 + al1;
- pixels[(h/2+yi+1)*w + w/2 - i] = 0xFFFFFF00 + al2;
- }
- for (int i = 0; i <= ffd; i++) {
- x = sqrt(radius*radius - i*i);
- xi = x;
- frac = x - floor(x);
- al1 = 0xff*frac;
- al2 = 0xff*(1-frac);
- pixels[(i+h/2)*w + w/2 + xi] = 0xFFFFFF00 + al2;
- pixels[(i+h/2)*w + w/2 + xi+1] = 0xFFFFFF00 + al1;
- pixels[(h/2-i)*w + w/2 + xi] = 0xFFFFFF00 + al2;
- pixels[(h/2-i)*w + w/2 + xi+1] = 0xFFFFFF00 + al1;
- pixels[(h/2-i)*w + w/2 - xi] = 0xFFFFFF00 + al2;
- pixels[(h/2-i)*w + w/2 - xi-1] = 0xFFFFFF00 + al1;
- pixels[(h/2+i)*w + w/2 - xi] = 0xFFFFFF00 + al2;
- pixels[(h/2+i)*w + w/2 - xi-1] = 0xFFFFFF00 + al1;
- }
-}
-
// This is not efficient
void
draw_circle(int x, int y, int radius)
@@ -98,7 +60,6 @@ draw_circle(int x, int y, int radius)
ix = sqrt(radius*radius - i*i);
start.x = -sqrt(radius*radius - i*i);
end.x = sqrt(radius*radius - i*i);
- SDL_Log("start, end: %d, %d", start.x, end.x);
frac = rx - ix;
SDL_SetRenderDrawColor(ren, r, g, b, a);
@@ -113,6 +74,40 @@ draw_circle(int x, int y, int radius)
started = false;
}
}
+#define PF_RGBA32 SDL_PIXELFORMAT_RGBA8888
+
+const SDL_Point zero = {0, 0};
+
+void
+draw_line(struct line line)
+{
+ int w = abs(line.start.x - line.end.x);
+ int h = abs(line.start.y - line.end.y);
+ int len = sqrt(w*w +h*h);
+ double angle = 180*atan(((double) h)/w)/M_PI;
+
+ if (line.start.y > line.end.y)
+ angle = -angle;
+
+ if (line.start.x > line.end.x)
+ angle = 180 - angle;
+
+ SDL_Rect src = {0, 0, len, 5};
+ SDL_Rect dest = {line.start.x, line.start.y, len, 2};
+ SDL_Texture *tex = SDL_CreateTexture(ren, PF_RGBA32, SDL_TEXTUREACCESS_TARGET, src.w, src.h);
+ if (tex == NULL) {
+ SDL_Log("%s warning: failed to create texture", __func__);
+ return;
+ }
+
+ SDL_SetRenderTarget(ren, tex);
+ SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
+ SDL_RenderClear(ren);
+
+ SDL_SetRenderTarget(ren, NULL);
+ SDL_RenderCopyEx(ren, tex, NULL, &dest, angle, &zero, SDL_FLIP_NONE);
+ SDL_DestroyTexture(tex);
+}
void *
xcalloc(int size)
@@ -127,7 +122,6 @@ xcalloc(int size)
void
ball_add(int x, int y)
{
- SDL_Log("%s", __func__);
if (!balls_last) {
balls_first = xcalloc(sizeof(*balls_first));
balls_first->x = x;
@@ -145,13 +139,12 @@ ball_add(int x, int y)
void
line_add(int x1, int y1, int x2, int y2)
{
- SDL_Log("%s", __func__);
if (!lines_last) {
lines_first = xcalloc(sizeof(*lines_first));
lines_first->start.x = x1;
lines_first->start.y = y1;
- lines_first->start.x = x2;
- lines_first->start.y = y2;
+ lines_first->end.x = x2;
+ lines_first->end.y = y2;
lines_last = lines_first;
} else {
lines_last->next = xcalloc(sizeof(*lines_first));
@@ -159,15 +152,14 @@ line_add(int x1, int y1, int x2, int y2)
lines_last = lines_last->next;
lines_last->start.x = x1;
lines_last->start.y = y1;
- lines_last->start.x = x2;
- lines_last->start.y = y2;
+ lines_last->end.x = x2;
+ lines_last->end.y = y2;
}
}
void
line_del(struct line *line)
{
- SDL_Log("%s", __func__);
if (line == lines_first) {
lines_first = lines_first->next;
} else {
@@ -185,7 +177,6 @@ line_del(struct line *line)
void
ball_del(struct ball *ball)
{
- SDL_Log("%s", __func__);
if (ball == balls_first) {
balls_first = balls_first->next;
} else {
@@ -218,104 +209,6 @@ setdropball(unsigned int interval, void *param)
return interval;
}
-// averages RGBA8888 colors
-Uint32
-avg4(Uint32 a, Uint32 b, Uint32 c, Uint32 d)
-{
- Uint8 *ac = (Uint8 *) &a;
- Uint8 *bc = (Uint8 *) &b;
- Uint8 *cc = (Uint8 *) &c;
- Uint8 *dc = (Uint8 *) &d;
-
- Uint8 red = (ac[0] + bc[0] + cc[0] + dc[0]) / 4;
- Uint8 green = (ac[1] + bc[1] + cc[1] + dc[1]) / 4;
- Uint8 blue = (ac[2] + bc[2] + cc[2] + dc[2]) / 4;
- Uint8 alpha = (ac[3] + bc[3] + cc[3] + dc[3]) / 4;
-
- return (alpha << 24) + (blue << 16) + (green << 8) + red;
-}
-
-Uint32
-avg6(Uint32 a, Uint32 b, Uint32 c, Uint32 d, Uint32 e, Uint32 f)
-{
- Uint8 *ac = (Uint8 *) &a;
- Uint8 *bc = (Uint8 *) &b;
- Uint8 *cc = (Uint8 *) &c;
- Uint8 *dc = (Uint8 *) &d;
- Uint8 *ec = (Uint8 *) &e;
- Uint8 *fc = (Uint8 *) &f;
-
- Uint8 red = (ac[0] + bc[0] + cc[0] + dc[0] + ec[0] + fc[0]) / 6;
- Uint8 green = (ac[1] + bc[1] + cc[1] + dc[1] + ec[1] + fc[1]) / 6;
- Uint8 blue = (ac[2] + bc[2] + cc[2] + dc[2] + ec[2] + fc[2]) / 6;
- Uint8 alpha = (ac[3] + bc[3] + cc[3] + dc[3] + ec[3] + fc[3]) / 6;
-
- return (alpha << 24) + (blue << 16) + (green << 8) + red;
-}
-
-Uint32
-avg9(Uint32 a, Uint32 b, Uint32 c, Uint32 d, Uint32 e, Uint32 f, Uint32 g, Uint32 h, Uint32 i)
-{
- Uint8 *ac = (Uint8 *) &a;
- Uint8 *bc = (Uint8 *) &b;
- Uint8 *cc = (Uint8 *) &c;
- Uint8 *dc = (Uint8 *) &d;
- Uint8 *ec = (Uint8 *) &e;
- Uint8 *fc = (Uint8 *) &f;
- Uint8 *gc = (Uint8 *) &g;
- Uint8 *hc = (Uint8 *) &h;
- Uint8 *ic = (Uint8 *) &i;
-
- Uint8 red = (ac[0] + bc[0] + cc[0] + dc[0] + ec[0] + fc[0] + gc[0] + hc[0] + ic[0]) / 9;
- Uint8 green = (ac[1] + bc[1] + cc[1] + dc[1] + ec[1] + fc[1] + gc[1] + hc[1] + ic[1]) / 9;
- Uint8 blue = (ac[2] + bc[2] + cc[2] + dc[2] + ec[2] + fc[2] + gc[2] + hc[2] + ic[2]) / 9;
- Uint8 alpha = (ac[3] + bc[3] + cc[3] + dc[3] + ec[3] + fc[3] + gc[3] + hc[3] + ic[3]) / 9;
-
- return (alpha << 24) + (blue << 16) + (green << 8) + red;
-}
-
-// assumes RGBA8888
-Uint32 *
-smooth(Uint32 *old, int w, int h)
-{
- int p = w*4;
- SDL_Log("size: %d", h*p);
- Uint32 *new = calloc(1, h*p);
- if (new == NULL)
- return NULL;
- // we could use a rolling thing for efficiency
- // corners
- new[0] = avg4(old[0], old[1], old[w], old[w+1]);
- new[w-1] = avg4(old[w-1], old[w-2], old[w+w-1], old[w+w-2]);
- new[w*(h-1)] = avg4(old[w*(h-1)], old[w*(h-1)+1], old[w*(h-2)], old[w*(h-2)+1]);
- new[w*(h-1)+w-1] = avg4(old[w*(h-1)], old[w*(h-1)+1], old[w*(h-2)], old[w*(h-2)+1]);
-
- // tow and bottom edges
- for (int i = 1; i < w - 1; i++) {
- new[i] = avg6(old[i-1], old[i], old[i+1], old[w+i-1], old[w+i], old[w+i+1]);
- new[w*(h-1)+i] = avg6(old[w*(h-1)+i-1], old[w*(h-1)+i], old[w*(h-1)+i+1], old[w*(h-2)+i-1], old[w*(h-2)+i], old[w*(h-2)+i+1]);
- }
-
- // left and right edges
- for (int i = 1; i < h - 1; i++) {
- new[w*i] = avg6(old[w*(i-1)], old[w*i], old[w*(i+1)], old[1+w*(i-1)], old[1+w*i], old[1+w*(i+1)]);
- new[w-1+w*i] = avg6(old[w*(i-1)+w-1], old[w*i+w-1], old[w*(i+1)+w-1], old[w*(i-1)+w-2], old[w*i+w-2], old[w*(i+1)+w-2]);
- }
-
- // middle
- for (int i = 1; i < w - 1; i++) {
- for (int j = 1; j < h - 1; j++) {
- new[w*j+i] = avg9(old[w*(j-1)+i-1], old[w*(j-1)+i], old[w*(j-1)+i+1],
- old[w*j+i-1], old[w*j+i], old[w*j+i+1],
- old[w*(j+1)+i-1], old[w*(j+1)+i], old[w*(j+1)+i+1]);
- }
- }
-
- free(old);
- return new;
-}
-
-#define PF_RGBA32 SDL_PIXELFORMAT_RGBA8888
const struct SDL_Rect dropper_srcrect = { 0, 0, 2*BALL_RADIUS + 10 + 2, 2*BALL_RADIUS + 10 + 3};
SDL_Texture *
@@ -334,10 +227,10 @@ render_dropper()
goto err2;
}
- SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
- SDL_RenderClear(ren);
SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
- draw_circle(BALL_RADIUS + 5, BALL_RADIUS + 5, BALL_RADIUS + 4);
+ draw_circle(BALL_RADIUS + 5, BALL_RADIUS + 5, BALL_RADIUS + 5);
+ SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
+ draw_circle(BALL_RADIUS + 5, BALL_RADIUS + 5, BALL_RADIUS);
SDL_RenderReadPixels(ren, &dropper_srcrect, PF_RGBA32, pixels, pitch);
SDL_Log("%08x%08x%08x%08x", pixels[0], pixels[1], pixels[2], pixels[3]);
@@ -389,7 +282,7 @@ main(int argc, char *argv[])
}
SDL_SetTextureBlendMode(dropper_texture, SDL_BLENDMODE_BLEND);
- dropper_dstrect = (SDL_Rect){ dropper.x - (BALL_RADIUS + 5), dropper.y - (BALL_RADIUS + 5), 2*BALL_RADIUS+10 + 1, 2*BALL_RADIUS+10 + 1 };
+ dropper_dstrect = (SDL_Rect){ dropper.x - (BALL_RADIUS + 5), dropper.y - (BALL_RADIUS + 5), 2*BALL_RADIUS+10, 2*BALL_RADIUS+10 };
balltimer = SDL_AddTimer(DROPRATE, setdropball, &dropball);
running = true;
@@ -407,6 +300,8 @@ main(int argc, char *argv[])
break;
case SDL_MOUSEBUTTONUP:
ismousedown = false;
+ if ((mousedown.x - e.button.x)*(mousedown.x - e.button.x) + (mousedown.y - e.button.y)*(mousedown.y - e.button.y) > MINLENGTH*MINLENGTH)
+ line_add(mousedown.x, mousedown.y, e.button.x, e.button.y);
break;
case SDL_QUIT:
running = false;
@@ -426,34 +321,43 @@ main(int argc, char *argv[])
dropball = false;
ball_add(dropper.x, dropper.y);
}
-
+
now = SDL_GetTicks();
delta = now - then;
if (delta < 5)
continue;
then = now;
-
- SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
- SDL_RenderClear(ren);
- SDL_RenderCopy(ren, dropper_texture, &dropper_srcrect, &dropper_dstrect);
-
- SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
+ /* update state */
for (struct ball *ball = balls_first; ball != NULL; ball = ball->next) {
ballrect = (struct SDL_Rect){ball->x - BALL_RADIUS, ball->y - BALL_RADIUS, ball->x + BALL_RADIUS, ball->y + BALL_RADIUS};
if (!SDL_HasIntersection(&ballrect, &screenrect)) {
ball_del(ball);
continue;
}
-
+
ball_update(ball, delta);
-
- //draw_circle(ball->x, ball->y, BALL_RADIUS);
}
-
+
+ /* render */
+ SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
+ SDL_RenderClear(ren);
+
+ SDL_RenderCopy(ren, dropper_texture, &dropper_srcrect, &dropper_dstrect);
+
+ SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
+
+ for (struct line *line = lines_first; line != NULL; line = line->next) {
+ draw_line(*line);
+ }
+
if (ismousedown)
- SDL_RenderDrawLine(ren, mousedown.x, mousedown.y, mousestate.x, mousestate.y);
+ SDL_RenderDrawLine(ren, mousedown.x, mousedown.y, e.button.x, e.button.y);
+
+ for (struct ball *ball = balls_first; ball != NULL; ball = ball->next) {
+ draw_circle(ball->x, ball->y, BALL_RADIUS);
+ }
SDL_RenderPresent(ren);
}