~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to demos/life/game.cpp

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        game.cpp
 
3
// Purpose:     Life! game logic
 
4
// Author:      Guillermo Rodriguez Garcia, <guille@iies.es>
 
5
// Modified by:
 
6
// Created:     Jan/2000
 
7
// RCS-ID:      $Id: game.cpp 60926 2009-06-06 23:16:27Z VZ $
 
8
// Copyright:   (c) 2000, Guillermo Rodriguez Garcia
 
9
// Licence:     wxWindows licence
 
10
/////////////////////////////////////////////////////////////////////////////
 
11
 
 
12
// ==========================================================================
 
13
// headers, declarations, constants
 
14
// ==========================================================================
 
15
 
 
16
// For compilers that support precompilation, includes "wx/wx.h".
 
17
#include "wx/wxprec.h"
 
18
 
 
19
#ifdef __BORLANDC__
 
20
#pragma hdrstop
 
21
#endif
 
22
 
 
23
#ifndef WX_PRECOMP
 
24
#include "wx/wx.h"
 
25
#endif
 
26
 
 
27
#include "wx/log.h"
 
28
#include "wx/module.h"
 
29
#include "game.h"
 
30
 
 
31
#include <string.h>           // for memset
 
32
 
 
33
 
 
34
#define CELLSARRAYSIZE  1024       // static array for BeginFind & co.
 
35
#define ALLOCBOXES 16         // number of cellboxes to alloc at once
 
36
#define MAXDEAD    8          // tics before removing cellbox from list
 
37
 
 
38
 
 
39
// ==========================================================================
 
40
// CellBox
 
41
// ==========================================================================
 
42
 
 
43
#define HASH(x, y) (((x >> 3) & 0x7f) << 7) + ((y >> 3) & 0x7f)
 
44
 
 
45
#define HASHSIZE   16384      // hash table size (do not change!)
 
46
#define CELLBOX    8          // cells in a cellbox (do not change!)
 
47
 
 
48
 
 
49
class LifeCellBox
 
50
{
 
51
public:
 
52
    // members
 
53
    inline bool IsAlive(int dx, int dy) const;
 
54
    inline bool SetCell(int dx, int dy, bool alive);
 
55
 
 
56
    // attributes
 
57
    wxInt32       m_x, m_y;                     // position in universe
 
58
    wxUint32      m_live1, m_live2;             // alive cells (1 bit per cell)
 
59
    wxUint32      m_old1, m_old2;               // old values for m_live1, 2
 
60
    wxUint32      m_on[8];                      // neighbouring info
 
61
    wxUint32      m_dead;                       // been dead for n generations
 
62
    LifeCellBox  *m_up, *m_dn, *m_lf, *m_rt;    // neighbour CellBoxes
 
63
    LifeCellBox  *m_prev, *m_next;              // in linked list
 
64
    LifeCellBox  *m_hprev, *m_hnext;            // in hash table
 
65
};
 
66
 
 
67
 
 
68
// IsAlive:
 
69
//  Returns whether cell dx, dy in this box is alive
 
70
//
 
71
bool LifeCellBox::IsAlive(int dx, int dy) const
 
72
{
 
73
    if (dy > 3)
 
74
        return (m_live2 & 1 << ((dy - 4) * 8 + dx)) ? true : false ;
 
75
    else
 
76
        return (m_live1 & 1 << ((dy) * 8 + dx)) ? true : false ;
 
77
}
 
78
 
 
79
// SetCell:
 
80
//  Sets cell dx, dy in this box to 'alive', returns true if
 
81
//  the previous value was different, false if it was the same.
 
82
//
 
83
bool LifeCellBox::SetCell(int dx, int dy, bool alive)
 
84
{
 
85
    if (IsAlive(dx, dy) != alive)
 
86
    {
 
87
       if (dy > 3)
 
88
           m_live2 ^= 1 << ((dy - 4) * 8 + dx);
 
89
       else
 
90
           m_live1 ^= 1 << ((dy) * 8 + dx);
 
91
 
 
92
       // reset this here to avoid updating problems
 
93
       m_dead = 0;
 
94
 
 
95
       return true;
 
96
    }
 
97
    else
 
98
       return false;
 
99
}
 
100
 
 
101
 
 
102
// ==========================================================================
 
103
// Life
 
104
// ==========================================================================
 
105
 
 
106
// --------------------------------------------------------------------------
 
107
// Ctor and dtor
 
108
// --------------------------------------------------------------------------
 
109
 
 
110
Life::Life()
 
111
{
 
112
    // pattern description
 
113
    m_name        = wxEmptyString;
 
114
    m_rules       = wxEmptyString;
 
115
    m_description = wxEmptyString;
 
116
 
 
117
    // pattern data
 
118
    m_numcells    = 0;
 
119
    m_boxes       = new LifeCellBox *[HASHSIZE];
 
120
    m_head        = NULL;
 
121
    m_available   = NULL;
 
122
    for (int i = 0; i < HASHSIZE; i++)
 
123
        m_boxes[i] = NULL;
 
124
 
 
125
    // state vars for BeginFind & FindMore
 
126
    m_cells       = new LifeCell[CELLSARRAYSIZE];
 
127
    m_ncells      = 0;
 
128
    m_findmore    = false;
 
129
    m_changed     = false;
 
130
}
 
131
 
 
132
Life::~Life()
 
133
{
 
134
    Clear();
 
135
 
 
136
    delete[] m_boxes;
 
137
    delete[] m_cells;
 
138
}
 
139
 
 
140
// Clear:
 
141
//  Clears the board, freeing all storage.
 
142
//
 
143
void Life::Clear()
 
144
{
 
145
    LifeCellBox *c, *nc;
 
146
 
 
147
    // clear the hash table pointers
 
148
    for (int i = 0; i < HASHSIZE; i++)
 
149
        m_boxes[i] = NULL;
 
150
 
 
151
    // free used boxes
 
152
    c = m_head;
 
153
    while (c)
 
154
    {
 
155
        nc = c->m_next;
 
156
        delete c;
 
157
        c = nc;
 
158
    }
 
159
    m_head = NULL;
 
160
 
 
161
    // free available boxes
 
162
    c = m_available;
 
163
    while (c)
 
164
    {
 
165
        nc = c->m_next;
 
166
        delete c;
 
167
        c = nc;
 
168
    }
 
169
    m_available = NULL;
 
170
 
 
171
    // reset state
 
172
    m_name        = wxEmptyString;
 
173
    m_rules       = wxEmptyString;
 
174
    m_description = wxEmptyString;
 
175
    m_numcells    = 0;
 
176
}
 
177
 
 
178
// --------------------------------------------------------------------------
 
179
// Test and set individual cells
 
180
// --------------------------------------------------------------------------
 
181
 
 
182
// IsAlive:
 
183
//  Returns whether cell (x, y) is alive.
 
184
//
 
185
bool Life::IsAlive(wxInt32 x, wxInt32 y)
 
186
{
 
187
    LifeCellBox *c = LinkBox(x, y, false);
 
188
 
 
189
    return (c && c->IsAlive( x - c->m_x, y - c->m_y ));
 
190
}
 
