X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fcrumbler.c;h=8e783dbc0d7d242c7af652f1659c240afd3183be;hp=cf21a94e1cd5d0716001e89ca0fe9aa2a088b138;hb=refs%2Fheads%2Fmaster;hpb=78add6e627ee5f10e1fa6f3852602ea5066eee5a diff --git a/hacks/glx/crumbler.c b/hacks/glx/crumbler.c index cf21a94e..8e783dbc 100644 --- a/hacks/glx/crumbler.c +++ b/hacks/glx/crumbler.c @@ -14,7 +14,6 @@ "*wireframe: False \n" \ "*suppressRotationAnimation: True\n" \ -# define free_crumbler 0 # define release_crumbler 0 #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) @@ -130,15 +129,16 @@ render_chunk (ModeInfo *mi, chunk *c) qh_mesh_t m; GLfloat d; - c->polygon_count = 0; - c->min.x = c->min.y = c->min.z = 999999; - c->max.x = c->max.y = c->max.z = -999999; if (c->nverts <= 3) { fprintf (stderr, "%s: nverts %d\n", progname, c->nverts); abort(); } + c->polygon_count = 0; + c->min.x = c->min.y = c->min.z = 999999; + c->max.x = c->max.y = c->max.z = -999999; + for (i = 0; i < c->nverts; i++) { if (c->verts[i].x < c->min.x) c->min.x = c->verts[i].x; @@ -218,8 +218,9 @@ render_chunk (ModeInfo *mi, chunk *c) static void free_chunk (chunk *c) { + if (c->dlist) + glDeleteLists (c->dlist, 1); free (c->verts); - glDeleteLists (c->dlist, 1); free (c); } @@ -334,15 +335,20 @@ split_chunk (ModeInfo *mi, chunk *c, int nchunks) render_chunk */ crumbler_configuration *bp = &bps[MI_SCREEN(mi)]; - chunk **chunks = (chunk **) calloc (nchunks, sizeof(*chunks)); - int *keys = (int *) calloc (nchunks, sizeof(*keys)); + chunk **chunks; + int *keys; int i, j; - chunk *c2; + int retries = 0; + + RETRY: + chunks = (chunk **) calloc (nchunks, sizeof(*chunks)); + keys = (int *) calloc (nchunks, sizeof(*keys)); for (i = 0; i < nchunks; i++) { /* Fill keys with random numbers that are not duplicates. */ Bool ok = True; + chunk *c2 = 0; if (nchunks >= c->nverts) { fprintf (stderr, "%s: nverts %d nchunks %d\n", progname, @@ -351,21 +357,21 @@ split_chunk (ModeInfo *mi, chunk *c, int nchunks) } do { keys[i] = random() % c->nverts; + ok = True; for (j = 0; j < i; j++) if (keys[i] == keys[j]) { ok = False; break; } - ok = True; } while (!ok); c2 = make_chunk(); chunks[i] = c2; chunks[i]->nverts = 0; c2->verts = (qh_vertex_t *) calloc (c->nverts, sizeof(*c2->verts)); - c2->color = (c->color + (random() % (1 + (bp->ncolors / 3))) - % bp->ncolors); + c2->color = (c->color + (random() % (1 + (bp->ncolors / 3)))) + % bp->ncolors; } /* Add the verts to the approprate chunks @@ -375,6 +381,8 @@ split_chunk (ModeInfo *mi, chunk *c, int nchunks) qh_vertex_t *v0 = &c->verts[i]; int target_chunk = -1; double target_d2 = 9999999; + chunk *c2 = 0; + for (j = 0; j < nchunks; j++) { qh_vertex_t *v1 = &c->verts[keys[j]]; @@ -392,17 +400,39 @@ split_chunk (ModeInfo *mi, chunk *c, int nchunks) c2 = chunks[target_chunk]; c2->verts[c2->nverts++] = *v0; + if (c2->nverts > c->nverts) abort(); } + free (keys); + keys = 0; + for (i = 0; i < nchunks; i++) { - c2 = chunks[i]; + chunk *c2 = chunks[i]; + + /* It is possible that the keys we have chosen have resulted in one or + more cells that have 3 or fewer points in them. If that's the case, + re-randomize. + */ + if (c2->nverts <= 3) + { + for (j = 0; j < nchunks; j++) + free_chunk (chunks[j]); + free (chunks); + chunks = 0; + if (retries++ > 100) + { + fprintf(stderr, "%s: unsplittable\n", progname); + abort(); + } + goto RETRY; + } + if (i == 0) /* The one we're gonna keep */ pad_chunk (c2, c->nverts); render_chunk (mi, c2); } - free (keys); return chunks; } @@ -646,6 +676,14 @@ init_crumbler (ModeInfo *mi) # undef R } +# ifdef HAVE_MOBILE +# ifdef USE_IPHONE + density *= 0.5; /* iPhone 6s runs out of memory at 4500 nverts. */ +# else + density *= 0.3; /* Android Nexus_5_8.1 emulator runs out earlier. */ +# endif +# endif + { chunk *c; bp->nchunks = 1; @@ -817,6 +855,21 @@ draw_crumbler (ModeInfo *mi) glXSwapBuffers(dpy, window); } + +ENTRYPOINT void +free_crumbler (ModeInfo *mi) +{ + crumbler_configuration *bp = &bps[MI_SCREEN(mi)]; + int i; + free (bp->trackball); + free (bp->rot); + free (bp->colors); + for (i = 0; i < bp->nchunks; i++) + free_chunk (bp->chunks[i]); + free (bp->chunks); +} + + XSCREENSAVER_MODULE ("Crumbler", crumbler) #endif /* USE_GL */