soundpong

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/soundpong
Log | Files | Refs

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:
Mmain.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); }