Added LDConfig.ldr parsing. All colors now available as long as LDConfig.ldr is provided.

Wed, 27 Mar 2013 11:24:16 +0200

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Wed, 27 Mar 2013 11:24:16 +0200
changeset 72
5755c02d89f0
parent 71
c9f02d2dd9eb
child 73
d20867ac03cc

Added LDConfig.ldr parsing. All colors now available as long as LDConfig.ldr is provided.

colors.cpp file | annotate | diff | comparison | revisions
colors.h file | annotate | diff | comparison | revisions
file.cpp file | annotate | diff | comparison | revisions
file.h file | annotate | diff | comparison | revisions
gldraw.cpp file | annotate | diff | comparison | revisions
gui.cpp file | annotate | diff | comparison | revisions
misc.cpp file | annotate | diff | comparison | revisions
misc.h file | annotate | diff | comparison | revisions
zz_addObjectDialog.cpp file | annotate | diff | comparison | revisions
zz_addObjectDialog.h file | annotate | diff | comparison | revisions
zz_colorSelectDialog.cpp file | annotate | diff | comparison | revisions
--- a/colors.cpp	Mon Mar 25 22:52:53 2013 +0200
+++ b/colors.cpp	Wed Mar 27 11:24:16 2013 +0200
@@ -18,59 +18,9 @@
 
 #include "common.h"
 #include "colors.h"
-
-// Placeholder static color table until I make an LDConfig.ldr parser
-static TemporaryColorMeta g_LDColorInfo[] = {
-	{0,		"Black",		"#101010",	1.0},
-	{1,		"Blue",			"#0000FF",	1.0},
-	{2,		"Green",		"#008000",	1.0},
-	{3,		"Teal",			"#008080",	1.0},
-	{4,		"Red",			"#C00000",	1.0},
-	{5,		"Dark pink",	"#C00060",	1.0},
-	{6,		"Brown",		"#604000",	1.0},
-	{7,		"Gray",			"#989890",	1.0},
-	{8,		"Dark Gray",	"#6E6D62",	1.0},
-	{9,		"Light Blue",	"#60A0C0",	1.0},
-	{10,	"Bright Green",	"#40C040",	1.0},
-	{11,	"Cyan",			"#00FFFF",	1.0},
-	{12,	"Salmon",		"#FF8080",	1.0},
-	{13,	"Pink",			"#FF2080",	1.0},
-	{14,	"Yellow",		"#FFEE00",	1.0},
-	{15,	"White",		"#FFFFFF",	1.0},
-	{16,	"Main Color",	"#808080",	1.0},
-	{17,	"Light Green",	"#80FF80",	1.0},
-	{18,	"Light Yellow",	"#FFFF80",	1.0},
-	{19,	"Tan",			"#EECC99",	1.0},
-	{21,	"Phosphorus",	"#E0FFB0",	0.975},
-	{22,	"Purple",		"#A000A0",	1.0},
-	{24,	"Edge Color",	"#000000",	1.0},
-	{25,	"Orange",		"#FF8000",	1.0},
-	{26,	"Magenta",		"#FFA0FF",	1.0},
-	{27,	"Lime",			"#00FF00",	1.0},
-	{28,	"Sand",			"#989070",	1.0},
-	{32,	"Lens Black",	"#101010",	0.8},
-	{33,	"Trans Blue",	"#0000FF",	0.5},
-	{34,	"Trans Green",	"#008000",	0.5},
-	{35,	"Trans Teal",	"#008080",	0.5},
-	{36,	"Trans Red",	"#C00000",	0.5},
-	{37,	"Trans Dk Pink",	"#C00060",	0.5},
-	{38,	"Trans Brown",	"#604000",	0.5},
-	{39,	"Trans Gray",	"#989890",	0.5},
-	{40,	"Smoke",		"#6E6D62",	0.5},
-	{41,	"Trans Lt Blue",	"#60A0C0",	0.5},
-	{42,	"Trans Bt Green",	"#40C040",	0.5},
-	{43,	"Trans Cyan",	"#00FFFF",	0.5},
-	{44,	"Trans Salmon",	"#FF8080",	0.5},
-	{45,	"Trans Pink",	"#FF2080",	0.5},
-	{46,	"Trans Yellow",	"#FFEE00",	0.5},
-	{47,	"Clear",		"#FFFFFF",	0.5},
-	{71,	"Medium Stone",	"#A0A0AA",	1.0},
-	{72,	"Dark Stone",	"#60606A",	1.0},
-	{79,	"Ghost White",	"#FFFFFF",	0.875},
-	{294,	"Trans Phosphorus",	"#E0FFB0",	0.6},
-	{378,	"Sand Green",	"#80A080",	1.0},
-	{511,	"Rubber White",	"#F8F8F8",	1.0},
-};
+#include "file.h"
+#include "misc.h"
+#include <qcolor.h>
 
 static color* g_LDColors[MAX_COLORS];
 static bool g_bColorsInit = false;
