]> git.saurik.com Git - wxWidgets.git/commitdiff
Modified for new THUMBRELEASE event
authorGuillermo Rodriguez Garcia <guille@iies.es>
Fri, 11 Feb 2000 17:56:39 +0000 (17:56 +0000)
committerGuillermo Rodriguez Garcia <guille@iies.es>
Fri, 11 Feb 2000 17:56:39 +0000 (17:56 +0000)
Optimized game engine a bit more

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5966 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

demos/life/game.cpp
demos/life/life.cpp

index f4fe8774d09e0f3da86ee160621d7ee3303f9290..b8f83e175c6a420a22863ef32470e4972aea34ed 100644 (file)
@@ -24,7 +24,7 @@
 #include <string.h>           // for memset
 
 
-#define ARRAYSIZE  1024      // size of the static arrays for BeginFind & co.
+#define ARRAYSIZE  8192       // size of the static array for BeginFind & co.
 #define ALLOCBOXES 16         // number of cellboxes to alloc at once
 
 // ==========================================================================
@@ -206,7 +206,7 @@ void Life::SetShape(const LifeShape& shape)
 // --------------------------------------------------------------------------
 
 // CreateBox:
-//  Creates a new box in x, y, either taking it from the list
+//  Creates a box in x, y, either taking it from the list
 //  of available boxes, or allocating a new one.
 //
 CellBox* Life::CreateBox(wxInt32 x, wxInt32 y, wxUint32 hv)
@@ -439,6 +439,7 @@ bool Life::FindMore(Cell *cells[], size_t *ncells)
 // Evolution engine
 // --------------------------------------------------------------------------
 
+extern unsigned char *g_tab;
 extern int g_tab1[];
 extern int g_tab2[];
 
@@ -448,7 +449,7 @@ extern int g_tab2[];
 bool Life::NextTic()
 {
     CellBox  *c, *up, *dn, *lf, *rt;
-    wxUint32 t1, t2, t3, t4;
+    wxUint32 t1, t2, t3;
     bool     changed = FALSE;
 
     m_numcells = 0;
@@ -699,64 +700,41 @@ bool Life::NextTic()
         t1 = c->m_live1;
         c->m_old1 = t1;
         t2 = 0;
-        int i;
-        for (i = 0; i <= 3; i++)
-        {
-            t3 = c->m_on[i];
-            if (!t3)
-            {
-                t1 >>= 8;
-                t2 >>= 8;
-                continue;
-            }
-
-            for (int j = 0; j < 8; j++)
-            {
-                t2 >>= 1;
-                t4 = t3 & 0x0000000f;
-
-                if ((t4 == 3) || ((t4 == 2) && (t1 & 0x00000001)))
-                {
-                    t2 |= 0x80000000;
-                    m_numcells++;
-                }
 
-                t3 >>= 4;
-                t1 >>= 1;
-            }
-            c->m_on[i] = 0;
-        }
+        t3 = c->m_on[0];
+        t2 |= g_tab[ ((t3 & 0x0000ffff) << 4 ) + ((t1      ) & 0xf) ];
+        t2 |= g_tab[ ((t3 & 0xffff0000) >> 12) + ((t1 >> 4 ) & 0xf) ] << 4;
+        t3 = c->m_on[1];
+        t2 |= g_tab[ ((t3 & 0x0000ffff) << 4 ) + ((t1 >> 8 ) & 0xf) ] << 8;
+        t2 |= g_tab[ ((t3 & 0xffff0000) >> 12) + ((t1 >> 12) & 0xf) ] << 12;
+        t3 = c->m_on[2];
+        t2 |= g_tab[ ((t3 & 0x0000ffff) << 4 ) + ((t1 >> 16) & 0xf) ] << 16;
+        t2 |= g_tab[ ((t3 & 0xffff0000) >> 12) + ((t1 >> 20) & 0xf) ] << 20;
+        t3 = c->m_on[3];
+        t2 |= g_tab[ ((t3 & 0x0000ffff) << 4 ) + ((t1 >> 24) & 0xf) ] << 24;
+        t2 |= g_tab[ ((t3 & 0xffff0000) >> 12) + ((t1 >> 28) & 0xf) ] << 28;
+
+        c->m_on[0] = c->m_on[1] = c->m_on[2] = c->m_on[3] = 0;
         c->m_live1 = t2;
 
         t1 = c->m_live2;
         c->m_old2 = t1;
         t2 = 0;
-        for (i = 4; i <= 7; i++)
-        {
-            t3 = c->m_on[i];
-            if (!t3)
-            {
-                t1 >>= 8;
-                t2 >>= 8;
-                continue;
-            }
 
-            for (int j = 0; j < 8; j++)
-            {
-                t2 >>= 1;
-                t4 = t3 & 0x0000000f;
-
-                if ((t4 == 3) || ((t4 == 2) && (t1 & 0x00000001)))
-                {
-                    t2 |= 0x80000000;
-                    m_numcells++;
-                }
-
-                t3 >>= 4;
-                t1 >>= 1;
-            }
-            c->m_on[i] = 0;
-        }
+        t3 = c->m_on[4];
+        t2 |= g_tab[ ((t3 & 0x0000ffff) << 4 ) + ((t1      ) & 0xf) ];
+        t2 |= g_tab[ ((t3 & 0xffff0000) >> 12) + ((t1 >> 4 ) & 0xf) ] << 4;
+        t3 = c->m_on[5];
+        t2 |= g_tab[ ((t3 & 0x0000ffff) << 4 ) + ((t1 >> 8 ) & 0xf) ] << 8;
+        t2 |= g_tab[ ((t3 & 0xffff0000) >> 12) + ((t1 >> 12) & 0xf) ] << 12;
+        t3 = c->m_on[6];
+        t2 |= g_tab[ ((t3 & 0x0000ffff) << 4 ) + ((t1 >> 16) & 0xf) ] << 16;
+        t2 |= g_tab[ ((t3 & 0xffff0000) >> 12) + ((t1 >> 20) & 0xf) ] << 20;
+        t3 = c->m_on[7];
+        t2 |= g_tab[ ((t3 & 0x0000ffff) << 4 ) + ((t1 >> 24) & 0xf) ] << 24;
+        t2 |= g_tab[ ((t3 & 0xffff0000) >> 12) + ((t1 >> 28) & 0xf) ] << 28;
+
+        c->m_on[4] = c->m_on[5] = c->m_on[6] = c->m_on[7] = 0;
         c->m_live2 = t2;
 
         // keep track of changes
@@ -781,9 +759,67 @@ bool Life::NextTic()
     return changed;
 }
 
