Noble Ape
The Central Directories of the Noble Ape Simulation.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
math.c
Go to the documentation of this file.
1 /****************************************************************
2 
3  math.c
4 
5  =============================================================
6 
7  Copyright 1996-2014 Tom Barbalet. All rights reserved.
8 
9  Permission is hereby granted, free of charge, to any person
10  obtaining a copy of this software and associated documentation
11  files (the "Software"), to deal in the Software without
12  restriction, including without limitation the rights to use,
13  copy, modify, merge, publish, distribute, sublicense, and/or
14  sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following
16  conditions:
17 
18  The above copyright notice and this permission notice shall be
19  included in all copies or substantial portions of the Software.
20 
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  OTHER DEALINGS IN THE SOFTWARE.
29 
30  This software and Noble Ape are a continuing work of Tom Barbalet,
31  begun on 13 June 1996. No apes or cats were harmed in the writing
32  of this software.
33 
34  ****************************************************************/
35 
42 #include "noble.h"
43 
45 static const n_int new_sd[256] =
46 {
47  0, 659, 1318, 1977, 2634, 3290, 3944, 4595, 5244, 5889, 6531, 7169, 7802, 8431, 9055, 9673,
48  10286, 10892, 11492, 12085, 12671, 13249, 13819, 14380, 14933, 15477, 16012, 16537, 17052, 17557, 18051, 18534,
49  19007, 19467, 19916, 20353, 20778, 21190, 21590, 21976, 22349, 22709, 23055, 23387, 23706, 24009, 24299, 24573,
50  24833, 25078, 25308, 25523, 25722, 25906, 26074, 26226, 26363, 26484, 26589, 26677, 26750, 26807, 26847, 26871,
51  26880, 26871, 26847, 26807, 26750, 26677, 26589, 26484, 26363, 26226, 26074, 25906, 25722, 25523, 25308, 25078,
52  24833, 24573, 24299, 24009, 23706, 23387, 23055, 22709, 22349, 21976, 21590, 21190, 20778, 20353, 19916, 19467,
53  19007, 18534, 18051, 17557, 17052, 16537, 16012, 15477, 14933, 14380, 13819, 13249, 12671, 12085, 11492, 10892,
54  10286, 9673, 9055, 8431, 7802, 7169, 6531, 5889, 5244, 4595, 3944, 3290, 2634, 1977, 1318, 659,
55  0, -659, -1318, -1977, -2634, -3290, -3944, -4595, -5244, -5889, -6531, -7169, -7802, -8431, -9055, -9673,
56  -10286, -10892, -11492, -12085, -12671, -13249, -13819, -14380, -14933, -15477, -16012, -16537, -17052, -17557, -18051, -18534,
57  -19007, -19467, -19916, -20353, -20778, -21190, -21590, -21976, -22349, -22709, -23055, -23387, -23706, -24009, -24299, -24573,
58  -24833, -25078, -25308, -25523, -25722, -25906, -26074, -26226, -26363, -26484, -26589, -26677, -26750, -26807, -26847, -26871,
59  -26880, -26871, -26847, -26807, -26750, -26677, -26589, -26484, -26363, -26226, -26074, -25906, -25722, -25523, -25308, -25078,
60  -24833, -24573, -24299, -24009, -23706, -23387, -23055, -22709, -22349, -21976, -21590, -21190, -20778, -20353, -19916, -19467,
61  -19007, -18534, -18051, -17557, -17052, -16537, -16012, -15477, -14933, -14380, -13819, -13249, -12671, -12085, -11492, -10892,
62  -10286, -9673, -9055, -8431, -7802, -7169, -6531, -5889, -5244, -4595, -3944, -3290, -2634, -1977, -1318, -659
63 };
64 
70 void vect2_byte2(n_vect2 * converter, n_byte2 * input)
71 {
72  NA_ASSERT(converter, "converter NULL");
73  NA_ASSERT(input, "input NULL");
74 
75  if (converter == 0L) return;
76  if (input == 0L) return;
77 
78  converter->x = input[0];
79  converter->y = input[1];
80 }
81 
88 void vect2_add(n_vect2 * equals, n_vect2 * initial, n_vect2 * second)
89 {
90  NA_ASSERT(equals, "equals NULL");
91  NA_ASSERT(initial, "initial NULL");
92  NA_ASSERT(second, "second NULL");
93 
94  if (equals == 0L) return;
95  if (initial == 0L) return;
96  if (second == 0L) return;
97 
98  equals->x = initial->x + second->x;
99  equals->y = initial->y + second->y;
100 }
101 
102 
103 void vect2_center(n_vect2 * center, n_vect2 * initial, n_vect2 * second)
104 {
105  vect2_add(center, initial, second);
106  center->x = center->x / 2;
107  center->y = center->y / 2;
108 }
109 
116 void vect2_subtract(n_vect2 * equals, n_vect2 * initial, n_vect2 * second)
117 {
118  NA_ASSERT(equals, "equals NULL");
119  NA_ASSERT(initial, "initial NULL");
120  NA_ASSERT(second, "second NULL");
121 
122  if (equals == 0L) return;
123  if (initial == 0L) return;
124  if (second == 0L) return;
125 
126  equals->x = initial->x - second->x;
127  equals->y = initial->y - second->y;
128 }
129 
138 void vect2_multiplier(n_vect2 * equals, n_vect2 * initial, n_vect2 * second,
139  n_int multiplier, n_int divisor)
140 {
141  NA_ASSERT(equals, "equals NULL");
142  NA_ASSERT(initial, "initial NULL");
143  NA_ASSERT(second, "second NULL");
144  NA_ASSERT(divisor, "divisor ZERO");
145 
146  if (equals == 0L) return;
147  if (initial == 0L) return;
148  if (second == 0L) return;
149  if (divisor == 0L) return;
150 
151  equals->x = (multiplier * initial->x * second->x) / divisor;
152  equals->y = (multiplier * initial->y * second->y) / divisor;
153 }
154 
163 void vect2_d(n_vect2 * initial, n_vect2 * second, n_int multiplier, n_int divisor)
164 {
165  NA_ASSERT(initial, "initial NULL");
166  NA_ASSERT(second, "second NULL");
167  NA_ASSERT(divisor, "divisor ZERO");
168 
169  if (initial == 0L) return;
170  if (second == 0L) return;
171  if (divisor == 0L) return;
172 
173  initial->x += ( (multiplier * second->x) / divisor);
174  initial->y += ( (multiplier * second->y) / divisor);
175 }
176 
185 n_int vect2_dot(n_vect2 * initial, n_vect2 * second,
186  n_int multiplier, n_int divisor)
187 {
188  NA_ASSERT(initial, "initial NULL");
189  NA_ASSERT(second, "second NULL");
190  NA_ASSERT(divisor, "divisor ZERO");
191 
192  if (initial == 0L) return 0;
193  if (second == 0L) return 0;
194 
195  return (multiplier * ((initial->x * second->x) + (initial->y * second->y))) / divisor;
196 }
197 
204 n_int math_sine(n_int direction, n_int divisor)
205 {
206  NA_ASSERT(divisor, "divisor ZERO");
207  return new_sd[(direction)&255] / (divisor);
208 }
209 
210 void vect2_rotate90(n_vect2 * rotation)
211 {
212  n_int temp = rotation->y;
213  rotation->y = 0 - rotation->x;
214  rotation->x = temp;
215 }
216 
223 void vect2_direction(n_vect2 * initial, n_int direction, n_int divisor)
224 {
225  NA_ASSERT(initial, "initial NULL");
226  NA_ASSERT(divisor, "divisor ZERO");
227  initial->x = ((new_sd[((direction)+64)&255]) / (divisor));
228  initial->y = ((new_sd[(direction)&255]) / (divisor));
229 }
230 
231 void vect2_offset(n_vect2 * initial, n_int dx, n_int dy)
232 {
233  NA_ASSERT(initial, "initial NULL");
234 
235  if (initial == 0L) return;
236 
237  initial->x += dx;
238  initial->y += dy;
239 }
240 
241 void vect2_back_byte2(n_vect2 * converter, n_byte2 * output)
242 {
243  NA_ASSERT(converter, "converter NULL");
244  NA_ASSERT(output, "output NULL");
245 
246  if (converter == 0L) return;
247  if (output == 0L) return;
248 
249  if (converter->x > 65535) converter->x = 65535;
250  if (converter->y > 65535) converter->y = 65535;
251  if (converter->x < 0) converter->x = 0;
252  if (converter->y < 0) converter->y = 0;
253 
254  output[0] = (n_byte2) converter->x;
255  output[1] = (n_byte2) converter->y;
256 }
257 
258 void vect2_copy(n_vect2 * to, n_vect2 * from)
259 {
260  to->x = from->x;
261  to->y = from->y;
262 }
263 
264 void vect2_populate(n_vect2 * value, n_int x, n_int y)
265 {
266  value->x = x;
267  value->y = y;
268 }
269 
270 void vect2_rotation(n_vect2 * location, n_vect2 * rotation)
271 {
272  n_vect2 temp;
273 
274  temp.x = ((location->x * rotation->x) + (location->y * rotation->y)) / SINE_MAXIMUM;
275  temp.y = ((location->x * rotation->y) - (location->y * rotation->x)) / SINE_MAXIMUM;
276 
277  location->x = temp.x;
278  location->y = temp.y;
279 }
280 
282 {
283  return ((nonzero->x != 0) || (nonzero->y != 0));
284 }
285 
287 {
288  n_vect2 * min_max = io_new(2 * sizeof(n_vect2));
289  if (min_max == 0L)
290  {
291  return 0L;
292  }
293  vect2_populate(&min_max[0], 2147483647, 2147483647);
294  vect2_populate(&min_max[1], -2147483648, -2147483648);
295  return min_max;
296 }
297 
298 void vect2_min_max(n_vect2 * points, n_int number, n_vect2 * maxmin)
299 {
300  n_int loop = 0;
301 
302  while(loop < number)
303  {
304  n_int px = points[loop].x;
305  n_int py = points[loop].y;
306  if (px < maxmin[0].x)
307  {
308  maxmin[0].x = px;
309  }
310  if (py < maxmin[0].y)
311  {
312  maxmin[0].y = py;
313  }
314 
315  if (px > maxmin[1].x)
316  {
317  maxmin[1].x = px;
318  }
319  if (py > maxmin[1].y)
320  {
321  maxmin[1].y = py;
322  }
323  loop++;
324  }
325 }
326 
327 
328 void math_pack(n_int size, n_byte value, n_byte * alloc1, n_byte *alloc2)
329 {
330  n_int loop = 0;
331  while (loop < size)
332  {
333  alloc1[loop]=value;
334  alloc2[loop]=value;
335  loop++;
336  }
337 }
338 
339 
341 {
342 #define POSITIVE_TILE_COORD(num) ((num+(3*MAP_DIMENSION))&(MAP_DIMENSION-1))
343 
344  return POSITIVE_TILE_COORD(px) + (POSITIVE_TILE_COORD(py) << MAP_BITS);
345 }
346 
347 
348 
349 void math_round(n_byte * local_map, n_byte * scratch,
350  n_memory_location * mem_func)
351 {
352  n_int local_tile_dimension = 1 << MAP_BITS;
353 
354  n_int span_minor = 0;
356  while (span_minor < 6)
357  {
358  n_byte *front, *back;
359  n_int py = 0;
360 
361  if ((span_minor&1) == 0)
362  {
363  front = local_map;
364  back = scratch;
365  }
366  else
367  {
368  front = scratch;
369  back = local_map;
370  }
371  while (py < local_tile_dimension)
372  {
373  n_int px = 0;
374  while (px < local_tile_dimension)
375  {
376  n_int sum = 0;
377  n_int ty = -1;
378  while (ty < 2)
379  {
380  n_int tx = -1;
381  while (tx < 2)
382  {
383  sum += front[(*mem_func)((px+tx),(py+ty))];
384  tx++;
385  }
386  ty++;
387  }
388  back[(*mem_func)((px),(py))] = (n_byte)(sum / 9);
389  px ++;
390  }
391  py ++;
392  }
393  span_minor ++;
394  }
395 }
396 
397 typedef struct{
403 
404 
405 static void math_round_smarter_scan(void * void_mrss, void * xlocation, void * unused)
406 {
408  n_byte *front = mrss->front;
409  n_byte *back = mrss->back;
410  n_int local_tile_dimension = mrss->local_tile_dimension;
411  n_memory_location * mem_func = mrss->mem_func;
412  n_int px = ((n_int*)(xlocation))[0];
413  n_int py = 0;
414 
415  n_int running_sum = front[(*mem_func)((px-1),(py-1))];
416  running_sum += front[(*mem_func)((px+0),(py-1))];
417  running_sum += front[(*mem_func)((px+1),(py-1))];
418 
419  running_sum += front[(*mem_func)((px-1),(py+0))];
420  running_sum += front[(*mem_func)((px+0),(py+0))];
421  running_sum += front[(*mem_func)((px+1),(py+0))];
422 
423  running_sum += front[(*mem_func)((px-1),(py+1))];
424  running_sum += front[(*mem_func)((px+0),(py+1))];
425  running_sum += front[(*mem_func)((px+1),(py+1))];
426 
427  while (py < local_tile_dimension)
428  {
429  back[(*mem_func)((px),(py))] = (n_byte)(running_sum / 9);
430 
431  running_sum -= front[(*mem_func)((px-1),(py-1))];
432  running_sum -= front[(*mem_func)((px+0),(py-1))];
433  running_sum -= front[(*mem_func)((px+1),(py-1))];
434 
435  py ++;
436 
437  running_sum += front[(*mem_func)((px-1),(py+1))];
438  running_sum += front[(*mem_func)((px+0),(py+1))];
439  running_sum += front[(*mem_func)((px+1),(py+1))];
440  }
441  io_free(&xlocation);
442 }
443 
444 void math_round_smarter(n_byte * local_map, n_byte * scratch,
445  n_memory_location * mem_func)
446 {
447  n_int span_minor = 0;
448 
450 
451  mrss.local_tile_dimension = 1 << MAP_BITS;
452  mrss.mem_func = mem_func;
454  while (span_minor < 6)
455  {
456  n_int px = 0;
457  if ((span_minor&1) == 0)
458  {
459  mrss.front = local_map;
460  mrss.back = scratch;
461  }
462  else
463  {
464  mrss.front = scratch;
465  mrss.back = local_map;
466  }
467 
468  while (px < mrss.local_tile_dimension)
469  {
470  n_int * xlocation = io_new(sizeof(n_int));
471  xlocation[0] = px;
472 
473 #ifdef EXECUTE_THREADED
474  execute_add(((execute_function*)math_round_smarter_scan), (void*)&mrss, (void*)xlocation, 0L);
475 #else
476  math_round_smarter_scan((void*)&mrss, xlocation, 0L);
477 #endif
478 
479  px ++;
480  }
481 
482 #ifdef EXECUTE_THREADED
484 #endif
485  span_minor ++;
486  }
487 }
488 
496 void math_patch(n_byte * local_map,
497  n_memory_location * mem_func,
498  n_patch * func, n_byte2 * arg,
499  n_int refine)
500 {
503  const n_int local_tiles = 1 << (MAP_BITS-8);
504  const n_int span_minor = (64 >> ((refine&7)^7));
505  const n_int span_major = (1 << ((refine&7)^7));
506  n_int tile_y = 0;
507 
508  NA_ASSERT(local_map, "local_map NULL");
509  NA_ASSERT(func, "func NULL");
510  NA_ASSERT(arg, "arg NULL");
511 
513  while (tile_y < local_tiles)
514  {
516  n_int tile_x = 0;
517  while (tile_x < local_tiles)
518  {
520  n_int py = 0;
521  while (py < span_minor)
522  {
523  n_int px = 0;
524  while (px < span_minor)
525  {
527  n_int val1 = ((px << 2) + (py << 10));
528  n_int ty = 0;
529  n_int tseed = (*func)(arg);
530 
531  while (ty < 4)
532  {
533  n_int tx = 0;
534  while (tx < 4)
535  {
536  n_int val2 = (tseed >> (tx | (ty << 2)));
537  n_int val3 = ((((val2 & 1) << 1)-1) * 20);
538  n_int my = 0;
539 
540  val2 = (tx | (ty << 8));
541 
542  while (my < span_major)
543  {
544  n_int mx = 0;
545  while (mx < span_major)
546  {
547  n_int point = ((mx | (my << 8)) + (span_major * (val1 + val2)));
548  n_int pointx = (point & 255);
549  n_int pointy = (point >> 8);
551  if (refine&2)
552  {
553  n_int pointx_tmp = pointx + pointy;
554  pointy = pointx - pointy;
555  pointx = pointx_tmp;
556  }
557  {
559  n_uint newloc = (*mem_func)((pointx + (tile_x<<8)) ,(pointy + (tile_y<<8)));
560  n_int local_map_point = local_map[newloc] + val3;
561  if (local_map_point < 0) local_map_point = 0;
562  if (local_map_point > 255) local_map_point = 255;
563  local_map[newloc] = (n_byte)local_map_point;
564  }
565  mx++;
566  }
567  my++;
568  }
569  tx++;
570  }
571  ty++;
572  }
573  px++;
574  }
575  py++;
576  }
577  tile_x++;
578  }
579  tile_y++;
580  }
581 }
582 
594 n_byte math_join(n_int sx, n_int sy, n_int dx, n_int dy, n_join * draw)
595 {
596  n_int px = sx;
597  n_int py = sy;
598 
599  n_pixel * local_draw;
600  void * local_info;
601 
602  NA_ASSERT(draw, "draw NULL");
603 
604  if (draw == 0L) return 1;
605  if (draw->pixel_draw == 0L) return 1;
606 
607  local_draw = draw->pixel_draw;
608  local_info = draw->information;
609 
610  NA_ASSERT(local_draw, "local_draw NULL");
611  NA_ASSERT(local_info, "local_info NULL");
612 
613  if ((*local_draw)(px, py, 0, 0, local_info))
614  {
615  return 1;
616  }
617  if ((dx == 0) && (dy == 0))
618  {
619  return 0;
620  }
621  {
622  n_int dxabs = dx;
623  n_int dyabs = dy;
624 
625  n_int sdx = (dxabs != 0);
626  n_int sdy = (dyabs != 0);
627  if (dxabs < 0)
628  {
629  dxabs = 0 - dxabs;
630  sdx = -1;
631  }
632  if (dyabs < 0)
633  {
634  dyabs = 0 - dyabs;
635  sdy = -1;
636  }
637  if (dxabs >= dyabs)
638  {
639  n_int y2 = dxabs >> 1;
640  n_int i = 0;
641  while (i++ < dxabs)
642  {
643  y2 += dyabs;
644  if (y2 >= dxabs)
645  {
646  y2 -= dxabs;
647  py += sdy;
648  }
649  px += sdx;
650  if ((*local_draw)(px, py, sdx, sdy, local_info))
651  return 1;
652  }
653  }
654  else
655  {
656  n_int x2 = dyabs >> 1;
657  n_int i = 0;
658  while (i++ < dyabs)
659  {
660  x2 += dxabs;
661  if (x2 >= dyabs)
662  {
663  x2 -= dyabs;
664  px += sdx;
665  }
666  py += sdy;
667  if ((*local_draw)(px, py, sdx, sdy, local_info))
668  return 1;
669  }
670  }
671  }
672  return 0;
673 }
674 
676 {
677  return math_join(sx, sy, vect->x, vect->y, draw);
678 }
679 
680 n_byte math_line_vect(n_vect2 * point1, n_vect2 * point2, n_join * draw)
681 {
682  n_vect2 delta;
683  vect2_subtract(&delta, point2, point1);
684  return math_join(point1->x, point1->y, delta.x, delta.y, draw);
685 }
686 
687 n_byte math_line(n_int x1, n_int y1, n_int x2, n_int y2, n_join * draw)
688 {
689  n_int dx = x2 - x1;
690  n_int dy = y2 - y1;
691  return math_join(x1, y1, dx, dy, draw);
692 }
693 
695 {
696  n_byte4 hash = 2166136261;
697  while(*key)
698  hash = (16777619 * hash) ^ (*key++);
699  return hash;
700 }
701 
709 n_uint math_hash(n_byte * values, n_uint length)
710 {
711  n_uint loop = 0;
712  n_byte2 round[5]= {0xfa78, 0xfad7, 0x53e7, 0xa728, 0x2c81};
713 
714  NA_ASSERT(values, "values NULL");
715 
716  if (sizeof(n_uint) == 8)
717  {
718  n_uint big_round[4];
719 
720  while( loop < length)
721  {
722  round[0]^=round[4];
723  round[1]^=values[loop++];
724  math_random3(round);
725  math_random3(&round[1]);
726  math_random3(&round[2]);
727  math_random3(&round[3]);
728  }
729  big_round[0] = round[0];
730  big_round[1] = round[1];
731  big_round[2] = round[2];
732  big_round[3] = round[3];
733 
734  return big_round[0] | (big_round[1]<<16) | (big_round[2] << 32) | (big_round[3]<<48);
735  }
736 
737  while(loop<length)
738  {
739  round[1]^=values[loop++];
740  math_random3(round);
741  }
742  return round[0] | (round[1]<<16);
743 }
744 
745 #define NUMBER_TURN_TOWARDS_POINTS 8
746 
758 {
760  {
761  64, 64, 32, 16, 8, 4, 2, 1
762  };
763  n_vect2 vector_facing;
764  n_int best_p;
765  n_int best_f = fac;
766  n_int loop = turn;
767 
768  NA_ASSERT(p, "p NULL");
769 
770  vect2_direction(&vector_facing, best_f, 32);
771 
772  best_p = vect2_dot(p, &vector_facing, 1, 1);
773 
774  while (loop < NUMBER_TURN_TOWARDS_POINTS)
775  {
776  n_int loc_track = track[loop];
777  n_int loc_f = (best_f + loc_track) & 255;
778  n_int project1;
779 
780  vect2_direction(&vector_facing, loc_f, 32);
781  project1 = vect2_dot(p, &vector_facing, 1, 1);
782 
783  if (project1 > best_p)
784  {
785  best_f = loc_f;
786  best_p = project1;
787  }
788  else
789  {
790  n_int loc_f2 = (best_f + 256 - loc_track) & 255;
791  n_int project2;
792 
793  vect2_direction(&vector_facing, loc_f, 32);
794  project2 = vect2_dot(p, &vector_facing, 1, 1);
795 
796  if (project2 > best_p)
797  {
798  best_f = loc_f2;
799  best_p = project2;
800  }
801  }
802  loop++;
803  }
804  return (n_byte)best_f;
805 }
806 
808 {
809  n_int result = (n_int)(val >> 1);
810 
811  if ((val & 1) == 1)
812  {
813  result = 0 - result;
814  }
815  return result;
816 }
817 
826 {
827  n_byte2 tmp0;
828  n_byte2 tmp1;
829 
830  NA_ASSERT(local, "local NULL");
831 
832  if (local == 0L) return 0;
833 
834  tmp0 = local[0];
835  tmp1 = local[1];
836 
837  local[0] = tmp1;
838  switch (tmp0 & 7)
839  {
840  case 0:
841  local[1] = (n_byte2)(tmp1 ^ (tmp0 >> 1) ^ 0xd028);
842  break;
843  case 3:
844  local[1] = (n_byte2)(tmp1 ^ (tmp0 >> 2) ^ 0xae08);
845  break;
846  case 7:
847  local[1] = (n_byte2)(tmp1 ^ (tmp0 >> 3) ^ 0x6320);
848  break;
849  default:
850  local[1] = (n_byte2)(tmp1 ^ (tmp0 >> 1));
851  break;
852  }
853  return (tmp1);
854 }
855 
856 void math_random3(n_byte2 * local)
857 {
858  NA_ASSERT(local, "local NULL");
859 
860  (void)math_random(local);
861  (void)math_random(local);
862  (void)math_random(local);
863 }
864 
865 /* all this hardcoding will need to be de-hardcoded in the future */
866 void math_bilinear_8_times(n_byte * side512, n_byte * data, n_byte double_spread)
867 {
868  n_int loop_y = 0;
869 
870  NA_ASSERT(side512, "side512 NULL");
871  NA_ASSERT(data, "data NULL");
872 
873  if (side512 == 0L) return;
874  if (data == 0L) return;
875 
876  while (loop_y < HI_RES_MAP_DIMENSION)
877  {
878  n_int loop_x = 0;
879  while (loop_x < HI_RES_MAP_DIMENSION)
880  {
881  /* find the micro x (on the map used for bilinear interpolation) */
882  n_int mic_x = ( loop_x & 7);
883  /* find the micro y (on the map used for bilinear interpolation) */
884  n_int mic_y = ( loop_y & 7);
885 
886  n_int mac_x = (loop_x >> 3);
887  n_int mac_y = (loop_y >> 3);
888 
889  n_uint px0 = (mac_x);
890  n_uint py0 = (mac_y * MAP_DIMENSION);
891 
892  n_uint px1 = (mac_x + 1) & (MAP_DIMENSION-1);
893  n_uint py1 = ((mac_y + 1) & (MAP_DIMENSION-1)) * MAP_DIMENSION;
894 
895  n_int z00 = side512[px0|py0];
896 
897  n_int z01 = side512[px1|py0];
898  n_int z10 = side512[px0|py1] - z00;
899  n_int z11 = side512[px1|py1] - z01 - z10;
900  n_uint point = loop_x + (loop_y * HI_RES_MAP_DIMENSION);
901  n_byte value;
902 
903  z01 = (z01 - z00) << 3;
904  z10 = z10 << 3;
905 
906  value = (n_byte)((z00 + (((z01 * mic_x) + (z10 * mic_y) + (z11 * mic_x * mic_y) ) >> 6)));
907  if (double_spread)
908  {
909  data[(point<<1)|1] = data[point<<1] = value;
910  }
911  else
912  {
913  data[point] = value;
914  }
915  loop_x++;
916  }
917  loop_y++;
918  }
919 }
920 
921 /* math_newton_root may need to be obsoleted */
923 {
924  n_uint op = input;
925  n_uint res = 0;
926  n_uint one = 1uL << ((sizeof(n_uint) * 8) - 2);
927  /* "one" starts at the highest power of four <= than the argument. */
928  while (one > op)
929  {
930  one >>= 2;
931  }
932  while (one != 0)
933  {
934  if (op >= res + one)
935  {
936  op = op - (res + one);
937  res = res + 2 * one;
938  }
939  res >>= 1;
940  one >>= 2;
941  }
942  return res;
943 }
944 
946 {
948  {
950  return &bc0[BRAINCODE_ADDRESS(i)];
951  }
953  return &bc1[BRAINCODE_ADDRESS(i) - BRAINCODE_SIZE];
954 }
955 
956 void math_general_execution(n_int instruction, n_int is_constant0, n_int is_constant1,
957  n_byte * addr0, n_byte * addr1, n_int value0, n_int * i,
958  n_int is_const0, n_int is_const1,
959  n_byte * pspace,
960  n_byte **maddr0, n_byte **maddr1,
961  n_byte *bc0, n_byte *bc1,
962  n_int braincode_min_loop)
963 {
965  switch( instruction )
966  {
967  case BRAINCODE_AND:
968  if (is_constant0)
969  {
970  addr0[0] &= addr1[0];
971  }
972  else
973  {
974  if ((addr0[0]>127) && (addr1[0]>127)) *i += BRAINCODE_BYTES_PER_INSTRUCTION;
975  }
976  break;
978  case BRAINCODE_OR:
979  if (is_constant0)
980  {
981  addr0[0] |= addr1[0];
982  }
983  else
984  {
985  if ((addr0[0]>127) || (addr1[0]>127)) *i += BRAINCODE_BYTES_PER_INSTRUCTION;
986  }
987  break;
989  case BRAINCODE_MOV:
990  if ((!is_constant0) && (!is_constant1))
991  {
992  addr1[0] = addr0[0];
993  }
994  else
995  {
996  addr1[0] = (n_byte)value0;
997  }
998  break;
1000  case BRAINCODE_MVB:
1001  {
1002  n_int ptr0, ptr1, n, instructions_to_copy, dat = 0;
1003 
1004  if (!is_constant0)
1005  {
1006  ptr0 = BRAINCODE_ADDRESS(*i + ((n_int)addr0[0]*BRAINCODE_BYTES_PER_INSTRUCTION));
1007  }
1008  else
1009  {
1011  }
1012 
1013  ptr1 = BRAINCODE_ADDRESS(*i + ((n_int)is_const0 * BRAINCODE_BYTES_PER_INSTRUCTION));
1014 
1015  instructions_to_copy = 1 + (pspace[1]%BRAINCODE_BLOCK_COPY);
1016 
1017  while (dat < instructions_to_copy)
1018  {
1019  if (ptr0 < BRAINCODE_SIZE)
1020  {
1021  addr0 = &bc0[ptr0];
1022  }
1023  else
1024  {
1025  addr0 = &bc1[ptr0 - BRAINCODE_SIZE];
1026  }
1027 
1028  if (ptr1 < BRAINCODE_SIZE)
1029  {
1030  addr1 = &bc0[ptr1];
1031  }
1032  else
1033  {
1034  addr1 = &bc1[ptr1 - BRAINCODE_SIZE];
1035  }
1036 
1037  for (n = 0; n < BRAINCODE_BYTES_PER_INSTRUCTION; n++)
1038  {
1039  addr1[n] = addr0[n];
1040  }
1041  dat++;
1042  ptr0 = BRAINCODE_ADDRESS(ptr0 + BRAINCODE_BYTES_PER_INSTRUCTION);
1043  ptr1 = BRAINCODE_ADDRESS(ptr1 + BRAINCODE_BYTES_PER_INSTRUCTION);
1044  }
1045 
1046  *maddr0 = addr0;
1047  *maddr0 = addr1;
1048  }
1049  break;
1050 
1052  case BRAINCODE_ADD:
1053  if ((!is_constant0) && (!is_constant1))
1054  {
1055  addr1[0] += addr0[0];
1056  }
1057  else
1058  {
1059  addr1[0] += value0;
1060  }
1061  break;
1063  case BRAINCODE_SUB:
1064  if ((!is_constant0) && (!is_constant1))
1065  {
1066  addr1[0] -= addr0[0];
1067  }
1068  else
1069  {
1070  addr1[0] -= value0;
1071  }
1072  break;
1074  case BRAINCODE_MUL:
1075  if ((!is_constant0) && (!is_constant1))
1076  {
1077  addr1[0] *= addr0[0];
1078  }
1079  else
1080  {
1081  addr1[0] *= value0;
1082  }
1083  break;
1085  case BRAINCODE_DIV:
1086  if ((!is_constant0) && (!is_constant1))
1087  {
1088  addr1[0] >>= (addr0[0]%4);
1089  }
1090  else
1091  {
1092  addr1[0] >>= (value0%4);
1093  }
1094  break;
1096  case BRAINCODE_MOD:
1097  if ((!is_constant0) && (!is_constant1))
1098  {
1099  if (addr0[0] != 0)
1100  {
1101  addr1[0] %= addr0[0];
1102  }
1103  }
1104  else
1105  {
1106  if (value0 != 0)
1107  {
1108  addr1[0] %= value0;
1109  }
1110  }
1111  break;
1113  case BRAINCODE_CTR:
1114  if (addr0[0] > 127)
1115  {
1116  if (addr1[0] < 255)
1117  {
1118  addr1[0]++;
1119  }
1120  else
1121  {
1122  addr1[0]=0;
1123  }
1124  }
1125  else
1126  {
1127  if (addr1[0] > 0)
1128  {
1129  addr1[0]--;
1130  }
1131  else
1132  {
1133  addr1[0]=255;
1134  }
1135  }
1136  break;
1138  case BRAINCODE_JMP:
1139  {
1140  n_int v0 = is_const0;
1141  n_int v1 = is_const1;
1142  n_int i2 = (*i + (((v0*256) + v1)*BRAINCODE_BYTES_PER_INSTRUCTION)) % BRAINCODE_SIZE;
1143  if (i2 <= *i)
1144  {
1145  if ((*i-i2) < braincode_min_loop)
1146  {
1147  i2 = *i - braincode_min_loop;
1148  if (i2 < 0) i2 += BRAINCODE_SIZE;
1149  }
1150  }
1152  break;
1153  }
1155  case BRAINCODE_JMZ:
1156  {
1157  n_int v0 = is_const0;
1158 
1159  if (v0 == 0)
1160  {
1161  n_int i2 = (*i + ((n_int) is_const1 *BRAINCODE_BYTES_PER_INSTRUCTION)) % BRAINCODE_SIZE;
1162 
1163  if (i2 <= *i)
1164  {
1165  if ((*i-i2) < braincode_min_loop)
1166  {
1167  i2 = *i - braincode_min_loop;
1168  if (i2 < 0) i2 += BRAINCODE_SIZE;
1169  }
1170  }
1172  }
1173  break;
1174  }
1176  case BRAINCODE_JMN:
1177  {
1178  n_int v0 = is_const0;
1179  if (v0 != 0)
1180  {
1181  n_int i2 = (*i + ((n_int) is_const1 *BRAINCODE_BYTES_PER_INSTRUCTION)) % BRAINCODE_SIZE;
1182  if (i2 <= *i)
1183  {
1184  if ((*i-i2) < braincode_min_loop)
1185  {
1186  i2 = *i - braincode_min_loop;
1187  if (i2 < 0) i2 += BRAINCODE_SIZE;
1188  }
1189  }
1191  }
1192  break;
1193  }
1195  case BRAINCODE_DJN:
1196  if (addr0[0]-1 != 0)
1197  {
1198  n_int i2 = (*i + ((n_int) is_const1 *BRAINCODE_BYTES_PER_INSTRUCTION)) % BRAINCODE_SIZE;
1199  addr0[0]--;
1200 
1201  if (i2 <= *i)
1202  {
1203  if ((*i-i2) < braincode_min_loop)
1204  {
1205  i2 = *i - braincode_min_loop;
1206  if (i2 < 0) i2 += BRAINCODE_SIZE;
1207  }
1208  }
1210  }
1211  break;
1213  case BRAINCODE_SEQ:
1214  if ((!is_constant0) && (!is_constant1))
1215  {
1216  if (addr1[0] == addr0[0])
1217  {
1218  *i = (*i + (BRAINCODE_BYTES_PER_INSTRUCTION * (1 + (n_int)pspace[0]))) % BRAINCODE_SIZE;
1219  }
1220  }
1221  else
1222  {
1223  if (addr1[0] == value0)
1224  {
1225  *i = (*i + (BRAINCODE_BYTES_PER_INSTRUCTION * (1 + (n_int)pspace[0]))) % BRAINCODE_SIZE;
1226  }
1227  }
1228  break;
1230  case BRAINCODE_SNE:
1231  if ((!is_constant0) && (!is_constant1))
1232  {
1233  if (addr1[0] != addr0[0])
1234  {
1235  *i = (*i + (BRAINCODE_BYTES_PER_INSTRUCTION * (1 + (n_int)pspace[0]))) % BRAINCODE_SIZE;
1236  }
1237  }
1238  else
1239  {
1240  if (addr1[0] != value0)
1241  {
1242  *i = (*i + (BRAINCODE_BYTES_PER_INSTRUCTION * (1 + (n_int)pspace[0]))) % BRAINCODE_SIZE;
1243  }
1244  }
1245  break;
1247  case BRAINCODE_SLT:
1248  if ((!is_constant0) && (!is_constant1))
1249  {
1250  if (addr1[0] < addr0[0])
1251  {
1252  *i = (*i + (BRAINCODE_BYTES_PER_INSTRUCTION * (1 + (n_int)pspace[0]))) % BRAINCODE_SIZE;
1253  }
1254  }
1255  else
1256  {
1257  if (addr1[0] < value0)
1258  {
1259  *i = (*i + (BRAINCODE_BYTES_PER_INSTRUCTION * (1 + (n_int)pspace[0]))) % BRAINCODE_SIZE;
1260  }
1261  }
1262  break;
1264  case BRAINCODE_DAT0:
1265  case BRAINCODE_DAT1:
1266  break;
1268  case BRAINCODE_SWP:
1269  {
1270  n_byte tmp = addr0[0];
1271  addr0[0] = addr1[0];
1272  addr1[0] = tmp;
1273  break;
1274  }
1276  case BRAINCODE_INV:
1277  if (is_constant0)
1278  {
1279  addr0[0] = 255 - addr0[0];
1280  }
1281  else
1282  {
1283  addr1[0] = 255 - addr1[0];
1284  }
1285  break;
1287  case BRAINCODE_STP:
1288  {
1289  n_byte v0 = (n_byte)is_const0;
1290  n_byte v1 = (n_byte)is_const1;
1291  pspace[v0 % BRAINCODE_PSPACE_REGISTERS] = v1;
1292  break;
1293  }
1295  case BRAINCODE_LTP:
1296  {
1297  n_byte v0 = (n_byte)is_const0;
1298  addr1[0] = pspace[v0 % BRAINCODE_PSPACE_REGISTERS];
1299  break;
1300  }
1301  }
1302 }
1303 
1304