191
 
 
192
// SetCell:
 
193
//  Sets or clears cell (x, y), according to the 'alive' param.
 
194
//
 
195
void Life::SetCell(wxInt32 x, wxInt32 y, bool alive)
 
196
{
 
197
    LifeCellBox *c  = LinkBox(x, y);
 
198
    wxUint32 dx = x - c->m_x;
 
199
    wxUint32 dy = y - c->m_y;
 
200
 
 
201
    if (c->SetCell(dx, dy, alive))
 
202
    {
 
203
        if (alive)
 
204
            m_numcells++;
 
205
        else
 
206
            m_numcells--;
 
207
    }
 
208
}
 
209
 
 
210
void Life::SetPattern(const LifePattern& pattern)
 
211
{
 
212
    wxArrayString data = pattern.m_shape;
 
213
    wxString line;
 
214
    long x = 0,
 
215
         y = 0;
 
216
 
 
217
    Clear();
 
218
    for (size_t n = 0; n < data.GetCount(); n++)
 
219
    {
 
220
        line = data[n];
 
221
 
 
222
        if ( (line.GetChar(0) != wxT('*')) &&
 
223
             (line.GetChar(0) != wxT('.')) )
 
224
        {
 
225
            // assume that it is a digit or a minus sign
 
226
            line.BeforeFirst(wxT(' ')).ToLong(&x);
 
227
            line.AfterFirst(wxT(' ')).ToLong(&y);
 
228
        }
 
229
        else
 
230
        {
 
231
            // pattern data
 
232
            for (size_t k = 0; k < line.Len(); k++)
 
233
                SetCell(x + k, y, line.GetChar(k) == wxT('*'));
 
234
 
 
235
            y++;
 
236
        }
 
237
    }
 
238
 
 
239
    m_name = pattern.m_name;
 
240
    m_rules = pattern.m_rules;
 
241
    m_description = pattern.m_description;
 
242
}
 
243
 
 
244
// --------------------------------------------------------------------------
 
245
// Cellbox management functions
 
246
// --------------------------------------------------------------------------
 
247
 
 
248
// CreateBox:
 
249
//  Creates a box in x, y, either taking it from the list
 
250
//  of available boxes, or allocating a new one.
 
251
//
 
252
LifeCellBox* Life::CreateBox(wxInt32 x, wxInt32 y, wxUint32 hv)
 
253
{
 
254
    LifeCellBox *c;
 
255
 
 
256
    // if there are no available boxes, alloc a few more
 
257
    if (!m_available)
 
258
        for (int i = 1; i <= ALLOCBOXES; i++)
 
259
        {
 
260
            c = new LifeCellBox();
 
261
 
 
262
            if (!c)
 
263
            {
 
264
                // TODO: handle memory errors. Note that right now, if we
 
265
                // couldn't allocate at least one cellbox, we will crash
 
266
                // before leaving CreateBox(). Probably we should try to
 
267
                // allocate some boxes *before* the m_available list goes
 
268
                // empty, so that we have a margin to handle errors
 
269
                // gracefully.
 
270
                wxLogFatalError(_("Out of memory! Aborting..."));
 
271
 
 
272
                // NOTREACHED
 
273
            }
 
274
 
 
275
            c->m_next = m_available;
 
276
            m_available = c;
 
277
        }
 
278
 
 
279
    // take a cellbox from the list of available boxes
 
280
    c = m_available;
 
281
    m_available = c->m_next;
 
282
 
 
283
    // reset everything
 
284
    memset((void *) c, 0, sizeof(LifeCellBox));
 
285
    c->m_x = x;
 
286
    c->m_y = y;
 
287
 
 
288
    // insert c in the list
 
289
    c->m_next = m_head;
 
290
    m_head = c;
 
291
    if (c->m_next) c->m_next->m_prev = c;
 
292
 
 
293
    // insert c in the hash table
 
294
    c->m_hnext = m_boxes[hv];
 
295
    m_boxes[hv] = c;
 
296
    if (c->m_hnext) c->m_hnext->m_hprev = c;
 
297
 
 
298
    return c;
 
299
}
 
300
 
 
301
// LinkBox:
 
302
//  Returns a pointer to the box (x, y); if it didn't exist yet,
 
303
//  it returns NULL or creates a new one, depending on the value
 
304
//  of the 'create' parameter.
 
305
//
 
306
LifeCellBox* Life::LinkBox(wxInt32 x, wxInt32 y, bool create)
 
307
{
 
308
    wxUint32 hv;
 
309
    LifeCellBox *c;
 
310
 
 
311
    x &= 0xfffffff8;
 
312
    y &= 0xfffffff8;
 
313
    hv = HASH(x, y);
 
314
 
 
315
    // search in the hash table
 
316
    for (c = m_boxes[hv]; c; c = c->m_hnext)
 
317
        if ((c->m_x == x) && (c->m_y == y)) return c;
 
318
 
 
319
    // if not found, and (create == true), create a new one
 
320
    return create? CreateBox(x, y, hv) : (LifeCellBox*) NULL;
 
321
}
 
322
 
 
323
// KillBox:
 
324
//  Removes this box from the list and the hash table and
 
325
//  puts it in the list of available boxes.
 
326
//
 
327
void Life::KillBox(LifeCellBox *c)
 
328
{
 
329
    wxUint32 hv = HASH(c->m_x, c->m_y);
 
330
 
 
331
    // remove from the list
 
332
    if (c != m_head)
 
333
        c->m_prev->m_next = c->m_next;
 
334
    else
 
335
        m_head = c->m_next;
 
336
 
 
337
    // remove from the hash table
 
338
    if (c != m_boxes[hv])
 
339
        c->m_hprev->m_hnext = c->m_hnext;
 
340
    else
 
341
        m_boxes[hv] = c->m_hnext;
 
342
 
 
343
    // update neighbours
 
344
    if (c->m_next) c->m_next->m_prev = c->m_prev;
 
345
    if (c->m_hnext) c->m_hnext->m_hprev = c->m_hprev;
 
346
    if (c->m_up) c->m_up->m_dn = NULL;
 
347
    if (c->m_dn) c->m_dn->m_up = NULL;
 
348
    if (c->m_lf) c->m_lf->m_rt = NULL;
 
349
    if (c->m_rt) c->m_rt->m_lf = NULL;
 
350
 
 
351
    // append to the list of available boxes
 
352
    c->m_next = m_available;
 
353
    m_available = c;
 
354
}
 
355
 
 
356
// --------------------------------------------------------------------------
 
357
// Navigation
 
358
// --------------------------------------------------------------------------
 
359
 
 
360
LifeCell Life::FindCenter()
 