-// --------------------------------------------------------------------------
-// Lookup tables - these will be generated on-the-fly soon.
-// --------------------------------------------------------------------------
+// ==========================================================================
+// LifeModule
+// ==========================================================================
+
+// A module to pregenerate lookup tables without having to do it
+// from the application.
+
+class LifeModule: public wxModule
+{
+DECLARE_DYNAMIC_CLASS(LifeModule)
+
+public:
+    LifeModule() {};
+    bool OnInit();
+    void OnExit();
+};
+
+IMPLEMENT_DYNAMIC_CLASS(LifeModule, wxModule)
+
+bool LifeModule::OnInit()
+{
+    // see below
+    g_tab = new unsigned char [0xfffff];
+
+    if (!g_tab) return FALSE;
+
+    for (wxUint32 i = 0; i < 0xfffff; i++)
+    {
+        wxUint32 val  = i >> 4;
+        wxUint32 old  = i & 0x0000f;
+        wxUint32 live = 0;
+
+        for (int j = 0; j < 4; j++)
+        {
+            live >>= 1;
+
+            if (((val & 0xf) == 3) || (((val & 0xf) == 2) && (old & 0x1)))
+                live |= 0x8;
+
+            old >>= 1;
+            val >>= 4;
+        }
+
+        g_tab[i] = (unsigned char) live;
+    }
+
+    return TRUE;
+}
+
+void LifeModule::OnExit()
+{
+    delete [] g_tab;
+}
+
+
+// This table converts from number of neighbors (like in on[]) to
+// bits, for a set of four cells. It takes as index a five-digit
+// hexadecimal value (0xNNNNB) where Ns hold number of neighbors
+// for each cell and B holds their previous state.
+//
+unsigned char *g_tab;
 
 // This table converts from bits (like in live1, live2) to number
 // of neighbors for each cell in the upper or lower row.
@@ -941,7 +977,7 @@ int g_tab1[]=
     0x11112110,
     0x11112121,
     0x11112221,
-    0x11112232,
+    0x11112232,                        
     0x11122100,
     0x11122111,
     0x11122211,
index ea39345fd4e4529b4d78cf9eb13cffe365a289d1..448b059fbc39a85de12f7d45db87e24d267de9b0 100644 (file)
@@ -174,12 +174,12 @@ LifeFrame::LifeFrame() : wxFrame((wxFrame *)0, -1, _("Life!"), wxPoint(50, 50))
     wxToolBar *toolBar = CreateToolBar();
     toolBar->SetMargins(5, 5);
     toolBar->SetToolBitmapSize(wxSize(16, 16));
