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