361
{
 
362
    double sx, sy;
 
363
    int n;
 
364
    sx = 0.0;
 
365
    sy = 0.0;
 
366
    n = 0;
 
367
 
 
368
    LifeCellBox *c;
 
369
    for (c = m_head; c; c = c->m_next)
 
370
        if (!c->m_dead)
 
371
        {
 
372
            sx += c->m_x;
 
373
            sy += c->m_y;
 
374
            n++;
 
375
        }
 
376
 
 
377
    if (n > 0)
 
378
    {
 
379
        sx = (sx / n) + CELLBOX / 2;
 
380
        sy = (sy / n) + CELLBOX / 2;
 
381
    }
 
382
 
 
383
    LifeCell cell;
 
384
    cell.i = (wxInt32) sx;
 
385
    cell.j = (wxInt32) sy;
 
386
    return cell;
 
387
}
 
388
 
 
389
LifeCell Life::FindNorth()
 
390
{
 
391
    wxInt32 x = 0, y = 0;
 
392
    bool first = true;
 
393
 
 
394
    LifeCellBox *c;
 
395
    for (c = m_head; c; c = c->m_next)
 
396
        if (!c->m_dead && ((first) || (c->m_y < y)))
 
397
        {
 
398
            x = c->m_x;
 
399
            y = c->m_y;
 
400
            first = false;
 
401
        }
 
402
 
 
403
    LifeCell cell;
 
404
    cell.i = first? 0 : x + CELLBOX / 2;
 
405
    cell.j = first? 0 : y + CELLBOX / 2;
 
406
    return cell;
 
407
}
 
408
 
 
409
LifeCell Life::FindSouth()
 
410
{
 
411
    wxInt32 x = 0, y = 0;
 
412
    bool first = true;
 
413
 
 
414
    LifeCellBox *c;
 
415
    for (c = m_head; c; c = c->m_next)
 
416
        if (!c->m_dead && ((first) || (c->m_y > y)))
 
417
        {
 
418
            x = c->m_x;
 
419
            y = c->m_y;
 
420
            first = false;
 
421
        }
 
422
 
 
423
    LifeCell cell;
 
424
    cell.i = first? 0 : x + CELLBOX / 2;
 
425
    cell.j = first? 0 : y + CELLBOX / 2;
 
426
    return cell;
 
427
}
 
428
 
 
429
LifeCell Life::FindWest()
 
430
{
 
431
    wxInt32 x = 0, y = 0;
 
432
    bool first = true;
 
433
 
 
434
    LifeCellBox *c;
 
435
    for (c = m_head; c; c = c->m_next)
 
436
        if (!c->m_dead && ((first) || (c->m_x < x)))
 
437
        {
 
438
            x = c->m_x;
 
439
            y = c->m_y;
 
440
            first = false;
 
441
        }
 
442
 
 
443
    LifeCell cell;
 
444
    cell.i = first? 0 : x + CELLBOX / 2;
 
445
    cell.j = first? 0 : y + CELLBOX / 2;
 
446
    return cell;
 
447
}
 
448
 
 
449
LifeCell Life::FindEast()
 
450
{
 
451
    wxInt32 x = 0, y = 0;
 
452
    bool first = true;
 
453
 
 
454
    LifeCellBox *c;
 
455
    for (c = m_head; c; c = c->m_next)
 
456
        if (!c->m_dead && ((first) || (c->m_x > x)))
 
457
        {
 
458
            x = c->m_x;
 
459
            y = c->m_y;
 
460
            first = false;
 
461
        }
 
462
 
 
463
    LifeCell cell;
 
464
    cell.i = first? 0 : x + CELLBOX / 2;
 
465
    cell.j = first? 0 : y + CELLBOX / 2;
 
466
    return cell;
 
467
}
 
468
 
 
469
// --------------------------------------------------------------------------
 
470
// FindMore & co.
 
471
// --------------------------------------------------------------------------
 
472
 
 
473
// DoLine:
 
474
//  Post eight cells to the cell arrays - leave out the fourth
 
475
//  argument (or pass 0, the default value) to post alive cells
 
476
//  only, else it will post cells which have changed.
 
477
//
 
478
void Life::DoLine(wxInt32 x, wxInt32 y, wxUint32 live, wxUint32 old)
 
479
{
 
480
    wxUint32 diff = (live ^ old) & 0xff;
 
481
 
 
482
    if (!diff) return;
 
483
 
 
484
    for (wxInt32 k = 8; k; k--, x++)
 
485
    {
 
486
        if (diff & 0x01)
 
487
        {
 
488
            m_cells[m_ncells].i = x;
 
489
            m_cells[m_ncells].j = y;
 
490
            m_ncells++;
 
491
        }
 
492
        diff >>= 1;
 
493
    }
 
494
}
 
495
 
 
496
void Life::BeginFind(wxInt32 x0, wxInt32 y0, wxInt32 x1, wxInt32 y1, bool changed)
 
497
{
 
498
    // TODO: optimize for the case where the maximum number of
 
499
    // cellboxes that fit in the specified viewport is smaller
 
500
    // than the current total of boxes; iterating over the list
 
501
    // should then be faster than searching in the hash table.
 
502
 
 
503
    m_x0 = m_x = x0 & 0xfffffff8;
 
504
    m_y0 = m_y = y0 & 0xfffffff8;
 
505
    m_x1 = (x1 + 7) & 0xfffffff8;
 
506
    m_y1 = (y1 + 7) & 0xfffffff8;
 
507
 
 
508
    m_findmore = true;
 
509
    m_changed = changed;
 
510
}
 
511
 
 
512
bool Life::FindMore(LifeCell *cells[], size_t *ncells)
 
513
{
 
514
    LifeCellBox *c;
 
515
    *cells = m_cells;
 
516
    m_ncells = 0;
 
517
 
 
518
    if (m_changed)
 
519
    {
 
520
        for ( ; m_y <= m_y1; m_y += 8, m_x = m_x0)
 
521
            for ( ; m_x <= m_x1; m_x += 8)
 
522
            {
 
523
                if ((c = LinkBox(m_x, m_y, false)) == NULL)
 
524
                    continue;
 
525
 
 
526
                // check whether there is enough space left in the array
 
527
                if (m_ncells > (CELLSARRAYSIZE - 64))
 
528
                {
 
529
                    *ncells = m_ncells;
 
530
                    return false;
 
531
                }
 
532
 
 
533
                DoLine(m_x, m_y    , c->m_live1,       c->m_old1      );
 
534
                DoLine(m_x, m_y + 1, c->m_live1 >> 8,  c->m_old1 >> 8 );
 
535
                DoLine(m_x, m_y + 2, c->m_live1 >> 16, c->m_old1 >> 16);
 
536
                DoLine(m_x, m_y + 3, c->m_live1 >> 24, c->m_old1 >> 24);
 
537
                DoLine(m_x, m_y + 4, c->m_live2,       c->m_old2      );
 
538
                DoLine(m_x, m_y + 5, c->m_live2 >> 8,  c->m_old2 >> 8 );
 
539
                DoLine(m_x, m_y + 6, c->m_live2 >> 16, c->m_old2 >> 16);
 
540
                DoLine(m_x, m_y + 7, c->m_live2 >> 24, c->m_old2 >> 24);
 
541
            }
 
542
    }
 
543
    else
 
544
    {
 
545
        for ( ; m_y <= m_y1; m_y += 8, m_x = m_x0)
 
546
            for ( ; m_x <= m_x1; m_x += 8)
 
547
            {
 
548
                if ((c = LinkBox(m_x, m_y, false)) == NULL)
 
549
                    continue;
 
550
 
 
551
                // check whether there is enough space left in the array
 
552
                if (m_ncells > (CELLSARRAYSIZE - 64))
 
553
                {
 
554
                    *ncells = m_ncells;
 
555
                    return false;
 
556
                }
 
557
 
 
558
                DoLine(m_x, m_y    , c->m_live1      );
 
559
                DoLine(m_x, m_y + 1, c->m_live1 >> 8 );
 
560
                DoLine(m_x, m_y + 2, c->m_live1 >> 16);
 
561
                DoLine(m_x, m_y + 3, c->m_live1 >> 24);
 
562
                DoLine(m_x, m_y + 4, c->m_live2      );
 
563
                DoLine(m_x, m_y + 5, c->m_live2 >> 8 );
 
564
                DoLine(m_x, m_y + 6, c->m_live2 >> 16);
 
565
                DoLine(m_x, m_y + 7, c->m_live2 >> 24);
 
566
            }
 
567
    }
 
568
 
 
569
    *ncells = m_ncells;
 
570
    m_findmore = false;
 
571
    return true;
 
572
}
 
