summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rwxr-xr-xcommon/library.cpp34
-rw-r--r--common/project.cpp130
-rw-r--r--common/project.h28
-rwxr-xr-xcommon/system.h21
-rw-r--r--common/typedefs.h23
-rw-r--r--common/view.cpp132
-rw-r--r--common/view.h41
7 files changed, 338 insertions, 71 deletions
diff --git a/common/library.cpp b/common/library.cpp
index 20c9ab5..eb2c48b 100755
--- a/common/library.cpp
+++ b/common/library.cpp
@@ -394,11 +394,12 @@ void PiecesLibrary::GetCategoryEntries(int CategoryIndex, PtrArray<PieceInfo>& S
{
bool m_bSubParts = false;
- String& SearchString = m_Categories[CategoryIndex].Keywords;
-
SinglePieces.RemoveAll();
GroupedPieces.RemoveAll();
+ String Keywords = m_Categories[CategoryIndex].Keywords;
+ Keywords.MakeLower();
+
for (int i = 0; i < m_nPieceCount; i++)
{
PieceInfo* Info = &m_pPieceIdx[i];
@@ -408,7 +409,34 @@ void PiecesLibrary::GetCategoryEntries(int CategoryIndex, PtrArray<PieceInfo>& S
continue;
// Check if the piece belongs to this category.
- if (strncmp(Info->m_strDescription, (const char*)SearchString, strlen(SearchString)) != 0)
+ String PieceName = Info->m_strDescription;
+ PieceName.MakeLower();
+
+ const char* p = Keywords;
+ bool Match = false;
+
+ while (*p)
+ {
+ const char* k = p;
+
+ while (*k && (*k != ',') && (*k != ';'))
+ k++;
+
+ String Search = Keywords.Mid(p - (const char*)Keywords, k - p);
+
+ if (PieceName.Find(Search) != -1)
+ {
+ Match = true;
+ break;
+ }
+
+ if (*k)
+ p = k + 1;
+ else
+ break;
+ }
+
+ if (!Match)
continue;
// Check if it's a patterned piece.
diff --git a/common/project.cpp b/common/project.cpp
index e5dc31f..ff96ddd 100644
--- a/common/project.cpp
+++ b/common/project.cpp
@@ -98,6 +98,7 @@ Project::Project()
m_nGridList = 0;
m_pTrackFile = NULL;
m_nCurClipboard = 0;
+ m_nCurAction = 0;
m_pTerrain = new Terrain();
m_pBackground = new Texture();
m_nAutosave = Sys_ProfileLoadInt ("Settings", "Autosave", 10);
@@ -2826,6 +2827,76 @@ void Project::RenderOverlays(int Viewport)
glEnable(GL_DEPTH_TEST);
}
+ else if (m_nCurAction == LC_ACTION_ROTATE_VIEW)
+ {
+ int x, y, w, h;
+
+ x = (int)(viewports[m_nViewportMode].dim[m_nActiveViewport][0] * (float)m_nViewX);
+ y = (int)(viewports[m_nViewportMode].dim[m_nActiveViewport][1] * (float)m_nViewY);
+ w = (int)(viewports[m_nViewportMode].dim[m_nActiveViewport][2] * (float)m_nViewX);
+ h = (int)(viewports[m_nViewportMode].dim[m_nActiveViewport][3] * (float)m_nViewY);
+
+ glViewport(0, 0, m_nViewX, m_nViewY);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, m_nViewX, 0, m_nViewY, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.375f, 0.375f, 0.0f);
+
+ glDisable(GL_DEPTH_TEST);
+ glColor3f(0, 0, 0);
+
+ // Draw circle.
+ glBegin(GL_LINE_LOOP);
+
+ float r = min(w, h) * 0.35f;
+ float cx = x + w / 2.0f;
+ float cy = y + h / 2.0f;
+
+ for (int i = 0; i < 32; i++)
+ {
+ float x = cosf((float)i / 32.0f * (2.0f * LC_PI)) * r + cx;
+ float y = sinf((float)i / 32.0f * (2.0f * LC_PI)) * r + cy;
+
+ glVertex2f(x, y);
+ }
+
+ glEnd();
+
+ const float OverlayCameraSquareSize = 8.0f;
+
+ // Draw squares.
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(cx + OverlayCameraSquareSize, cy + r + OverlayCameraSquareSize);
+ glVertex2f(cx - OverlayCameraSquareSize, cy + r + OverlayCameraSquareSize);
+ glVertex2f(cx - OverlayCameraSquareSize, cy + r - OverlayCameraSquareSize);
+ glVertex2f(cx + OverlayCameraSquareSize, cy + r - OverlayCameraSquareSize);
+ glEnd();
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(cx + OverlayCameraSquareSize, cy - r + OverlayCameraSquareSize);
+ glVertex2f(cx - OverlayCameraSquareSize, cy - r + OverlayCameraSquareSize);
+ glVertex2f(cx - OverlayCameraSquareSize, cy - r - OverlayCameraSquareSize);
+ glVertex2f(cx + OverlayCameraSquareSize, cy - r - OverlayCameraSquareSize);
+ glEnd();
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(cx + r + OverlayCameraSquareSize, cy + OverlayCameraSquareSize);
+ glVertex2f(cx + r - OverlayCameraSquareSize, cy + OverlayCameraSquareSize);
+ glVertex2f(cx + r - OverlayCameraSquareSize, cy - OverlayCameraSquareSize);
+ glVertex2f(cx + r + OverlayCameraSquareSize, cy - OverlayCameraSquareSize);
+ glEnd();
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(cx - r + OverlayCameraSquareSize, cy + OverlayCameraSquareSize);
+ glVertex2f(cx - r - OverlayCameraSquareSize, cy + OverlayCameraSquareSize);
+ glVertex2f(cx - r - OverlayCameraSquareSize, cy - OverlayCameraSquareSize);
+ glVertex2f(cx - r + OverlayCameraSquareSize, cy - OverlayCameraSquareSize);
+ glEnd();
+
+ glEnable(GL_DEPTH_TEST);
+ }
}
void Project::RenderViewports(bool bBackground, bool bLines)
@@ -6458,7 +6529,8 @@ void Project::SetAction(int nAction)
SystemUpdateAction(nAction, m_nCurAction);
m_nCurAction = nAction;
- if ((m_nCurAction == LC_ACTION_MOVE) || (m_nCurAction == LC_ACTION_ROTATE))
+ if ((m_nCurAction == LC_ACTION_MOVE) || (m_nCurAction == LC_ACTION_ROTATE) ||
+ (m_nCurAction == LC_ACTION_ROTATE_VIEW))
{
ActivateOverlay();
@@ -8769,7 +8841,6 @@ void Project::OnMouseMove(int x, int y, bool bControl, bool bShift)
SystemUpdateCurrentCamera(NULL, pCamera, m_pCameras);
}
-
float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 };
for (Piece* pPiece = m_pPieces; pPiece; pPiece = pPiece->m_pNext)
if (pPiece->IsSelected())
@@ -8778,7 +8849,25 @@ void Project::OnMouseMove(int x, int y, bool bControl, bool bShift)
bs[1] = (bs[1]+bs[4])/2;
bs[2] = (bs[2]+bs[5])/2;
- m_pViewCameras[m_nActiveViewport]->DoRotate(x - m_nDownX, y - m_nDownY, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys, bs);
+ switch (m_OverlayMode)
+ {
+ case LC_OVERLAY_XYZ:
+ m_pViewCameras[m_nActiveViewport]->DoRotate(x - m_nDownX, y - m_nDownY, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys, bs);
+ break;
+
+ case LC_OVERLAY_X:
+ m_pViewCameras[m_nActiveViewport]->DoRotate(x - m_nDownX, 0, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys, bs);
+ break;
+
+ case LC_OVERLAY_Y:
+ m_pViewCameras[m_nActiveViewport]->DoRotate(0, y - m_nDownY, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys, bs);
+ break;
+
+ case LC_OVERLAY_Z:
+ m_pViewCameras[m_nActiveViewport]->DoRoll(x - m_nDownX, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys);
+ break;
+ }
+
m_nDownX = x;
m_nDownY = y;
SystemUpdateFocus(NULL);
@@ -9066,11 +9155,44 @@ void Project::MouseUpdateOverlays(int x, int y)
UpdateAllViews();
}
}
+ else if (m_nCurAction == LC_ACTION_ROTATE_VIEW)
+ {
+ int vx, vy, vw, vh;
+ vx = (int)(viewports[m_nViewportMode].dim[m_nActiveViewport][0] * (float)m_nViewX);
+ vy = (int)(viewports[m_nViewportMode].dim[m_nActiveViewport][1] * (float)m_nViewY);
+ vw = (int)(viewports[m_nViewportMode].dim[m_nActiveViewport][2] * (float)m_nViewX);
+ vh = (int)(viewports[m_nViewportMode].dim[m_nActiveViewport][3] * (float)m_nViewY);
+
+ int cx = vx + vw / 2;
+ int cy = vy + vh / 2;
+
+ float d = sqrtf((float)((cx - x) * (cx - x) + (cy - y) * (cy - y)));
+ float r = min(vw, vh) * 0.35f;
+
+ if ((d < r + 4.0f) && (d > r - 4.0f))
+ {
+ if ((cx - x < 4) && (cx - x > -4))
+ m_OverlayMode = LC_OVERLAY_Y;
+
+ if ((cy - y < 4) && (cy - y > -4))
+ m_OverlayMode = LC_OVERLAY_X;
+ }
+ else
+ {
+ if (d < r)
+ m_OverlayMode = LC_OVERLAY_XYZ;
+ else
+ m_OverlayMode = LC_OVERLAY_Z;
+ }
+ }
}
void Project::ActivateOverlay()
{
- m_OverlayActive = GetSelectionCenter(m_OverlayCenter);
+ if ((m_nCurAction == LC_ACTION_MOVE) || (m_nCurAction == LC_ACTION_ROTATE))
+ m_OverlayActive = GetSelectionCenter(m_OverlayCenter);
+ else if (m_nCurAction == LC_ACTION_ROTATE_VIEW)
+ m_OverlayActive = true;
if (m_OverlayActive)
{
diff --git a/common/project.h b/common/project.h
index 1492b40..2182518 100644
--- a/common/project.h
+++ b/common/project.h
@@ -14,6 +14,18 @@ typedef enum
LC_TRACK_START_RIGHT, LC_TRACK_RIGHT
} LC_MOUSE_TRACK;
+// Mouse control overlays.
+typedef enum
+{
+ LC_OVERLAY_XYZ,
+ LC_OVERLAY_X,
+ LC_OVERLAY_Y,
+ LC_OVERLAY_Z,
+ LC_OVERLAY_XY,
+ LC_OVERLAY_XZ,
+ LC_OVERLAY_YZ
+} LC_OVERLAY_MODES;
+
class Piece;
class Camera;
class Light;
@@ -70,6 +82,10 @@ public:
{ return m_nCurGroup; }
float* GetBackgroundColor()
{ return m_fBackground; }
+ unsigned char GetAction() const
+ { return m_nCurAction; }
+ int GetOverlayMode() const
+ { return m_OverlayMode; }
Camera* GetCamera(int i);
void GetTimeRange(int* from, int* to)
{
@@ -201,18 +217,6 @@ protected:
Vector3 m_MouseSnapLeftover;
Vector3 m_MouseTotalDelta;
- // Mouse control overlays.
- typedef enum
- {
- LC_OVERLAY_XYZ,
- LC_OVERLAY_X,
- LC_OVERLAY_Y,
- LC_OVERLAY_Z,
- LC_OVERLAY_XY,
- LC_OVERLAY_XZ,
- LC_OVERLAY_YZ
- } LC_OVERLAY_MODES;
-
int m_OverlayMode;
bool m_OverlayActive;
float m_OverlayScale[4];
diff --git a/common/system.h b/common/system.h
index f8161ae..dc3005c 100755
--- a/common/system.h
+++ b/common/system.h
@@ -4,6 +4,27 @@
#include "defines.h"
#include "typedefs.h"
+// Assert macros.
+#ifdef LC_DEBUG
+
+extern bool lcAssert(const char* FileName, int Line, const char* Expression, const char* Description);
+
+#define LC_ASSERT(Expr, Desc) \
+do \
+{ \
+ static bool Ignore = false; \
+ if (!Expr && !Ignore) \
+ Ignore = lcAssert(__FILE__, __LINE__, #Expr, Desc); \
+} while (0)
+
+#define LC_ASSERT_FALSE(Desc) LC_ASSERT(0, Desc)
+
+#else
+
+#define LC_ASSERT(expr, desc) do { } while(0)
+
+#endif
+
// Profile functions
bool Sys_ProfileSaveInt (const char *section, const char *key, int value);
bool Sys_ProfileSaveString (const char *section, const char *key, const char *value);
diff --git a/common/typedefs.h b/common/typedefs.h
index 754bbae..0ce4dc5 100644
--- a/common/typedefs.h
+++ b/common/typedefs.h
@@ -160,6 +160,29 @@ typedef enum
LC_ACTION_CURVE
} LC_ACTIONS;
+typedef enum
+{
+ LC_CURSOR_NONE,
+ LC_CURSOR_BRICK,
+ LC_CURSOR_LIGHT,
+ LC_CURSOR_SPOTLIGHT,
+ LC_CURSOR_CAMERA,
+ LC_CURSOR_SELECT,
+ LC_CURSOR_SELECT_GROUP,
+ LC_CURSOR_MOVE,
+ LC_CURSOR_ROTATE,
+ LC_CURSOR_ROTATEX,
+ LC_CURSOR_ROTATEY,
+ LC_CURSOR_DELETE,
+ LC_CURSOR_PAINT,
+ LC_CURSOR_ZOOM,
+ LC_CURSOR_ZOOM_REGION,
+ LC_CURSOR_PAN,
+ LC_CURSOR_ROLL,
+ LC_CURSOR_ROTATE_VIEW,
+ LC_CURSOR_COUNT
+} LC_CURSOR_TYPE;
+
// Piece connections (complicated and wastes memory but fast).
typedef struct CONNECTION
diff --git a/common/view.cpp b/common/view.cpp
index 27e0595..237a398 100644
--- a/common/view.cpp
+++ b/common/view.cpp
@@ -5,67 +5,135 @@
#include <stdlib.h>
#include "project.h"
#include "view.h"
+#include "system.h"
-View::View (Project *pProject, GLWindow *share)
- : GLWindow (share)
+View::View(Project *pProject, GLWindow *share)
+ : GLWindow(share)
{
- m_pProject = pProject;
+ m_Project = pProject;
}
-View::~View ()
+View::~View()
{
- if (m_pProject != NULL)
- m_pProject->RemoveView (this);
+ if (m_Project != NULL)
+ m_Project->RemoveView(this);
}
-void View::OnDraw ()
+LC_CURSOR_TYPE View::GetCursor(int Ptx, int Pty) const
{
- MakeCurrent ();
+ // TODO: check if we're the focused window and return just the default arrow if we aren't.
- m_pProject->SetViewSize (m_nWidth, m_nHeight);
- m_pProject->Render (false);
+ switch (m_Project->GetAction())
+ {
+ case LC_ACTION_SELECT:
+ if (Sys_KeyDown(KEY_CONTROL))
+ return LC_CURSOR_SELECT_GROUP;
+ else
+ return LC_CURSOR_SELECT;
- SwapBuffers ();
+ case LC_ACTION_INSERT:
+ return LC_CURSOR_BRICK;
+
+ case LC_ACTION_LIGHT:
+ return LC_CURSOR_LIGHT;
+
+ case LC_ACTION_SPOTLIGHT:
+ return LC_CURSOR_SPOTLIGHT;
+
+ case LC_ACTION_CAMERA:
+ return LC_CURSOR_CAMERA;
+
+ case LC_ACTION_MOVE:
+ return LC_CURSOR_MOVE;
+
+ case LC_ACTION_ROTATE:
+ return LC_CURSOR_ROTATE;
+
+ case LC_ACTION_ERASER:
+ return LC_CURSOR_DELETE;
+
+ case LC_ACTION_PAINT:
+ return LC_CURSOR_PAINT;
+
+ case LC_ACTION_ZOOM:
+ return LC_CURSOR_ZOOM;
+
+ case LC_ACTION_ZOOM_REGION:
+ return LC_CURSOR_ZOOM_REGION;
+
+ case LC_ACTION_PAN:
+ return LC_CURSOR_PAN;
+
+ case LC_ACTION_ROTATE_VIEW:
+ switch (m_Project->GetOverlayMode())
+ {
+ case LC_OVERLAY_X: return LC_CURSOR_ROTATEX;
+ case LC_OVERLAY_Y: return LC_CURSOR_ROTATEY;
+ case LC_OVERLAY_Z: return LC_CURSOR_ROLL;
+ case LC_OVERLAY_XYZ: return LC_CURSOR_ROTATE_VIEW;
+ default:
+ LC_ASSERT_FALSE("Unknown cursor type.");
+ return LC_CURSOR_NONE;
+ }
+
+ case LC_ACTION_ROLL:
+ return LC_CURSOR_ROLL;
+
+ case LC_ACTION_CURVE:
+ default:
+ LC_ASSERT_FALSE("Unknown cursor type.");
+ return LC_CURSOR_NONE;
+ }
+}
+
+void View::OnDraw()
+{
+ MakeCurrent();
+
+ m_Project->SetViewSize(m_nWidth, m_nHeight);
+ m_Project->Render(false);
+
+ SwapBuffers();
}
-void View::OnInitialUpdate ()
+void View::OnInitialUpdate()
{
- GLWindow::OnInitialUpdate ();
- m_pProject->AddView (this);
+ GLWindow::OnInitialUpdate();
+ m_Project->AddView(this);
}
-void View::OnLeftButtonDown (int x, int y, bool bControl, bool bShift)
+void View::OnLeftButtonDown(int x, int y, bool bControl, bool bShift)
{
- m_pProject->SetViewSize (m_nWidth, m_nHeight);
- m_pProject->OnLeftButtonDown (x, y, bControl, bShift);
+ m_Project->SetViewSize(m_nWidth, m_nHeight);
+ m_Project->OnLeftButtonDown(x, y, bControl, bShift);
}
-void View::OnLeftButtonUp (int x, int y, bool bControl, bool bShift)
+void View::OnLeftButtonUp(int x, int y, bool bControl, bool bShift)
{
- m_pProject->SetViewSize (m_nWidth, m_nHeight);
- m_pProject->OnLeftButtonUp (x, y, bControl, bShift);
+ m_Project->SetViewSize(m_nWidth, m_nHeight);
+ m_Project->OnLeftButtonUp(x, y, bControl, bShift);
}
-void View::OnLeftButtonDoubleClick (int x, int y, bool bControl, bool bShift)
+void View::OnLeftButtonDoubleClick(int x, int y, bool bControl, bool bShift)
{
- m_pProject->SetViewSize (m_nWidth, m_nHeight);
- m_pProject->OnLeftButtonDoubleClick (x, y, bControl, bShift);
+ m_Project->SetViewSize(m_nWidth, m_nHeight);
+ m_Project->OnLeftButtonDoubleClick(x, y, bControl, bShift);
}
-void View::OnRightButtonDown (int x, int y, bool bControl, bool bShift)
+void View::OnRightButtonDown(int x, int y, bool bControl, bool bShift)
{
- m_pProject->SetViewSize (m_nWidth, m_nHeight);
- m_pProject->OnRightButtonDown (x, y, bControl, bShift);
+ m_Project->SetViewSize(m_nWidth, m_nHeight);
+ m_Project->OnRightButtonDown(x, y, bControl, bShift);
}
-void View::OnRightButtonUp (int x, int y, bool bControl, bool bShift)
+void View::OnRightButtonUp(int x, int y, bool bControl, bool bShift)
{
- m_pProject->SetViewSize (m_nWidth, m_nHeight);
- m_pProject->OnRightButtonUp (x, y, bControl, bShift);
+ m_Project->SetViewSize(m_nWidth, m_nHeight);
+ m_Project->OnRightButtonUp(x, y, bControl, bShift);
}
-void View::OnMouseMove (int x, int y, bool bControl, bool bShift)
+void View::OnMouseMove(int x, int y, bool bControl, bool bShift)
{
- m_pProject->SetViewSize (m_nWidth, m_nHeight);
- m_pProject->OnMouseMove (x, y, bControl, bShift);
+ m_Project->SetViewSize(m_nWidth, m_nHeight);
+ m_Project->OnMouseMove(x, y, bControl, bShift);
}
diff --git a/common/view.h b/common/view.h
index 3a1bcac..2727f2d 100644
--- a/common/view.h
+++ b/common/view.h
@@ -7,26 +7,27 @@ class Project;
class View : public GLWindow
{
- public:
- View (Project *pProject, GLWindow *share);
- virtual ~View ();
-
- void OnDraw ();
- void OnInitialUpdate ();
- void OnLeftButtonDown (int x, int y, bool bControl, bool bShift);
- void OnLeftButtonUp (int x, int y, bool bControl, bool bShift);
- void OnLeftButtonDoubleClick (int x, int y, bool bControl, bool bShift);
- void OnRightButtonDown (int x, int y, bool bControl, bool bShift);
- void OnRightButtonUp (int x, int y, bool bControl, bool bShift);
- void OnMouseMove (int x, int y, bool bControl, bool bShift);
-
- Project* GetProject () const
- { return m_pProject; }
-
- protected:
- Project* m_pProject;
-
- // virtual void OnInitialUpdate (); // called first time after construct
+public:
+ View (Project *pProject, GLWindow *share);
+ virtual ~View ();
+
+ void OnDraw ();
+ void OnInitialUpdate ();
+ void OnLeftButtonDown (int x, int y, bool bControl, bool bShift);
+ void OnLeftButtonUp (int x, int y, bool bControl, bool bShift);
+ void OnLeftButtonDoubleClick (int x, int y, bool bControl, bool bShift);
+ void OnRightButtonDown (int x, int y, bool bControl, bool bShift);
+ void OnRightButtonUp (int x, int y, bool bControl, bool bShift);
+ void OnMouseMove (int x, int y, bool bControl, bool bShift);
+
+ LC_CURSOR_TYPE GetCursor(int x, int y) const;
+ Project* GetProject () const
+ { return m_Project; }
+
+protected:
+ Project* m_Project;
+
+ // virtual void OnInitialUpdate (); // called first time after construct
};
#endif // _VIEW_H_