summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-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
15 files changed, 1154 insertions, 334 deletions
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;