573
 
 
574
// --------------------------------------------------------------------------
 
575
// Evolution engine
 
576
// --------------------------------------------------------------------------
 
577
 
 
578
extern unsigned char *g_tab;
 
579
extern int g_tab1[];
 
580
extern int g_tab2[];
 
581
 
 
582
// NextTic:
 
583
//  Advance one step in evolution :-)
 
584
//
 
585
bool Life::NextTic()
 
586
{
 
587
    LifeCellBox  *c, *up, *dn, *lf, *rt;
 
588
    wxUint32 t1, t2, t3, t4;
 
589
    bool     changed = false;
 
590
 
 
591
    m_numcells = 0;
 
592
 
 
593
    // Stage 1:
 
594
    // Compute neighbours of each cell
 
595
    //
 
596
    // WARNING: unrolled loops and lengthy code follows!
 
597
    //
 
598
    c = m_head;
 
599
 
 
600
    while (c)
 
601
    {
 
602
        if (! (c->m_live1 || c->m_live2))
 
603
        {
 
604
            c = c->m_next;
 
605
            continue;
 
606
        }
 
607
        up = c->m_up;
 
608
        dn = c->m_dn;
 
609
        lf = c->m_lf;
 
610
        rt = c->m_rt;
 
611
 
 
612
        // up
 
613
        t1 = c->m_live1 & 0x000000ff;
 
614
        if (t1)
 
615
        {
 
616
            if (!up)
 
617
            {
 
618
                up = LinkBox(c->m_x, c->m_y - 8);
 
619
                up->m_dn = c;
 
620
            }
 
621
            t2 = g_tab1[t1];
 
622
            up->m_on[7] += t2;
 
623
            c->m_on[1] += t2;
 
624
            c->m_on[0] += g_tab2[t1];
 
625
        }
 
626
 
 
627
        // down
 
628
        t1 = (c->m_live2 & 0xff000000) >> 24;
 
629
        if (t1)
 
630
        {
 
631
            if (!dn)
 
632
            {
 
633
                dn = LinkBox(c->m_x, c->m_y + 8);
 
634
                dn->m_up = c;
 
635
            }
 
636
            t2 = g_tab1[t1];
 
637
            dn->m_on[0] += t2;
 
638
            c->m_on[6] += t2;
 
639
            c->m_on[7] += g_tab2[t1];
 
640
        }
 
641
 
 
642
        t1 = c->m_live1;
 
643
        t2 = c->m_live2;
 
644
 
 
645
        // left
 
646
        if (t1 & 0x01010101)
 
647
        {
 
648
            if (!lf)
 
649
            {
 
650
                lf = LinkBox(c->m_x - 8, c->m_y);
 
651
                lf->m_rt = c;
 
652
            }
 
653
            if (t1 & 0x00000001)
 
654
            {
 
655
               if (!lf->m_up)
 
656
               {
 
657
                   lf->m_up = LinkBox(c->m_x - 8, c->m_y - 8);
 
658
                   lf->m_up->m_dn = lf;
 
659
               }
 
660
               lf->m_up->m_on[7] += 0x10000000;
 
661
               lf->m_on[0] += 0x10000000;
 
662
               lf->m_on[1] += 0x10000000;
 
663
            }
 
664
            if (t1 & 0x00000100)
 
665
            {
 
666
               lf->m_on[0] += 0x10000000;
 
667
               lf->m_on[1] += 0x10000000;
 
668
               lf->m_on[2] += 0x10000000;
 
669
            }
 
670
            if (t1 & 0x00010000)
 
671
            {
 
672
               lf->m_on[1] += 0x10000000;
 
673
               lf->m_on[2] += 0x10000000;
 
674
               lf->m_on[3] += 0x10000000;
 
675
            }
 
676
            if (t1 & 0x01000000)
 
677
            {
 
678
               lf->m_on[2] += 0x10000000;
 
679
               lf->m_on[3] += 0x10000000;
 
680
               lf->m_on[4] += 0x10000000;
 
681
            }
 
682
        }
 
683
        if (t2 & 0x01010101)
 
684
        {
 
685
            if (!lf)
 
686
            {
 
687
                lf = LinkBox(c->m_x - 8, c->m_y);
 
688
                lf->m_rt = c;
 
689
            }
 
690
            if (t2 & 0x00000001)
 
691
            {
 
692
               lf->m_on[3] += 0x10000000;
 
693
               lf->m_on[4] += 0x10000000;
 
694
               lf->m_on[5] += 0x10000000;
 
695
            }
 
696
            if (t2 & 0x00000100)
 
697
            {
 
698
               lf->m_on[4] += 0x10000000;
 
699
               lf->m_on[5] += 0x10000000;
 
700
               lf->m_on[6] += 0x10000000;
 
701
            }
 
702
            if (t2 & 0x00010000)
 
703
            {
 
704
               lf->m_on[5] += 0x10000000;
 
705
               lf->m_on[6] += 0x10000000;
 
706
               lf->m_on[7] += 0x10000000;
 
707
            }
 
708
            if (t2 & 0x01000000)
 
709
            {
 
710
               if (!lf->m_dn)
 
711
               {
 
712
                   lf->m_dn = LinkBox(c->m_x - 8, c->m_y + 8);
 
713
                   lf->m_dn->m_up = lf;
 
714
               }
 
715
               lf->m_on[6] += 0x10000000;
 
716
               lf->m_on[7] += 0x10000000;
 
717
               lf->m_dn->m_on[0] += 0x10000000;
 
718
            }
 
719
        }
 
720
 
 
721
        // right
 
722
        if (t1 & 0x80808080)
 
723
        {
 
724
            if (!rt)
 
725
            {
 
726
                rt = LinkBox(c->m_x + 8, c->m_y);
 
727
                rt->m_lf = c;
 
728
            }
 
729
            if (t1 & 0x00000080)
 
730
            {
 
731
               if (!rt->m_up)
 
732
               {
 
733
                   rt->m_up = LinkBox(c->m_x + 8, c->m_y - 8);
 
734
                   rt->m_up->m_dn = rt;
 
735
               }
 
736
               rt->m_up->m_on[7] += 0x00000001;
 
737
               rt->m_on[0] += 0x00000001;
 
738
               rt->m_on[1] += 0x00000001;
 
739
            }
 
740
            if (t1 & 0x00008000)
 
741
            {
 
742
               rt->m_on[0] += 0x00000001;
 
743
               rt->m_on[1] += 0x00000001;
 
744
               rt->m_on[2] += 0x00000001;
 
745
            }
 
746
            if (t1 & 0x00800000)
 
747
            {
 
748
               rt->m_on[1] += 0x00000001;
 
749
               rt->m_on[2] += 0x00000001;
 
750
               rt->m_on[3] += 0x00000001;
 
751
            }
 
752
            if (t1 & 0x80000000)
 
753
            {
 
754
               rt->m_on[2] += 0x00000001;
 
755
               rt->m_on[3] += 0x00000001;
 
756
               rt->m_on[4] += 0x00000001;
 
757
            }
 
758
        }
 
759
        if (t2 & 0x80808080)
 
760
        {
 
761
            if (!rt)
 
762
            {
 
763
                rt = LinkBox(c->m_x + 8, c->m_y);
 
764
                rt->m_lf = c;
 
765
            }
 
766
            if (t2 & 0x00000080)
 
767
            {
 
768
               rt->m_on[3] += 0x00000001;
 
769
               rt->m_on[4] += 0x00000001;
 
770
               rt->m_on[5] += 0x00000001;
 
771
            }
 
772
            if (t2 & 0x00008000)
 
773
            {
 
774
               rt->m_on[4] += 0x00000001;
 
775
               rt->m_on[5] += 0x00000001;
 
776
               rt->m_on[6] += 0x00000001;
 
777
            }
 
778
            if (t2 & 0x00800000)
 
779
            {
 
780
               rt->m_on[5] += 0x00000001;
 
781
               rt->m_on[6] += 0x00000001;
 
782
               rt->m_on[7] += 0x00000001;
 
783
            }
 
784
            if (t2 & 0x80000000)
 
785
            {
 
786
               if (!rt->m_dn)
 
787
               {
 
788
                   rt->m_dn = LinkBox(c->m_x + 8, c->m_y + 8);
 
789
                   rt->m_dn->m_up = rt;
 
790
               }
 
791
               rt->m_on[6] += 0x00000001;
 
792
               rt->m_on[7] += 0x00000001;
 
793
               rt->m_dn->m_on[0] += 0x00000001;
 
794
            }
 
795
        }
 
796
 
 
797
        // inner cells
 
798
        int i;
 
799
        for (i = 1; i <= 3; i++)
 
800
        {
 
801
            t1 = ((c->m_live1) >> (i * 8)) & 0x000000ff;
 
802
            if (t1)
 
803
            {
 
804
                c->m_on[i - 1] += g_tab1[t1];
 
805
                c->m_on[i    ] += g_tab2[t1];
 
806
                c->m_on[i + 1] += g_tab1[t1];
 
807
            }
 
808
        }
 
809
        for (i = 0; i <= 2; i++)
 
810
        {
 
811
            t1 = ((c->m_live2) >> (i * 8)) & 0x000000ff;
 
812
            if (t1)
 
813
            {
 
814
                c->m_on[i + 3] += g_tab1[t1];
 
815
                c->m_on[i + 4] += g_tab2[t1];
 
816
                c->m_on[i + 5] += g_tab1[t1];
 
817
            }
 
818
        }
 
819
 
 
820
        c->m_up = up;
 
821
        c->m_dn = dn;
 
822
        c->m_lf = lf;
 
823
        c->m_rt = rt;
 
824
        c = c->m_next;
 
825
    }
 
826
 
 
827
    // Stage 2:
 
828
    // Stabilize
 
829
    //
 
830
    c = m_head;
 
831
 
 
832
    while (c)
 
833
    {
 
834
        t1 = 0;
 
835
        t2 = 0;
 
836
 
 
837
        t3 = c->m_live1;
 
838
        c->m_old1 = t3;
 
839
 
 
840
        t4 = c->m_on[0];
 
841
        t1 |= g_tab[ ((t4 & 0x0000ffff) << 4 ) + ((t3      ) & 0xf) ];
 
842
        t1 |= g_tab[ ((t4 & 0xffff0000) >> 12) + ((t3 >> 4 ) & 0xf) ] << 4;
 
843
        t4 = c->m_on[1];
 
844
        t1 |= g_tab[ ((t4 & 0x0000ffff) << 4 ) + ((t3 >> 8 ) & 0xf) ] << 8;
 
845
        t1 |= g_tab[ ((t4 & 0xffff0000) >> 12) + ((t3 >> 12) & 0xf) ] << 12;
 
846
        t4 = c->m_on[2];
 
847
        t1 |= g_tab[ ((t4 & 0x0000ffff) << 4 ) + ((t3 >> 16) & 0xf) ] << 16;
 
848
        t1 |= g_tab[ ((t4 & 0xffff0000) >> 12) + ((t3 >> 20) & 0xf) ] << 20;
 
849
        t4 = c->m_on[3];
 
850
        t1 |= g_tab[ ((t4 & 0x0000ffff) << 4 ) + ((t3 >> 24) & 0xf) ] << 24;
 
851
        t1 |= g_tab[ ((t4 & 0xffff0000) >> 12) + ((t3 >> 28) & 0xf) ] << 28;
 
852
 
 
853
        t3 = c->m_live2;
 
854
        c->m_old2 = t3;
 
855
 
 
856
        t4 = c->m_on[4];
 
857
        t2 |= g_tab[ ((t4 & 0x0000ffff) << 4 ) + ((t3      ) & 0xf) ];
 
858
        t2 |= g_tab[ ((t4 & 0xffff0000) >> 12) + ((t3 >> 4 ) & 0xf) ] << 4;
 
859
        t4 = c->m_on[5];
 
860
        t2 |= g_tab[ ((t4 & 0x0000ffff) << 4 ) + ((t3 >> 8 ) & 0xf) ] << 8;
 
861
        t2 |= g_tab[ ((t4 & 0xffff0000) >> 12) + ((t3 >> 12) & 0xf) ] << 12;
 
862
        t4 = c->m_on[6];
 
863
        t2 |= g_tab[ ((t4 & 0x0000ffff) << 4 ) + ((t3 >> 16) & 0xf) ] << 16;
 
864
        t2 |= g_tab[ ((t4 & 0xffff0000) >> 12) + ((t3 >> 20) & 0xf) ] << 20;
 
865
        t4 = c->m_on[7];
 
866
        t2 |= g_tab[ ((t4 & 0x0000ffff) << 4 ) + ((t3 >> 24) & 0xf) ] << 24;
 
867
        t2 |= g_tab[ ((t4 & 0xffff0000) >> 12) + ((t3 >> 28) & 0xf) ] << 28;
 
868
 
 
869
        c->m_on[0] = c->m_on[1] = c->m_on[2] = c->m_on[3] =
 
870
        c->m_on[4] = c->m_on[5] = c->m_on[6] = c->m_on[7] = 0;
 
871
        c->m_live1 = t1;
 
872
        c->m_live2 = t2;
 
873
 
 
874
        // count alive cells
 
875
#if 1
 
876
        wxUint32 t1_, t2_;
 
877
 
 
878
        t1_ = (t1  & 0x55555555) + (t1  >> 1 & 0x55555555);
 
879
        t1_ = (t1_ & 0x33333333) + (t1_ >> 2 & 0x33333333);
 
880
 
 
881
        t2_ = (t2  & 0x55555555) + (t2  >> 1 & 0x55555555);
 
882
        t2_ = (t2_ & 0x33333333) + (t2_ >> 2 & 0x33333333) + t1_;
 
883
        t2_ = (t2_ & 0x0F0F0F0F) + (t2_ >> 4 & 0x0F0F0F0F);
 
884
        t2_ = (t2_ & 0x00FF00FF) + (t2_ >> 8 & 0x00FF00FF);
 
885
 
 
886
        m_numcells += (t2_ & 0xFF) + (t2_ >> 16 & 0xFF);
 
887
#else
 
888
        // Original, slower code
 
889
        for (int i = 0; i < 32; i++)
 
890
        {
 
891
            if (t1 & (1 << i)) m_numcells++;
 
892
            if (t2 & (1 << i)) m_numcells++;
 
893
        }
 
894
#endif
 
895
 
 
896
        changed |= ((t1 ^ c->m_old1) || (t2 ^ c->m_old2));
 
897
 
 
898
        // mark, and discard if necessary, dead boxes
 
899
        if (t1 || t2)
 
900
        {
 
901
            c->m_dead = 0;
 
902
            c = c->m_next;
 
903
        }
 
904
        else
 
905
        {
 
906
            LifeCellBox *aux = c->m_next;
 
907
            if (c->m_dead++ > MAXDEAD)
 
908
               KillBox(c);
 
909
 
 
910
            c = aux;
 
911
        }
 
912
    }
 
913
 
 
914
    return changed;
 
915
}
 
