summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--common/camera.cpp6
-rw-r--r--common/globals.cpp106
-rw-r--r--common/globals.h3
-rwxr-xr-xcommon/library.cpp233
-rwxr-xr-xcommon/library.h98
-rw-r--r--common/light.cpp2
-rw-r--r--common/minifig.cpp578
-rw-r--r--common/minifig.h60
-rw-r--r--common/module.mk2
-rw-r--r--common/piece.cpp84
-rw-r--r--common/piece.h10
-rw-r--r--common/project.cpp252
-rw-r--r--common/project.h25
-rwxr-xr-xcommon/system.h4
-rw-r--r--common/typedefs.h25
-rw-r--r--config.mk10
-rwxr-xr-xlinux/dlgpiece.cpp345
-rw-r--r--linux/main.cpp16
-rw-r--r--linux/system.cpp26
-rw-r--r--win/System.cpp21
21 files changed, 1277 insertions, 631 deletions
diff --git a/Makefile b/Makefile
index 4c0b610..271e7f1 100644
--- a/Makefile
+++ b/Makefile
@@ -27,6 +27,8 @@ OBJ := \
$(patsubst %.c,%.o,$(filter %.c,$(SRC))) \
$(patsubst %.cpp,%.o,$(filter %.cpp,$(SRC)))
+### use c++ for all files (the gtkglarea .c files will be removed shortly)
+CFLAGS += -x c++
### link the program
.PHONY: all static
diff --git a/common/camera.cpp b/common/camera.cpp
index 1fbf576..17155c4 100644
--- a/common/camera.cpp
+++ b/common/camera.cpp
@@ -317,7 +317,8 @@ Camera::Camera (float ex, float ey, float ez, float tx, float ty, float tz, Came
Camera::~Camera()
{
- RemoveKeys();
+ RemoveKeys ();
+ delete m_pTarget;
}
void Camera::Initialize()
@@ -593,7 +594,7 @@ void Camera::ChangeKey (unsigned short nTime, bool bAnimation, bool bAddKey, flo
newpos->param[2] = param[2];
}
-void Camera::Move(unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz)
+void Camera::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz)
{
if (IsSide())
{
@@ -916,7 +917,6 @@ void Camera::MinIntersectDist(LC_CLICKLINE* pLine)
return;
dist = BoundingBoxIntersectDist (pLine);
-
if (dist < pLine->mindist)
{
pLine->mindist = dist;
diff --git a/common/globals.cpp b/common/globals.cpp
index e57757f..34e4336 100644
--- a/common/globals.cpp
+++ b/common/globals.cpp
@@ -87,109 +87,3 @@ unsigned char ColorArray[31][4] = {
{ 51, 51, 51, 255 }, //28 - Edges
{ 229, 76, 102, 255 }, //29 - Selected
{ 102, 76, 229, 255 }}; //30 - Focused
-
-// =========================================================
-// Minifig Wizard options
-
-MFW_PIECEINFO mfwpieceinfo[] = {
- { "3624", "Police Hat", MF_HAT },
- { "3626BP01", "Smiley Face", MF_HEAD },
- { "973", "Plain Torso", MF_TORSO },
- { "3838", "Airtanks", MF_NECK },
- { "976", "Left Arm", MF_ARML },
- { "975", "Right Arm", MF_ARMR },
- { "977", "Hand", MF_HAND },
- { "977", "Hand", MF_HAND },
- { "3899", "Cup", MF_TOOL },
- { "4528", "Frypan", MF_TOOL },
- { "970", "Hips", MF_HIPS },
- { "972", "Left Leg", MF_LEGL },
- { "971", "Right Leg", MF_LEGR },
- { "2599", "Flipper", MF_SHOE },
- { "6120", "Ski", MF_SHOE },
- { "4485", "Baseball Cap", MF_HAT },
- { "3626B", "Plain Face", MF_HEAD },
- { "3626BP02", "Woman Face", MF_HEAD },
- { "973P11", "Dungarees", MF_TORSO },
- { "973P47", "Castle Red/Gray Symbol", MF_TORSO },
- { "973P51", "Blacktron II", MF_TORSO },
- { "973P01", "Vertical Strips Red/Blue", MF_TORSO },
- { "973P02", "Vertical Strips Blue/Red", MF_TORSO },
- { "973P60", "Shell Logo", MF_TORSO },
- { "973P61", "Gold Ice Planet Pattern", MF_TORSO },
- { "4349", "Loudhailer", MF_TOOL },
- { "3962", "Radio", MF_TOOL },
- { "4529", "Saucepan", MF_TOOL },
- { "3959", "Space Gun", MF_TOOL },
- { "4360", "Space Laser Gun", MF_TOOL },
- { "4479", "Metal Detector", MF_TOOL },
- { "6246A", "Screwdriver", MF_TOOL },
- { "6246B", "Hammer", MF_TOOL },
- { "6246D", "Box Wrench", MF_TOOL },
- { "6246E", "Open End Wrench", MF_TOOL },
- { "3896", "Castle Helmet with Chin-Guard", MF_HAT },
- { "3844", "Castle Helmet with Neck Protect", MF_HAT },
- { "3833", "Construction Helmet", MF_HAT },
- { "82359", "Skeleton Skull", MF_HEAD },
- { "973P14", "'S' Logo", MF_TORSO },
- { "973P16", "Airplane Logo", MF_TORSO },
- { "973P52", "Blacktron I Pattern", MF_TORSO },
- { "973P15", "Horizontal Stripes", MF_TORSO },
- { "973P68", "Mtron Logo", MF_TORSO },
- { "973P17", "Red V-Neck and Buttons", MF_TORSO },
- { "973P63", "Robot Pattern", MF_TORSO },
- { "973P18", "Suit and Tie ", MF_TORSO },
- { "4736", "Jet-Pack with Stud On Front", MF_NECK },
- { "4522", "Mallet", MF_TOOL },
- { "6246C", "Power Drill", MF_TOOL },
- { "4006", "Spanner/Screwdriver", MF_TOOL },
- { "194", "Hose Nozzle", MF_TOOL },
- { "2446", "Helmet", MF_HAT },
- { "3840", "Vest", MF_NECK },
- { "970P63", "Hips with Robot Pattern", MF_HIPS },
- { "972P63", "Left Leg with Robot Pattern", MF_LEGL },
- { "971P63", "Right Leg with Robot Pattern", MF_LEGR },
- { "2524", "Backpack Non-Opening", MF_NECK },
- { "4497", "Spear", MF_TOOL },
- { "37", "Knife", MF_TOOL },
- { "38", "Harpoon", MF_TOOL },
- { "3626BP03", "Pointed Moustache", MF_HEAD },
- { "3626BP04", "Sunglasses", MF_HEAD },
- { "3626BP05", "Grin and Eyebrows", MF_HEAD },
- { "973P19", "Train Chevron", MF_TORSO },
- { "973P31", "Pirate Strips (Red/Cream)", MF_TORSO },
- { "973P32", "Pirate Strips (Blue/Cream)", MF_TORSO },
- { "973P33", "Pirate Strips (Red/Black)", MF_TORSO },
- { "973P41", "Castle Chainmail", MF_TORSO },
- { "973P62", "Silver Ice Planet", MF_TORSO },
- { "6131", "Wizard Hat", MF_HAT },
- { "973P20", "Waiter", MF_TORSO },
- { "973P49", "Forestman Blue Collar", MF_TORSO },
- { "973P48", "Forestman Maroon Collar", MF_TORSO },
- { "973P50", "Forestman Black Collar", MF_TORSO },
- { "3841", "Pickaxe", MF_TOOL },
- { "973P21", "Five Button Fire Fighter", MF_TORSO },
- { "973P22", "Red Shirt and Suit", MF_TORSO },
- { "973P34", "Open Jacket over Striped Vest", MF_TORSO },
- { "973P46", "Forestman and Purse", MF_TORSO },
- { "973P101", "SW Rebel Pilot", MF_TORSO },
- { "4498", "Arrow Quiver", MF_NECK },
- { "4499", "Bow with Arrow", MF_TOOL },
- { "3852", "Hairbrush", MF_TOOL },
- { "30152", "Magnifying Glass", MF_TOOL },
- { "973P23", "'S' Logo Yellow / Blue Pattern", MF_TORSO },
- { "973P42", "Castle Crossed Pikes Pattern", MF_TORSO },
- { "973P65", "Futuron Pattern", MF_TORSO },
- { "973P25", "Red Cross & Stethoscope Pattern", MF_TORSO },
- { "973P24", "Red Cross Pattern", MF_TORSO },
- { "973P64", "Unitron Pattern", MF_TORSO },
- { "4524", "Cape", MF_NECK },
- { "2570", "Crossbow", MF_TOOL },
- { "3834", "Fire Helmet", MF_HAT },
- { "2614", "Fishing Rod", MF_TOOL }
-};
-
-int MFW_PIECES = sizeof(mfwpieceinfo)/sizeof(MFW_PIECEINFO);
-
-// { "770", "Shield Ovoid", MF_TOOL },
-// 2447 Minifig Helmet Visor
diff --git a/common/globals.h b/common/globals.h
index 88d4711..ff1cbda 100644
--- a/common/globals.h
+++ b/common/globals.h
@@ -11,6 +11,3 @@ extern unsigned char FlatColorArray[31][3];
extern unsigned char ColorArray[31][4];
extern const char* colornames[LC_MAXCOLORS];
extern const char* altcolornames[LC_MAXCOLORS];
-
-extern int MFW_PIECES;
-extern MFW_PIECEINFO mfwpieceinfo[];
diff --git a/common/library.cpp b/common/library.cpp
index f46291c..af110c5 100755
--- a/common/library.cpp
+++ b/common/library.cpp
@@ -12,8 +12,239 @@
#include "system.h"
#include "file.h"
#include "library.h"
+#include "pieceinf.h"
-// ========================================================
+// =============================================================================
+// LibraryDialog class
+
+static const char ver_str[32] = "LeoCAD Group Configuration File";
+static const float ver_flt = 0.3f;
+
+LibraryDialog::LibraryDialog ()
+{
+ m_nPieces = 0;
+ m_pPieces = NULL;
+ m_nGroups = 0;
+ m_nCurrentGroup = 0;
+ m_bReload = false;
+ m_bModified = false;
+ strcpy (m_strFile, "");
+}
+
+LibraryDialog::~LibraryDialog ()
+{
+ free (m_pPieces);
+}
+
+bool LibraryDialog::Initialize ()
+{
+ FileDisk idx;
+ char filename[LC_MAXPATH];
+
+ // Read the piece library index.
+ strcpy(filename, project->GetLibraryPath());
+ strcat(filename, "pieces.idx");
+ if (!idx.Open(filename, "rb"))
+ return false;
+ idx.Seek(34, SEEK_SET); // skip update byte
+
+ m_nPieces = project->GetPieceLibraryCount();
+ m_pPieces = (LC_LIBDLG_PIECEINFO*) malloc (sizeof (LC_LIBDLG_PIECEINFO) * m_nPieces);
+ for (int i = 0; i < m_nPieces; i++)
+ {
+ LC_LIBDLG_PIECEINFO* inf = &m_pPieces[i];
+ inf->info = project->GetPieceInfo(i);
+ inf->current_groups = inf->info->m_nGroups;
+
+ idx.Seek (85, SEEK_CUR);
+ idx.ReadLong (&inf->default_groups, 1);
+ idx.Seek (8, SEEK_CUR);
+ }
+ idx.Close();
+
+ // FIX ME: get the current settings
+ strcpy (m_strGroups[0], "Plates");
+ strcpy (m_strGroups[1], "Bricks");
+ strcpy (m_strGroups[2], "Tiles");
+ strcpy (m_strGroups[3], "Slope Bricks");
+ strcpy (m_strGroups[4], "Technic");
+ strcpy (m_strGroups[5], "Space");
+ strcpy (m_strGroups[6], "Train");
+ strcpy (m_strGroups[7], "Other Bricks");
+ strcpy (m_strGroups[8], "Accessories");
+ m_nGroups = 9;
+
+ // UpdateList();
+ UpdateTree();
+
+ return true;
+}
+
+void LibraryDialog::HandleCommand (int id)
+{
+ switch (id)
+ {
+ case LC_LIBDLG_FILE_RESET:
+ {
+ int i;
+
+ for (i = 0; i < m_nPieces; i++)
+ m_pPieces[i].current_groups = m_pPieces[i].default_groups;
+
+ strcpy (m_strFile, "");
+ m_nGroups = 9;
+ /*
+ m_ImageList.DeleteImageList();
+ m_ImageList.Create(IDB_PIECEBAR, 16, 0, 0x00ff00ff);
+
+ CString str;
+ for (i = 0; i < 32; i++)
+ {
+ str.LoadString (ID_PIECE_GROUP01 + i);
+ strcpy (m_strGroups[i], str);
+ m_nBitmaps[i] = min(i,9);
+ }
+ */
+ m_bModified = false;
+ UpdateList();
+ UpdateTree();
+ } break;
+
+ case LC_LIBDLG_FILE_OPEN:
+ {
+ } break;
+
+ case LC_LIBDLG_FILE_SAVE:
+ {
+ } break;
+
+ case LC_LIBDLG_FILE_SAVEAS:
+ {
+ } break;
+
+ case LC_LIBDLG_FILE_PRINTCATALOG:
+ {
+ } break;
+
+ case LC_LIBDLG_FILE_MERGEUPDATE:
+ {
+ char filename[LC_MAXPATH];
+
+ // CFileDialog filedlg(TRUE, ".lup\0", NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+ // "LeoCAD Library Updates (*.lup)|*.lup|All Files (*.*)|*.*||", this);
+ if (!SystemDoDialog (LC_DLG_FILE_OPEN, filename))
+ return;
+
+ LoadUpdate (filename);
+
+// update m_Parts
+ UpdateList();
+ m_bReload = true;
+ } break;
+
+ case LC_LIBDLG_FILE_IMPORTPIECE:
+ {
+ char filename[LC_MAXPATH];
+ LC_LDRAW_PIECE piece;
+
+ // CFileDialog dlg(TRUE, ".dat\0", NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+ // "LDraw Files (*.dat)|*.dat|All Files (*.*)|*.*||",this);
+ if (!SystemDoDialog (LC_DLG_FILE_OPEN, filename))
+ return;
+
+ Sys_BeginWait ();
+
+ if (ReadLDrawPiece(filename, &piece))
+ {
+ if (project->FindPieceInfo(piece.name) != NULL)
+ Sys_MessageBox ("Piece already exists in the library !");
+
+ if (SaveLDrawPiece(&piece))
+ Sys_MessageBox ("Piece successfully imported.");
+ else
+ Sys_MessageBox ("Error saving library.");
+ }
+ else
+ Sys_MessageBox ("Error reading file.");
+
+ Sys_EndWait ();
+ FreeLDrawPiece(&piece);
+ } break;
+
+ case LC_LIBDLG_FILE_RETURN:
+ break;
+ case LC_LIBDLG_FILE_CANCEL:
+ break;
+ case LC_LIBDLG_GROUP_INSERT:
+ break;
+ case LC_LIBDLG_GROUP_DELETE:
+ break;
+ case LC_LIBDLG_GROUP_EDIT:
+ break;
+ case LC_LIBDLG_GROUP_MOVEUP:
+ break;
+ case LC_LIBDLG_GROUP_MOVEDOWN:
+ break;
+ case LC_LIBDLG_PIECE_NEW:
+ break;
+ case LC_LIBDLG_PIECE_EDIT:
+ break;
+ case LC_LIBDLG_PIECE_DELETE:
+ break;
+ }
+}
+
+bool LibraryDialog::DoSave (bool bAskName)
+{
+ if (bAskName || (strlen (m_strFile) == 0))
+ {
+ char filename[LC_MAXPATH];
+
+ // CFileDialog dlg(FALSE, ".lgf\0", NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+ // "LeoCAD Group Files (*.lgf)|*.lgf|All Files (*.*)|*.*||",this);
+ if (!SystemDoDialog (LC_DLG_FILE_SAVE, filename))
+ return false;
+ strcpy (m_strFile, filename);
+ }
+
+ /*
+ Sys_BeginWait ();
+ FileDisk f;
+ int i;
+
+ if (!f.Open (m_strFile, "wb"))
+ return false;
+
+ f.Write (ver_str, sizeof (ver_str));
+ f.Write (ver_flt, sizeof (ver_flt));
+ f.WriteByte (&m_nMaxGroups);
+
+ for (i = 0; i < m_nMaxGroups; i++)
+ {
+ f.Write (m_strGroups[i], sizeof(m_strGroups[i]));
+ ar << m_nBitmaps[i];
+ }
+
+ m_ImageList.Write(&ar);
+
+ ar << (int) m_Parts.GetSize();
+ for (i = 0; i < m_Parts.GetSize(); i++)
+ {
+ ar.Write (m_Parts[i].info->m_strName, sizeof(m_Parts[i].info->m_strName));
+ ar << m_Parts[i].group;
+ }
+ ar.Close();
+ f.Close();
+ m_bModified = FALSE;
+// m_bLoaded = TRUE;
+
+ fclose (f);
+ Sys_EndWait ();
+ */
+ return true;
+}
+
+// =============================================================================
static unsigned long GetDefaultPieceGroup(char* name)
{
diff --git a/common/library.h b/common/library.h
index 77d142e..464627f 100755
--- a/common/library.h
+++ b/common/library.h
@@ -1,5 +1,97 @@
-#ifndef _MISC_H_
-#define _MISC_H_
+#ifndef _LIBRARY_H_
+#define _LIBRARY_H_
+
+typedef enum {
+ LC_LIBDLG_FILE_RESET,
+ LC_LIBDLG_FILE_OPEN,
+ LC_LIBDLG_FILE_SAVE,
+ LC_LIBDLG_FILE_SAVEAS,
+ LC_LIBDLG_FILE_PRINTCATALOG,
+ LC_LIBDLG_FILE_MERGEUPDATE,
+ LC_LIBDLG_FILE_IMPORTPIECE,
+ LC_LIBDLG_FILE_RETURN,
+ LC_LIBDLG_FILE_CANCEL,
+ LC_LIBDLG_GROUP_INSERT,
+ LC_LIBDLG_GROUP_DELETE,
+ LC_LIBDLG_GROUP_EDIT,
+ LC_LIBDLG_GROUP_MOVEUP,
+ LC_LIBDLG_GROUP_MOVEDOWN,
+ LC_LIBDLG_PIECE_NEW,
+ LC_LIBDLG_PIECE_EDIT,
+ LC_LIBDLG_PIECE_DELETE
+} LC_LIBDLG_COMMANDS;
+
+class PieceInfo;
+class LibraryDialog;
+
+typedef struct
+{
+ PieceInfo* info;
+ unsigned long current_groups;
+ unsigned long default_groups;
+} LC_LIBDLG_PIECEINFO;
+
+#define LC_LIBDLG_MAXGROUPS 32
+#define LC_LIBDLG_MAXNAME 32
+
+typedef void (*PFNLIBDLGUPDATELISTFUNC) (LC_LIBDLG_PIECEINFO *piece_info, int count, int group, void *data);
+typedef void (*PFNLIBDLGUPDATETREEFUNC) (int num_groups, char str_groups[][LC_LIBDLG_MAXNAME+1], void *data);
+
+class LibraryDialog
+{
+ public:
+ LibraryDialog ();
+ virtual ~LibraryDialog ();
+
+ void HandleCommand (int id);
+ bool DoSave (bool bAskName);
+ bool Initialize ();
+
+ void SetListFunc (PFNLIBDLGUPDATELISTFUNC func, void *data)
+ {
+ m_pUpdateListFunc = func;
+ m_pUpdateListData = data;
+ }
+
+ void SetTreeFunc (PFNLIBDLGUPDATETREEFUNC func, void *data)
+ {
+ m_pUpdateTreeFunc = func;
+ m_pUpdateTreeData = data;
+ }
+
+ void UpdateList ()
+ {
+ m_pUpdateListFunc (m_pPieces, m_nPieces, m_nCurrentGroup, m_pUpdateListData);
+ }
+
+ void UpdateTree ()
+ {
+ m_pUpdateTreeFunc (m_nGroups, m_strGroups, m_pUpdateTreeData);
+ }
+
+ void SetCurrentGroup (unsigned long group)
+ {
+ m_nCurrentGroup = group;
+ UpdateList ();
+ }
+
+ protected:
+ void *m_pUpdateListData;
+ void *m_pUpdateTreeData;
+ PFNLIBDLGUPDATELISTFUNC m_pUpdateListFunc;
+ PFNLIBDLGUPDATETREEFUNC m_pUpdateTreeFunc;
+
+ int m_nPieces;
+ LC_LIBDLG_PIECEINFO* m_pPieces;
+
+ unsigned char m_nGroups;
+ char m_strGroups[LC_LIBDLG_MAXGROUPS][LC_LIBDLG_MAXNAME+1];
+ int m_nCurrentGroup;
+
+ bool m_bModified;
+ bool m_bReload;
+ char m_strFile[LC_MAXPATH];
+};
typedef struct connection_s
{
@@ -50,4 +142,4 @@ void FreeLDrawPiece(LC_LDRAW_PIECE* piece);
bool DeletePiece(char** names, int numpieces);
bool LoadUpdate(const char* update);
-#endif // _MISC_H_
+#endif // _LIBRARY_H_
diff --git a/common/light.cpp b/common/light.cpp
index 5638b35..b106f33 100644
--- a/common/light.cpp
+++ b/common/light.cpp
@@ -10,8 +10,6 @@
Light::Light()
: Object (LC_OBJECT_LIGHT)
{
- // m_BoundingBox.Initialize(this, LC_LIGHT);
- // m_TargetBoundingBox.Initialize(this, LC_LIGHT_TARGET);
m_pNext = NULL;
m_nState = 0;
}
diff --git a/common/minifig.cpp b/common/minifig.cpp
new file mode 100644
index 0000000..f56148d
--- /dev/null
+++ b/common/minifig.cpp
@@ -0,0 +1,578 @@
+//
+// Minifig Wizard base class, calculates position/rotation of all pieces.
+//
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "minifig.h"
+#include "opengl.h"
+#include "pieceinf.h"
+#include "globals.h"
+#include "project.h"
+#include "matrix.h"
+
+// =============================================================================
+// Static variables
+
+static LC_MFW_PIECEINFO mfw_pieceinfo[] = {
+ { "3624", "Police Hat", LC_MFW_HAT },
+ { "3626BP01", "Smiley Face", LC_MFW_HEAD },
+ { "973", "Plain Torso", LC_MFW_TORSO },
+ { "3838", "Airtanks", LC_MFW_NECK },
+ { "976", "Left Arm", LC_MFW_LEFT_ARM },
+ { "975", "Right Arm", LC_MFW_RIGHT_ARM },
+ { "977", "Hand", LC_MFW_LEFT_HAND },
+ { "977", "Hand", LC_MFW_LEFT_HAND },
+ { "3899", "Cup", LC_MFW_LEFT_TOOL },
+ { "4528", "Frypan", LC_MFW_LEFT_TOOL },
+ { "970", "Hips", LC_MFW_HIPS },
+ { "972", "Left Leg", LC_MFW_LEFT_LEG },
+ { "971", "Right Leg", LC_MFW_RIGHT_LEG },
+ { "2599", "Flipper", LC_MFW_LEFT_SHOE },
+ { "6120", "Ski", LC_MFW_LEFT_SHOE },
+ { "4485", "Baseball Cap", LC_MFW_HAT },
+ { "3626B", "Plain Face", LC_MFW_HEAD },
+ { "3626BP02", "Woman Face", LC_MFW_HEAD },
+ { "973P11", "Dungarees", LC_MFW_TORSO },
+ { "973P47", "Castle Red/Gray Symbol", LC_MFW_TORSO },
+ { "973P51", "Blacktron II", LC_MFW_TORSO },
+ { "973P01", "Vertical Strips Red/Blue", LC_MFW_TORSO },
+ { "973P02", "Vertical Strips Blue/Red", LC_MFW_TORSO },
+ { "973P60", "Shell Logo", LC_MFW_TORSO },
+ { "973P61", "Gold Ice Planet Pattern", LC_MFW_TORSO },
+ { "4349", "Loudhailer", LC_MFW_LEFT_TOOL },
+ { "3962", "Radio", LC_MFW_LEFT_TOOL },
+ { "4529", "Saucepan", LC_MFW_LEFT_TOOL },
+ { "3959", "Space Gun", LC_MFW_LEFT_TOOL },
+ { "4360", "Space Laser Gun", LC_MFW_LEFT_TOOL },
+ { "4479", "Metal Detector", LC_MFW_LEFT_TOOL },
+ { "6246A", "Screwdriver", LC_MFW_LEFT_TOOL },
+ { "6246B", "Hammer", LC_MFW_LEFT_TOOL },
+ { "6246D", "Box Wrench", LC_MFW_LEFT_TOOL },
+ { "6246E", "Open End Wrench", LC_MFW_LEFT_TOOL },
+ { "3896", "Castle Helmet with Chin-Guard", LC_MFW_HAT },
+ { "3844", "Castle Helmet with Neck Protect", LC_MFW_HAT },
+ { "3833", "Construction Helmet", LC_MFW_HAT },
+ { "82359", "Skeleton Skull", LC_MFW_HEAD },
+ { "973P14", "'S' Logo", LC_MFW_TORSO },
+ { "973P16", "Airplane Logo", LC_MFW_TORSO },
+ { "973P52", "Blacktron I Pattern", LC_MFW_TORSO },
+ { "973P15", "Horizontal Stripes", LC_MFW_TORSO },
+ { "973P68", "Mtron Logo", LC_MFW_TORSO },
+ { "973P17", "Red V-Neck and Buttons", LC_MFW_TORSO },
+ { "973P63", "Robot Pattern", LC_MFW_TORSO },
+ { "973P18", "Suit and Tie ", LC_MFW_TORSO },
+ { "4736", "Jet-Pack with Stud On Front", LC_MFW_NECK },
+ { "4522", "Mallet", LC_MFW_LEFT_TOOL },
+ { "6246C", "Power Drill", LC_MFW_LEFT_TOOL },
+ { "4006", "Spanner/Screwdriver", LC_MFW_LEFT_TOOL },
+ { "194", "Hose Nozzle", LC_MFW_LEFT_TOOL },
+ { "2446", "Helmet", LC_MFW_HAT },
+ { "3840", "Vest", LC_MFW_NECK },
+ { "970P63", "Hips with Robot Pattern", LC_MFW_HIPS },
+ { "972P63", "Left Leg with Robot Pattern", LC_MFW_LEFT_LEG },
+ { "971P63", "Right Leg with Robot Pattern", LC_MFW_RIGHT_LEG },
+ { "2524", "Backpack Non-Opening", LC_MFW_NECK },
+ { "4497", "Spear", LC_MFW_LEFT_TOOL },
+ { "37", "Knife", LC_MFW_LEFT_TOOL },
+ { "38", "Harpoon", LC_MFW_LEFT_TOOL },
+ { "3626BP03", "Pointed Moustache", LC_MFW_HEAD },
+ { "3626BP04", "Sunglasses", LC_MFW_HEAD },
+ { "3626BP05", "Grin and Eyebrows", LC_MFW_HEAD },
+ { "973P19", "Train Chevron", LC_MFW_TORSO },
+ { "973P31", "Pirate Strips (Red/Cream)", LC_MFW_TORSO },
+ { "973P32", "Pirate Strips (Blue/Cream)", LC_MFW_TORSO },
+ { "973P33", "Pirate Strips (Red/Black)", LC_MFW_TORSO },
+ { "973P41", "Castle Chainmail", LC_MFW_TORSO },
+ { "973P62", "Silver Ice Planet", LC_MFW_TORSO },
+ { "6131", "Wizard Hat", LC_MFW_HAT },
+ { "973P20", "Waiter", LC_MFW_TORSO },
+ { "973P49", "Forestman Blue Collar", LC_MFW_TORSO },
+ { "973P48", "Forestman Maroon Collar", LC_MFW_TORSO },
+ { "973P50", "Forestman Black Collar", LC_MFW_TORSO },
+ { "3841", "Pickaxe", LC_MFW_LEFT_TOOL },
+ { "973P21", "Five Button Fire Fighter", LC_MFW_TORSO },
+ { "973P22", "Red Shirt and Suit", LC_MFW_TORSO },
+ { "973P34", "Open Jacket over Striped Vest", LC_MFW_TORSO },
+ { "973P46", "Forestman and Purse", LC_MFW_TORSO },
+ { "973P101", "SW Rebel Pilot", LC_MFW_TORSO },
+ { "4498", "Arrow Quiver", LC_MFW_NECK },
+ { "4499", "Bow with Arrow", LC_MFW_LEFT_TOOL },
+ { "3852", "Hairbrush", LC_MFW_LEFT_TOOL },
+ { "30152", "Magnifying Glass", LC_MFW_LEFT_TOOL },
+ { "973P23", "'S' Logo Yellow / Blue Pattern", LC_MFW_TORSO },
+ { "973P42", "Castle Crossed Pikes Pattern", LC_MFW_TORSO },
+ { "973P65", "Futuron Pattern", LC_MFW_TORSO },
+ { "973P25", "Red Cross & Stethoscope Pattern", LC_MFW_TORSO },
+ { "973P24", "Red Cross Pattern", LC_MFW_TORSO },
+ { "973P64", "Unitron Pattern", LC_MFW_TORSO },
+ { "4524", "Cape", LC_MFW_NECK },
+ { "2570", "Crossbow", LC_MFW_LEFT_TOOL },
+ { "3834", "Fire Helmet", LC_MFW_HAT },
+ { "2614", "Fishing Rod", LC_MFW_LEFT_TOOL }
+// { "770", "Shield Ovoid", LC_MFW_LEFT_TOOL },
+// 2447 Minifig Helmet Visor
+};
+
+static int mfw_pieces = sizeof (mfw_pieceinfo)/sizeof (LC_MFW_PIECEINFO);
+
+// =============================================================================
+// MinifigWizard class
+
+MinifigWizard::MinifigWizard ()
+{
+ const unsigned char colors[15] = { 0, 6, 4, 22, 0, 0, 6, 6, 22, 22, 9, 9, 9, 22, 22 };
+ const float pos[15][3] = { {0,0,3.84f}, {0,0,3.84f}, {0,0,2.88f}, {0,0,2.96f}, {0,0,2.56f},
+ {0,0,2.56f}, {0.9f,-0.62f,1.76f}, {-0.9f,-0.62f,1.76f}, {0.92f,-0.62f,1.76f},
+ {-0.92f,-0.62f,1.76f}, {0,0,1.6f}, {0,0,1.12f}, {0,0,1.12f}, {0.42f,0,0},
+ {-0.42f,0,0} };
+ int i;
+
+ for (i = 0; i < 15; i++)
+ {
+ m_Info[i] = NULL;
+ m_Colors[i] = colors[i];
+ m_Pos[i][0] = pos[i][0];
+ m_Pos[i][1] = pos[i][1];
+ m_Pos[i][2] = pos[i][2];
+ m_Rot[i][0] = 0;
+ m_Rot[i][1] = 0;
+ m_Rot[i][2] = 0;
+ }
+
+ for (i = 0; i < 13; i++)
+ {
+ if (i == 3 || i == 7 || i == 8 || i == 9)
+ continue;
+
+ PieceInfo* pInfo = project->FindPieceInfo (mfw_pieceinfo[i].name);
+ if (pInfo == NULL)
+ continue;
+
+ if (i == 6)
+ {
+ m_Info[6] = pInfo;
+ m_Info[7] = pInfo;
+ pInfo->AddRef();
+ pInfo->AddRef();
+ m_Rot[6][0] = 45;
+ m_Rot[6][2] = 90;
+ m_Rot[7][0] = 45;
+ m_Rot[7][2] = 90;
+ }
+ else
+ {
+ m_Info[i] = pInfo;
+ pInfo->AddRef();
+ }
+ }
+}
+
+MinifigWizard::~MinifigWizard ()
+{
+}
+
+void MinifigWizard::Resize (int width, int height)
+{
+ float aspect = (float)width/(float)height;
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(30.0f, aspect, 1.0f, 20.0f);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ gluLookAt (0, -9, 4, 0, 5, 1, 0, 0, 1);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ float *bg = project->GetBackgroundColor();
+ glClearColor(bg[0], bg[1], bg[2], bg[3]);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glDisable (GL_DITHER);
+ glShadeModel (GL_FLAT);
+}
+
+void MinifigWizard::Redraw ()
+{
+ int i;
+
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ Calculate ();
+
+ for (i = 0; i < LC_MFW_NUMITEMS; i++)
+ {
+ if (m_Info[i] == NULL)
+ continue;
+
+ glPushMatrix ();
+ glTranslatef (m_Position[i][0], m_Position[i][1], m_Position[i][2]);
+ glRotatef (m_Rotation[i][3], m_Rotation[i][0], m_Rotation[i][1], m_Rotation[i][2]);
+ m_Info[i]->RenderPiece(m_Colors[i]);
+ glPopMatrix ();
+ }
+
+ glFinish();
+}
+
+void MinifigWizard::Calculate ()
+{
+ Matrix mat, m2, m3;
+
+ // hat
+ m_Position[LC_MFW_HAT][0] = m_Pos[LC_MFW_HAT][0];
+ m_Position[LC_MFW_HAT][1] = m_Pos[LC_MFW_HAT][1];
+ m_Position[LC_MFW_HAT][2] = m_Pos[LC_MFW_HAT][2];
+ m_Rotation[LC_MFW_HAT][0] = 0.0f;
+ m_Rotation[LC_MFW_HAT][1] = 0.0f;
+ m_Rotation[LC_MFW_HAT][2] = -1.0f;
+ m_Rotation[LC_MFW_HAT][3] = m_Angles[LC_MFW_HAT] + m_Angles[LC_MFW_HEAD];
+
+ // head
+ m_Position[LC_MFW_HEAD][0] = m_Pos[LC_MFW_HEAD][0];
+ m_Position[LC_MFW_HEAD][1] = m_Pos[LC_MFW_HEAD][1];
+ m_Position[LC_MFW_HEAD][2] = m_Pos[LC_MFW_HEAD][2];
+ m_Rotation[LC_MFW_HEAD][0] = 0.0f;
+ m_Rotation[LC_MFW_HEAD][1] = 0.0f;
+ m_Rotation[LC_MFW_HEAD][2] = -1.0f;
+ m_Rotation[LC_MFW_HEAD][3] = m_Angles[LC_MFW_HEAD];
+
+ // neck
+ mat.LoadIdentity ();
+ mat.CreateOld (0,0,0,m_Rot[LC_MFW_NECK][0], m_Rot[LC_MFW_NECK][1], m_Rot[LC_MFW_NECK][2]);
+ mat.Rotate (m_Angles[LC_MFW_NECK], 0, 0, -1);
+ mat.SetTranslation (m_Pos[LC_MFW_NECK][0], m_Pos[LC_MFW_NECK][1],
+ m_Pos[LC_MFW_NECK][2]);
+ mat.ToAxisAngle (m_Rotation[LC_MFW_NECK]);
+ mat.GetTranslation (m_Position[LC_MFW_NECK]);
+
+ // torso
+ m_Position[LC_MFW_TORSO][0] = m_Pos[LC_MFW_TORSO][0];
+ m_Position[LC_MFW_TORSO][1] = m_Pos[LC_MFW_TORSO][1];
+ m_Position[LC_MFW_TORSO][2] = m_Pos[LC_MFW_TORSO][2];
+ m_Rotation[LC_MFW_TORSO][0] = 0.0f;
+ m_Rotation[LC_MFW_TORSO][1] = 0.0f;
+ m_Rotation[LC_MFW_TORSO][2] = 1.0f;
+ m_Rotation[LC_MFW_TORSO][3] = 0.0f;
+
+ // left arm/hand/tool
+ mat.LoadIdentity ();
+ mat.Rotate (m_Angles[LC_MFW_LEFT_ARM], -1, 0, 0);
+ mat.SetTranslation (m_Pos[LC_MFW_LEFT_ARM][0], m_Pos[LC_MFW_LEFT_ARM][1],
+ m_Pos[LC_MFW_LEFT_ARM][2]);
+ mat.ToAxisAngle (m_Rotation[LC_MFW_LEFT_ARM]);
+ mat.GetTranslation (m_Position[LC_MFW_LEFT_ARM]);
+
+ mat.Translate (m_Pos[LC_MFW_LEFT_HAND][0]-m_Pos[LC_MFW_LEFT_ARM][0],
+ m_Pos[LC_MFW_LEFT_HAND][1]-m_Pos[LC_MFW_LEFT_ARM][1],
+ m_Pos[LC_MFW_LEFT_HAND][2]-m_Pos[LC_MFW_LEFT_ARM][2]);
+ m2.CreateOld (0,0,0,m_Rot[LC_MFW_LEFT_HAND][0],m_Rot[LC_MFW_LEFT_HAND][1],m_Rot[LC_MFW_LEFT_HAND][2]);
+ m3.Multiply (mat, m2);
+ m3.Translate (0,0,-0.16f);
+ mat.LoadIdentity ();
+ mat.Translate (0,0,0.16f);
+ mat.Rotate (m_Angles[LC_MFW_LEFT_HAND], 1, 0, 0);
+ m2.Multiply (m3, mat);
+ m2.ToAxisAngle (m_Rotation[LC_MFW_LEFT_HAND]);
+ m2.GetTranslation (m_Position[LC_MFW_LEFT_HAND]);
+
+ m2.Translate (m_Pos[LC_MFW_LEFT_TOOL][0]-m_Pos[LC_MFW_LEFT_ARM][0],
+ m_Pos[LC_MFW_LEFT_TOOL][1]-m_Pos[LC_MFW_LEFT_ARM][1],
+ m_Pos[LC_MFW_LEFT_TOOL][2]-m_Pos[LC_MFW_LEFT_ARM][2]);
+ m3.CreateOld (0,0,0,m_Rot[LC_MFW_LEFT_TOOL][0]-m_Rot[LC_MFW_LEFT_HAND][0],
+ m_Rot[LC_MFW_LEFT_TOOL][1]-m_Rot[LC_MFW_LEFT_HAND][1],
+ m_Rot[LC_MFW_LEFT_TOOL][2]-m_Rot[LC_MFW_LEFT_HAND][2]);
+ mat.Multiply (m2, m3);
+ m2.LoadIdentity ();
+ m2.Rotate (m_Angles[LC_MFW_LEFT_TOOL], 0, 0, 1);
+ m3.Multiply (mat, m2);
+ m3.ToAxisAngle (m_Rotation[LC_MFW_LEFT_TOOL]);
+ m3.GetTranslation (m_Position[LC_MFW_LEFT_TOOL]);
+
+ // right arm/hand/tool
+ mat.LoadIdentity ();
+ mat.Rotate (m_Angles[LC_MFW_RIGHT_ARM], -1, 0, 0);
+ mat.SetTranslation (m_Pos[LC_MFW_RIGHT_ARM][0], m_Pos[LC_MFW_RIGHT_ARM][1],
+ m_Pos[LC_MFW_RIGHT_ARM][2]);
+ mat.ToAxisAngle (m_Rotation[LC_MFW_RIGHT_ARM]);
+ mat.GetTranslation (m_Position[LC_MFW_RIGHT_ARM]);
+
+ mat.Translate (m_Pos[LC_MFW_RIGHT_HAND][0]-m_Pos[LC_MFW_RIGHT_ARM][0],
+ m_Pos[LC_MFW_RIGHT_HAND][1]-m_Pos[LC_MFW_RIGHT_ARM][1],
+ m_Pos[LC_MFW_RIGHT_HAND][2]-m_Pos[LC_MFW_RIGHT_ARM][2]);
+ m2.CreateOld (0,0,0,m_Rot[LC_MFW_RIGHT_HAND][0],m_Rot[LC_MFW_RIGHT_HAND][1],m_Rot[LC_MFW_RIGHT_HAND][2]);
+ m3.Multiply (mat, m2);
+ m3.Translate (0,0,-0.16f);
+ mat.LoadIdentity ();
+ mat.Translate (0,0,0.16f);
+ mat.Rotate (m_Angles[LC_MFW_RIGHT_HAND], 1, 0, 0);
+ m2.Multiply (m3, mat);
+ m2.ToAxisAngle (m_Rotation[LC_MFW_RIGHT_HAND]);
+ m2.GetTranslation (m_Position[LC_MFW_RIGHT_HAND]);
+
+ // hips
+ m_Position[LC_MFW_HIPS][0] = m_Pos[LC_MFW_HIPS][0];
+ m_Position[LC_MFW_HIPS][1] = m_Pos[LC_MFW_HIPS][1];
+ m_Position[LC_MFW_HIPS][2] = m_Pos[LC_MFW_HIPS][2];
+ m_Rotation[LC_MFW_HIPS][0] = 0.0f;
+ m_Rotation[LC_MFW_HIPS][1] = 0.0f;
+ m_Rotation[LC_MFW_HIPS][2] = 1.0f;
+ m_Rotation[LC_MFW_HIPS][3] = 0.0f;
+
+ // left leg/shoe
+ mat.LoadIdentity ();
+ mat.Rotate (m_Angles[LC_MFW_LEFT_LEG], -1, 0, 0);
+ mat.SetTranslation (m_Pos[LC_MFW_LEFT_LEG][0], m_Pos[LC_MFW_LEFT_LEG][1],
+ m_Pos[LC_MFW_LEFT_LEG][2]);
+ mat.ToAxisAngle (m_Rotation[LC_MFW_LEFT_LEG]);
+ mat.GetTranslation (m_Position[LC_MFW_LEFT_LEG]);
+ mat.Translate (m_Pos[LC_MFW_LEFT_SHOE][0]-m_Pos[LC_MFW_LEFT_LEG][0],
+ m_Pos[LC_MFW_LEFT_SHOE][1]-m_Pos[LC_MFW_LEFT_LEG][1],
+ m_Pos[LC_MFW_LEFT_SHOE][2]-m_Pos[LC_MFW_LEFT_LEG][2]);
+ m2.CreateOld (0,0,0,m_Rot[LC_MFW_LEFT_SHOE][0],m_Rot[LC_MFW_LEFT_SHOE][1],m_Rot[LC_MFW_LEFT_SHOE][2]);
+ m3.Multiply (mat, m2);
+ mat.LoadIdentity ();
+ mat.Rotate (m_Angles[LC_MFW_LEFT_SHOE], 0, 0, 1);
+ m2.Multiply (m3, mat);
+ m2.ToAxisAngle (m_Rotation[LC_MFW_LEFT_SHOE]);
+ m2.GetTranslation (m_Position[LC_MFW_LEFT_SHOE]);
+
+ // right leg/shoe
+ mat.LoadIdentity ();
+ mat.Rotate (m_Angles[LC_MFW_RIGHT_LEG], -1, 0, 0);
+ mat.SetTranslation (m_Pos[LC_MFW_RIGHT_LEG][0], m_Pos[LC_MFW_RIGHT_LEG][1],
+ m_Pos[LC_MFW_RIGHT_LEG][2]);
+ mat.ToAxisAngle (m_Rotation[LC_MFW_RIGHT_LEG]);
+ mat.GetTranslation (m_Position[LC_MFW_RIGHT_LEG]);
+ mat.Translate (m_Pos[LC_MFW_RIGHT_SHOE][0]-m_Pos[LC_MFW_RIGHT_LEG][0],
+ m_Pos[LC_MFW_RIGHT_SHOE][1]-m_Pos[LC_MFW_RIGHT_LEG][1],
+ m_Pos[LC_MFW_RIGHT_SHOE][2]-m_Pos[LC_MFW_RIGHT_LEG][2]);
+ m2.CreateOld (0,0,0,m_Rot[LC_MFW_RIGHT_SHOE][0],m_Rot[LC_MFW_RIGHT_SHOE][1],m_Rot[LC_MFW_RIGHT_SHOE][2]);
+ m3.Multiply (mat, m2);
+ mat.LoadIdentity ();
+ mat.Rotate (m_Angles[LC_MFW_RIGHT_SHOE], 0, 0, 1);
+ m2.Multiply (m3, mat);
+ m2.ToAxisAngle (m_Rotation[LC_MFW_RIGHT_SHOE]);
+ m2.GetTranslation (m_Position[LC_MFW_RIGHT_SHOE]);
+}
+
+void MinifigWizard::GetDescriptions (int type, char ***names, int *count)
+{
+ char **list = (char**)malloc (sizeof (char*)*mfw_pieces);
+ *names = list;
+ *count = 0;
+ int i, j;
+
+ for (i = 0; i < mfw_pieces; i++)
+ {
+ PieceInfo* piece_info;
+
+ piece_info = project->FindPieceInfo (mfw_pieceinfo[i].name);
+ if (piece_info == NULL)
+ continue;
+
+ switch (type)
+ {
+ case LC_MFW_HAT:
+ case LC_MFW_HEAD:
+ case LC_MFW_TORSO:
+ case LC_MFW_NECK:
+ case LC_MFW_LEFT_ARM:
+ case LC_MFW_RIGHT_ARM:
+ case LC_MFW_HIPS:
+ case LC_MFW_LEFT_LEG:
+ case LC_MFW_RIGHT_LEG:
+ case LC_MFW_LEFT_HAND:
+ case LC_MFW_LEFT_TOOL:
+ case LC_MFW_LEFT_SHOE:
+ if (mfw_pieceinfo[i].type != type)
+ continue;
+ break;
+
+ case LC_MFW_RIGHT_HAND:
+ if (mfw_pieceinfo[i].type != LC_MFW_LEFT_HAND)
+ continue;
+ break;
+
+ case LC_MFW_RIGHT_TOOL:
+ if (mfw_pieceinfo[i].type != LC_MFW_LEFT_TOOL)
+ continue;
+ break;
+
+ case LC_MFW_RIGHT_SHOE:
+ if (mfw_pieceinfo[i].type != LC_MFW_LEFT_SHOE)
+ continue;
+ break;
+
+ default:
+ continue;
+ }
+
+ list[(*count)++] = mfw_pieceinfo[i].description;
+
+ if (i == 6) i++; // two hands are listed
+ }
+
+ // ugly sort
+ for (i = 0; i < (*count) - 1; i++)
+ for (j = 0; j < (*count) - 1; j++)
+ {
+ if (strcmp (list[j], list[j+1]) > 0)
+ {
+ char *tmp = list[j];
+ list[j] = list[j+1];
+ list[j+1] = tmp;
+ }
+ }
+
+ if ((type == LC_MFW_HAT) || (type == LC_MFW_NECK) ||
+ (type == LC_MFW_LEFT_TOOL) || (type == LC_MFW_RIGHT_TOOL) ||
+ (type == LC_MFW_LEFT_SHOE) || (type == LC_MFW_RIGHT_SHOE))
+ {
+ memmove (list+1, list, *count*sizeof (char*));
+ list[0] = "None";
+ (*count)++;
+ }
+}
+
+void MinifigWizard::ChangePiece (int type, const char *desc)
+{
+ PieceInfo* piece_info = NULL;
+ int j;
+
+ for (j = 0; j < mfw_pieces; j++)
+ {
+ if (strcmp (desc, mfw_pieceinfo[j].description) == 0)
+ {
+ piece_info = project->FindPieceInfo (mfw_pieceinfo[j].name);
+ if (piece_info == NULL)
+ continue;
+
+ if (m_Info[type])
+ m_Info[type]->DeRef();
+ m_Info[type] = piece_info;
+ piece_info->AddRef();
+ break;
+ }
+ }
+
+ // Piece not found ("None")
+ if (j == mfw_pieces)
+ {
+ if (m_Info[type])
+ m_Info[type]->DeRef();
+ m_Info[type] = NULL;
+ }
+
+ // Get the pieces in the right place
+ if (type == LC_MFW_NECK)
+ {
+ if (m_Info[3] != NULL)
+ {
+ m_Pos[0][2] = 3.92f;
+ m_Pos[1][2] = 3.92f;
+
+ if (strcmp (piece_info->m_strName,"4498") == 0)
+ m_Rot[3][2] = 180.0f;
+ else
+ m_Rot[3][2] = 0.0f;
+ }
+ else
+ {
+ m_Pos[0][2] = 3.84f;
+ m_Pos[1][2] = 3.84f;
+ }
+ }
+
+ if (type == LC_MFW_LEFT_SHOE)
+ {
+ if (strcmp (desc, "Ski"))
+ m_Pos[13][1] = 0;
+ else
+ m_Pos[13][1] = -0.12f;
+ }
+
+ if (type == LC_MFW_RIGHT_SHOE)
+ {
+ if (strcmp (desc, "Ski"))
+ m_Pos[14][1] = 0;
+ else
+ m_Pos[14][1] = -0.12f;
+ }
+
+ if ((type == LC_MFW_LEFT_TOOL) || (type == LC_MFW_RIGHT_TOOL))
+ if (piece_info != NULL)
+ {
+ float rx = 45, ry = 0, rz = 0, x = 0.92f, y = -0.62f, z = 1.76f;
+
+ if (strcmp (piece_info->m_strName,"4529") == 0)
+ { rx = -45; y = -1.14f; z = 2.36f; }
+ if (strcmp (piece_info->m_strName,"3899") == 0)
+ { y = -1.64f; z = 1.38f; }
+ if (strcmp (piece_info->m_strName,"4528") == 0)
+ { rx = -45; y = -1.26f; z = 2.36f; }
+ if (strcmp (piece_info->m_strName,"4479") == 0)
+ { rz = 90; y = -1.22f; z = 2.44f; }
+ if (strcmp (piece_info->m_strName,"3962") == 0)
+ { rz = 90; y = -0.7f; z = 1.62f; }
+ if (strcmp (piece_info->m_strName,"4360") == 0)
+ { rz = -90; y = -1.22f; z = 2.44f; }
+ if (strncmp (piece_info->m_strName,"6246",4) == 0)
+ { y = -1.82f; z = 2.72f; rz = 90; }
+ if (strcmp (piece_info->m_strName,"4349") == 0)
+ { y = -1.16f; z = 2.0f; }
+ if (strcmp (piece_info->m_strName,"4479") == 0)
+ { y = -1.42f; z = 2.26f; }
+ if (strcmp (piece_info->m_strName,"3959") == 0)
+ { y = -1.0f; z = 1.88f; }
+ if (strcmp (piece_info->m_strName,"4522") == 0)
+ { y = -1.64f; z = 2.48f; }
+ if (strcmp (piece_info->m_strName,"194") == 0)
+ { rz = 180; y = -1.04f; z = 1.94f; }
+ if (strcmp (piece_info->m_strName,"4006") == 0)
+ { rz = 180; y = -1.24f; z = 2.18f; }
+ if (strcmp (piece_info->m_strName,"6246C") == 0)
+ { rx = 45; rz = 0; y = -0.86f; z = 1.78f; }
+ if (strcmp (piece_info->m_strName,"4497") == 0)
+ { y = -2.16f; z = 3.08f; rz = 90; }
+ if (strcmp (piece_info->m_strName,"30092") == 0)
+ { x = 0; rz = 180; }
+ if (strcmp (piece_info->m_strName,"37") == 0)
+ { z = 1.52f; y = -0.64f; }
+ if (strcmp (piece_info->m_strName,"38") == 0)
+ { z = 1.24f; y = -0.34f; }
+ if (strcmp (piece_info->m_strName,"3841") == 0)
+ { z = 2.24f; y = -1.34f; rz = 180; }
+ if (strcmp (piece_info->m_strName,"4499") == 0)
+ { rz = ((type == LC_MFW_RIGHT_TOOL) ? 10 : -10); z = 1.52f; }
+ if (strcmp (piece_info->m_strName,"3852") == 0)
+ { rz = -90; x = 0.90f; y = -0.8f; z = 1.84f; }
+ if (strcmp (piece_info->m_strName,"30152") == 0)
+ { z = 3.06f; y = -2.16f; }
+ if (strcmp (piece_info->m_strName,"2570") == 0)
+ { z = 1.68f; y = -0.8f; }
+ if (strcmp (piece_info->m_strName,"2614") == 0)
+ { z = 1.74f; y = -0.86f; }
+
+ if (type == LC_MFW_RIGHT_TOOL)
+ x = -x;
+
+ m_Pos[type][0] = x;
+ m_Pos[type][1] = y;
+ m_Pos[type][2] = z;
+ m_Rot[type][0] = rx;
+ m_Rot[type][1] = ry;
+ m_Rot[type][2] = rz;
+ }
+}
+
+void MinifigWizard::ChangeColor (int type, int color)
+{
+ m_Colors[type] = color;
+}
+
+void MinifigWizard::ChangeAngle (int type, float angle)
+{
+ m_Angles[type] = angle;
+}
diff --git a/common/minifig.h b/common/minifig.h
new file mode 100644
index 0000000..409d81b
--- /dev/null
+++ b/common/minifig.h
@@ -0,0 +1,60 @@
+#ifndef _MINIFIG_H_
+#define _MINIFIG_H_
+
+class PieceInfo;
+
+typedef enum
+{
+ LC_MFW_HAT,
+ LC_MFW_HEAD,
+ LC_MFW_TORSO,
+ LC_MFW_NECK,
+ LC_MFW_LEFT_ARM,
+ LC_MFW_RIGHT_ARM,
+ LC_MFW_LEFT_HAND,
+ LC_MFW_RIGHT_HAND,
+ LC_MFW_LEFT_TOOL,
+ LC_MFW_RIGHT_TOOL,
+ LC_MFW_HIPS,
+ LC_MFW_LEFT_LEG,
+ LC_MFW_RIGHT_LEG,
+ LC_MFW_LEFT_SHOE,
+ LC_MFW_RIGHT_SHOE,
+ LC_MFW_NUMITEMS
+} LC_MFW_TYPES;
+
+typedef struct
+{
+ char name[9];
+ char description[32];
+ int type;
+} LC_MFW_PIECEINFO;
+
+class MinifigWizard
+{
+ public:
+ MinifigWizard ();
+ ~MinifigWizard ();
+
+ void Redraw ();
+ void Resize (int width, int height);
+ void Calculate ();
+ void GetDescriptions (int type, char ***names, int *count);
+ void ChangePiece (int type, const char *description);
+ void ChangeColor (int type, int color);
+ void ChangeAngle (int type, float angle);
+
+ public:
+ PieceInfo* m_Info[LC_MFW_NUMITEMS];
+ int m_Colors[LC_MFW_NUMITEMS];
+ float m_Position[LC_MFW_NUMITEMS][3];
+ float m_Rotation[LC_MFW_NUMITEMS][4];
+
+ protected:
+ // internal variables used to calculate the real position/rotation
+ float m_Pos[LC_MFW_NUMITEMS][3];
+ float m_Rot[LC_MFW_NUMITEMS][3];
+ float m_Angles[LC_MFW_NUMITEMS];
+};
+
+#endif // _MINIFIG_H_
diff --git a/common/module.mk b/common/module.mk
index add1743..a22bcbe 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -1,4 +1,4 @@
-SRC += common/camera.cpp common/file.cpp common/globals.cpp common/group.cpp common/image.cpp common/im_bmp.cpp common/im_png.cpp common/library.cpp common/light.cpp common/matrix.cpp common/piece.cpp common/pieceinf.cpp common/project.cpp common/quant.cpp common/terrain.cpp common/texture.cpp common/tr.cpp common/vector.cpp common/opengl.cpp common/object.cpp
+SRC += common/camera.cpp common/file.cpp common/globals.cpp common/group.cpp common/image.cpp common/im_bmp.cpp common/im_png.cpp common/library.cpp common/light.cpp common/matrix.cpp common/piece.cpp common/pieceinf.cpp common/project.cpp common/quant.cpp common/terrain.cpp common/texture.cpp common/tr.cpp common/vector.cpp common/opengl.cpp common/object.cpp common/minifig.cpp
LIBS += -ljpeg -lpng -lz -lm
diff --git a/common/piece.cpp b/common/piece.cpp
index 1f14020..133ccec 100644
--- a/common/piece.cpp
+++ b/common/piece.cpp
@@ -16,26 +16,26 @@
/////////////////////////////////////////////////////////////////////////////
// Static functions
-static PIECE_KEY* AddNode (PIECE_KEY *node, unsigned short nTime, unsigned char nType)
+static LC_PIECE_KEY* AddNode (LC_PIECE_KEY *node, unsigned short nTime, unsigned char nType)
{
- PIECE_KEY* newnode = (PIECE_KEY*)malloc(sizeof(PIECE_KEY));
+ LC_PIECE_KEY* newnode = (LC_PIECE_KEY*)malloc(sizeof(LC_PIECE_KEY));
- if (node)
- {
- newnode->next = node->next;
- node->next = newnode;
- }
- else
- newnode->next = NULL;
+ if (node)
+ {
+ newnode->next = node->next;
+ node->next = newnode;
+ }
+ else
+ newnode->next = NULL;
- newnode->type = nType;
- newnode->time = nTime;
- newnode->param[0] = newnode->param[1] = newnode->param[2] = newnode->param[3] = 0;
+ newnode->type = nType;
+ newnode->time = nTime;
+ newnode->param[0] = newnode->param[1] = newnode->param[2] = newnode->param[3] = 0;
- if (nType == PK_ROTATION)
- newnode->param[2] = 1;
+ if (nType == PK_ROTATION)
+ newnode->param[2] = 1;
- return newnode;
+ return newnode;
}
inline static void SetCurrentColor(unsigned char nColor, bool* bTrans, bool bLighting, bool bNoAlpha)
@@ -94,50 +94,18 @@ inline static void SetCurrentColor(unsigned char nColor, bool* bTrans, bool bLig
/////////////////////////////////////////////////////////////////////////////
// Piece construction/destruction
-#if ! (defined (GL_EXT_compiled_vertex_array))
-
-#ifdef LC_LINUX
-#include <GL/glx.h>
-#define wglGetProcAddress(func) glXGetProcAddressARB((const GLubyte *) func)
-#endif
-
-#ifdef LC_WINDOWS
-typedef void (APIENTRY * GLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
-typedef void (APIENTRY * GLUNLOCKARRAYSEXTPROC) ();
-#else
-// TODO: get the entry point under different OS's
-#define glLockArraysEXT(a,b) {}
-#define glUnlockArraysEXT() {}
-#endif
-
-static GLLOCKARRAYSEXTPROC glLockArraysEXT;
-static GLUNLOCKARRAYSEXTPROC glUnlockArraysEXT;
-
static bool lockarrays = false;
-#else
-static bool lockarrays = true;
-#endif
Piece::Piece(PieceInfo* pPieceInfo)
: Object (LC_OBJECT_PIECE)
{
-#if ! (defined (GL_EXT_compiled_vertex_array))
+ static bool first_time = true;
- static bool first_time = true;
-
- if (first_time)
- {
- first_time = false;
- char* extensions = (char*)glGetString(GL_EXTENSIONS);
-
- if (strstr(extensions, "GL_EXT_compiled_vertex_array "))
- {
- glLockArraysEXT = (GLLOCKARRAYSEXTPROC)wglGetProcAddress("glLockArraysEXT");
- glUnlockArraysEXT = (GLUNLOCKARRAYSEXTPROC)wglGetProcAddress("glUnlockArraysEXT");
- lockarrays = true;
- }
- }
-#endif
+ if (first_time)
+ {
+ first_time = false;
+ lockarrays = GL_HasCompiledVertexArrays ();
+ }
m_pNext = NULL;
m_pPieceInfo = pPieceInfo;
@@ -205,7 +173,7 @@ void Piece::SetPieceInfo(PieceInfo* pPieceInfo)
void Piece::FileLoad(File* file, char* name)
{
- PIECE_KEY *node;
+ LC_PIECE_KEY *node;
unsigned char version, ch;
file->ReadByte(&version, 1);
@@ -370,7 +338,7 @@ void Piece::FileLoad(File* file, char* name)
void Piece::FileSave(File* file, Group* pGroups)
{
- PIECE_KEY *node;
+ LC_PIECE_KEY *node;
unsigned char ch = 8; // LeoCAD 0.70
unsigned long n;
@@ -614,7 +582,7 @@ void Piece::Move(unsigned short nTime, bool bAnimation, bool bAddKey, float x, f
void Piece::ChangeKey(unsigned short nTime, bool bAnimation, bool bAddKey, float* param, unsigned char nKeyType)
{
- PIECE_KEY *node, *poskey = NULL, *newpos = NULL;
+ LC_PIECE_KEY *node, *poskey = NULL, *newpos = NULL;
if (bAnimation)
node = m_pAnimationKeys;
else
@@ -653,7 +621,7 @@ void Piece::ChangeKey(unsigned short nTime, bool bAnimation, bool bAddKey, float
void Piece::RemoveKeys()
{
- PIECE_KEY *node, *prev;
+ LC_PIECE_KEY *node, *prev;
for (node = m_pInstructionKeys; node;)
{
@@ -718,7 +686,7 @@ void Piece::CompareBoundingBox(float box[6])
bool Piece::CalculatePositionRotation(unsigned short nTime, bool bAnimation, float pos[3], float rot[4])
{
- PIECE_KEY *node, *prevpos = NULL, *nextpos = NULL, *prevrot = NULL, *nextrot = NULL;
+ LC_PIECE_KEY *node, *prevpos = NULL, *nextpos = NULL, *prevrot = NULL, *nextrot = NULL;
if (bAnimation)
node = m_pAnimationKeys;
else
diff --git a/common/piece.h b/common/piece.h
index 849ec23..cafa5ec 100644
--- a/common/piece.h
+++ b/common/piece.h
@@ -21,12 +21,12 @@ class PieceInfo;
typedef enum { PK_POSITION, PK_ROTATION } PK_TYPES;
-typedef struct PIECE_KEY {
+typedef struct LC_PIECE_KEY {
unsigned short time;
float param[4];
unsigned char type;
- PIECE_KEY* next;
-} PIECE_KEY;
+ LC_PIECE_KEY* next;
+} LC_PIECE_KEY;
class Piece : public Object
{
@@ -159,8 +159,8 @@ protected:
void BuildDrawInfo();
// Position
- PIECE_KEY* m_pAnimationKeys;
- PIECE_KEY* m_pInstructionKeys;
+ LC_PIECE_KEY* m_pAnimationKeys;
+ LC_PIECE_KEY* m_pInstructionKeys;
// Atributes
PieceInfo* m_pPieceInfo;
diff --git a/common/project.cpp b/common/project.cpp
index c76af9e..2b070ab 100644
--- a/common/project.cpp
+++ b/common/project.cpp
@@ -20,36 +20,51 @@
#include "image.h"
#include "system.h"
#include "globals.h"
+#include "minifig.h"
typedef struct
{
- unsigned char n;
- float dim [4][4];
-} VIEWPORT;
-
-static VIEWPORT viewports[14] = {
- { 1, {{0, 0, 1, 1}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0} }}, // 1
- { 2, {{0, 0, 0.5f, 1}, { 0.5f, 0, 0.5f, 1}, { 0, 0, 0, 0}, { 0, 0, 0, 0} }}, // 2V
- { 2, {{0, 0, 1, 0.5f}, { 0, 0.5f, 1, 0.5f}, { 0, 0, 0, 0}, { 0, 0, 0, 0} }}, // 2H
- { 2, {{0, 0, 1, 0.7f}, { 0, 0.7f, 1, 0.3f}, { 0, 0, 0, 0}, { 0, 0, 0, 0} }}, // 2HT
- { 2, {{0, 0, 1, 0.3f}, { 0, 0.3f, 1, 0.7f}, { 0, 0, 0, 0}, { 0, 0, 0, 0} }}, // 2HB
- { 3, {{0, 0, 0.5f, 0.5f}, { 0, 0.5f, 0.5f, 0.5f}, { 0.5f, 0, 0.5f, 1}, { 0, 0, 0, 0} }}, // 3VL
- { 3, {{0, 0, 0.5f, 1}, { 0.5f, 0, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 0.5f}, { 0, 0, 0, 0} }}, // 3VR
- { 3, {{0, 0, 1, 0.5f}, { 0, 0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 0.5f}, { 0, 0, 0, 0} }}, // 3HB
- { 3, {{0, 0, 0.5f, 0.5f}, { 0.5f, 0, 0.5f, 0.5f}, { 0, 0.5f, 1, 0.5f}, { 0, 0, 0, 0} }}, // 3HT
- { 4, {{0, 0, 0.3f, 0.3f}, { 0, 0.3f, 0.3f, 0.4f}, { 0, 0.7f, 0.3f, 0.3f}, { 0.3f, 0, 0.7f, 1} }}, // 4VL
- { 4, {{0, 0, 0.7f, 1}, { 0.7f, 0, 0.3f, 0.3f}, { 0.7f, 0.3f, 0.3f, 0.4f}, { 0.7f, 0.7f, 0.3f, 0.3f} }}, // 4VR
- { 4, {{0, 0, 1, 0.7f}, { 0, 0.7f, 0.3f, 0.3f}, { 0.3f, 0.7f, 0.4f, 0.3f}, { 0.7f, 0.7f, 0.3f, 0.3f} }}, // 4HT
- { 4, {{0, 0, 0.3f, 0.3f}, { 0.3f, 0, 0.4f, 0.3f}, { 0.7f, 0, 0.3f, 0.3f}, { 0, 0.3f, 1, 0.7f} }}, // 4HB
- { 4, {{0, 0, 0.5f, 0.5f}, { 0.5f, 0, 0.5f, 0.5f}, { 0, 0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 0.5f} }}};// 4
+ unsigned char n;
+ float dim [4][4];
+} LC_VIEWPORT;
+
+static LC_VIEWPORT viewports[14] = {
+ { 1, {{ 0.0f, 0.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 0.0f, 0.0f },
+ { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f } }}, // 1
+ { 2, {{ 0.0f, 0.0f, 0.5f, 1.0f }, { 0.5f, 0.0f, 0.5f, 1.0f },
+ { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f } }}, // 2V
+ { 2, {{ 0.0f, 0.0f, 1.0f, 0.5f }, { 0.0f, 0.5f, 1.0f, 0.5f },
+ { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f } }}, // 2H
+ { 2, {{ 0.0f, 0.0f, 1.0f, 0.7f }, { 0.0f, 0.7f, 1.0f, 0.3f },
+ { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f } }}, // 2HT
+ { 2, {{ 0.0f, 0.0f, 1.0f, 0.3f }, { 0.0f, 0.3f, 1.0f, 0.7f },
+ { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f } }}, // 2HB
+ { 3, {{ 0.0f, 0.0f, 0.5f, 0.5f }, { 0.0f, 0.5f, 0.5f, 0.5f },
+ { 0.5f, 0.0f, 0.5f, 1.0f }, { 0.0f, 0.0f, 0.0f, 0.0f } }}, // 3VL
+ { 3, {{ 0.0f, 0.0f, 0.5f, 1.0f }, { 0.5f, 0.0f, 0.5f, 0.5f },
+ { 0.5f, 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f, 0.0f, 0.0f } }}, // 3VR
+ { 3, {{ 0.0f, 0.0f, 1.0f, 0.5f }, { 0.0f, 0.5f, 0.5f, 0.5f },
+ { 0.5f, 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f, 0.0f, 0.0f } }}, // 3HB
+ { 3, {{ 0.0f, 0.0f, 0.5f, 0.5f }, { 0.5f, 0.0f, 0.5f, 0.5f },
+ { 0.0f, 0.5f, 1.0f, 0.5f }, { 0.0f, 0.0f, 0.0f, 0.0f } }}, // 3HT
+ { 4, {{ 0.0f, 0.0f, 0.3f, 0.3f }, { 0.0f, 0.3f, 0.3f, 0.4f },
+ { 0.0f, 0.7f, 0.3f, 0.3f }, { 0.3f, 0.0f, 0.7f, 1.0f } }}, // 4VL
+ { 4, {{ 0.0f, 0.0f, 0.7f, 1.0f }, { 0.7f, 0.0f, 0.3f, 0.3f },
+ { 0.7f, 0.3f, 0.3f, 0.4f }, { 0.7f, 0.7f, 0.3f, 0.3f } }}, // 4VR
+ { 4, {{ 0.0f, 0.0f, 1.0f, 0.7f }, { 0.0f, 0.7f, 0.3f, 0.3f },
+ { 0.3f, 0.7f, 0.4f, 0.3f }, { 0.7f, 0.7f, 0.3f, 0.3f } }}, // 4HT
+ { 4, {{ 0.0f, 0.0f, 0.3f, 0.3f }, { 0.3f, 0.0f, 0.4f, 0.3f },
+ { 0.7f, 0.0f, 0.3f, 0.3f }, { 0.0f, 0.3f, 1.0f, 0.7f } }}, // 4HB
+ { 4, {{ 0.0f, 0.0f, 0.5f, 0.5f }, { 0.5f, 0.0f, 0.5f, 0.5f },
+ { 0.0f, 0.5f, 0.5f, 0.5f }, { 0.5f, 0.5f, 0.5f, 0.5f } }}};// 4
typedef struct
{
- unsigned char width;
- float left, right, top, bottom;
-} TXFVERT;
+ unsigned char width;
+ float left, right, top, bottom;
+} LC_TXFVERT;
-static TXFVERT glyphs[93];
+static LC_TXFVERT glyphs[93];
/////////////////////////////////////////////////////////////////////////////
// Project construction/destruction
@@ -177,9 +192,18 @@ Project::~Project()
// Project attributes, general services
// The main window should be created before calling this
-bool Project::Initialize(int argc, char *argv[], char* libpath)
+bool Project::Initialize(int argc, char *argv[], char* binpath, char* libpath)
{
- m_LibraryPath = libpath;
+ char *env_path;
+ bool loaded = false;
+
+ strcpy (m_AppPath, binpath);
+
+ // check if there's an environment variable for the piece library
+ env_path = getenv ("LEOCAD_LIB");
+ if (env_path != NULL)
+ libpath = env_path;
+
m_strPathName[0] = 0;
LC_IMAGE_OPTS imopts;
@@ -208,7 +232,7 @@ bool Project::Initialize(int argc, char *argv[], char* libpath)
if ((strcmp (param, "l") == 0) && ((i+1) < argc))
{
i++;
- m_LibraryPath = argv[i];
+ libpath = argv[i];
}
if (strcmp (param, "i") == 0)
@@ -254,7 +278,15 @@ bool Project::Initialize(int argc, char *argv[], char* libpath)
}
}
- if (LoadPieceLibrary() == false)
+ // if the user specified a library, try to load it first
+ if (libpath != NULL)
+ loaded = LoadPieceLibrary (libpath);
+
+ // if we couldn't find a library, try the executable path
+ if (!loaded)
+ loaded = LoadPieceLibrary (binpath);
+
+ if (!loaded)
{
#ifdef LC_WINDOWS
SystemDoMessageBox("Cannot load piece library.", LC_MB_OK|LC_MB_ICONERROR);
@@ -324,7 +356,7 @@ bool Project::Initialize(int argc, char *argv[], char* libpath)
}
// Load the piece library
-bool Project::LoadPieceLibrary()
+bool Project::LoadPieceLibrary (char *libpath)
{
FileDisk idx;
char filename[LC_MAXPATH];
@@ -335,6 +367,8 @@ bool Project::LoadPieceLibrary()
Texture* pTexture;
int i;
+ strcpy (m_LibraryPath, libpath);
+
// Make sure that the path ends with a '/'
i = strlen(m_LibraryPath)-1;
if ((m_LibraryPath[i] != '\\') && (m_LibraryPath[i] != '/'))
@@ -477,7 +511,7 @@ void Project::DeleteContents(bool bUndo)
if (!bUndo)
{
- UNDOINFO* pUndo;
+ LC_UNDOINFO* pUndo;
while (m_pUndoList)
{
@@ -1620,10 +1654,10 @@ void Project::SetPathName(char* lpszPathName, bool bAddToMRU)
// Undo/Redo support
// Save current state.
-void Project::CheckPoint(char* text)
+void Project::CheckPoint (const char* text)
{
- UNDOINFO* pTmp;
- UNDOINFO* pUndo = new UNDOINFO;
+ LC_UNDOINFO* pTmp;
+ LC_UNDOINFO* pUndo = new LC_UNDOINFO;
int i;
strcpy(pUndo->strText, text);
@@ -1957,7 +1991,7 @@ glLightfv(GL_LIGHT0, GL_SPECULAR, one);
glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
- TXFVERT* glyph;
+ LC_TXFVERT* glyph;
glPushMatrix();
glTranslatef(1.4f*ds, 0, 0);
@@ -2562,6 +2596,7 @@ void CCADDoc::AddPiece(CPiece* pNewPiece)
else
{
m_pPieces = pPiece;
+ pPiece->m_pNext = NULL;
}
pPiece->AddConnections(m_pConnections);
@@ -3976,7 +4011,7 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam)
case LC_EDIT_UNDO:
case LC_EDIT_REDO:
{
- UNDOINFO *pUndo, *pTmp;
+ LC_UNDOINFO *pUndo, *pTmp;
int i;
if (id == LC_EDIT_UNDO)
@@ -4401,6 +4436,7 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam)
pPiece->Initialize(pos[0], pos[1], pos[2], m_nCurStep, m_nCurFrame, m_nCurColor);
pPiece->ChangeKey(1, false, false, rot, PK_ROTATION);
pPiece->ChangeKey(1, true, false, rot, PK_ROTATION);
+ pPiece->UpdatePosition(1, false);
}
else
pPiece->Initialize(0, 0, 0, m_nCurStep, m_nCurFrame, m_nCurColor);
@@ -4437,78 +4473,35 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam)
case LC_PIECE_MINIFIG:
{
- LC_MINIFIGDLG_OPTS opts;
- const unsigned char colors[15] = { 0, 6, 4, 22, 0, 0, 6, 6, 22, 22, 9, 9, 9, 22, 22 };
- const float pos[15][3] = { {0,0,3.84f},{0,0,3.84f},{0,0,2.88f},{0,0,2.96f},{0,0,2.56f},{0,0,2.56f},{0.9f,-0.62f,1.76f},
- {-0.9f,-0.62f,1.76f},{0.92f,-0.62f,1.76f},{-0.92f,-0.62f,1.76f},{0,0,1.6f},{0,0,1.12f},{0,0,1.12f},{0.42f,0,0},{-0.42f,0,0} };
- int i;
-
- for (i = 0; i < 15; i++)
- {
- opts.info[i] = NULL;
- opts.colors[i] = colors[i];
- opts.pos[i][0] = pos[i][0];
- opts.pos[i][1] = pos[i][1];
- opts.pos[i][2] = pos[i][2];
- opts.rot[i][0] = 0;
- opts.rot[i][1] = 0;
- opts.rot[i][2] = 0;
- }
+ MinifigWizard wiz;
+ int i;
- for (i = 0; i < 13; i++)
- {
- if (i == 3 || i == 7 || i == 8 || i == 9)
- continue;
+ if (SystemDoDialog (LC_DLG_MINIFIG, &wiz))
+ {
+ SelectAndFocusNone(false);
- PieceInfo* pInfo = FindPieceInfo(mfwpieceinfo[i].name);
- if (pInfo == NULL)
- continue;
+ for (i = 0; i < LC_MFW_NUMITEMS; i++)
+ {
+ if (wiz.m_Info[i] == NULL)
+ continue;
- if (i == 6)
- {
- opts.info[6] = pInfo;
- opts.info[7] = pInfo;
- pInfo->AddRef();
- pInfo->AddRef();
- opts.rot[6][0] = 45;
- opts.rot[6][2] = 90;
- opts.rot[7][0] = 45;
- opts.rot[7][2] = 90;
- }
- else
- {
- opts.info[i] = pInfo;
- pInfo->AddRef();
- }
- }
+ Matrix mat;
+ Piece* pPiece = new Piece(wiz.m_Info[i]);
- if (SystemDoDialog(LC_DLG_MINIFIG, &opts))
- {
- SelectAndFocusNone(false);
+ pPiece->Initialize(wiz.m_Position[i][0], wiz.m_Position[i][1], wiz.m_Position[i][2],
+ m_nCurStep, m_nCurFrame, wiz.m_Colors[i]);
+ pPiece->CreateName(m_pPieces);
+ AddPiece(pPiece);
+ pPiece->Select();
- for (i = 0; i < 15; i++)
- {
- if (opts.info[i] == NULL)
- continue;
+ pPiece->ChangeKey(1, false, false, wiz.m_Rotation[i], PK_ROTATION);
+ pPiece->ChangeKey(1, true, false, wiz.m_Rotation[i], PK_ROTATION);
+ pPiece->UpdatePosition(m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation);
+ pPiece->CalculateConnections(m_pConnections, m_bAnimation ? m_nCurFrame : m_nCurStep,
+ m_bAnimation, false, true);
- Matrix mat;
- float rot[4];
- Piece* pPiece = new Piece(opts.info[i]);
-
- pPiece->Initialize(opts.pos[i][0], opts.pos[i][1], opts.pos[i][2], m_nCurStep, m_nCurFrame, opts.colors[i]);
- pPiece->CreateName(m_pPieces);
- AddPiece(pPiece);
- pPiece->Select();
-
- mat.CreateOld(0,0,0,opts.rot[i][0],opts.rot[i][1],opts.rot[i][2]);
- mat.ToAxisAngle(rot);
- pPiece->ChangeKey(1, false, false, rot, PK_ROTATION);
- pPiece->ChangeKey(1, true, false, rot, PK_ROTATION);
- pPiece->UpdatePosition(m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation);
- pPiece->CalculateConnections(m_pConnections, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, false, true);
-
- SystemPieceComboAdd(opts.info[i]->m_strDescription);
- }
+ SystemPieceComboAdd(wiz.m_Info[i]->m_strDescription);
+ }
float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 };
int max = 0;
@@ -4543,9 +4536,9 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam)
CheckPoint("Minifig");
}
- for (i = 0; i < 15; i++)
- if (opts.info[i])
- opts.info[i]->DeRef();
+ for (i = 0; i < LC_MFW_NUMITEMS; i++)
+ if (wiz.m_Info[i])
+ wiz.m_Info[i]->DeRef();
} break;
case LC_PIECE_ARRAY:
@@ -5072,14 +5065,10 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam)
case LC_VIEW_ZOOMEXTENTS:
{
+ // FIXME: rewrite using the FustrumCull function
if (m_pPieces == 0) break;
+ bool bControl = Sys_KeyDown (KEY_CONTROL);
- // HACK !!! HACK !!! HACK
-#ifdef LC_WINDOWS
- bool bControl = (GetKeyState(KEY_CONTROL) < 0);
-#else
- bool bControl = false;
-#endif
GLdouble modelMatrix[16], projMatrix[16];
float up[3], eye[3], target[3];
float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 };
@@ -5881,6 +5870,11 @@ bool Project::StopTracking(bool bAccept)
SetModifiedFlag(true);
CheckPoint("Inserting");
}
+ else if (m_nCurAction == LC_ACTION_CURVE)
+ {
+ SetModifiedFlag(true);
+ CheckPoint("Inserting");
+ }
}
else if (m_pTrackFile != NULL)
{
@@ -6483,7 +6477,7 @@ bool Project::OnKeyDown(char nKey, bool bControl, bool bShift)
MoveSelectedObjects(axis[0], axis[1], axis[2]);
SystemRedrawView();
SetModifiedFlag(true);
- CheckPoint((bShift) ? (char*) "Rotating" : (char*) "Moving");
+ CheckPoint((bShift) ? "Rotating" : "Moving");
SystemUpdateFocus(NULL, 0);
ret = true;
} break;
@@ -6783,11 +6777,12 @@ void Project::OnLeftButtonDoubleClick(int x, int y, bool bControl, bool bShift)
if (SetActiveViewport(x, y))
return;
- LoadViewportProjection();
- glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
- glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
- glGetIntegerv(GL_VIEWPORT, viewport);
+ LoadViewportProjection ();
+ glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
+ glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
+ glGetIntegerv (GL_VIEWPORT, viewport);
+ // why this is here ?
gluUnProject(x, y, 0.9, modelMatrix, projMatrix, viewport, &point[0], &point[1], &point[2]);
m_fTrack[0] = (float)point[0]; m_fTrack[1] = (float)point[1]; m_fTrack[2] = (float)point[2];
@@ -7154,5 +7149,34 @@ void Project::OnMouseMove(int x, int y, bool bControl, bool bShift)
SystemUpdateFocus(NULL, 0);
SystemRedrawView();
} break;
+ /*
+ case LC_ACTION_CURVE:
+ {
+ float mouse = 10.0f/(21 - m_nMouse);
+ float dx = (ptx - m_fTrack[0])*mouse;
+ float dy = (pty - m_fTrack[1])*mouse;
+ float dz = (ptz - m_fTrack[2])*mouse;
+ Object *pObj = NULL;
+ Curve *pCurve;
+
+ m_fTrack[0] = ptx;
+ m_fTrack[1] = pty;
+ m_fTrack[2] = ptz;
+
+ for (pObj = m_pObjects; pObj != NULL; pObj = pObj->m_pNext)
+ if (pObj->IsSelected ())
+ break;
+
+ if (pObj == NULL)
+ break;
+ pCurve = (Curve*)pObj;
+
+ pCurve->Move (1, m_bAnimation, false, dx, dy, dz);
+ pCurve->UpdatePosition(1, m_bAnimation);
+
+ SystemUpdateFocus(NULL, 0);
+ SystemRedrawView();
+ } break;
+ */
}
}
diff --git a/common/project.h b/common/project.h
index 651c199..ff0ba4e 100644
--- a/common/project.h
+++ b/common/project.h
@@ -25,13 +25,13 @@ class Matrix;
#include "file.h"
-typedef struct UNDOINFO
+typedef struct LC_UNDOINFO
{
- FileMem file;
- char strText[21];
- UNDOINFO* pNext;
- UNDOINFO() { pNext = NULL; };
-} UNDOINFO;
+ FileMem file;
+ char strText[21];
+ LC_UNDOINFO* pNext;
+ LC_UNDOINFO() { pNext = NULL; };
+} LC_UNDOINFO;
class Project
{
@@ -39,7 +39,7 @@ public:
// Constructors
Project();
~Project();
- bool Initialize(int argc, char *argv[], char* libpath);
+ bool Initialize(int argc, char *argv[], char* binpath, char* libpath);
// Attributes
public:
@@ -107,8 +107,9 @@ protected:
char m_strComments[256];
// Piece library
- bool LoadPieceLibrary();
- char* m_LibraryPath; // path to the library files
+ bool LoadPieceLibrary (char* libpath);
+ char m_LibraryPath[LC_MAXPATH]; // path to the library files
+ char m_AppPath[LC_MAXPATH]; // path to the LeoCAD executable
int m_nPieceCount; // number of pieces
PieceInfo* m_pPieceIdx; // index
int m_nTextureCount;
@@ -117,10 +118,10 @@ protected:
int m_nMovedCount;
// Undo support
- UNDOINFO* m_pUndoList;
- UNDOINFO* m_pRedoList;
+ LC_UNDOINFO* m_pUndoList;
+ LC_UNDOINFO* m_pRedoList;
bool m_bUndoOriginal;
- void CheckPoint(char* text);
+ void CheckPoint (const char* text);
// Objects
Piece* m_pPieces;
diff --git a/common/system.h b/common/system.h
index a41aff9..8a53939 100755
--- a/common/system.h
+++ b/common/system.h
@@ -46,8 +46,8 @@ void Sys_SetCursorPos (int x, int y);
int Sys_MessageBox (const char* text, const char* caption="LeoCAD", int type=LC_MB_OK|LC_MB_ICONINFORMATION);
-
-
+// Misc stuff
+bool Sys_KeyDown (int key);
diff --git a/common/typedefs.h b/common/typedefs.h
index 4930cfb..fea9198 100644
--- a/common/typedefs.h
+++ b/common/typedefs.h
@@ -90,6 +90,7 @@ typedef enum {
LC_ACTION_LIGHT,
LC_ACTION_SPOTLIGHT,
LC_ACTION_CAMERA,
+ LC_ACTION_CURVE,
LC_ACTION_MOVE,
LC_ACTION_ROTATE,
LC_ACTION_ERASER,
@@ -125,20 +126,6 @@ typedef struct
unsigned short numentries;
} CONNECTION_TYPE;
-// Minifig Wizard information
-
-typedef enum {
- MF_HAT, MF_HEAD, MF_TORSO, MF_NECK, MF_ARML, MF_ARMR,
- MF_HAND, MF_TOOL, MF_HIPS, MF_LEGL, MF_LEGR, MF_SHOE
-} MFW_TYPES;
-
-typedef struct {
- char name[9];
- char description[32];
- int type;
-} MFW_PIECEINFO;
-
-
// Select by Name dialog data
typedef enum
@@ -263,16 +250,6 @@ typedef struct
LC_IMAGEDLG_OPTS imdlg;
} LC_HTMLDLG_OPTS;
-// hat, head, torso, neck, arml, armr, handl, handr, tooll,
-// toolr, hips, legl, legr, shoel, shoer
-typedef struct
-{
- PieceInfo* info[15];
- int colors[15];
- float pos[15][3];
- float rot[15][3];
-} LC_MINIFIGDLG_OPTS;
-
typedef struct
{
unsigned short n1DCount;
diff --git a/config.mk b/config.mk
index 66474cd..37d5d63 100644
--- a/config.mk
+++ b/config.mk
@@ -2,17 +2,17 @@
#
include version.mk
-CC := gcc
-CXX := g++
+CC := gcc
+CXX := g++
-ifeq ($(shell uname), linux)
-OS := -DLC_LINUX
+ifeq ($(shell uname), Linux)
+OS := -DLC_LINUX
OSDIR := linux
else
ifeq ($(shell uname), BeOS)
-OS := -DLC_BEOS
+OS := -DLC_BEOS
OSDIR := beos
endif
diff --git a/linux/dlgpiece.cpp b/linux/dlgpiece.cpp
index 17d91b2..2735356 100755
--- a/linux/dlgpiece.cpp
+++ b/linux/dlgpiece.cpp
@@ -11,6 +11,7 @@
#include <gdk/gdkkeysyms.h>
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include "opengl.h"
#include "gtkglarea.h"
#include "gtktools.h"
@@ -20,43 +21,24 @@
#include "dialogs.h"
#include "matrix.h"
#include "pieceinf.h"
-#include "project.h"
#include "main.h"
+#include "minifig.h"
// =========================================================
// Minifig Wizard
-typedef enum {
- MFW_HAT,
- MFW_HEAD,
- MFW_TORSO,
- MFW_NECK,
- MFW_LEFT_ARM,
- MFW_RIGHT_ARM,
- MFW_LEFT_HAND,
- MFW_RIGHT_HAND,
- MFW_LEFT_TOOL,
- MFW_RIGHT_TOOL,
- MFW_HIPS,
- MFW_LEFT_LEG,
- MFW_RIGHT_LEG,
- MFW_LEFT_SHOE,
- MFW_RIGHT_SHOE,
- MFW_NUMITEMS
-};
-
typedef struct
{
- LC_MINIFIGDLG_OPTS* opts;
- GtkWidget *pieces[MFW_NUMITEMS];
- GtkWidget *colors[MFW_NUMITEMS];
+ MinifigWizard* opts;
+ GtkWidget *pieces[LC_MFW_NUMITEMS];
+ GtkWidget *colors[LC_MFW_NUMITEMS];
+ GtkWidget *angles[LC_MFW_NUMITEMS];
GtkWidget *preview;
} LC_MINIFIGDLG_STRUCT;
static gint minifigdlg_redraw (GtkWidget *widget, GdkEventExpose *event)
{
LC_MINIFIGDLG_STRUCT* data;
- int i;
// Draw only last expose.
if (event->count > 0)
@@ -70,25 +52,8 @@ static gint minifigdlg_redraw (GtkWidget *widget, GdkEventExpose *event)
if (!gtk_gl_area_make_current(GTK_GL_AREA(widget)))
return TRUE;
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- for (i = 0; i < 15; i++)
- {
- if (data->opts->info[i] == NULL)
- continue;
-
- glPushMatrix();
- Matrix mat;
- float rot[4];
- mat.CreateOld(0,0,0, data->opts->rot[i][0], data->opts->rot[i][1], data->opts->rot[i][2]);
- mat.ToAxisAngle(rot);
- glTranslatef(data->opts->pos[i][0], data->opts->pos[i][1], data->opts->pos[i][2]);
- glRotatef(rot[3], rot[0], rot[1], rot[2]);
- data->opts->info[i]->RenderPiece(data->opts->colors[i]);
- glPopMatrix();
- }
+ data->opts->Redraw ();
- glFinish();
gtk_gl_area_swapbuffers(GTK_GL_AREA(widget));
gtk_gl_area_make_current(GTK_GL_AREA(drawing_area));
@@ -98,26 +63,15 @@ static gint minifigdlg_redraw (GtkWidget *widget, GdkEventExpose *event)
// Setup the OpenGL projection
static gint minifigdlg_resize (GtkWidget *widget, GdkEventConfigure *event)
{
+ LC_MINIFIGDLG_STRUCT* data = (LC_MINIFIGDLG_STRUCT*)gtk_object_get_data (GTK_OBJECT (widget), "minifig");
+
+ if (!data)
+ return TRUE;
+
if (!gtk_gl_area_make_current(GTK_GL_AREA(widget)))
return TRUE;
- float aspect = (float)widget->allocation.width/(float)widget->allocation.height;
- glViewport(0, 0, widget->allocation.width, widget->allocation.height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(30.0f, aspect, 1.0f, 20.0f);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- gluLookAt (0, -9, 4, 0, 5, 1, 0, 0, 1);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- float *bg = project->GetBackgroundColor();
- glClearColor(bg[0], bg[1], bg[2], bg[3]);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glDisable (GL_DITHER);
- glShadeModel (GL_FLAT);
+ data->opts->Resize (widget->allocation.width, widget->allocation.height);
gtk_gl_area_make_current(GTK_GL_AREA(drawing_area));
@@ -150,7 +104,7 @@ static void minifigdlg_color_response (GtkWidget *widget, gpointer data)
if (info->colors[i] == button)
break;
- info->opts->colors[i] = (int)data;
+ info->opts->ChangeColor (i, GPOINTER_TO_INT (data));
gtk_widget_draw (info->preview, NULL);
set_button_pixmap2 (button, FlatColorArray[(int)data]);
}
@@ -186,18 +140,17 @@ static gint minifigdlg_color_expose (GtkWidget *widget)
}
// New piece was selected
-static void minifigdlg_piece_changed (GtkWidget *widget)
+static void minifigdlg_piece_changed (GtkWidget *widget, gpointer data)
{
LC_MINIFIGDLG_STRUCT* info;
- PieceInfo* piece_info = NULL;
- int i, j, piece_type;
+ int i, piece_type;
char* desc;
info = (LC_MINIFIGDLG_STRUCT*)gtk_object_get_data (GTK_OBJECT (widget), "info");
if (info == NULL)
return;
- for (i = 0; i < 15; i++)
+ for (i = 0; i < LC_MFW_NUMITEMS; i++)
if (GTK_COMBO (info->pieces[i])->entry == widget)
{
piece_type = i;
@@ -206,140 +159,35 @@ static void minifigdlg_piece_changed (GtkWidget *widget)
desc = gtk_entry_get_text (GTK_ENTRY (widget));
- for (j = 0; j < MFW_PIECES; j++)
- {
- if (strcmp (desc, mfwpieceinfo[j].description) == 0)
- {
- piece_info = project->FindPieceInfo(mfwpieceinfo[j].name);
- if (piece_info == NULL)
- continue;
-
- if (info->opts->info[i])
- info->opts->info[i]->DeRef();
- info->opts->info[i] = piece_info;
- piece_info->AddRef();
- break;
- }
- }
+ info->opts->ChangePiece (i, desc);
- // Piece not found ("None")
- if (j == MFW_PIECES)
- {
- if (info->opts->info[i])
- info->opts->info[i]->DeRef();
- info->opts->info[i] = NULL;
- }
+ gtk_widget_draw (info->preview, NULL);
+}
- // Get the pieces in the right place
- // TODO: Find a way to make this cross-platform
- if (i == MFW_NECK)
- {
- if (info->opts->info[3] != NULL)
- {
- info->opts->pos[0][2] = 3.92f;
- info->opts->pos[1][2] = 3.92f;
-
- if (strcmp (piece_info->m_strName,"4498") == 0)
- info->opts->rot[3][2] = 180.0f;
- else
- info->opts->rot[3][2] = 0.0f;
- }
- else
- {
- info->opts->pos[0][2] = 3.84f;
- info->opts->pos[1][2] = 3.84f;
- }
- }
+static void adj_changed (GtkAdjustment *adj, gpointer data)
+{
+ LC_MINIFIGDLG_STRUCT* info = (LC_MINIFIGDLG_STRUCT*)data;
+ int i;
- if (i == MFW_LEFT_SHOE)
- {
- if (strcmp (desc, "Ski"))
- info->opts->pos[13][1] = 0;
- else
- info->opts->pos[13][1] = -0.12f;
- }
+ for (i = 0; i < LC_MFW_NUMITEMS; i++)
+ if (info->angles[i] != NULL)
+ if (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (info->angles[i])) == adj)
+ break;
- if (i == MFW_RIGHT_SHOE)
- {
- if (strcmp (desc, "Ski"))
- info->opts->pos[14][1] = 0;
- else
- info->opts->pos[14][1] = -0.12f;
- }
+ if (i == LC_MFW_NUMITEMS)
+ return;
- if ((i == MFW_LEFT_TOOL) || (i == MFW_RIGHT_TOOL))
- if (piece_info != NULL)
- {
- float rx = 45, ry = 0, rz = 0, x = 0.92f, y = -0.62f, z = 1.76f;
-
- if (strcmp (piece_info->m_strName,"4529") == 0)
- { rx = -45; y = -1.14f; z = 2.36f; }
- if (strcmp (piece_info->m_strName,"3899") == 0)
- { y = -1.64f; z = 1.38f; }
- if (strcmp (piece_info->m_strName,"4528") == 0)
- { rx = -45; y = -1.26f; z = 2.36f; }
- if (strcmp (piece_info->m_strName,"4479") == 0)
- { rz = 90; y = -1.22f; z = 2.44f; }
- if (strcmp (piece_info->m_strName,"3962") == 0)
- { rz = 90; y = -0.7f; z = 1.62f; }
- if (strcmp (piece_info->m_strName,"4360") == 0)
- { rz = -90; y = -1.22f; z = 2.44f; }
- if (strncmp (piece_info->m_strName,"6246",4) == 0)
- { y = -1.82f; z = 2.72f; rz = 90; }
- if (strcmp (piece_info->m_strName,"4349") == 0)
- { y = -1.16f; z = 2.0f; }
- if (strcmp (piece_info->m_strName,"4479") == 0)
- { y = -1.42f; z = 2.26f; }
- if (strcmp (piece_info->m_strName,"3959") == 0)
- { y = -1.0f; z = 1.88f; }
- if (strcmp (piece_info->m_strName,"4522") == 0)
- { y = -1.64f; z = 2.48f; }
- if (strcmp (piece_info->m_strName,"194") == 0)
- { rz = 180; y = -1.04f; z = 1.94f; }
- if (strcmp (piece_info->m_strName,"4006") == 0)
- { rz = 180; y = -1.24f; z = 2.18f; }
- if (strcmp (piece_info->m_strName,"6246C") == 0)
- { rx = 45; rz = 0; y = -0.86f; z = 1.78f; }
- if (strcmp (piece_info->m_strName,"4497") == 0)
- { y = -2.16f; z = 3.08f; rz = 90; }
- if (strcmp (piece_info->m_strName,"30092") == 0)
- { x = 0; rz = 180; }
- if (strcmp (piece_info->m_strName,"37") == 0)
- { z = 1.52f; y = -0.64f; }
- if (strcmp (piece_info->m_strName,"38") == 0)
- { z = 1.24f; y = -0.34f; }
- if (strcmp (piece_info->m_strName,"3841") == 0)
- { z = 2.24f; y = -1.34f; rz = 180; }
- if (strcmp (piece_info->m_strName,"4499") == 0)
- { rz = ((i == MFW_RIGHT_TOOL) ? 10 : -10); z = 1.52f; }
- if (strcmp (piece_info->m_strName,"3852") == 0)
- { rz = -90; x = 0.90f; y = -0.8f; z = 1.84f; }
- if (strcmp (piece_info->m_strName,"30152") == 0)
- { z = 3.06f; y = -2.16f; }
- if (strcmp (piece_info->m_strName,"2570") == 0)
- { z = 1.68f; y = -0.8f; }
- if (strcmp (piece_info->m_strName,"2614") == 0)
- { z = 1.74f; y = -0.86f; }
-
- if (i == MFW_RIGHT_TOOL)
- x = -x;
-
- info->opts->pos[i][0] = x;
- info->opts->pos[i][1] = y;
- info->opts->pos[i][2] = z;
- info->opts->rot[i][0] = rx;
- info->opts->rot[i][1] = ry;
- info->opts->rot[i][2] = rz;
- }
+ info->opts->ChangeAngle (i, gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (info->angles[i])));
- gtk_widget_draw (info->preview, NULL);
+ if (info->preview != NULL)
+ gtk_widget_draw (info->preview, NULL);
}
-
// Create a combo box with a color selection control
static void minifigdlg_createpair (LC_MINIFIGDLG_STRUCT* info, int num, GtkWidget* vbox)
{
- GtkWidget *hbox, *combo, *color;
+ GtkWidget *hbox, *combo, *color, *spin;
+ GtkObject *adj;
hbox = gtk_hbox_new (FALSE, 5);
gtk_widget_show (hbox);
@@ -357,7 +205,7 @@ static void minifigdlg_createpair (LC_MINIFIGDLG_STRUCT* info, int num, GtkWidge
color = info->colors[num] = gtk_button_new_with_label ("");
gtk_widget_set_events (color, GDK_EXPOSURE_MASK);
gtk_widget_show (color);
- gtk_object_set_data (GTK_OBJECT (color), "color", &info->opts->colors[num]);
+ gtk_object_set_data (GTK_OBJECT (color), "color", &info->opts->m_Colors[num]);
gtk_object_set_data (GTK_OBJECT (color), "info", info);
gtk_widget_set_usize (color, 40, 25);
gtk_signal_connect (GTK_OBJECT (color), "expose_event",
@@ -365,12 +213,19 @@ static void minifigdlg_createpair (LC_MINIFIGDLG_STRUCT* info, int num, GtkWidge
gtk_signal_connect (GTK_OBJECT (color), "clicked",
GTK_SIGNAL_FUNC (minifigdlg_color_clicked), info);
gtk_box_pack_start (GTK_BOX (hbox), color, FALSE, TRUE, 0);
-}
-// sort the names from the combo boxes
-static gint minifigdlg_compare (gconstpointer a, gconstpointer b)
-{
- return strcmp ((const char*)a, (const char*)b);
+ if ((num == LC_MFW_TORSO) || (num == LC_MFW_HIPS))
+ return;
+
+ adj = gtk_adjustment_new (0, -180, 180, 1, 10, 10);
+ gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (adj_changed), info);
+
+ spin = info->angles[num] = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
+ gtk_widget_show (spin);
+ gtk_object_set_data (GTK_OBJECT (color), "info", info);
+ // gtk_widget_set_usize (spin, 40, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), spin, FALSE, TRUE, 0);
+ gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spin), TRUE);
}
int minifigdlg_execute(void* param)
@@ -382,7 +237,8 @@ int minifigdlg_execute(void* param)
GtkWidget *button;
int i;
- s.opts = (LC_MINIFIGDLG_OPTS*)param;
+ memset (&s, 0, sizeof (s));
+ s.opts = (MinifigWizard*)param;
dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
@@ -391,7 +247,7 @@ int minifigdlg_execute(void* param)
GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
gtk_widget_set_usize (dlg, 600, 360);
gtk_window_set_title (GTK_WINDOW (dlg), "Minifig Wizard");
- gtk_window_set_policy (GTK_WINDOW (dlg), FALSE, FALSE, FALSE);
+ // gtk_window_set_policy (GTK_WINDOW (dlg), FALSE, FALSE, FALSE);
gtk_widget_realize (dlg);
vbox1 = gtk_vbox_new (FALSE, 10);
@@ -401,20 +257,20 @@ int minifigdlg_execute(void* param)
hbox = gtk_hbox_new (FALSE, 5);
gtk_widget_show (hbox);
- gtk_box_pack_start (GTK_BOX (vbox1), hbox, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox1), hbox, TRUE, TRUE, 0);
vbox2 = gtk_vbox_new (FALSE, 5);
gtk_widget_show (vbox2);
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
- minifigdlg_createpair (&s, MFW_HAT, vbox2);
- minifigdlg_createpair (&s, MFW_NECK, vbox2);
- minifigdlg_createpair (&s, MFW_RIGHT_ARM, vbox2);
- minifigdlg_createpair (&s, MFW_RIGHT_HAND, vbox2);
- minifigdlg_createpair (&s, MFW_RIGHT_TOOL, vbox2);
- minifigdlg_createpair (&s, MFW_HIPS, vbox2);
- minifigdlg_createpair (&s, MFW_RIGHT_LEG, vbox2);
- minifigdlg_createpair (&s, MFW_RIGHT_SHOE, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_HAT, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_NECK, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_RIGHT_ARM, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_RIGHT_HAND, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_RIGHT_TOOL, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_HIPS, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_RIGHT_LEG, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_RIGHT_SHOE, vbox2);
// Create new OpenGL widget.
s.preview = gtk_gl_area_share_new (attrlist, GTK_GL_AREA (drawing_area));
@@ -430,7 +286,7 @@ int minifigdlg_execute(void* param)
gtk_container_add (GTK_CONTAINER (hbox), frame);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
- gtk_widget_set_usize (GTK_WIDGET (s.preview), 100, 300);
+ gtk_widget_set_usize (GTK_WIDGET (s.preview), 150, 300);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (s.preview));
gtk_widget_show (GTK_WIDGET (s.preview));
gtk_object_set_data (GTK_OBJECT (s.preview), "minifig", &s);
@@ -439,13 +295,13 @@ int minifigdlg_execute(void* param)
gtk_widget_show (vbox2);
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
- minifigdlg_createpair (&s, MFW_HEAD, vbox2);
- minifigdlg_createpair (&s, MFW_TORSO, vbox2);
- minifigdlg_createpair (&s, MFW_LEFT_ARM, vbox2);
- minifigdlg_createpair (&s, MFW_LEFT_HAND, vbox2);
- minifigdlg_createpair (&s, MFW_LEFT_TOOL, vbox2);
- minifigdlg_createpair (&s, MFW_LEFT_LEG, vbox2);
- minifigdlg_createpair (&s, MFW_LEFT_SHOE, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_HEAD, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_TORSO, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_LEFT_ARM, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_LEFT_HAND, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_LEFT_TOOL, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_LEFT_LEG, vbox2);
+ minifigdlg_createpair (&s, LC_MFW_LEFT_SHOE, vbox2);
hbox = gtk_hbox_new (FALSE, 10);
gtk_widget_show (hbox);
@@ -473,64 +329,27 @@ int minifigdlg_execute(void* param)
GDK_Escape, 0, GTK_ACCEL_VISIBLE);
// Fill the combo boxes with the available pieces
- GList* names[15];
- for (i = 0; i < 15; i++)
- names[i] = NULL;
-
- for (i = 0; i < MFW_PIECES; i++)
+ for (i = 0; i < LC_MFW_NUMITEMS; i++)
{
- PieceInfo* piece_info;
- int id;
+ GList* names = NULL;
+ int count;
+ char **list;
+ s.opts->GetDescriptions (i, &list, &count);
- piece_info = project->FindPieceInfo(mfwpieceinfo[i].name);
- if (piece_info == NULL)
- continue;
+ for (int j = 0; j < count; j++)
+ names = g_list_append (names, list[j]);
- switch (mfwpieceinfo[i].type)
+ if (names != NULL)
{
- case MF_HAT: id = MFW_HAT; break;
- case MF_HEAD: id = MFW_HEAD; break;
- case MF_TORSO: id = MFW_TORSO; break;
- case MF_NECK: id = MFW_NECK; break;
- case MF_ARML: id = MFW_LEFT_ARM; break;
- case MF_ARMR: id = MFW_RIGHT_ARM; break;
- case MF_HAND: id = MFW_LEFT_HAND; break;
- case MF_TOOL: id = MFW_LEFT_TOOL; break;
- case MF_HIPS: id = MFW_HIPS; break;
- case MF_LEGL: id = MFW_LEFT_LEG; break;
- case MF_LEGR: id = MFW_RIGHT_LEG; break;
- case MF_SHOE: id = MFW_LEFT_SHOE; break;
- default:
- continue;
+ gtk_combo_set_popdown_strings (GTK_COMBO (s.pieces[i]), names);
+ g_list_free (names);
}
-
- if (i != 29)
- names[id] = g_list_insert_sorted (names[id], mfwpieceinfo[i].description, minifigdlg_compare);
-
- if (id == MFW_LEFT_HAND || id == MFW_LEFT_TOOL || id == MFW_LEFT_SHOE)
- names[id+1] = g_list_insert_sorted (names[id+1], mfwpieceinfo[i].description, minifigdlg_compare);
-
- if (i == 6) i++;
+ free (list);
}
- names[MFW_HAT] = g_list_prepend (names[MFW_HAT], (void*)"None");
- names[MFW_NECK] = g_list_prepend (names[MFW_NECK], (void*)"None");
- names[MFW_LEFT_TOOL] = g_list_prepend (names[MFW_LEFT_TOOL], (void*)"None");
- names[MFW_RIGHT_TOOL] = g_list_prepend (names[MFW_RIGHT_TOOL], (void*)"None");
- names[MFW_LEFT_SHOE] = g_list_prepend (names[MFW_LEFT_SHOE], (void*)"None");
- names[MFW_RIGHT_SHOE] = g_list_prepend (names[MFW_RIGHT_SHOE], (void*)"None");
-
- for (i = 0; i < 15; i++)
- gtk_combo_set_popdown_strings ( GTK_COMBO (s.pieces[i]), names[i]);
-
- gtk_list_select_item ( GTK_LIST (GTK_COMBO (s.pieces[MFW_HAT])->list), 7);
- gtk_list_select_item ( GTK_LIST (GTK_COMBO (s.pieces[MFW_HEAD])->list), 4);
- gtk_list_select_item ( GTK_LIST (GTK_COMBO (s.pieces[MFW_TORSO])->list), 22);
+ gtk_list_select_item (GTK_LIST (GTK_COMBO (s.pieces[LC_MFW_HAT])->list), 7);
+ gtk_list_select_item (GTK_LIST (GTK_COMBO (s.pieces[LC_MFW_HEAD])->list), 4);
+ gtk_list_select_item (GTK_LIST (GTK_COMBO (s.pieces[LC_MFW_TORSO])->list), 22);
return dlg_domodal(dlg, LC_CANCEL);
}
-
-
-
-
-
diff --git a/linux/main.cpp b/linux/main.cpp
index 2655cb7..93b7ba1 100644
--- a/linux/main.cpp
+++ b/linux/main.cpp
@@ -24,7 +24,8 @@ void create_main_menu (GtkObject *window, GtkWidget *vbox);
GtkWidget *main_window;
GtkWidget *drawing_area;
-static char default_path[PATH_MAX];
+static char app_path[PATH_MAX];
+static char lib_path[] = "/usr/local/share/leocad/";
bool ignore_commands = false;
void init_paths (char *argv0)
@@ -89,10 +90,10 @@ void init_paths (char *argv0)
} while (*last && !found);
}
else
- argv0 = strrchr(argv0, '/')+1;
+ argv0 = strrchr (argv0, '/') + 1;
- if (realpath (temppath, default_path))
- *(strrchr (default_path, '/')) = '\0';
+ if (realpath (temppath, app_path))
+ *(strrchr (app_path, '/') + 1) = '\0';
}
// Functions
@@ -495,12 +496,7 @@ int main(int argc, char* argv[])
gtk_widget_show(GTK_WIDGET(main_window));
- char* path;
- path = getenv("LEOCAD_LIB");
- if (path == NULL)
- path = default_path;
-
- if (project->Initialize(argc, argv, path) == false)
+ if (project->Initialize (argc, argv, app_path, lib_path) == false)
{
delete project;
// return 1;
diff --git a/linux/system.cpp b/linux/system.cpp
index 9fc8124..8c50608 100644
--- a/linux/system.cpp
+++ b/linux/system.cpp
@@ -3,6 +3,7 @@
#include <string.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
+#include <X11/keysym.h>
#include "opengl.h"
#include "gdkgl.h"
#include "gtkglarea.h"
@@ -18,21 +19,21 @@
// =============================================================================
// Cursor functions
-/*
void Sys_BeginWait ()
{
GdkCursor *cursor = gdk_cursor_new (GDK_WATCH);
- gdk_window_set_cursor (g_pParentWnd->m_pWidget->window, cursor);
+ gdk_window_set_cursor (main_window->window, cursor);
gdk_cursor_destroy (cursor);
}
void Sys_EndWait ()
{
GdkCursor *cursor = gdk_cursor_new (GDK_LEFT_PTR);
- gdk_window_set_cursor (g_pParentWnd->m_pWidget->window, cursor);
+ gdk_window_set_cursor (main_window->window, cursor);
gdk_cursor_destroy (cursor);
}
+/*
void Sys_GetCursorPos (int *x, int *y)
{
gdk_window_get_pointer (NULL, x, y, NULL);
@@ -242,8 +243,27 @@ void Sys_FinishMemoryRender(void* param)
free(render);
}
+// =============================================================================
+// Misc stuff
+
+// FIXME: should have a table of LC_KEY_* defined
+bool Sys_KeyDown (int key)
+{
+ char keys[32];
+ int x;
+ XQueryKeymap (GDK_DISPLAY (), keys);
+ x = XKeysymToKeycode (GDK_DISPLAY (), XK_Control_L);
+ if (keys[x/8] & (1 << (x % 8)))
+ return true;
+
+ x = XKeysymToKeycode (GDK_DISPLAY (), XK_Control_R);
+ if (keys[x/8] & (1 << (x % 8)))
+ return true;
+
+ return false;
+}
diff --git a/win/System.cpp b/win/System.cpp
index 3e9ad46..8cc5c46 100644
--- a/win/System.cpp
+++ b/win/System.cpp
@@ -46,22 +46,6 @@ static void ShowLastError()
LocalFree( lpMsgBuf );
}
-/*
-typedef void (APIENTRY * GLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
-typedef void (APIENTRY * GLUNLOCKARRAYSEXTPROC) ();
-
-// Compiled vertex array function pointers.
-static GLLOCKARRAYSEXTPROC glLockArraysEXT;
-static GLUNLOCKARRAYSEXTPROC glUnlockArraysEXT;
-
-char* extensions = (char*)glGetString(GL_EXTENSIONS);
-if (strstr(extensions, "GL_EXT_compiled_vertex_array") != NULL)
-{
- glLockArraysEXT = (GLLOCKARRAYSEXTPROC)wglGetProcAddress("glLockArraysEXT");
- glUnlockArraysEXT = (GLUNLOCKARRAYSEXTPROC)wglGetProcAddress("glUnlockArraysEXT");
-}
-*/
-
static CMenu* GetMainMenu(int nIndex)
{
CWnd* pFrame = AfxGetMainWnd();
@@ -1608,3 +1592,8 @@ File* SystemImportClipboard()
return clip;
}
+
+bool Sys_KeyDown (int key)
+{
+ return GetKeyState (KEY_CONTROL) < 0;
+}