Modified for new THUMBRELEASE event
Optimized game engine a bit more git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5966 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
7d56fb8fcd
commit
33e3914780
@ -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;
|
||||
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;
|
||||
|
||||
if ((t4 == 3) || ((t4 == 2) && (t1 & 0x00000001)))
|
||||
{
|
||||
t2 |= 0x80000000;
|
||||
m_numcells++;
|
||||
}
|
||||
|
||||
t3 >>= 4;
|
||||
t1 >>= 1;
|
||||
}
|
||||
c->m_on[i] = 0;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
|
||||
if ((t4 == 3) || ((t4 == 2) && (t1 & 0x00000001)))
|
||||
{
|
||||
t2 |= 0x80000000;
|
||||
m_numcells++;
|
||||
}
|
||||
|
||||
t3 >>= 4;
|
||||
t1 >>= 1;
|
||||
}
|
||||
c->m_on[i] = 0;
|
||||
}
|
||||
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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user