916
 
 
917
// ==========================================================================
 
918
// LifeModule
 
919
// ==========================================================================
 
920
 
 
921
// A module to pregenerate lookup tables without having to do it
 
922
// from the application.
 
923
 
 
924
class LifeModule: public wxModule
 
925
{
 
926
DECLARE_DYNAMIC_CLASS(LifeModule)
 
927
 
 
928
public:
 
929
    LifeModule() {};
 
930
    bool OnInit();
 
931
    void OnExit();
 
932
};
 
933
 
 
934
IMPLEMENT_DYNAMIC_CLASS(LifeModule, wxModule)
 
935
 
 
936
bool LifeModule::OnInit()
 
937
{
 
938
    // see below
 
939
    g_tab = new unsigned char [0xfffff];
 
940
 
 
941
    if (!g_tab) return false;
 
942
 
 
943
    for (wxUint32 i = 0; i < 0xfffff; i++)
 
944
    {
 
945
        wxUint32 val  = i >> 4;
 
946
        wxUint32 old  = i & 0x0000f;
 
947
        wxUint32 live = 0;
 
948
 
 
949
        for (int j = 0; j < 4; j++)
 
950
        {
 
951
            live >>= 1;
 
952
 
 
953
            if (((val & 0xf) == 3) || (((val & 0xf) == 2) && (old & 0x1)))
 
954
                live |= 0x8;
 
955
 
 
956
            old >>= 1;
 
957
            val >>= 4;
 
958
        }
 
959
 
 
960
        g_tab[i] = (unsigned char) live;
 
961
    }
 
962
 
 
963
    return true;
 
964
}
 