@@ -79,15 +29,19 @@
 	if (g_bColorsInit)
 		return;
 	
-	memset (g_LDColors, 0, sizeof g_LDColors);
-	for (ulong i = 0; i < sizeof g_LDColorInfo / sizeof *g_LDColorInfo; ++i) {
-		color* col = new color;
-		col->zColor = g_LDColorInfo[i].sColor;
-		col->zName = g_LDColorInfo[i].sName;
-		col->fAlpha = g_LDColorInfo[i].fAlpha;
-		
-		g_LDColors[g_LDColorInfo[i].dIndex] = col;
-	}
+	// Always make sure there's 16 and 24 available. They're special like that.
+	color* maincolor = new color;
+	maincolor->zColorString = "#AAAAAA";
+	maincolor->qColor = maincolor->zColorString.chars();
+	maincolor->qEdge = "#000000";
+	g_LDColors[dMainColor] = maincolor;
+	
+	color* edgecolor = new color;
+	edgecolor->zColorString = "#000000";
+	edgecolor->qEdge = edgecolor->qColor = edgecolor->zColorString.chars();
+	g_LDColors[dEdgeColor] = edgecolor;
+	
+	parseLDConfig ();
 	
 	g_bColorsInit = true;
 }
@@ -101,4 +55,94 @@
 		return nullptr;
 	
 	return g_LDColors[dColorNum];
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+static bool parseLDConfigTag (stringparser& pars, char const* sTag, str& zVal) {
+	short dPos;
+	if (!pars.findToken (dPos, sTag, 1))
+		return false;
+	
+	return pars.getToken (zVal, dPos + 1);
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void parseLDConfig () {
+	FILE* fp = openLDrawFile ("LDConfig.ldr", false);
+	
+	if (!fp)
+		return;
+	
+	// Even though LDConfig.ldr is technically an LDraw file, parsing it as one
+	// would be overkill by any standard.
+	char line[1024];
+	while (fgets (line, sizeof line, fp)) {
+		if (strlen (line) == 0 || line[0] != '0')
+			continue; // empty or illogical
+		
+		str zLine = line;
+		zLine.replace ("\n", "");
+		zLine.replace ("\r", "");
+		
+		stringparser pars (zLine, ' ');
+		short dCode = 0, dAlpha = 255;
+		str zName, zColor, zEdge, zValue;
+		
+		// Check 0 !COLOUR, parse the name
+		if (!pars.tokenCompare (0, "0") || !pars.tokenCompare (1, "!COLOUR") || !pars.getToken (zName, 2))
+			continue;
+		
+		// Replace underscores in the name with spaces for readability
+		zName.replace ("_", " ");
+		
+		// get the CODE tag
+		if (!parseLDConfigTag (pars, "CODE", zValue))
+			continue;
+		
+		// Ensure that the code is within range. must be within 0 - 512
+		dCode = atoi (zValue);
+		if (dCode < 0 || dCode >= 512)
+			continue;
+		
+		// Don't let LDConfig.ldr override the special colors 16 and 24. However,
+		// do take the name it gives for the color
+		if (dCode == dMainColor || dCode == dEdgeColor) {
+			g_LDColors[dCode]->zName = zName;
+			continue;
+		}
+		
+		// VALUE tag
+		if (!parseLDConfigTag (pars, "VALUE", zColor))
+			continue;
+		
+		// EDGE tag
+		if (!parseLDConfigTag (pars, "EDGE", zEdge))
+			continue;
+		
+		// Ensure that our colors are correct
+		QColor qColor (zColor.chars()),
+			qEdge (zEdge.chars());
+		
+		if (!qColor.isValid () || !qEdge.isValid ())
+			continue;
+		
+		// Parse alpha if given.
+		if (parseLDConfigTag (pars, "ALPHA", zValue))
+			dAlpha = clamp<short> (atoi (zValue), 0, 255);
+		
+		color* col = new color;
+		col->zName = zName;
+		col->qColor = qColor;
+		col->qEdge = qEdge;
+		col->zColorString = zColor;
+		col->qColor.setAlpha (dAlpha);
+		
+		g_LDColors[dCode] = col;
+	}
+	
+	fclose (fp);
 }
\ No newline at end of file
--- a/colors.h	Mon Mar 25 22:52:53 2013 +0200
+++ b/colors.h	Wed Mar 27 11:24:16 2013 +0200
@@ -19,15 +19,15 @@
 #ifndef __COLORS_H__
 #define __COLORS_H__
 
+#include <qcolor.h>
 #include "common.h"
 
 #define MAX_COLORS 512
 
 class color {
 public:
-	str zName;
-	str zColor;
-	float fAlpha;
+	str zName, zColorString;
+	QColor qColor, qEdge;
 };
 
 typedef struct {
@@ -37,6 +37,7 @@
 } TemporaryColorMeta;
 
 void initColors ();
+void parseLDConfig ();
 
 // Safely gets a color with the given number or nullptr if no such color.
 color* getColor (short dColorNum);
--- a/file.cpp	Mon Mar 25 22:52:53 2013 +0200
+++ b/file.cpp	Wed Mar 27 11:24:16 2013 +0200
@@ -41,35 +41,61 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
+FILE* openLDrawFile (str path, bool bSubDirectories) {
+	str zTruePath = path;
+	
+#ifndef WIN32
+	zTruePath.replace ("\\", "/");
+#endif // WIN32
+	
+	FILE* fp = fopen (path.chars (), "r");
+	str zFilePath;
+	
+	if (fp != nullptr)
+		return fp;
+	
+	if (~io_ldpath.value) {
+		// Try with just the LDraw path first
+		zFilePath = str::mkfmt ("%s" DIRSLASH "%s",
+			io_ldpath.value.chars(), zTruePath.chars());
+		printf ("try %s\n", zFilePath.chars());
+		
+		fp = fopen (zFilePath, "r");
+		if (fp != nullptr)
+			return fp;
+		
+		if (bSubDirectories) {
+			char const* saSubdirectories[] = {
+				"parts",
+				"p",
+			};
+			
+			for (char const* sSubdir : saSubdirectories) {
+				zFilePath = str::mkfmt ("%s" DIRSLASH "%s" DIRSLASH "%s",
+					io_ldpath.value.chars(), sSubdir, zTruePath.chars());
+				printf ("try %s\n", zFilePath.chars());
+				
+				fp = fopen (zFilePath.chars (), "r");
+				
+				if (fp)
+					return fp;
+			}
+		}
+	}
+	
+	return nullptr;
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 OpenFile* openDATFile (str path) {
 	logf ("Opening %s...\n", path.chars());
 	
 	// Convert the file name to lowercase since some parts contain uppercase
 	// file names. I'll assume here that the library will always use lowercase
 	// file names for the actual parts..
-	str zTruePath = -path;
-#ifndef WIN32
-	zTruePath.replace ("\\", "/");
-#endif // WIN32
-	
-	FILE* fp = fopen (path.chars (), "r");
-	
-	if (!fp && ~io_ldpath.value) {
-		char const* saSubdirectories[] = {
-			"parts",
-			"p",
-		};
-		
-		for (char const* sSubdir : saSubdirectories) {
-			str zFilePath = str::mkfmt ("%s" DIRSLASH "%s" DIRSLASH "%s",
-				io_ldpath.value.chars(), sSubdir, zTruePath.chars());
-			
-			fp = fopen (zFilePath.chars (), "r");
-			
-			if (fp)
-				break;
-		}
-	}
+	FILE* fp = openLDrawFile (-path, true);
 	
 	if (!fp) {
 		logf (LOG_Error, "Couldn't open %s: %s\n", path.chars (), strerror (errno));
--- a/file.h	Mon Mar 25 22:52:53 2013 +0200
+++ b/file.h	Wed Mar 27 11:24:16 2013 +0200
@@ -61,6 +61,9 @@
 // to the opened file or nullptr on error.
 OpenFile* openDATFile (str path);
 
+// Opens the given file and returns a pointer to it, potentially looking in /parts and /p
+FILE* openLDrawFile (str path, bool bSubDirectories);
+
 // Close all open files, whether user-opened or subfile caches.
 void closeAll ();
 
--- a/gldraw.cpp	Mon Mar 25 22:52:53 2013 +0200
+++ b/gldraw.cpp	Wed Mar 27 11:24:16 2013 +0200
@@ -139,19 +139,16 @@
 			if (obj->dColor == i)
 				return;
 		
-		printf ("%s: Unknown color %d!\n", __func__, obj->dColor);
+		printf ("setObjectColor Unknown color %d!\n", obj->dColor);
 		g_daWarnedColors.push_back (obj->dColor);
 		return;
 	}
 	
-	QColor qCol (col->zColor.chars());
-	
-	if (qCol.isValid ())
-		glColor4f (
-			((double)qCol.red()) / 255.0f,
-			((double)qCol.green()) / 255.0f,
-			((double)qCol.blue()) / 255.0f,
-			col->fAlpha);
+	glColor4f (
+		((double)col->qColor.red()) / 255.0f,
+		((double)col->qColor.green()) / 255.0f,
+		((double)col->qColor.blue()) / 255.0f,
+		((double)col->qColor.alpha()) / 255.0f);
 }
 
 // =============================================================================
--- a/gui.cpp	Mon Mar 25 22:52:53 2013 +0200
+++ b/gui.cpp	Wed Mar 27 11:24:16 2013 +0200
@@ -507,7 +507,6 @@
 void ForgeWindow::slot_makeBorders () {
 	vector<LDObject*> objs = getSelectedObjects ();
 	
-	// Delete the objects that were being selected
 	for (LDObject* obj : objs) {
 		if (obj->getType() != OBJ_Quad && obj->getType() != OBJ_Triangle)
 			continue;
@@ -667,7 +666,7 @@
 			// list entry in said color.
 			color* col = getColor (obj->dColor);
 			if (col)
-				item->setForeground (0, QColor (col->zColor.chars()));
+				item->setForeground (0, col->qColor);
 		}
 		
 		obj->qObjListEntry = item;
--- a/misc.cpp	Mon Mar 25 22:52:53 2013 +0200
+++ b/misc.cpp	Wed Mar 27 11:24:16 2013 +0200
@@ -19,6 +19,7 @@
 #include <math.h>
 #include <locale.h>
 #include "common.h"
+#include "misc.h"
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -85,4 +86,77 @@
 	}
 	
 	return true;
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+stringparser::stringparser (str zInText, char cSeparator) {
+	zaTokens = zInText.split (cSeparator, true);
+	dPos = -1;
+}
+
+// -----------------------------------------------------------------------------
+bool stringparser::atBeginning () {
+	return (dPos == -1);
+}
+
+// -----------------------------------------------------------------------------
+bool stringparser::atEnd () {
+	return (dPos == zaTokens.size() - 1);
+}
+
+// -----------------------------------------------------------------------------
+bool stringparser::getToken (str& zVal, const ushort uInPos) {
+	if (uInPos < 0 || uInPos >= zaTokens.size())
+		return false;
+	
+	zVal = zaTokens[uInPos];
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+bool stringparser::next (str& zVal) {
+	return getToken (zVal, ++dPos);
+}
+
+// -----------------------------------------------------------------------------
+bool stringparser::peekNext (str& zVal) {
+	return getToken (zVal, dPos + 1);
+}
+
+// -----------------------------------------------------------------------------
+bool stringparser::findToken (short& dResult, char const* sNeedle, short dArgs) {
+	for (short i = 0; i < (zaTokens.size() - dArgs); ++i) {
+		if (zaTokens[i] == sNeedle) {
+			dResult = i;
+			return true;
+		}
+	}
+	
+	return false;
+}
+
+// -----------------------------------------------------------------------------
+void stringparser::rewind () {
+	dPos = -1;
+}
+
+// -----------------------------------------------------------------------------
+void stringparser::seek (short int dAmount, bool bRelative) {
+	dPos = (bRelative ? dPos : 0) + dAmount;
+}
+
+// -----------------------------------------------------------------------------
+size_t stringparser::size () {
+	return zaTokens.size();
+}
+
+// -----------------------------------------------------------------------------
+bool stringparser::tokenCompare (short int dInPos, const char* sOther) {
+	str tok;
+	if (!getToken (tok, dInPos))
+		return false;
+	
+	return (tok == sOther);
 }
\ No newline at end of file
--- a/misc.h	Mon Mar 25 22:52:53 2013 +0200
+++ b/misc.h	Wed Mar 27 11:24:16 2013 +0200
@@ -43,4 +43,32 @@
 	return false;
 }
 
+// =============================================================================
+// stringparser
+//
+// String parsing utility
+// =============================================================================
+class stringparser {
+public:
+	std::vector<str> zaTokens;
+	short dPos;
+	
+	stringparser (str zInText, char cSeparator);
+	
+	bool atEnd ();
+	bool atBeginning ();
+	bool next (str& zVal);
+	bool peekNext (str& zVal);
+	bool getToken (str& zVal, const ushort uInPos);
+	bool findToken (short& dResult, char const* sNeedle, short dArgs);
+	size_t size ();
+	void rewind ();
+	void seek (short dAmount, bool bRelative);
+	bool tokenCompare (short int dInPos, const char* sOther);
+	
+	str operator[] (const size_t uIndex) {
+		return zaTokens[uIndex];
+	}
+};
+
 #endif // __MISC_H__
\ No newline at end of file
--- a/zz_addObjectDialog.cpp	Mon Mar 25 22:52:53 2013 +0200
+++ b/zz_addObjectDialog.cpp	Wed Mar 27 11:24:16 2013 +0200
@@ -81,7 +81,7 @@
 		dColor = (type == OBJ_CondLine || type == OBJ_Line) ? dEdgeColor : dMainColor;
 		
 		qColorButton = new QPushButton;
-		setButtonBackground (qColorButton, getColor (dColor)->zColor);
+		setButtonBackground (qColorButton, dColor);
 		connect (qColorButton, SIGNAL (clicked ()), this, SLOT (slot_colorButtonClicked ()));
 	}
 	
@@ -128,11 +128,11 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void AddObjectDialog::setButtonBackground (QPushButton* qButton, str zValue) {
+void AddObjectDialog::setButtonBackground (QPushButton* qButton, short dColor) {
 	qButton->setIcon (QIcon ("icons/palette.png"));
 	qButton->setAutoFillBackground (true);
 	qButton->setStyleSheet (
-		str::mkfmt ("background-color: %s", zValue.chars()).chars()
+		str::mkfmt ("background-color: %s", getColor (dColor)->zColorString.chars()).chars()
 	);
 }
 
@@ -141,7 +141,7 @@
 // =============================================================================
 void AddObjectDialog::slot_colorButtonClicked () {
 	ColorSelectDialog::staticDialog (dColor, dColor, this);
-	setButtonBackground (qColorButton, getColor (dColor)->zColor);
+	setButtonBackground (qColorButton, dColor);
 }
 
 // =============================================================================
--- a/zz_addObjectDialog.h	Mon Mar 25 22:52:53 2013 +0200
+++ b/zz_addObjectDialog.h	Wed Mar 27 11:24:16 2013 +0200
@@ -48,7 +48,7 @@
 	QDialogButtonBox* qButtons;
 	
 private:
-	void setButtonBackground (QPushButton* qButton, str zValue);
+	void setButtonBackground (QPushButton* qButton, short dColor);
 	
 	short dColor;
 	
--- a/zz_colorSelectDialog.cpp	Mon Mar 25 22:52:53 2013 +0200
+++ b/zz_colorSelectDialog.cpp	Wed Mar 27 11:24:16 2013 +0200
@@ -78,14 +78,11 @@
 	qColorInfo = new QLabel;
 	drawColorInfo ();
 	
-	QHBoxLayout* qLayout = new QHBoxLayout;
+	QVBoxLayout* qLayout = new QVBoxLayout;
+	qLayout->addWidget (qView);
 	qLayout->addWidget (qColorInfo);
 	qLayout->addWidget (qButtons);
-	
-	QVBoxLayout* qLayout2 = new QVBoxLayout;
-	qLayout2->addWidget (qView);
-	qLayout2->addLayout (qLayout);
-	setLayout (qLayout2);
+	setLayout (qLayout);
 	
 	setWindowIcon (QIcon ("icons/palette.png"));
 	setWindowTitle (APPNAME_DISPLAY " - choose a color");
@@ -109,15 +106,12 @@
 		const double y = (i / g_dNumColumns) * g_dSquareSize;
 		const double w = (g_dSquareSize) - (fPenWidth / 2);
 		
-		QColor qColor;
+		QColor qColor = meta->qColor;
 		
 		if (i == dMainColor) {
 			// Use the user preferences for main color here
 			qColor = gl_maincolor.value.chars ();
 			qColor.setAlpha (gl_maincolor_alpha * 255.0f);
-		} else {
-			qColor = meta->zColor.chars ();
-			qColor.setAlpha (meta->fAlpha * 255.0f);
 		}
 		
 		uchar ucLuma = (0.2126f * qColor.red()) +

mercurial