-    ADD_TOOL(ID_RESET,   tbBitmaps[0], _("Reset"), _("Start a new game"));
-    ADD_TOOL(ID_START,   tbBitmaps[1], _("Start"), _("Start"));
-    ADD_TOOL(ID_STOP,    tbBitmaps[2], _("Stop"),  _("Stop"));
+    ADD_TOOL(ID_RESET, tbBitmaps[0], _("Reset"), _("Start a new game"));
+    ADD_TOOL(ID_START, tbBitmaps[1], _("Start"), _("Start"));
+    ADD_TOOL(ID_STOP, tbBitmaps[2], _("Stop"), _("Stop"));
     toolBar->AddSeparator();
-    ADD_TOOL(ID_ZOOMIN,  tbBitmaps[3], _("Zoom in"),  _("Zoom in"));
-    ADD_TOOL(ID_ZOOMOUT, tbBitmaps[4], _("Zoom out"),  _("Zoom out"));
+    ADD_TOOL(ID_ZOOMIN, tbBitmaps[3], _("Zoom in"), _("Zoom in"));
+    ADD_TOOL(ID_ZOOMOUT, tbBitmaps[4], _("Zoom out"), _("Zoom out"));
     toolBar->Realize();
     toolBar->EnableTool(ID_STOP, FALSE);    // must be after Realize() !
 
@@ -209,10 +209,10 @@ LifeFrame::LifeFrame() : wxFrame((wxFrame *)0, -1, _("Life!"), wxPoint(50, 50))
     // component layout
     wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
     sizer->Add(new wxStaticLine(panel, -1), 0, wxGROW | wxCENTRE);
-    sizer->Add(m_canvas, 1, wxGROW | wxCENTRE | wxALL, 5);
+    sizer->Add(m_canvas, 1, wxGROW | wxCENTRE | wxALL, 2);
     sizer->Add(new wxStaticLine(panel, -1), 0, wxGROW | wxCENTRE);
-    sizer->Add(m_text, 0, wxCENTRE | wxTOP, 5);
-    sizer->Add(slider, 0, wxCENTRE | wxALL, 5);
+    sizer->Add(m_text, 0, wxCENTRE | wxTOP, 4);
+    sizer->Add(slider, 0, wxCENTRE | wxALL, 4);
     panel->SetSizer(sizer);
     panel->SetAutoLayout(TRUE);
     sizer->Fit(this);
@@ -748,10 +748,9 @@ void LifeCanvas::OnScroll(wxScrollWinEvent& event)
     WXTYPE type = event.GetEventType();
     int pos     = event.GetPosition();
     int orient  = event.GetOrientation();
-    bool scrolling = event.IsScrolling();
-    int  scrollinc = 0;
 
     // calculate scroll increment
+    int scrollinc = 0;
     switch (type)
     {
         case wxEVT_SCROLLWIN_TOP:
@@ -776,33 +775,28 @@ void LifeCanvas::OnScroll(wxScrollWinEvent& event)
         case wxEVT_SCROLLWIN_PAGEDOWN: scrollinc = +10; break;
         case wxEVT_SCROLLWIN_THUMBTRACK:
         {
-            if (scrolling)
+            if (orient == wxHORIZONTAL)
             {
-                // user is dragging the thumb in the scrollbar
-                if (orient == wxHORIZONTAL)
-                {
-                    scrollinc = pos - m_thumbX;
-                    m_thumbX = pos;
-                }
-                else
-                {
-                    scrollinc = pos - m_thumbY;
-                    m_thumbY = pos;
-                }
+                scrollinc = pos - m_thumbX;
+                m_thumbX = pos;
             }
             else
             {
-                // user released the thumb after dragging
-                m_thumbX = m_viewportW;
-                m_thumbY = m_viewportH;
+                scrollinc = pos - m_thumbY;
+                m_thumbY = pos;
             }
             break;
         }
+        case wxEVT_SCROLLWIN_THUMBRELEASE:
+        {
+            m_thumbX = m_viewportW;
+            m_thumbY = m_viewportH;
+        }
     }
 
 #ifdef __WXGTK__ // what about Motif?
     // wxGTK updates the thumb automatically (wxMSW doesn't); reset it back
-    if ((type != wxEVT_SCROLLWIN_THUMBTRACK) || !scrolling)
+    if (type != wxEVT_SCROLLWIN_THUMBTRACK)
     {
         SetScrollbar(wxHORIZONTAL, m_viewportW, m_viewportW, 3 * m_viewportW);
         SetScrollbar(wxVERTICAL,   m_viewportH, m_viewportH, 3 * m_viewportH);