965
 
 
966
void LifeModule::OnExit()
 
967
{
 
968
    delete [] g_tab;
 
969
}
 
970
 
 
971
 
 
972
// This table converts from number of neighbors (like in on[]) to
 
973
// bits, for a set of four cells. It takes as index a five-digit
 
974
// hexadecimal value (0xNNNNB) where Ns hold number of neighbors
 
975
// for each cell and B holds their previous state.
 
976
//
 
977
unsigned char *g_tab;
 
978
 
 
979
// This table converts from bits (like in live1, live2) to number
 
980
// of neighbors for each cell in the upper or lower row.
 
981
//
 
982
int g_tab1[]=
 
983
{
 
984
    0x00000000,
 
985
    0x00000011,
 
986
    0x00000111,
 
987
    0x00000122,
 
988
    0x00001110,
 
989
    0x00001121,
 
990
    0x00001221,
 
991
    0x00001232,
 
992
    0x00011100,
 
993
    0x00011111,
 
994
    0x00011211,
 
995
    0x00011222,
 
996
    0x00012210,
 
997
    0x00012221,
 
998
    0x00012321,
 
999
    0x00012332,
 
1000
    0x00111000,
 
1001
    0x00111011,
 
1002
    0x00111111,
 
1003
    0x00111122,
 
1004
    0x00112110,
 
1005
    0x00112121,
 
1006
    0x00112221,
 
1007
    0x00112232,
 
1008
    0x00122100,
 
1009
    0x00122111,
 
1010
    0x00122211,
 
1011
    0x00122222,
 
1012
    0x00123210,
 
1013
    0x00123221,
 
1014
    0x00123321,
 
1015
    0x00123332,
 
1016
    0x01110000,
 
1017
    0x01110011,
 
1018
    0x01110111,
 
1019
    0x01110122,
 
1020
    0x01111110,
 
1021
    0x01111121,
 
1022
    0x01111221,
 
1023
    0x01111232,
 
1024
    0x01121100,
 
1025
    0x01121111,
 
1026
    0x01121211,
 
1027
    0x01121222,
 
1028
    0x01122210,
 
1029
    0x01122221,
 
1030
    0x01122321,
 
1031
    0x01122332,
 
1032
    0x01221000,
 
1033
    0x01221011,
 
1034
    0x01221111,
 
1035
    0x01221122,
 
1036
    0x01222110,
 
1037
    0x01222121,
 
1038
    0x01222221,
 
1039
    0x01222232,
 
1040
    0x01232100,
 
1041
    0x01232111,
 
1042
    0x01232211,
 
1043
    0x01232222,
 
1044
    0x01233210,
 
1045
    0x01233221,
 
1046
    0x01233321,
 
1047
    0x01233332,
 
1048
    0x11100000,
 
1049
    0x11100011,
 
1050
    0x11100111,
 
1051
    0x11100122,
 
1052
    0x11101110,
 
1053
    0x11101121,
 
1054
    0x11101221,
 
1055
    0x11101232,
 
1056
    0x11111100,
 
1057
    0x11111111,
 
1058
    0x11111211,
 
1059
    0x11111222,
 
1060
    0x11112210,
 
1061
    0x11112221,
 
1062
    0x11112321,
 
1063
    0x11112332,
 
1064
    0x11211000,
 
1065
    0x11211011,
 
1066
    0x11211111,
 
1067
    0x11211122,
 
1068
    0x11212110,
 
1069
    0x11212121,
 
1070
    0x11212221,
 
1071
    0x11212232,
 
1072
    0x11222100,
 
1073
    0x11222111,
 
1074
    0x11222211,
 
1075
    0x11222222,
 
1076
    0x11223210,
 
1077
    0x11223221,
 
1078
    0x11223321,
 
1079
    0x11223332,
 
1080
    0x12210000,
 
1081
    0x12210011,
 
1082
    0x12210111,
 
1083
    0x12210122,
 
1084
    0x12211110,
 
1085
    0x12211121,
 
1086
    0x12211221,
 
1087
    0x12211232,
 
1088
    0x12221100,
 
1089
    0x12221111,
 
1090
    0x12221211,
 
1091
    0x12221222,
 
1092
    0x12222210,
 
1093
    0x12222221,
 
1094
    0x12222321,
 
1095
    0x12222332,
 
1096
    0x12321000,
 
1097
    0x12321011,
 
1098
    0x12321111,
 
1099
    0x12321122,
 
1100
    0x12322110,
 
1101
    0x12322121,
 
1102
    0x12322221,
 
1103
    0x12322232,
 
1104
    0x12332100,
 
1105
    0x12332111,
 
1106
    0x12332211,
 
1107
    0x12332222,
 
1108
    0x12333210,
 
1109
    0x12333221,
 
1110
    0x12333321,
 
1111
    0x12333332,
 
1112
    0x11000000,
 
1113
    0x11000011,
 
1114
    0x11000111,
 
1115
    0x11000122,
 
1116
    0x11001110,
 
1117
    0x11001121,
 
1118
    0x11001221,
 
1119
    0x11001232,
 
1120
    0x11011100,
 
1121
    0x11011111,
 
1122
    0x11011211,
 
1123
    0x11011222,
 
1124
    0x11012210,
 
1125
    0x11012221,
 
1126
    0x11012321,
 
1127
    0x11012332,
 
1128
    0x11111000,
 
1129
    0x11111011,
 
1130
    0x11111111,
 
1131
    0x11111122,
 
1132
    0x11112110,
 
1133
    0x11112121,
 
1134
    0x11112221,
 
1135
    0x11112232,
 
1136
    0x11122100,
 
1137
    0x11122111,
 
1138
    0x11122211,
 
1139
    0x11122222,
 
1140
    0x11123210,
 
1141
    0x11123221,
 
1142
    0x11123321,
 
1143
    0x11123332,
 
1144
    0x12110000,
 
1145
    0x12110011,
 
1146
    0x12110111,
 
1147
    0x12110122,
 
1148
    0x12111110,
 
1149
    0x12111121,
 
1150
    0x12111221,
 
1151
    0x12111232,
 
1152
    0x12121100,
 
1153
    0x12121111,
 
1154
    0x12121211,
 
1155
    0x12121222,
 
1156
    0x12122210,
 
1157
    0x12122221,
 
1158
    0x12122321,
 
1159
    0x12122332,
 
1160
    0x12221000,
 
1161
    0x12221011,
 
1162
    0x12221111,
 
1163
    0x12221122,
 
1164
    0x12222110,
 
1165
    0x12222121,
 
1166
    0x12222221,
 
1167
    0x12222232,
 
1168
    0x12232100,
 
1169
    0x12232111,
 
1170
    0x12232211,
 
1171
    0x12232222,
 
1172
    0x12233210,
 
1173
    0x12233221,
 
1174
    0x12233321,
 
1175
    0x12233332,
 
1176
    0x22100000,
 
1177
    0x22100011,
 
1178
    0x22100111,
 
1179
    0x22100122,
 
1180
    0x22101110,
 
1181
    0x22101121,
 
1182
    0x22101221,
 
1183
    0x22101232,
 
1184
    0x22111100,
 
1185
    0x22111111,
 
1186
    0x22111211,
 
1187
    0x22111222,
 
1188
    0x22112210,
 
1189
    0x22112221,
 
1190
    0x22112321,
 
1191
    0x22112332,
 
1192
    0x22211000,
 
1193
    0x22211011,
 
1194
    0x22211111,
 
1195
    0x22211122,
 
1196
    0x22212110,
 
1197
    0x22212121,
 
1198
    0x22212221,
 
1199
    0x22212232,
 
1200
    0x22222100,
 
1201
    0x22222111,
 
1202
    0x22222211,
 
1203
    0x22222222,
 
1204
    0x22223210,
 
1205
    0x22223221,
 
1206
    0x22223321,
 
1207
    0x22223332,
 
1208
    0x23210000,
 
1209
    0x23210011,
 
1210
    0x23210111,
 
1211
    0x23210122,
 
1212
    0x23211110,
 
1213
    0x23211121,
 
1214
    0x23211221,
 
1215
    0x23211232,
 
1216
    0x23221100,
 
1217
    0x23221111,
 
1218
    0x23221211,
 
1219
    0x23221222,
 
1220
    0x23222210,
 
1221
    0x23222221,
 
1222
    0x23222321,
 
1223
    0x23222332,
 
1224
    0x23321000,
 
1225
    0x23321011,
 
1226
    0x23321111,
 
1227
    0x23321122,
 
1228
    0x23322110,
 
1229
    0x23322121,
 
1230
    0x23322221,
 
1231
    0x23322232,
 
1232
    0x23332100,
 
1233
    0x23332111,
 
1234
    0x23332211,
 
1235
    0x23332222,
 
1236
    0x23333210,
 
1237
    0x23333221,
 
1238
    0x23333321,
 
1239
    0x23333332
 
1240
};
 
