+ for ( ; m_y <= m_y1; m_y += 8, m_x = m_x0)
+ for ( ; m_x <= m_x1; m_x += 8)
+ {
+ if ((c = LinkBox(m_x, m_y, false)) == NULL)
+ continue;
+
+ // check whether there is enough space left in the array
+ if (m_ncells > (ARRAYSIZE - 64))
+ {
+ *ncells = m_ncells;
+ return false;
+ }
+
+ DoLine(m_x, m_y , c->m_live1 );
+ DoLine(m_x, m_y + 1, c->m_live1 >> 8 );
+ DoLine(m_x, m_y + 2, c->m_live1 >> 16);
+ DoLine(m_x, m_y + 3, c->m_live1 >> 24);
+ DoLine(m_x, m_y + 4, c->m_live2 );
+ DoLine(m_x, m_y + 5, c->m_live2 >> 8 );
+ DoLine(m_x, m_y + 6, c->m_live2 >> 16);
+ DoLine(m_x, m_y + 7, c->m_live2 >> 24);
+ }
+ }
+
+ *ncells = m_ncells;
+ m_findmore = false;
+ return true;
+}
+
+// --------------------------------------------------------------------------
+// Evolution engine
+// --------------------------------------------------------------------------
+
+extern unsigned char *g_tab;
+extern int g_tab1[];
+extern int g_tab2[];
+
+// NextTic:
+// Advance one step in evolution :-)
+//
+bool Life::NextTic()
+{
+ LifeCellBox *c, *up, *dn, *lf, *rt;
+ wxUint32 t1, t2, t3, t4;
+ bool changed = false;
+
+ m_numcells = 0;
+
+ // Stage 1:
+ // Compute neighbours of each cell
+ //
+ // WARNING: unrolled loops and lengthy code follows!
+ //
+ c = m_head;
+
+ while (c)
+ {
+ if (! (c->m_live1 || c->m_live2))
+ {
+ c = c->m_next;
+ continue;
+ }
+ up = c->m_up;
+ dn = c->m_dn;
+ lf = c->m_lf;
+ rt = c->m_rt;
+
+ // up
+ t1 = c->m_live1 & 0x000000ff;
+ if (t1)
+ {
+ if (!up)
+ {
+ up = LinkBox(c->m_x, c->m_y - 8);
+ up->m_dn = c;
+ }
+ t2 = g_tab1[t1];
+ up->m_on[7] += t2;
+ c->m_on[1] += t2;
+ c->m_on[0] += g_tab2[t1];
+ }
+
+ // down
+ t1 = (c->m_live2 & 0xff000000) >> 24;
+ if (t1)
+ {
+ if (!dn)
+ {
+ dn = LinkBox(c->m_x, c->m_y + 8);
+ dn->m_up = c;
+ }
+ t2 = g_tab1[t1];
+ dn->m_on[0] += t2;
+ c->m_on[6] += t2;
+ c->m_on[7] += g_tab2[t1];
+ }
+
+ t1 = c->m_live1;
+ t2 = c->m_live2;
+
+ // left
+ if (t1 & 0x01010101)
+ {
+ if (!lf)
+ {
+ lf = LinkBox(c->m_x - 8, c->m_y);
+ lf->m_rt = c;
+ }
+ if (t1 & 0x00000001)
+ {
+ if (!lf->m_up)
+ {
+ lf->m_up = LinkBox(c->m_x - 8, c->m_y - 8);
+ lf->m_up->m_dn = lf;
+ }
+ lf->m_up->m_on[7] += 0x10000000;
+ lf->m_on[0] += 0x10000000;
+ lf->m_on[1] += 0x10000000;
+ }
+ if (t1 & 0x00000100)
+ {
+ lf->m_on[0] += 0x10000000;
+ lf->m_on[1] += 0x10000000;
+ lf->m_on[2] += 0x10000000;
+ }
+ if (t1 & 0x00010000)
+ {
+ lf->m_on[1] += 0x10000000;
+ lf->m_on[2] += 0x10000000;
+ lf->m_on[3] += 0x10000000;
+ }
+ if (t1 & 0x01000000)
+ {
+ lf->m_on[2] += 0x10000000;
+ lf->m_on[3] += 0x10000000;
+ lf->m_on[4] += 0x10000000;
+ }
+ }
+ if (t2 & 0x01010101)
+ {
+ if (!lf)
+ {
+ lf = LinkBox(c->m_x - 8, c->m_y);
+ lf->m_rt = c;
+ }
+ if (t2 & 0x00000001)
+ {
+ lf->m_on[3] += 0x10000000;
+ lf->m_on[4] += 0x10000000;
+ lf->m_on[5] += 0x10000000;
+ }
+ if (t2 & 0x00000100)
+ {
+ lf->m_on[4] += 0x10000000;
+ lf->m_on[5] += 0x10000000;
+ lf->m_on[6] += 0x10000000;
+ }
+ if (t2 & 0x00010000)
+ {
+ lf->m_on[5] += 0x10000000;
+ lf->m_on[6] += 0x10000000;
+ lf->m_on[7] += 0x10000000;
+ }
+ if (t2 & 0x01000000)
+ {
+ if (!lf->m_dn)
+ {
+ lf->m_dn = LinkBox(c->m_x - 8, c->m_y + 8);
+ lf->m_dn->m_up = lf;
+ }
+ lf->m_on[6] += 0x10000000;
+ lf->m_on[7] += 0x10000000;
+ lf->m_dn->m_on[0] += 0x10000000;
+ }
+ }
+
+ // right
+ if (t1 & 0x80808080)
+ {
+ if (!rt)
+ {
+ rt = LinkBox(c->m_x + 8, c->m_y);
+ rt->m_lf = c;
+ }
+ if (t1 & 0x00000080)
+ {
+ if (!rt->m_up)
+ {
+ rt->m_up = LinkBox(c->m_x + 8, c->m_y - 8);
+ rt->m_up->m_dn = rt;
+ }
+ rt->m_up->m_on[7] += 0x00000001;
+ rt->m_on[0] += 0x00000001;
+ rt->m_on[1] += 0x00000001;
+ }
+ if (t1 & 0x00008000)
+ {
+ rt->m_on[0] += 0x00000001;
+ rt->m_on[1] += 0x00000001;
+ rt->m_on[2] += 0x00000001;
+ }
+ if (t1 & 0x00800000)
+ {
+ rt->m_on[1] += 0x00000001;
+ rt->m_on[2] += 0x00000001;
+ rt->m_on[3] += 0x00000001;
+ }
+ if (t1 & 0x80000000)
+ {
+ rt->m_on[2] += 0x00000001;
+ rt->m_on[3] += 0x00000001;
+ rt->m_on[4] += 0x00000001;
+ }
+ }
+ if (t2 & 0x80808080)
+ {
+ if (!rt)
+ {
+ rt = LinkBox(c->m_x + 8, c->m_y);
+ rt->m_lf = c;
+ }
+ if (t2 & 0x00000080)
+ {
+ rt->m_on[3] += 0x00000001;
+ rt->m_on[4] += 0x00000001;
+ rt->m_on[5] += 0x00000001;
+ }
+ if (t2 & 0x00008000)
+ {
+ rt->m_on[4] += 0x00000001;
+ rt->m_on[5] += 0x00000001;
+ rt->m_on[6] += 0x00000001;
+ }
+ if (t2 & 0x00800000)
+ {
+ rt->m_on[5] += 0x00000001;
+ rt->m_on[6] += 0x00000001;
+ rt->m_on[7] += 0x00000001;
+ }
+ if (t2 & 0x80000000)
+ {
+ if (!rt->m_dn)
+ {
+ rt->m_dn = LinkBox(c->m_x + 8, c->m_y + 8);
+ rt->m_dn->m_up = rt;
+ }
+ rt->m_on[6] += 0x00000001;
+ rt->m_on[7] += 0x00000001;
+ rt->m_dn->m_on[0] += 0x00000001;
+ }
+ }
+
+ // inner cells
+ int i;
+ for (i = 1; i <= 3; i++)
+ {
+ t1 = ((c->m_live1) >> (i * 8)) & 0x000000ff;
+ if (t1)
+ {
+ c->m_on[i - 1] += g_tab1[t1];
+ c->m_on[i ] += g_tab2[t1];
+ c->m_on[i + 1] += g_tab1[t1];
+ }
+ }
+ for (i = 0; i <= 2; i++)
+ {
+ t1 = ((c->m_live2) >> (i * 8)) & 0x000000ff;
+ if (t1)
+ {
+ c->m_on[i + 3] += g_tab1[t1];
+ c->m_on[i + 4] += g_tab2[t1];
+ c->m_on[i + 5] += g_tab1[t1];
+ }
+ }
+
+ c->m_up = up;
+ c->m_dn = dn;
+ c->m_lf = lf;
+ c->m_rt = rt;
+ c = c->m_next;