void calc()

    1 void calc()
    2 {
    3     SEEDRAND (seed->value++);
    4     register Uint16 *o;
    5     static int usedcounter = 0;
    6     static int oldborder;
    7     static int oldreverse;
    8 
    9     static Uint16 *dont = 0;
   10     static int oldwidth = 0;
   11     int s = width*2+10;
   12     if (oldwidth != width)
   13     {
   14         delete (dont);
   15         dont = new Uint16[s];
   16     }
   17     for (int i3 = 0; i3 < s; i3++) dont[i3] = 10000;
   18     oldwidth = width;
   19     int dontp;
   20     static Var *vnextInteraction = (Var*)setVar("NEXTINTERACTION",0);
   21     vnextInteraction->value = 0;
   22     if (usedcounter++ > 1000) { recalcused(); usedcounter = 0; }
   23     if (rev->value == 0) reverse = 1;
   24     if (rev->value == 1) reverse = -1;
   25     if (oldreverse != reverse) recalc = 3;
   26     oldreverse = reverse;
   27 
   28     if ( (oldinteractions != varinteractions->value) || (olddeath != vardeath->value) ||(oldgravity != vargravity->value) )
   29     {
   30         if (recalc < 3) recalc = 3;
   31         oldinteractions = varinteractions->value;
   32         olddeath = vardeath->value;
   33         oldgravity = vargravity->value;
   34     }
   35 
   36     if (recalc < 2) for (int i = 0; i < sandelements; i++)
   37         if (oldused[i] != used[i]) recalc = 2;
   38     for (int i2 = 0; i2 < sandelements; i2++)
   39         oldused[i2] = used[i2];
   40     if (recalc) precalc(recalc);
   41     static int y, start;
   42     static int r, yr, w;
   43     static Uint16 *end;
   44     static Uint16 *ybuf;
   45     static Uint16 random, tmp = 0, tmp2;
   46     tmp = 0;
   47     register int t = 0;
   48     static Uint16 *op;
   49     static int i, eatcounter, diecounter;
   50     static bool goleft = true, goright = true;
   51     goleft = goright = true;
   52 
   53     if (rl)
   54     {
   55         rl = false;
   56         start = 1;
   57     }
   58     else
   59     {
   60         rl = true;
   61         start = width-2;
   62     }
   63 
   64     static int windright, windleft;
   65     windright = 32768 + varwind->value * 32768 / 1000;
   66     windleft = 32768 - varwind->value * 32768 / 1000;
   67     if (windleft <= 0) windleft = 1;
   68     if (windright <= 0) windright = 1;
   69 
   70     if (reverse > 0) y = height-1; else y = 0;
   71     while ( ((reverse > 0) && (y >= 0)) || ((reverse < 0) && (y < height)) )
   72     {
   73         static bool nospray;
   74         if ((y == height -1) || (y == 0)) nospray = true; else nospray = false;
   75         if ((random = RANDOMNUMBER) % 2)
   76         { r = 1; yr = ypitch; }
   77         else
   78         { r = -1; yr = -ypitch; }
   79         ybuf = bufp + ypitch * y;
   80 
   81         if (rl) end = ybuf; else end = (ybuf+width)-1;
   82         *end = 1;
   83 
   84         o = (Uint16*)(ybuf+start);
   85         dontp = dont + width + 5 - o;
   86         do {
   87             if ((*(eat+(t = *o))) && ( *(*(doeseatelement+t)+(*(o-r)%DOESEATELEMENTSMAX)) || *(*(doeseatelement+t)+(*(o+r)%DOESEATELEMENTSMAX)) || *(*(doeseatelement+t)+(*(o+yr)%DOESEATELEMENTSMAX)) || *(*(doeseatelement+t)+(*(o-yr)%DOESEATELEMENTSMAX)) ) && (*(o+dontp) != y))
   88             {
   89                 eatcounter = 0;
   90                 do
   91                 {
   92                     if (*(*(eatelement+t)+eatcounter) != 1)
   93                     {
   94                         if (tmp2 = ((tmp = *(*(eatelement+t)+eatcounter)) == *(o-1)) + (tmp == *(o+1)) + ((tmp == *(o+yr)) && !nospray) + (tmp == *(o-yr)) )
   95                         {
   96 #define INTERACTION(x,dx,dy)  if ((tmp == *(x)) && !(tmp2--)) \
   97                             { \
   98                                 if (*(*(eattrigger+t)+eatcounter)) \
   99                                 { \
  100                                     *(used+(*(x) = *(*(eattoother+t)+eatcounter))) = true;\
  101                                     *(used+(*o = *(*(eattoself+t)+eatcounter))) = true;\
  102                                     *(o+doutSurface) = *(color+*o);\
  103                                     *((x)+doutSurface) = *(color+*(x));\
  104                                     t = 1;\
  105                                     goto next; \
  106                                 } else { \
  107                                     interactionTrigger((void*) eattoother[t][eatcounter],t,tmp,o-ybuf,y+1,o-ybuf+dx,y+dy+1);\
  108                                     *end = 1; \
  109                                     if (vnextInteraction->value) \
  110                                         vnextInteraction->value = 0; \
  111                                     else \
  112                                     { \
  113                                         if (*(nobias+t)) { if (rl) { if (*(o-1) != 1) o--; } else { if (*(o+1) != 1) o++; } } \
  114                                         goto next; \
  115                                     } \
  116                                 } \
  117                             }
  118                             if (*(nobias+t))
  119                             {
  120                                 if ((RANDOMNUMBER < eatspeed[t][eatcounter]))
  121                                 {
  122                                     *(o+dontp) = y - reverse;
  123                                     tmp2 = RANDOMNUMBER % tmp2;
  124                                     INTERACTION(o+yr,0,yr/abs(yr)) INTERACTION(o-yr,0,-yr/abs(yr))
  125                                     INTERACTION(o-r,-r/abs(r),0) INTERACTION(o+r,r/abs(r),0)
  126                                 }
  127                             }
  128                             else
  129                             {
  130                                 tmp2 = 0;
  131                                 if (RANDOMNUMBER < eatspeed[t][eatcounter]) { INTERACTION(o-r,-r/abs(r),0) tmp2 = 0;}
  132                                 if (RANDOMNUMBER < eatspeed[t][eatcounter]) { INTERACTION(o+r,r/abs(r),0) tmp2 = 0;}
  133                                 if (RANDOMNUMBER < eatspeed[t][eatcounter]) { INTERACTION(o+yr,0,yr/abs(yr)) tmp2 = 0;}
  134                                 if (RANDOMNUMBER < eatspeed[t][eatcounter]) { INTERACTION(o-yr,0,-yr/abs(yr)) }
  135                             }
  136                         }
  137                     }
  138                     else
  139                     {
  140 #define INTERACTION_ALL(x,dx,dy) if ( (t != *(x)) &&  (eatnot[t][eatcounter] != *(x)) \
  141                                 &&  (1 != *(x)) && !(tmp2--)) \
  142                             { \
  143                                 if (eattrigger[t][eatcounter]) \
  144                                 { \
  145                                     if (eattoother[t][eatcounter] != 1) \
  146                                         used[*(x) = eattoother[t][eatcounter]] = true; \
  147                                     if (eattoself[t][eatcounter] != 1) \
  148                                         used[*o = eattoself[t][eatcounter]] = true;\
  149                                     else \
  150                                         *o = *(x); \
  151                                     *(o+doutSurface) = *(color+*o);\
  152                                     *((x)+doutSurface) = *(color+*(x));\
  153                                     t = 1;\
  154                                     goto next; \
  155                                 } else { \
  156                                     interactionTrigger((void*) eattoother[t][eatcounter],t,*(x),o-ybuf,y+1,o-ybuf+dx,y+dy+1);\
  157                                     *end = 1; \
  158                                     if (vnextInteraction->value) \
  159                                         vnextInteraction->value = 0; \
  160                                     else \
  161                                     { \
  162                                         if (*(nobias+t)) { if (rl) { if (*(o-1) != 1) o--; } else { if (*(o+1) != 1) o++; } } \
  163                                         goto next; \
  164                                     } \
  165                                 } \
  166                             }
  167                             if (*(nobias+t))
  168                             {
  169                                 if ((RANDOMNUMBER < eatspeed[t][eatcounter]))
  170                                 {
  171                                     tmp2 = ((t != *(o-r )) &&  (eatnot[t][eatcounter] != *(o-r )) &&  (1 != *(o-r ))) +
  172                                            ((t != *(o+r )) &&  (eatnot[t][eatcounter] != *(o+r )) &&  (1 != *(o+r ))) +
  173                                            ((t != *(o-yr)) &&  (eatnot[t][eatcounter] != *(o-yr)) &&  (1 != *(o-yr))) +
  174                                            ((t != *(o+yr)) &&  (eatnot[t][eatcounter] != *(o+yr)) &&  (1 != *(o+yr)) && !nospray);
  175                                     if (tmp2)
  176                                     {
  177                                         *(o+dontp) = y - reverse;
  178                                         tmp2 = RANDOMNUMBER % tmp2;
  179                                         INTERACTION_ALL(o-r,-r/abs(r),0) INTERACTION_ALL(o+r,r/abs(r),0)
  180                                         INTERACTION_ALL(o+yr,0,yr/abs(yr)) INTERACTION_ALL(o-yr,0,-yr/abs(yr))
  181                                     }
  182                                 }
  183                             }
  184                             else
  185                             {
  186                                 tmp2 = 0;
  187                                 if (RANDOMNUMBER < eatspeed[t][eatcounter]) { INTERACTION_ALL(o-r,-r/abs(r),0) tmp2 = 0; }
  188                                 if (RANDOMNUMBER < eatspeed[t][eatcounter]) { INTERACTION_ALL(o+r,r/abs(r),0) tmp2 = 0; }
  189                                 if (RANDOMNUMBER < eatspeed[t][eatcounter]) { INTERACTION_ALL(o+yr,0,yr/abs(yr)) tmp2 = 0; }
  190                                 if (RANDOMNUMBER < eatspeed[t][eatcounter]) { INTERACTION_ALL(o-yr,0,-yr/abs(yr)) }
  191                             }
  192                     }
  193                 } while ( eatspeed[t][++eatcounter]);
  194             }
  195             if (*(dierate+t) && ((random = (random*3723+6) % 32768) <= *(dierate+t)))
  196             {
  197                 diecounter = 0;
  198                 do
  199                 {
  200                     if (RANDOMNUMBER <= *(*(life+t)+diecounter))
  201                     {
  202                         *(o+doutSurface) = *(color+(*o = *(*(dieto+t)+diecounter)));
  203                         goto next;
  204                     }
  205                 } while( *(*(life+t)+ ++diecounter));
  206             }
  207             else if ((w=*(aweight+(t))) != 999999)
  208             {
  209                 if ( (*(op = o + *(directionypitch+t)) != t) &&
  210                     (!(*op) &&
  211                     (
  212                         nospray || ( (random % *(spray+t)) && (*(op+*(directionypitch+t))==t) ) ||
  213                         ( (random = (random*7) % 32768) < w ) && (*(o+dontp) != y)
  214                     ) || ( (*(weight+t)>*(weight+*op)) && (*(o+dontp) != y) && ( (random = (random*7) % 32768) < (( *(weight+t)-*(weight+*op)) / (*(viscousity+t)+*(viscousity+*op))) ) ) ) )
  215                 {
  216                     if (*(nobias+t)) *(o+dontp) = y - reverse;
  217                     *(o+doutSurface) = *(color+(*(o) = *(op)));
  218                     *(op+doutSurface) = *(color+(*(op) = t));
  219                 }
  220                 else if (((*(o+1) != t) || (*(o-1) != t)) && ((random++) % *(side+t)))
  221                 {
  222                     i = 1;
  223                     do
  224                     {
  225                         if (w <= *(aweight+*(o+i))) { goright = false; }
  226                         else if (w > *(aweight+*(op+i)))
  227                         {
  228                             if (w > *(aweight+*(op-i)))  { if (random % 2) { goright = false; } else { goleft = false; break; } }
  229                             else { goleft = false; break; }
  230                         }
  231                         if (w <= *(aweight+*(o-i))) { goleft  = false; }
  232                         else if (w > *(aweight+*(op-i)))
  233                         {
  234                             if (w > *(aweight+*(op+i)))  { if (random % 2) { goright = false; } else { goleft = false; break; } }
  235                             else { goright = false; break; }
  236                         }
  237                     } while (goleft && goright && i++);
  238                     if (goleft || goright)
  239                     {
  240                         if (!goright && (random < windright))
  241                         {
  242                             if (i > 2) i = 2;
  243                             *(o+doutSurface) = *(color+(*(o) = *(o-i)));
  244                             *(o+doutSurface-i) = *(color+(*(o-i) = t));
  245                         }
  246                         else if (!goleft && (random < windleft))
  247                         {
  248                             if (i > 2) i = 2;
  249                             *(o+doutSurface) = *(color+(*(o) = *(o+i)));
  250                             *(o+doutSurface+i) = *(color+(*(o+i) = t));
  251                         }
  252                     }
  253                     else
  254                     {
  255                         goleft = goright = true;
  256                     }
  257                 }
  258             }
  259             next:
  260             if (rl)
  261             {
  262                 #ifdef COMPILER_GCC
  263                 do while (!(*(long*)(o-2))) o -= 2;
  264                     while (*(skip+*(--o)) && *(skip+*(--o)) && *(skip+*(--o)) && *(skip+*(--o)));
  265                 #else
  266                 while (!--o);
  267                 while (*(skip+*(o))) o--;
  268                 #endif
  269 //              do while (!(*(long*)(o-2))) o -= 2; while (*(skip+*(--o)) && *(skip+*(--o)) && *(skip+*(--o)) && *(skip+*(--o)));
  270             }
  271             else
  272             {
  273                 /*__asm__ __volatile__ (
  274                 "   prefetchnta 512(%0)\n"
  275                 : : "r" (o) );*/
  276                 #ifdef COMPILER_GCC
  277                 do while (!(*(long*)(o+1))) o += 2;
  278                     while (*(skip+*(++o)) && *(skip+*(++o)) && *(skip+*(++o)) && *(skip+*(++o)));
  279                 #else
  280                 while (!++o);
  281                 while (*(skip+*(o))) o++;
  282                 #endif
  283 //              do while (!(*(long*)(o+1))) o += 2; while (*(skip+*(++o)) && *(skip+*(++o)) && *(skip+*(++o)) && *(skip+*(++o)));
  284             }
  285         } while (o != end);
  286 
  287         if (reverse > 0) --y; else ++y;
  288     }
  289 
  290     o = (Uint16*)(bufp-width);
  291     op = (Uint16*)(bufp);
  292     int delta = (height*ypitch+ypitch);
  293 
  294     t = varborder->value;
  295     if (t == 1)
  296     {
  297         while (o < op)
  298         {
  299             *(o) = 1;
  300             *(o++ +delta) = 1;
  301         }
  302     }
  303     else if (t == 0)
  304     {
  305         while (o < op)
  306         {
  307             *(o + doutSurface) = *(o) = 0;
  308             *(o + delta + doutSurface) = *(o + delta) = 0;
  309             o++;
  310         }
  311     }
  312     else if (t == 2)
  313     {
  314         if (oldborder != t)
  315             while (o < op)
  316             {
  317                 *(o) = 0;
  318                 *(o++ +delta) = 0;
  319             }
  320         while (o < op)
  321         {
  322             if (!*(o +         ypitch))
  323             {
  324                 *(o +         ypitch + doutSurface) = *(color+(*(o +         ypitch) = *(o + delta)));
  325                 *(o + delta + doutSurface) = *(o + delta) = 0;
  326             }
  327             if (!*(o + delta - ypitch))
  328             {
  329                 *(o + delta - ypitch + doutSurface) = *(color+(*(o + delta - ypitch) = *(o        )));
  330                 *(o + doutSurface) = *(o) = 0;
  331             }
  332             o++;
  333         }
  334         o = (Uint16*)(bufp-width);
  335     }
  336     oldborder = t;
  337 }


©2008 Max Nagl
Web-design, development and programming by Max Nagl