1241
 
 
1242
// This table converts from bits (like in live1, live2) to number
 
1243
// of neighbors for each cell in the same row (excluding ourselves)
 
1244
//
 
1245
int g_tab2[]=
 
1246
{
 
1247
    0x00000000,
 
1248
    0x00000010,
 
1249
    0x00000101,
 
1250
    0x00000111,
 
1251
    0x00001010,
 
1252
    0x00001020,
 
1253
    0x00001111,
 
1254
    0x00001121,
 
1255
    0x00010100,
 
1256
    0x00010110,
 
1257
    0x00010201,
 
1258
    0x00010211,
 
1259
    0x00011110,
 
1260
    0x00011120,
 
1261
    0x00011211,
 
1262
    0x00011221,
 
1263
    0x00101000,
 
1264
    0x00101010,
 
1265
    0x00101101,
 
1266
    0x00101111,
 
1267
    0x00102010,
 
1268
    0x00102020,
 
1269
    0x00102111,
 
1270
    0x00102121,
 
1271
    0x00111100,
 
1272
    0x00111110,
 
1273
    0x00111201,
 
1274
    0x00111211,
 
1275
    0x00112110,
 
1276
    0x00112120,
 
1277
    0x00112211,
 
1278
    0x00112221,
 
1279
    0x01010000,
 
1280
    0x01010010,
 
1281
    0x01010101,
 
1282
    0x01010111,
 
1283
    0x01011010,
 
1284
    0x01011020,
 
1285
    0x01011111,
 
1286
    0x01011121,
 
1287
    0x01020100,
 
1288
    0x01020110,
 
1289
    0x01020201,
 
1290
    0x01020211,
 
1291
    0x01021110,
 
1292
    0x01021120,
 
1293
    0x01021211,
 
1294
    0x01021221,
 
1295
    0x01111000,
 
1296
    0x01111010,
 
1297
    0x01111101,
 
1298
    0x01111111,
 
1299
    0x01112010,
 
1300
    0x01112020,
 
1301
    0x01112111,
 
1302
    0x01112121,
 
1303
    0x01121100,
 
1304
    0x01121110,
 
1305
    0x01121201,
 
1306
    0x01121211,
 
1307
    0x01122110,
 
1308
    0x01122120,
 
1309
    0x01122211,
 
1310
    0x01122221,
 
1311
    0x10100000,
 
1312
    0x10100010,
 
1313
    0x10100101,
 
1314
    0x10100111,
 
1315
    0x10101010,
 
1316
    0x10101020,
 
1317
    0x10101111,
 
1318
    0x10101121,
 
1319
    0x10110100,
 
1320
    0x10110110,
 
1321
    0x10110201,
 
1322
    0x10110211,
 
1323
    0x10111110,
 
1324
    0x10111120,
 
1325
    0x10111211,
 
1326
    0x10111221,
 
1327
    0x10201000,
 
1328
    0x10201010,
 
1329
    0x10201101,
 
1330
    0x10201111,
 
1331
    0x10202010,
 
1332
    0x10202020,
 
1333
    0x10202111,
 
1334
    0x10202121,
 
1335
    0x10211100,
 
1336
    0x10211110,
 
1337
    0x10211201,
 
1338
    0x10211211,
 
1339
    0x10212110,
 
1340
    0x10212120,
 
1341
    0x10212211,
 
1342
    0x10212221,
 
1343
    0x11110000,
 
1344
    0x11110010,
 
1345
    0x11110101,
 
1346
    0x11110111,
 
1347
    0x11111010,
 
1348
    0x11111020,
 
1349
    0x11111111,
 
1350
    0x11111121,
 
1351
    0x11120100,
 
1352
    0x11120110,
 
1353
    0x11120201,
 
1354
    0x11120211,
 
1355
    0x11121110,
 
1356
    0x11121120,
 
1357
    0x11121211,
 
1358
    0x11121221,
 
1359
    0x11211000,
 
1360
    0x11211010,
 
1361
    0x11211101,
 
1362
    0x11211111,
 
1363
    0x11212010,
 
1364
    0x11212020,
 
1365
    0x11212111,
 
1366
    0x11212121,
 
1367
    0x11221100,
 
1368
    0x11221110,
 
1369
    0x11221201,
 
1370
    0x11221211,
 
1371
    0x11222110,
 
1372
    0x11222120,
 
1373
    0x11222211,
 
1374
    0x11222221,
 
1375
    0x01000000,
 
1376
    0x01000010,
 
1377
    0x01000101,
 
1378
    0x01000111,
 
1379
    0x01001010,
 
1380
    0x01001020,
 
1381
    0x01001111,
 
1382
    0x01001121,
 
1383
    0x01010100,
 
1384
    0x01010110,
 
1385
    0x01010201,
 
1386
    0x01010211,
 
1387
    0x01011110,
 
1388
    0x01011120,
 
1389
    0x01011211,
 
1390
    0x01011221,
 
1391
    0x01101000,
 
1392
    0x01101010,
 
1393
    0x01101101,
 
1394
    0x01101111,
 
1395
    0x01102010,
 
1396
    0x01102020,
 
1397
    0x01102111,
 
1398
    0x01102121,
 
1399
    0x01111100,
 
1400
    0x01111110,
 
1401
    0x01111201,
 
1402
    0x01111211,
 
1403
    0x01112110,
 
1404
    0x01112120,
 
1405
    0x01112211,
 
1406
    0x01112221,
 
1407
    0x02010000,
 
1408
    0x02010010,
 
1409
    0x02010101,
 
1410
    0x02010111,
 
1411
    0x02011010,
 
1412
    0x02011020,
 
1413
    0x02011111,
 
1414
    0x02011121,
 
1415
    0x02020100,
 
1416
    0x02020110,
 
1417
    0x02020201,
 
1418
    0x02020211,
 
1419
    0x02021110,
 
1420
    0x02021120,
 
1421
    0x02021211,
 
1422
    0x02021221,
 
1423
    0x02111000,
 
1424
    0x02111010,
 
1425
    0x02111101,
 
1426
    0x02111111,
 
1427
    0x02112010,
 
1428
    0x02112020,
 
1429
    0x02112111,
 
1430
    0x02112121,
 
1431
    0x02121100,
 
1432
    0x02121110,
 
1433
    0x02121201,
 
1434
    0x02121211,
 
1435
    0x02122110,
 
1436
    0x02122120,
 
1437
    0x02122211,
 
1438
    0x02122221,
 
1439
    0x11100000,
 
1440
    0x11100010,
 
1441
    0x11100101,
 
1442
    0x11100111,
 
1443
    0x11101010,
 
1444
    0x11101020,
 
1445
    0x11101111,
 
1446
    0x11101121,
 
1447
    0x11110100,
 
1448
    0x11110110,
 
1449
    0x11110201,
 
1450
    0x11110211,
 
1451
    0x11111110,
 
1452
    0x11111120,
 
1453
    0x11111211,
 
1454
    0x11111221,
 
1455
    0x11201000,
 
1456
    0x11201010,
 
1457
    0x11201101,
 
1458
    0x11201111,
 
1459
    0x11202010,
 
1460
    0x11202020,
 
1461
    0x11202111,
 
1462
    0x11202121,
 
1463
    0x11211100,
 
1464
    0x11211110,
 
1465
    0x11211201,
 
1466
    0x11211211,
 
1467
    0x11212110,
 
1468
    0x11212120,
 
1469
    0x11212211,
 
1470
    0x11212221,
 
1471
    0x12110000,
 
1472
    0x12110010,
 
1473
    0x12110101,
 
1474
    0x12110111,
 
1475
    0x12111010,
 
1476
    0x12111020,
 
1477
    0x12111111,
 
1478
    0x12111121,
 
1479
    0x12120100,
 
1480
    0x12120110,
 
1481
    0x12120201,
 
1482
    0x12120211,
 
1483
    0x12121110,
 
1484
    0x12121120,
 
1485
    0x12121211,
 
1486
    0x12121221,
 
1487
    0x12211000,
 
1488
    0x12211010,
 
1489
    0x12211101,
 
1490
    0x12211111,
 
1491
    0x12212010,
 
1492
    0x12212020,
 
1493
    0x12212111,
 
1494
    0x12212121,
 
1495
    0x12221100,
 
1496
    0x12221110,
 
1497
    0x12221201,
 
1498
    0x12221211,
 
1499
    0x12222110,
 
1500
    0x12222120,
 
1501
    0x12222211,
 
1502
    0x12222221
 
1503
};