Renamed io.cpp to file.cpp, draw.cpp to gldraw.cpp

Mon, 18 Mar 2013 12:20:48 +0200

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Mon, 18 Mar 2013 12:20:48 +0200
changeset 26
83184d9407c7
parent 25
c74bb88f537d
child 27
2ba799d294bc

Renamed io.cpp to file.cpp, draw.cpp to gldraw.cpp

bbox.cpp file | annotate | diff | comparison | revisions
draw.cpp file | annotate | diff | comparison | revisions
draw.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
gldraw.h file | annotate | diff | comparison | revisions
gui.cpp file | annotate | diff | comparison | revisions
gui.h file | annotate | diff | comparison | revisions
io.cpp file | annotate | diff | comparison | revisions
io.h file | annotate | diff | comparison | revisions
ldtypes.cpp file | annotate | diff | comparison | revisions
main.cpp file | annotate | diff | comparison | revisions
zz_setContentsDialog.cpp file | annotate | diff | comparison | revisions
--- a/bbox.cpp	Mon Mar 18 12:15:23 2013 +0200
+++ b/bbox.cpp	Mon Mar 18 12:20:48 2013 +0200
@@ -1,7 +1,7 @@
 #include "common.h"
 #include "bbox.h"
 #include "ldtypes.h"
-#include "io.h"
+#include "file.h"
 
 void bbox::calculate () {
 	if (!g_CurrentFile)
--- a/draw.cpp	Mon Mar 18 12:15:23 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-#include <QtGui>
-#include <QGLWidget>
-#include "common.h"
-#include "io.h"
-#include "draw.h"
-#include "bbox.h"
-
-renderer::renderer (QWidget* parent) {
-	parent = parent; // shhh, GCC
-	fRotX = fRotY = fRotZ = 0.0;
-	fZoom = 1.0;
-}
-
-void renderer::initializeGL () {
-	glLoadIdentity();
-	glMatrixMode (GL_MODELVIEW);
-	glClearColor (0.8f, 0.8f, 0.85f, 1.0f);
-	glEnable (GL_DEPTH_TEST);
-	glShadeModel (GL_SMOOTH);
-	glEnable (GL_MULTISAMPLE);
-	
-	CompileObjects ();
-}
-
-void renderer::hardRefresh () {
-	CompileObjects ();
-	paintGL ();
-}
-
-void renderer::resizeGL (int w, int h) {
-	glViewport (0, 0, w, h);
-}
-
-void renderer::paintGL () {
-	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-	
-	glPushMatrix ();
-		glTranslatef (
-			(g_BBox.v0.x + g_BBox.v1.x) / -2.0,
-			(g_BBox.v0.y + g_BBox.v1.y) / -2.0,
-			(g_BBox.v0.z + g_BBox.v1.z) / -2.0
-		);
-		
-		// glTranslatef (0.0f, 0.0f, -5.0f);
-		glTranslatef (0.0f, 0.0f, fZoom);
-		
-		// glScalef (0.75f, 1.15f, 0.0f);
-		glRotatef (fRotX, 1.0f, 0.0f, 0.0f);
-		glRotatef (fRotY, 0.0f, 1.0f, 0.0f);
-		glRotatef (fRotZ, 0.0f, 0.0f, 1.0f);
-		
-		glMatrixMode (GL_MODELVIEW);
-		
-		glCallList (objlist);
-		glColor3f (0.0, 0.5, 1.0);
-	glPopMatrix ();
-}
-
-void renderer::CompileObjects () {
-	printf ("compile all objects\n");
-	
-	objlist = glGenLists (1);
-	glNewList (objlist, GL_COMPILE);
-	
-	if (!g_CurrentFile) {
-		printf ("renderer: no files loaded, cannot compile anything\n");
-		return;
-	}
-	
-	for (ulong i = 0; i < g_CurrentFile->objects.size(); i++)
-		CompileOneObject (g_CurrentFile->objects[i]);
-	
-	glEndList ();
-}
-
-#define GL_VERTEX(V) \
-	glVertex3d (V.x, V.y, V.z);
-
-void renderer::CompileOneObject (LDObject* obj) {
-	if (!obj)
-		return;
-	
-	switch (obj->getType ()) {
-	case OBJ_CondLine: // For now, treat condlines like normal lines.
-	case OBJ_Line:
-		{
-			glColor3f (0.0f, 0.0f, 0.0f); // Draw all lines black for now
-			// draw lines
-			LDLine* line = static_cast<LDLine*> (obj);
-			glBegin (GL_LINES);
-			for (short i = 0; i < 2; ++i)
-				GL_VERTEX (line->vaCoords[i])
-			glEnd ();
-		}
-		break;
-	
-	case OBJ_Triangle:
-		{
-			LDTriangle* tri = static_cast<LDTriangle*> (obj);
-			glColor3f (0.5f, 0.5f, 0.5f); // Draw all polygons gray for now
-			glBegin (GL_TRIANGLES);
-			for (short i = 0; i < 3; ++i)
-				GL_VERTEX (tri->vaCoords[i])
-			glEnd ();
-		}
-		break;
-		
-	case OBJ_Quad:
-		{
-			LDQuad* quad = static_cast<LDQuad*> (obj);
-			glColor3f (0.5f, 0.5f, 0.5f);
-			glBegin (GL_QUADS);
-			for (short i = 0; i < 4; ++i)
-				GL_VERTEX (quad->vaCoords[i])
-			glEnd ();
-		}
-		break;
-	
-	default:
-		break;
-	}
-}
-
-void renderer::ClampAngle (double& fAngle) {
-	while (fAngle < 0)
-		fAngle += 360.0;
-	while (fAngle > 360.0)
-		fAngle -= 360.0;
-}
-
-void renderer::mouseMoveEvent (QMouseEvent *event) {
-	int dx = event->x () - lastPos.x ();
-	int dy = event->y () - lastPos.y ();
-	
-	if (event->buttons () & Qt::LeftButton) {
-		fRotX = fRotX + (dy);
-		fRotY = fRotY + (dx);
-		ClampAngle (fRotX);
-		ClampAngle (fRotY);
-	}
-	
-	if (event->buttons () & Qt::RightButton) {
-		fRotX = fRotX + (dy);
-		fRotZ = fRotZ + (dx);
-		ClampAngle (fRotX);
-		ClampAngle (fRotZ);
-	}
-	
-	if (event->buttons () & Qt::MidButton) {
-		fZoom += (dy / 100.0);
-		fZoom = clamp (fZoom, 0.1, 10.0);
-	}
-	
-	printf ("%.3f %.3f %.3f %.3f\n",
-		fRotX, fRotY, fRotZ, fZoom);
-	lastPos = event->pos();
-	updateGL ();
-}
\ No newline at end of file
--- a/draw.h	Mon Mar 18 12:15:23 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#ifndef __REND_H__
-#define __REND_H__
-
-#include <QGLWidget>
-#include "common.h"
-#include "ldtypes.h"
-
-class renderer : public QGLWidget {
-	Q_OBJECT
-	
-public:
-	renderer(QWidget* parent = NULL);
-	void hardRefresh ();
-	void CompileObjects ();
-	double fRotX, fRotY, fRotZ;
-	QPoint lastPos;
-	double fZoom;
-
-protected:
-	void initializeGL ();
-	void resizeGL (int w, int h);
-	void paintGL ();
-	
-	void mouseMoveEvent (QMouseEvent *event);
-
-private:
-	GLuint objlist;
-	void CompileOneObject (LDObject* obj);
-	void ClampAngle (double& fAngle);
-};
-
-#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/file.cpp	Mon Mar 18 12:20:48 2013 +0200
@@ -0,0 +1,312 @@
+#include <vector>
+
+#include "common.h"
+#include "file.h"
+#include "misc.h"
+#include "bbox.h"
+#include "gui.h"
+
+vector<str> g_zaFileLoadPaths;
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+OpenFile* findLoadedFile (str name) {
+	for (ulong i = 0; i < g_LoadedFiles.size(); i++) {
+		OpenFile* const file = g_LoadedFiles[i];
+		if (file->zFileName == name)
+			return file;
+	}
+	
+	return nullptr;
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+OpenFile* openDATFile (str path) {
+	logf ("Opening %s...\n", path.chars());
+	
+	FILE* fp = fopen (path.chars (), "r");
+	
+	if (!fp) {
+		for (ushort i = 0; i < g_zaFileLoadPaths.size(); ++i) {
+			str zFilePath = str::mkfmt ("%s/%s", g_zaFileLoadPaths[i].chars(), path.chars());
+			fp = fopen (zFilePath.chars (), "r");
+			
+			if (fp)
+				break;
+		}
+	}
+	
+	if (!fp) {
+		logf (LOG_Error, "Couldn't open %s: %s\n", path.chars (), strerror (errno));
+		return nullptr;
+	}
+	
+	OpenFile* load = new OpenFile;
+	ulong numWarnings = 0;
+	
+	load->zFileName = path;
+	
+	vector<str> lines;
+	
+	{
+		char line[1024];
+		while (fgets (line, sizeof line, fp)) {
+			// Trim the trailing newline
+			str zLine = line;
+			while (zLine[~zLine - 1] == '\n' || zLine[~zLine - 1] == '\r')
+				zLine -= 1;
+			
+			lines.push_back (zLine);
+		}
+	}
+	
+	fclose (fp);
+	
+	for (ulong i = 0; i < lines.size(); ++i) {
+		LDObject* obj = parseLine (lines[i]);
+		load->objects.push_back (obj);
+		
+		// Check for parse errors and warn abotu tthem
+		if (obj->getType() == OBJ_Gibberish) {
+			logf (LOG_Warning, "Couldn't parse line #%lu: %s\n",
+				i, static_cast<LDGibberish*> (obj)->zReason.chars());
+			logf (LOG_Warning, "- Line was: %s\n", lines[i].chars());
+			numWarnings++;
+		}
+	}
+	
+	g_LoadedFiles.push_back (load);
+	
+	logf (LOG_Success, "File %s parsed successfully (%lu warning%s).\n",
+		path.chars(), numWarnings, PLURAL (numWarnings));
+	
+	return load;
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+// Clear everything from the model
+void OpenFile::close () {
+	for (ulong j = 0; j < objects.size(); ++j)
+		delete objects[j];
+	
+	delete this;
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void closeAll () {
+	if (!g_LoadedFiles.size())
+		return;
+	
+	// Remove all loaded files and the objects they contain
+	for (ushort i = 0; i < g_LoadedFiles.size(); i++) {
+		OpenFile* f = g_LoadedFiles[i];
+		f->close ();
+	}
+	
+	// Clear the array
+	g_LoadedFiles.clear();
+	g_CurrentFile = NULL;
+	
+	g_qWindow->R->hardRefresh();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void newFile () {
+	// Create a new anonymous file and set it to our current
+	closeAll ();
+	
+	OpenFile* f = new OpenFile;
+	f->zFileName = "";
+	g_LoadedFiles.push_back (f);
+	g_CurrentFile = f;
+	
+	g_BBox.calculate();
+	g_qWindow->buildObjList ();
+	g_qWindow->R->hardRefresh();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void openMainFile (str zPath) {
+	closeAll ();
+	
+	OpenFile* pFile = openDATFile (zPath);
+	g_CurrentFile = pFile;
+	
+	// Recalculate the bounding box
+	g_BBox.calculate();
+	
+	// Rebuild the object tree view now.
+	g_qWindow->buildObjList ();
+	g_qWindow->setTitle ();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void OpenFile::save (str zPath) {
+	if (!~zPath)
+		zPath = zFileName;
+	
+	FILE* fp = fopen (zPath, "w");
+	if (!fp)
+		return;
+	
+	// Write all entries now
+	for (ulong i = 0; i < objects.size(); ++i) {
+		LDObject* obj = objects[i];
+		
+		// LDraw requires lines to have DOS line endings
+		str zLine = str::mkfmt ("%s\r\n",obj->getContents ().chars ());
+		
+		fwrite (zLine.chars(), 1, ~zLine, fp);
+	}
+	
+	fclose (fp);
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+#define CHECK_TOKEN_COUNT(N) \
+	if (tokens.size() != N) \
+		return new LDGibberish (zLine, "Bad amount of tokens");
+
+#define CHECK_TOKEN_NUMBERS(MIN,MAX) \
+	for (ushort i = MIN; i <= MAX; ++i) \
+		if (!isNumber (tokens[i])) \
+			return new LDGibberish (zLine, str::mkfmt ("Token #%u was `%s`, expected a number", \
+				(i + 1), tokens[i].chars()));
+
+LDObject* parseLine (str zLine) {
+	str zNoWhitespace = zLine;
+	stripWhitespace (zNoWhitespace);
+	if (!~zNoWhitespace) {
+		// Line was empty, or only consisted of whitespace
+		return new LDEmpty;
+	}
+	
+	vector<str> tokens = zLine / " ";
+	
+	// Rid leading all-whitespace tokens
+	while (tokens.size() && !(~tokens[0]))
+		tokens.erase (tokens.begin());
+	
+	if (~tokens[0] != 1)
+		return new LDGibberish (zLine, "Illogical line code");
+	
+	char const c = tokens[0][0];
+	switch (c - '0') {
+	case 0:
+		{
+			// Comment
+			LDComment* obj = new LDComment;
+			obj->zText = zLine.substr (2, -1);
+			return obj;
+		}
+	
+	case 1:
+		{
+			// Subfile
+			CHECK_TOKEN_COUNT (15)
+			CHECK_TOKEN_NUMBERS (1, 13)
+			
+#ifndef WIN32
+			tokens[14].replace ("\\", "/");
+#endif // WIN32
+			
+			// Try open the file
+			OpenFile* pFile = findLoadedFile (tokens[14]);
+			if (!pFile)
+				pFile = openDATFile (tokens[14]);
+			
+			// If we cannot open the file, mark it an error
+			if (!pFile)
+				return new LDGibberish (zLine, "Could not open referred file");
+			
+			LDSubfile* obj = new LDSubfile;
+			obj->dColor = atoi (tokens[1]);
+			obj->vPosition = parseVertex (zLine, 2); // 2 - 4
+			
+			for (short i = 0; i < 9; ++i)
+				obj->faMatrix[i] = atof (tokens[i + 5]); // 5 - 13
+			
+			obj->zFileName = tokens[14];
+			obj->pFile = pFile;
+			return obj;
+		}
+	
+	case 2:
+		{
+			CHECK_TOKEN_COUNT (8)
+			CHECK_TOKEN_NUMBERS (1, 7)
+			
+			// Line
+			LDLine* obj = new LDLine;
+			obj->dColor = getWordInt (zLine, 1);
+			for (short i = 0; i < 2; ++i)
+				obj->vaCoords[i] = parseVertex (zLine, 2 + (i * 3)); // 2 - 7
+			return obj;
+		}
+	
+	case 3:
+		{
+			CHECK_TOKEN_COUNT (11)
+			CHECK_TOKEN_NUMBERS (1, 10)
+			
+			// Triangle
+			LDTriangle* obj = new LDTriangle;
+			obj->dColor = getWordInt (zLine, 1);
+			
+			for (short i = 0; i < 3; ++i)
+				obj->vaCoords[i] = parseVertex (zLine, 2 + (i * 3)); // 2 - 10
+			
+			return obj;
+		}
+	
+	case 4:
+		{
+			CHECK_TOKEN_COUNT (14)
+			CHECK_TOKEN_NUMBERS (1, 13)
+			
+			// Quadrilateral
+			LDQuad* obj = new LDQuad;
+			obj->dColor = getWordInt (zLine, 1);
+			
+			for (short i = 0; i < 4; ++i)
+				obj->vaCoords[i] = parseVertex (zLine, 2 + (i * 3)); // 2 - 13
+			
+			return obj;
+		}
+	
+	case 5:
+		{
+			CHECK_TOKEN_COUNT (14)
+			CHECK_TOKEN_NUMBERS (1, 13)
+			
+			// Conditional line
+			LDCondLine* obj = new LDCondLine;
+			obj->dColor = getWordInt (zLine, 1);
+			
+			for (short i = 0; i < 2; ++i)
+				obj->vaCoords[i] = parseVertex (zLine, 2 + (i * 3)); // 2 - 7
+			
+			for (short i = 0; i < 2; ++i)
+				obj->vaControl[i] = parseVertex (zLine, 8 + (i * 3)); // 8 - 13
+			return obj;
+		}
+		
+	default: // Strange line we couldn't parse
+		return new LDGibberish (zLine, "Unknown line code number");
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/file.h	Mon Mar 18 12:20:48 2013 +0200
@@ -0,0 +1,48 @@
+#ifndef __FILE_H__
+#define __FILE_H__
+
+#include "common.h"
+#include "ldtypes.h"
+#include "str.h"
+
+// =============================================================================
+// OpenFile
+//
+// The OpenFile class stores a file opened in LDForge either as a editable file
+// for the user or for subfile caching. Its methods handle file input and output.
+// =============================================================================
+class OpenFile {
+public:
+	str zFileName, zTitle;
+	vector<LDObject*> objects;
+	
+	// Closes this OpenFile. The object is deleted in the process.
+	void close ();
+	
+	// Saves this file to disk.
+	void save (str zPath = "");
+};
+
+// Close all current loaded files and start off blank.
+void newFile ();
+
+// Opens the given file as the main file. Everything is closed first.
+void openMainFile (str zPath);
+
+// Finds an OpenFile by name or nullptr if not open
+OpenFile* findLoadedFile (str name);
+
+// Opens the given file and parses the LDraw code within. Returns a pointer
+// to the opened file or nullptr on error.
+OpenFile* openDATFile (str path);
+
+// Close all open files, whether user-opened or subfile caches.
+void closeAll ();
+
+// Parses a string line containing an LDraw object and returns the object parsed.
+LDObject* parseLine (str zLine);
+
+extern vector<str> g_zaFileLoadPaths;
+extern vector<OpenFile*> g_LoadedFiles;
+
+#endif // __FILE_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gldraw.cpp	Mon Mar 18 12:20:48 2013 +0200
@@ -0,0 +1,158 @@
+#include <QtGui>
+#include <QGLWidget>
+#include "common.h"
+#include "file.h"
+#include "gldraw.h"
+#include "bbox.h"
+
+renderer::renderer (QWidget* parent) {
+	parent = parent; // shhh, GCC
+	fRotX = fRotY = fRotZ = 0.0;
+	fZoom = 1.0;
+}
+
+void renderer::initializeGL () {
+	glLoadIdentity();
+	glMatrixMode (GL_MODELVIEW);
+	glClearColor (0.8f, 0.8f, 0.85f, 1.0f);
+	glEnable (GL_DEPTH_TEST);
+	glShadeModel (GL_SMOOTH);
+	glEnable (GL_MULTISAMPLE);
+	
+	CompileObjects ();
+}
+
+void renderer::hardRefresh () {
+	CompileObjects ();
+	paintGL ();
+}
+
+void renderer::resizeGL (int w, int h) {
+	glViewport (0, 0, w, h);
+}
+
+void renderer::paintGL () {
+	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+	
+	glPushMatrix ();
+		glTranslatef (
+			(g_BBox.v0.x + g_BBox.v1.x) / -2.0,
+			(g_BBox.v0.y + g_BBox.v1.y) / -2.0,
+			(g_BBox.v0.z + g_BBox.v1.z) / -2.0
+		);
+		
+		// glTranslatef (0.0f, 0.0f, -5.0f);
+		glTranslatef (0.0f, 0.0f, fZoom);
+		
+		// glScalef (0.75f, 1.15f, 0.0f);
+		glRotatef (fRotX, 1.0f, 0.0f, 0.0f);
+		glRotatef (fRotY, 0.0f, 1.0f, 0.0f);
+		glRotatef (fRotZ, 0.0f, 0.0f, 1.0f);
+		
+		glMatrixMode (GL_MODELVIEW);
+		
+		glCallList (objlist);
+		glColor3f (0.0, 0.5, 1.0);
+	glPopMatrix ();
+}
+
+void renderer::CompileObjects () {
+	printf ("compile all objects\n");
+	
+	objlist = glGenLists (1);
+	glNewList (objlist, GL_COMPILE);
+	
+	if (!g_CurrentFile) {
+		printf ("renderer: no files loaded, cannot compile anything\n");
+		return;
+	}
+	
+	for (ulong i = 0; i < g_CurrentFile->objects.size(); i++)
+		CompileOneObject (g_CurrentFile->objects[i]);
+	
+	glEndList ();
+}
+
+#define GL_VERTEX(V) \
+	glVertex3d (V.x, V.y, V.z);
+
+void renderer::CompileOneObject (LDObject* obj) {
+	if (!obj)
+		return;
+	
+	switch (obj->getType ()) {
+	case OBJ_CondLine: // For now, treat condlines like normal lines.
+	case OBJ_Line:
+		{
+			glColor3f (0.0f, 0.0f, 0.0f); // Draw all lines black for now
+			// draw lines
+			LDLine* line = static_cast<LDLine*> (obj);
+			glBegin (GL_LINES);
+			for (short i = 0; i < 2; ++i)
+				GL_VERTEX (line->vaCoords[i])
+			glEnd ();
+		}
+		break;
+	
+	case OBJ_Triangle:
+		{
+			LDTriangle* tri = static_cast<LDTriangle*> (obj);
+			glColor3f (0.5f, 0.5f, 0.5f); // Draw all polygons gray for now
+			glBegin (GL_TRIANGLES);
+			for (short i = 0; i < 3; ++i)
+				GL_VERTEX (tri->vaCoords[i])
+			glEnd ();
+		}
+		break;
+		
+	case OBJ_Quad:
+		{
+			LDQuad* quad = static_cast<LDQuad*> (obj);
+			glColor3f (0.5f, 0.5f, 0.5f);
+			glBegin (GL_QUADS);
+			for (short i = 0; i < 4; ++i)
+				GL_VERTEX (quad->vaCoords[i])
+			glEnd ();
+		}
+		break;
+	
+	default:
+		break;
+	}
+}
+
+void renderer::ClampAngle (double& fAngle) {
+	while (fAngle < 0)
+		fAngle += 360.0;
+	while (fAngle > 360.0)
+		fAngle -= 360.0;
+}
+
+void renderer::mouseMoveEvent (QMouseEvent *event) {
+	int dx = event->x () - lastPos.x ();
+	int dy = event->y () - lastPos.y ();
+	
+	if (event->buttons () & Qt::LeftButton) {
+		fRotX = fRotX + (dy);
+		fRotY = fRotY + (dx);
+		ClampAngle (fRotX);
+		ClampAngle (fRotY);
+	}
+	
+	if (event->buttons () & Qt::RightButton) {
+		fRotX = fRotX + (dy);
+		fRotZ = fRotZ + (dx);
+		ClampAngle (fRotX);
+		ClampAngle (fRotZ);
+	}
+	
+	if (event->buttons () & Qt::MidButton) {
+		fZoom += (dy / 100.0);
+		fZoom = clamp (fZoom, 0.1, 10.0);
+	}
+	
+	printf ("%.3f %.3f %.3f %.3f\n",
+		fRotX, fRotY, fRotZ, fZoom);
+	lastPos = event->pos();
+	updateGL ();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gldraw.h	Mon Mar 18 12:20:48 2013 +0200
@@ -0,0 +1,32 @@
+#ifndef __GLDRAW_H__
+#define __GLDRAW_H__
+
+#include <QGLWidget>
+#include "common.h"
+#include "ldtypes.h"
+
+class renderer : public QGLWidget {
+	Q_OBJECT
+	
+public:
+	renderer(QWidget* parent = NULL);
+	void hardRefresh ();
+	void CompileObjects ();
+	double fRotX, fRotY, fRotZ;
+	QPoint lastPos;
+	double fZoom;
+
+protected:
+	void initializeGL ();
+	void resizeGL (int w, int h);
+	void paintGL ();
+	
+	void mouseMoveEvent (QMouseEvent *event);
+
+private:
+	GLuint objlist;
+	void CompileOneObject (LDObject* obj);
+	void ClampAngle (double& fAngle);
+};
+
+#endif // __GLDRAW_H__
\ No newline at end of file
--- a/gui.cpp	Mon Mar 18 12:15:23 2013 +0200
+++ b/gui.cpp	Mon Mar 18 12:20:48 2013 +0200
@@ -1,9 +1,9 @@
 #include <QtGui>
 
 #include "common.h"
-#include "draw.h"
+#include "gldraw.h"
 #include "gui.h"
-#include "io.h"
+#include "file.h"
 
 #include "zz_setContentsDialog.h"
 
--- a/gui.h	Mon Mar 18 12:15:23 2013 +0200
+++ b/gui.h	Mon Mar 18 12:20:48 2013 +0200
@@ -8,7 +8,7 @@
 #include <QTreeWidget>
 #include <QToolBar>
 #include <QTextEdit>
-#include "draw.h"
+#include "gldraw.h"
 
 class ForgeWindow : public QMainWindow {
 	Q_OBJECT
--- a/io.cpp	Mon Mar 18 12:15:23 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,312 +0,0 @@
-#include <vector>
-
-#include "common.h"
-#include "io.h"
-#include "misc.h"
-#include "bbox.h"
-#include "gui.h"
-
-vector<str> g_zaFileLoadPaths;
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-OpenFile* findLoadedFile (str name) {
-	for (ulong i = 0; i < g_LoadedFiles.size(); i++) {
-		OpenFile* const file = g_LoadedFiles[i];
-		if (file->zFileName == name)
-			return file;
-	}
-	
-	return nullptr;
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-OpenFile* openDATFile (str path) {
-	logf ("Opening %s...\n", path.chars());
-	
-	FILE* fp = fopen (path.chars (), "r");
-	
-	if (!fp) {
-		for (ushort i = 0; i < g_zaFileLoadPaths.size(); ++i) {
-			str zFilePath = str::mkfmt ("%s/%s", g_zaFileLoadPaths[i].chars(), path.chars());
-			fp = fopen (zFilePath.chars (), "r");
-			
-			if (fp)
-				break;
-		}
-	}
-	
-	if (!fp) {
-		logf (LOG_Error, "Couldn't open %s: %s\n", path.chars (), strerror (errno));
-		return nullptr;
-	}
-	
-	OpenFile* load = new OpenFile;
-	ulong numWarnings = 0;
-	
-	load->zFileName = path;
-	
-	vector<str> lines;
-	
-	{
-		char line[1024];
-		while (fgets (line, sizeof line, fp)) {
-			// Trim the trailing newline
-			str zLine = line;
-			while (zLine[~zLine - 1] == '\n' || zLine[~zLine - 1] == '\r')
-				zLine -= 1;
-			
-			lines.push_back (zLine);
-		}
-	}
-	
-	fclose (fp);
-	
-	for (ulong i = 0; i < lines.size(); ++i) {
-		LDObject* obj = parseLine (lines[i]);
-		load->objects.push_back (obj);
-		
-		// Check for parse errors and warn abotu tthem
-		if (obj->getType() == OBJ_Gibberish) {
-			logf (LOG_Warning, "Couldn't parse line #%lu: %s\n",
-				i, static_cast<LDGibberish*> (obj)->zReason.chars());
-			logf (LOG_Warning, "- Line was: %s\n", lines[i].chars());
-			numWarnings++;
-		}
-	}
-	
-	g_LoadedFiles.push_back (load);
-	
-	logf (LOG_Success, "File %s parsed successfully (%lu warning%s).\n",
-		path.chars(), numWarnings, PLURAL (numWarnings));
-	
-	return load;
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-// Clear everything from the model
-void OpenFile::close () {
-	for (ulong j = 0; j < objects.size(); ++j)
-		delete objects[j];
-	
-	delete this;
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void closeAll () {
-	if (!g_LoadedFiles.size())
-		return;
-	
-	// Remove all loaded files and the objects they contain
-	for (ushort i = 0; i < g_LoadedFiles.size(); i++) {
-		OpenFile* f = g_LoadedFiles[i];
-		f->close ();
-	}
-	
-	// Clear the array
-	g_LoadedFiles.clear();
-	g_CurrentFile = NULL;
-	
-	g_qWindow->R->hardRefresh();
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void newFile () {
-	// Create a new anonymous file and set it to our current
-	closeAll ();
-	
-	OpenFile* f = new OpenFile;
-	f->zFileName = "";
-	g_LoadedFiles.push_back (f);
-	g_CurrentFile = f;
-	
-	g_BBox.calculate();
-	g_qWindow->buildObjList ();
-	g_qWindow->R->hardRefresh();
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void openMainFile (str zPath) {
-	closeAll ();
-	
-	OpenFile* pFile = openDATFile (zPath);
-	g_CurrentFile = pFile;
-	
-	// Recalculate the bounding box
-	g_BBox.calculate();
-	
-	// Rebuild the object tree view now.
-	g_qWindow->buildObjList ();
-	g_qWindow->setTitle ();
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void OpenFile::save (str zPath) {
-	if (!~zPath)
-		zPath = zFileName;
-	
-	FILE* fp = fopen (zPath, "w");
-	if (!fp)
-		return;
-	
-	// Write all entries now
-	for (ulong i = 0; i < objects.size(); ++i) {
-		LDObject* obj = objects[i];
-		
-		// LDraw requires lines to have DOS line endings
-		str zLine = str::mkfmt ("%s\r\n",obj->getContents ().chars ());
-		
-		fwrite (zLine.chars(), 1, ~zLine, fp);
-	}
-	
-	fclose (fp);
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-#define CHECK_TOKEN_COUNT(N) \
-	if (tokens.size() != N) \
-		return new LDGibberish (zLine, "Bad amount of tokens");
-
-#define CHECK_TOKEN_NUMBERS(MIN,MAX) \
-	for (ushort i = MIN; i <= MAX; ++i) \
-		if (!isNumber (tokens[i])) \
-			return new LDGibberish (zLine, str::mkfmt ("Token #%u was `%s`, expected a number", \
-				(i + 1), tokens[i].chars()));
-
-LDObject* parseLine (str zLine) {
-	str zNoWhitespace = zLine;
-	stripWhitespace (zNoWhitespace);
-	if (!~zNoWhitespace) {
-		// Line was empty, or only consisted of whitespace
-		return new LDEmpty;
-	}
-	
-	vector<str> tokens = zLine / " ";
-	
-	// Rid leading all-whitespace tokens
-	while (tokens.size() && !(~tokens[0]))
-		tokens.erase (tokens.begin());
-	
-	if (~tokens[0] != 1)
-		return new LDGibberish (zLine, "Illogical line code");
-	
-	char const c = tokens[0][0];
-	switch (c - '0') {
-	case 0:
-		{
-			// Comment
-			LDComment* obj = new LDComment;
-			obj->zText = zLine.substr (2, -1);
-			return obj;
-		}
-	
-	case 1:
-		{
-			// Subfile
-			CHECK_TOKEN_COUNT (15)
-			CHECK_TOKEN_NUMBERS (1, 13)
-			
-#ifndef WIN32
-			tokens[14].replace ("\\", "/");
-#endif // WIN32
-			
-			// Try open the file
-			OpenFile* pFile = findLoadedFile (tokens[14]);
-			if (!pFile)
-				pFile = openDATFile (tokens[14]);
-			
-			// If we cannot open the file, mark it an error
-			if (!pFile)
-				return new LDGibberish (zLine, "Could not open referred file");
-			
-			LDSubfile* obj = new LDSubfile;
-			obj->dColor = atoi (tokens[1]);
-			obj->vPosition = parseVertex (zLine, 2); // 2 - 4
-			
-			for (short i = 0; i < 9; ++i)
-				obj->faMatrix[i] = atof (tokens[i + 5]); // 5 - 13
-			
-			obj->zFileName = tokens[14];
-			obj->pFile = pFile;
-			return obj;
-		}
-	
-	case 2:
-		{
-			CHECK_TOKEN_COUNT (8)
-			CHECK_TOKEN_NUMBERS (1, 7)
-			
-			// Line
-			LDLine* obj = new LDLine;
-			obj->dColor = getWordInt (zLine, 1);
-			for (short i = 0; i < 2; ++i)
-				obj->vaCoords[i] = parseVertex (zLine, 2 + (i * 3)); // 2 - 7
-			return obj;
-		}
-	
-	case 3:
-		{
-			CHECK_TOKEN_COUNT (11)
-			CHECK_TOKEN_NUMBERS (1, 10)
-			
-			// Triangle
-			LDTriangle* obj = new LDTriangle;
-			obj->dColor = getWordInt (zLine, 1);
-			
-			for (short i = 0; i < 3; ++i)
-				obj->vaCoords[i] = parseVertex (zLine, 2 + (i * 3)); // 2 - 10
-			
-			return obj;
-		}
-	
-	case 4:
-		{
-			CHECK_TOKEN_COUNT (14)
-			CHECK_TOKEN_NUMBERS (1, 13)
-			
-			// Quadrilateral
-			LDQuad* obj = new LDQuad;
-			obj->dColor = getWordInt (zLine, 1);
-			
-			for (short i = 0; i < 4; ++i)
-				obj->vaCoords[i] = parseVertex (zLine, 2 + (i * 3)); // 2 - 13
-			
-			return obj;
-		}
-	
-	case 5:
-		{
-			CHECK_TOKEN_COUNT (14)
-			CHECK_TOKEN_NUMBERS (1, 13)
-			
-			// Conditional line
-			LDCondLine* obj = new LDCondLine;
-			obj->dColor = getWordInt (zLine, 1);
-			
-			for (short i = 0; i < 2; ++i)
-				obj->vaCoords[i] = parseVertex (zLine, 2 + (i * 3)); // 2 - 7
-			
-			for (short i = 0; i < 2; ++i)
-				obj->vaControl[i] = parseVertex (zLine, 8 + (i * 3)); // 8 - 13
-			return obj;
-		}
-		
-	default: // Strange line we couldn't parse
-		return new LDGibberish (zLine, "Unknown line code number");
-	}
-}
\ No newline at end of file
--- a/io.h	Mon Mar 18 12:15:23 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-#ifndef __IO_H__
-#define __IO_H__
-
-#include "common.h"
-#include "ldtypes.h"
-#include "str.h"
-
-// =============================================================================
-// OpenFile
-//
-// The OpenFile class stores a file opened in LDForge either as a editable file
-// for the user or for subfile caching. Its methods handle file input and output.
-// =============================================================================
-class OpenFile {
-public:
-	str zFileName, zTitle;
-	vector<LDObject*> objects;
-	
-	// Closes this OpenFile. The object is deleted in the process.
-	void close ();
-	
-	// Saves this file to disk.
-	void save (str zPath = "");
-};
-
-// Close all current loaded files and start off blank.
-void newFile ();
-
-// Opens the given file as the main file. Everything is closed first.
-void openMainFile (str zPath);
-
-// Finds an OpenFile by name or nullptr if not open
-OpenFile* findLoadedFile (str name);
-
-// Opens the given file and parses the LDraw code within. Returns a pointer
-// to the opened file or nullptr on error.
-OpenFile* openDATFile (str path);
-
-// Close all open files, whether user-opened or subfile caches.
-void closeAll ();
-
-// Parses a string line containing an LDraw object and returns the object parsed.
-LDObject* parseLine (str zLine);
-
-extern vector<str> g_zaFileLoadPaths;
-extern vector<OpenFile*> g_LoadedFiles;
-
-#endif
\ No newline at end of file
--- a/ldtypes.cpp	Mon Mar 18 12:15:23 2013 +0200
+++ b/ldtypes.cpp	Mon Mar 18 12:20:48 2013 +0200
@@ -1,6 +1,6 @@
 #include "common.h"
 #include "ldtypes.h"
-#include "io.h"
+#include "file.h"
 #include "misc.h"
 
 const char* g_saObjTypeNames[] = {
--- a/main.cpp	Mon Mar 18 12:15:23 2013 +0200
+++ b/main.cpp	Mon Mar 18 12:20:48 2013 +0200
@@ -1,6 +1,6 @@
 #include <QApplication>
 #include "gui.h"
-#include "io.h"
+#include "file.h"
 #include "bbox.h"
 #include "misc.h"
 
--- a/zz_setContentsDialog.cpp	Mon Mar 18 12:15:23 2013 +0200
+++ b/zz_setContentsDialog.cpp	Mon Mar 18 12:20:48 2013 +0200
@@ -1,7 +1,7 @@
 #include <QAbstractButton>
 #include <qboxlayout.h>
 #include "zz_setContentsDialog.h"
-#include "io.h"
+#include "file.h"
 #include "gui.h"
 
 // =============================================================================

mercurial