<commit_before>//- Standard Library -
#include <cstdlib>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <fstream>

//- Beach Judge -
#include <BeachJudge/HTTP.h>
#include <BeachJudge/Base.h>

#define BEACHJUDGE_SESSION_EXPIREMS 30 * 60 * 1000 //- TODO: Externalize to Config -

using namespace std;
//\r\nSet-Cookie: BEACHJUDGESESSID=123456789
const char *header_OK = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-type: text/html\r\n\r\n";
const char *wwwPrefix = "../www/";

namespace beachjudge
{
	map<string, Page *> g_pageMap;
	map<string, void (*)(stringstream &, Socket *, Session *)> g_templateMap;

	void Page::RegisterTemplate(string entry, void (*func)(stringstream &, Socket *, Session *))
	{
		g_templateMap[entry] = func;
	}
	Page *Page::Create(string file)
	{
		if(!fileExists(file.c_str()))
			return 0;

		if(g_pageMap.count(file))
			return g_pageMap[file];

		string html, lineIn;
		ifstream inFile(file.c_str());
		while(getline(inFile, lineIn))
			html = html.append(lineIn);

		Page *page = new Page();
		page->m_fileSource = file;
		page->m_html = html;
		g_pageMap[file] = page;
		return page;
	}
	void Page::Cleanup()
	{
		while(g_pageMap.size())
			delete g_pageMap.begin()->second;
	}

	Page::Page()
	{
	}
	Page::~Page()
	{
		g_pageMap.erase(m_fileSource);
	}
	void Page::AddToStream(stringstream &stream, Socket *client, Session *session)
	{
		stringstream pageStream(m_html);
		string chunk, varChunk;
		while(getline(pageStream, chunk, '$'))
		{
			stream << chunk;

			if(pageStream.eof())
				break;

			varChunk = "";
			while(true)
			{
				char peek = pageStream.peek();
				if((peek >= 'A' && peek <= 'Z') || (peek >= 'a' && peek <= 'z'))
				{
					varChunk.push_back(peek);
					pageStream.get();
				}
				else
					break;
			}
			cout << "Smart Chunk: |" << varChunk << "|" << endl;
			if(g_templateMap.count(varChunk))
				g_templateMap[varChunk](stream, client, session);
			else
				stream << "$" << varChunk;
		}

		delete this;
	}

	bool SessionExpireComp(Session *sessA, Session *sessB)
	{
		return sessA->GetExpireTimeMS() > sessB->GetExpireTimeMS();
	}

	map<unsigned long, Session *> g_sessionMap;
	map<unsigned short, Session *> g_sessionIDMap;
	vector<Session *> g_sessionVec;

	Session *Session::Create(unsigned long address, unsigned short port, unsigned short userID)
	{
		Session *session = 0;
		if(g_sessionMap.count(address))
		{
			session = g_sessionMap[address];
		}
		else
		{
			session = new Session();
			session->m_address = address;
			g_sessionMap[address] = session;

			do
			{
				session->m_id = (unsigned short)rand();
			}
			while(g_sessionIDMap.count(session->m_id));
			g_sessionIDMap[session->m_id] = session;
			g_sessionVec.push_back(session);
		}

		session->m_expireTimeMS = getRunTimeMS() + BEACHJUDGE_SESSION_EXPIREMS;
		session->m_port = port;
		session->m_userID = userID;
		sort(g_sessionVec.begin(), g_sessionVec.end(), SessionExpireComp);
		return session;
	}
	Session *Session::Lookup(unsigned long address)
	{
		if(g_sessionMap.count(address))
			return g_sessionMap[address];
		return 0;
	}
	void Session::Cleanup(bool deleteAll)
	{
		unsigned long currTimeMS = getRunTimeMS();
		while(g_sessionVec.size())
		{
			Session *session = g_sessionVec.back();
			if(deleteAll || session->GetExpireTimeMS() <= currTimeMS)
				delete session;
		}
	}

	Session::Session()
	{
		m_id = 0;
		m_userID = 0;
		m_expireTimeMS = 0;
	}
	Session::~Session()
	{
		g_sessionVec.erase(find(g_sessionVec.begin(), g_sessionVec.end(), this));
		g_sessionMap.erase(this->m_address);
		g_sessionIDMap.erase(this->m_id);
	}
	unsigned long Session::GetExpireTimeMS() const
	{
		return m_expireTimeMS;
	}
	unsigned short Session::GetID() const
	{
		return m_id;
	}
	unsigned short Session::GetUserID() const
	{
		return m_userID;
	}

	void HTTP::HandleRequest(Socket *client, std::string &request)
	{
		unsigned short port = 0;
		unsigned long addr = 0;
		client->GetPeerIP4Info(&addr, &port);

		unsigned char ip[4], *ipPtr = (unsigned char *)&addr;
		for(unsigned char a = 0; a < 4; a++)
		{
			ip[a] = *ipPtr & 0xFF;
			ipPtr++;
		}

		Session *session = Session::Create(addr, port, 5);
		stringstream stream(request);
		string method;
		stream >> method;
		print("[%d: %d %d] Receiving Msg: %d.%d.%d.%d:%d\r\n", getRunTimeMS(), session, session->GetID(), (unsigned short)ip[0], (unsigned short)ip[1], (unsigned short)ip[2], (unsigned short)ip[3], port);
		cout << request << endl;

		if(!method.compare("GET"))
		{
			string arguments;
			stream >> arguments;

			string in;
			while(stream >> in)
			{
				if(!in.compare("Cookie:"))
				{
					string cookie;
					while(getline(stream, cookie, '='))
					{
						string value;
						stream >> value;
						if(*value.rbegin() == ';')
							value.erase(value.end());

						if(!cookie.compare(" BEACHJUDGESESSID"))
						{
							print("Beach Judge Sess ID: %s\r\n", value.c_str());
						}
					}

					break;
				}
			}

			stringstream argStream(arguments);
			string arg, filePath = wwwPrefix;

			stringstream webPageStream;
			webPageStream << header_OK;

			getline(argStream, arg, '/');
			if(getline(argStream, arg, '/'))
			{
				string testPath = filePath;
				testPath.append(arg);
				testPath.append(".html");
				if(fileExists(testPath.c_str()))
					filePath = testPath;
				else
					filePath.append("404.html");
			}
			else
				filePath.append("index.html");

			Page *index = Page::Create(filePath);
			index->AddToStream(webPageStream, client, session);
			string webPage = webPageStream.str();
			client->Write((char *)webPage.c_str(), webPage.length());
		}
	}
	void HTTP::AppendHeader_OK(string &str)
	{
		str.append(header_OK);
	}
}
<commit_msg>Another minor fix<commit_after>//- Standard Library -
#include <cstdlib>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <fstream>

//- Beach Judge -
#include <BeachJudge/HTTP.h>
#include <BeachJudge/Base.h>

#define BEACHJUDGE_SESSION_EXPIREMS 30 * 60 * 1000 //- TODO: Externalize to Config -

using namespace std;
//\r\nSet-Cookie: BEACHJUDGESESSID=123456789
const char *header_OK = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-type: text/html\r\n\r\n";
const char *wwwPrefix = "../www/";

namespace beachjudge
{
	map<string, Page *> g_pageMap;
	map<string, void (*)(stringstream &, Socket *, Session *)> g_templateMap;

	void Page::RegisterTemplate(string entry, void (*func)(stringstream &, Socket *, Session *))
	{
		g_templateMap[entry] = func;
	}
	Page *Page::Create(string file)
	{
		if(!fileExists(file.c_str()))
			return 0;

		if(g_pageMap.count(file))
			return g_pageMap[file];

		string html, lineIn;
		ifstream inFile(file.c_str());
		while(getline(inFile, lineIn))
			html = html.append(lineIn);

		Page *page = new Page();
		page->m_fileSource = file;
		page->m_html = html;
		g_pageMap[file] = page;
		return page;
	}
	void Page::Cleanup()
	{
		while(g_pageMap.size())
			delete g_pageMap.begin()->second;
	}

	Page::Page()
	{
	}
	Page::~Page()
	{
		g_pageMap.erase(m_fileSource);
	}
	void Page::AddToStream(stringstream &stream, Socket *client, Session *session)
	{
		stringstream pageStream(m_html);
		string chunk, varChunk;
		while(getline(pageStream, chunk, '$'))
		{
			stream << chunk;

			if(pageStream.eof())
				break;

			varChunk = "";
			while(true)
			{
				char peek = pageStream.peek();
				if((peek >= 'A' && peek <= 'Z') || (peek >= 'a' && peek <= 'z'))
				{
					varChunk.push_back(peek);
					pageStream.get();
				}
				else
					break;
			}
			cout << "Smart Chunk: |" << varChunk << "|" << endl;
			if(g_templateMap.count(varChunk))
				g_templateMap[varChunk](stream, client, session);
			else
				stream << "$" << varChunk;
		}

		delete this;
	}

	bool SessionExpireComp(Session *sessA, Session *sessB)
	{
		return sessA->GetExpireTimeMS() > sessB->GetExpireTimeMS();
	}

	map<unsigned long, Session *> g_sessionMap;
	map<unsigned short, Session *> g_sessionIDMap;
	vector<Session *> g_sessionVec;

	Session *Session::Create(unsigned long address, unsigned short port, unsigned short userID)
	{
		Session *session = 0;
		if(g_sessionMap.count(address))
		{
			session = g_sessionMap[address];
		}
		else
		{
			session = new Session();
			session->m_address = address;
			g_sessionMap[address] = session;

			do
			{
				session->m_id = (unsigned short)rand();
			}
			while(g_sessionIDMap.count(session->m_id));
			g_sessionIDMap[session->m_id] = session;
			g_sessionVec.push_back(session);
		}

		session->m_expireTimeMS = getRunTimeMS() + BEACHJUDGE_SESSION_EXPIREMS;
		session->m_port = port;
		session->m_userID = userID;
		sort(g_sessionVec.begin(), g_sessionVec.end(), SessionExpireComp);
		return session;
	}
	Session *Session::Lookup(unsigned long address)
	{
		if(g_sessionMap.count(address))
			return g_sessionMap[address];
		return 0;
	}
	void Session::Cleanup(bool deleteAll)
	{
		unsigned long currTimeMS = getRunTimeMS();
		while(g_sessionVec.size())
		{
			Session *session = g_sessionVec.back();
			if(deleteAll || session->GetExpireTimeMS() <= currTimeMS)
				delete session;
		}
	}

	Session::Session()
	{
		m_id = 0;
		m_userID = 0;
		m_expireTimeMS = 0;
	}
	Session::~Session()
	{
		g_sessionVec.erase(find(g_sessionVec.begin(), g_sessionVec.end(), this));
		g_sessionMap.erase(this->m_address);
		g_sessionIDMap.erase(this->m_id);
	}
	unsigned long Session::GetExpireTimeMS() const
	{
		return m_expireTimeMS;
	}
	unsigned short Session::GetID() const
	{
		return m_id;
	}
	unsigned short Session::GetUserID() const
	{
		return m_userID;
	}

	void HTTP::HandleRequest(Socket *client, std::string &request)
	{
		unsigned short port = 0;
		unsigned long addr = 0;
		client->GetPeerIP4Info(&addr, &port);

		unsigned char ip[4], *ipPtr = (unsigned char *)&addr;
		for(unsigned char a = 0; a < 4; a++)
		{
			ip[a] = *ipPtr & 0xFF;
			ipPtr++;
		}

		Session *session = Session::Create(addr, port, 5);
		stringstream stream(request);
		string method;
		stream >> method;
		print("[%d: %d %d] Receiving Msg: %d.%d.%d.%d:%d\r\n", getRunTimeMS(), session, session->GetID(), (unsigned short)ip[0], (unsigned short)ip[1], (unsigned short)ip[2], (unsigned short)ip[3], port);
		cout << request << endl;

		if(!method.compare("GET"))
		{
			string arguments;
			stream >> arguments;

			string in;
			while(stream >> in)
			{
				if(!in.compare("Cookie:"))
				{
					string cookie;
					while(getline(stream, cookie, '='))
					{
						string value;
						stream >> value;
						if(!value.empty())
							if(*value.rbegin() == ';')
								value = value.substr(0, value.size() - 1);

						if(!cookie.compare(" BEACHJUDGESESSID"))
						{
							print("Beach Judge Sess ID: %s\r\n", value.c_str());
						}
					}

					break;
				}
			}

			stringstream argStream(arguments);
			string arg, filePath = wwwPrefix;

			stringstream webPageStream;
			webPageStream << header_OK;

			getline(argStream, arg, '/');
			if(getline(argStream, arg, '/'))
			{
				string testPath = filePath;
				testPath.append(arg);
				testPath.append(".html");
				if(fileExists(testPath.c_str()))
					filePath = testPath;
				else
					filePath.append("404.html");
			}
			else
				filePath.append("index.html");

			Page *index = Page::Create(filePath);
			index->AddToStream(webPageStream, client, session);
			string webPage = webPageStream.str();
			client->Write((char *)webPage.c_str(), webPage.length());
		}
	}
	void HTTP::AppendHeader_OK(string &str)
	{
		str.append(header_OK);
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2016 Dan Leinir Turthra Jensen <admin@leinir.dk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) version 3, or any
 * later version accepted by the membership of KDE e.V. (or its
 * successor approved by the membership of KDE e.V.), which shall
 * act as a proxy defined in Section 6 of version 3 of the license.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "PDFCoverImageProvider.h"

#include <QCoreApplication>
#include <QIcon>
#include <QMimeDatabase>
#include <QProcess>
#include <QTemporaryDir>
#include <QUrl>
#include <QDebug>

class PDFCoverImageProvider::Private {
public:
    Private() {}
    QTemporaryDir thumbDir;
};

PDFCoverImageProvider::PDFCoverImageProvider()
    : QQuickImageProvider(QQuickImageProvider::Image)
    , d(new Private)
{
}

PDFCoverImageProvider::~PDFCoverImageProvider()
{
    delete d;
}

QImage PDFCoverImageProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize)
{
    Q_UNUSED(size)
    Q_UNUSED(requestedSize)
    QImage img;

    if(!d->thumbDir.isValid()) {
        qDebug() << "WAT?! Failed to create temporary directory for storage of PDF thumbnails... bad.";
        return img;
    }

    QMimeDatabase db;
    db.mimeTypeForFile(id, QMimeDatabase::MatchContent);
    const QMimeType mime = db.mimeTypeForFile(id, QMimeDatabase::MatchContent);
    if(mime.inherits("application/pdf")) {
        //-sOutputFile=FILENAME.png FILENAME
        QString outFile = QString("%1/%2.png").arg(d->thumbDir.path()).arg(QUrl(id).toString().replace("/", "-").replace(":", "-"));
        if(!QFile::exists(outFile)) {
            // then we've not already generated a thumbnail, try to make one...
            QProcess thumbnailer;
            QStringList args;
            args << "-sPageList=1" << "-dLastPage=1" << "-dSAFER" << "-dBATCH" << "-dNOPAUSE" << "-dQUIET" << "-sDEVICE=png16m" << "-dGraphicsAlphaBits=4" << "-r150";
            args << QString("-sOutputFile=%1").arg(outFile) << id;
            QString gsApp;
            #ifdef Q_OS_WIN
                gsApp = qApp->applicationDirPath();
                #ifdef Q_OS_WIN64
                    gsApp += "/gswin64c.exe";
                #else
                    gsApp += "/gswin32c.exe";
                #endif
            #else
                gsApp = "gs";
            #endif
            thumbnailer.start(gsApp, args);
            thumbnailer.waitForFinished();
        }
        bool success = false;
        // Now, does it exist this time?
        if(QFile::exists(outFile)) {
            success = img.load(outFile);
        }
        if(!success) {
            QIcon oops = QIcon::fromTheme("unknown");
            img = oops.pixmap(oops.availableSizes().last()).toImage();
            qDebug() << "Failed to load image with id" << id << "from thumbnail file" << outFile;
        }
    }

    return img;
}
<commit_msg>Make the pdf thumb cache persistent<commit_after>/*
 * Copyright (C) 2016 Dan Leinir Turthra Jensen <admin@leinir.dk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) version 3, or any
 * later version accepted by the membership of KDE e.V. (or its
 * successor approved by the membership of KDE e.V.), which shall
 * act as a proxy defined in Section 6 of version 3 of the license.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "PDFCoverImageProvider.h"

#include <QCoreApplication>
#include <QDir>
#include <QIcon>
#include <QMimeDatabase>
#include <QProcess>
#include <QStandardPaths>
#include <QUrl>
#include <QDebug>

class PDFCoverImageProvider::Private {
public:
    Private() {
        QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
        thumbDir = QDir(path);
        QString subpath("thumbcache");
        if(!thumbDir.exists(subpath)) {
            thumbDir.mkpath(subpath);
        }
        thumbDir.cd(subpath);
    }
    QDir thumbDir;
};

PDFCoverImageProvider::PDFCoverImageProvider()
    : QQuickImageProvider(QQuickImageProvider::Image)
    , d(new Private)
{
}

PDFCoverImageProvider::~PDFCoverImageProvider()
{
    delete d;
}

QImage PDFCoverImageProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize)
{
    Q_UNUSED(size)
    Q_UNUSED(requestedSize)
    QImage img;

    QMimeDatabase db;
    db.mimeTypeForFile(id, QMimeDatabase::MatchContent);
    const QMimeType mime = db.mimeTypeForFile(id, QMimeDatabase::MatchContent);
    if(mime.inherits("application/pdf")) {
        //-sOutputFile=FILENAME.png FILENAME
        QString outFile = QString("%1/%2.png").arg(d->thumbDir.absolutePath()).arg(QUrl(id).toString().replace("/", "-").replace(":", "-"));
        if(!QFile::exists(outFile)) {
            // then we've not already generated a thumbnail, try to make one...
            QProcess thumbnailer;
            QStringList args;
            args << "-sPageList=1" << "-dLastPage=1" << "-dSAFER" << "-dBATCH" << "-dNOPAUSE" << "-dQUIET" << "-sDEVICE=png16m" << "-dGraphicsAlphaBits=4" << "-r150";
            args << QString("-sOutputFile=%1").arg(outFile) << id;
            QString gsApp;
            #ifdef Q_OS_WIN
                gsApp = qApp->applicationDirPath();
                #ifdef Q_OS_WIN64
                    gsApp += "/gswin64c.exe";
                #else
                    gsApp += "/gswin32c.exe";
                #endif
            #else
                gsApp = "gs";
            #endif
            thumbnailer.start(gsApp, args);
            thumbnailer.waitForFinished();
        }
        bool success = false;
        // Now, does it exist this time?
        if(QFile::exists(outFile)) {
            success = img.load(outFile);
        }
        if(!success) {
            QIcon oops = QIcon::fromTheme("unknown");
            img = oops.pixmap(oops.availableSizes().last()).toImage();
            qDebug() << "Failed to load image with id" << id << "from thumbnail file" << outFile;
        }
    }

    return img;
}
<|endoftext|>


<commit_before>#include <windows.h>

#include <gl\gl.h>

#ifdef _MSC_VER
#define _USE_MATH_DEFINES
#endif
#include <math.h>

#include "Window.h"
#include "Body.h"
#include "Error.h"
#include "Info.h"

#define NAME_FONT_NAME "Arial"
#define NAME_FONT_SIZE_AT_H600 24
#define NAME_FONT_SIZE (NAME_FONT_SIZE_AT_H600*scrheight/600)

#define NAME_TEXT_COLOR_R 1.00f
#define NAME_TEXT_COLOR_G 1.00f
#define NAME_TEXT_COLOR_B 1.00f
#define NAME_TEXT_COLOR_A 0.50f

#define INFO_FONT_NAME "Arial"
#define INFO_FONT_SIZE_AT_H600 16
#define INFO_FONT_SIZE (INFO_FONT_SIZE_AT_H600*scrheight/600)

#define INFO_TEXT_COLOR_R 1.00f
#define INFO_TEXT_COLOR_G 1.00f
#define INFO_TEXT_COLOR_B 1.00f
#define INFO_TEXT_COLOR_A 0.50f

#define SPACING_COEF 1.75f
#define LINES_AFTER_NAME 1.00f

#define WINDOW_COLOR_R 0.50f
#define WINDOW_COLOR_G 0.50f
#define WINDOW_COLOR_B 0.50f
#define WINDOW_COLOR_A 0.25f

#define MAX_FADE_TIME 3.0f
#define FADE_TIME_RATIO 0.10f
#define FADE_TIME(totaltime) min(MAX_FADE_TIME, (totaltime)*FADE_TIME_RATIO)

#define WINDOW_BORDER_REL 0.0125f
#define WINDOW_BORDER (WINDOW_BORDER_REL*scrheight)
#define WINDOW_WIDTH_REL_Y (0.3075f*4.0f/3.0f)
#define WINDOW_WIDTH (WINDOW_WIDTH_REL_Y*scrheight)
#define WINDOW_HEIGHT_REL 0.2575f
#define WINDOW_HEIGHT (WINDOW_HEIGHT_REL*scrheight)

#define WINDOW_POS_X1 (WINDOW_BORDER)
#define WINDOW_POS_Y1 (WINDOW_BORDER)
#define WINDOW_POS_X2 (WINDOW_POS_X1+WINDOW_WIDTH)
#define WINDOW_POS_Y2 (WINDOW_POS_Y1+WINDOW_HEIGHT)

#define MARGIN_TOP_REL 0.100f
#define MARGIN_LEFT_REL 0.075f
#define MARGIN_WIDTH (WINDOW_WIDTH*MARGIN_LEFT_REL)
#define MARGIN_HEIGHT (WINDOW_HEIGHT*MARGIN_TOP_REL)

CInfo::CInfo()
{
	Init();
}

CInfo::~CInfo()
{
	Free();
}

void CInfo::Init()
{
	loaded=false;
	scrwidth=0;
	scrheight=0;
	winlist=0;
	namelist=infolist=0;
	time=0;
	starttime=endtime=0;
	fadetime=1;
	alpha=0;
}

void CInfo::Free()
{
	nametext.Free();
	infotext.Free();
	if (winlist)
	{
		if (glIsList(winlist))
			glDeleteLists(winlist,3);
	}
	Init();
}

bool CInfo::Load()
{
	Free();

	scrwidth=(float)CWindow::GetWidth();
	scrheight=(float)CWindow::GetHeight();

	winlist=glGenLists(3);
	if (!winlist)
	{
		CError::LogError(WARNING_CODE,"Unable to load planet info - failed to generate display lists.");
		Free();
		return false;
	}
	namelist=winlist+1;
	infolist=namelist+1;

	MakeWindow(winlist);

	loaded=true;
	loaded&=nametext.BuildFTFont(NAME_FONT_NAME,NAME_FONT_SIZE);
	loaded&=infotext.BuildFTFont(INFO_FONT_NAME,INFO_FONT_SIZE);
	if (!loaded)
	{
		CError::LogError(WARNING_CODE,"Unable to load planet info - failed to load font.");
		Free();
	}

	return loaded;
}

void CInfo::MakeWindow(int list)
{
	glNewList(list,GL_COMPILE);
	{
		int l=(int)WINDOW_POS_X1;
		int r=(int)WINDOW_POS_X2;
		int b=(int)WINDOW_POS_Y1;
		int t=(int)WINDOW_POS_Y2;
		glDisable(GL_TEXTURE_2D);
		glLoadIdentity();
		glBegin(GL_QUADS);
		{
			glVertex2f(l,b);
			glVertex2f(r,b);
			glVertex2f(r,t);
			glVertex2f(l,t);
		}
		glEnd();
	}
	glEndList();
}

void CInfo::GetNameCoords(const char *text, float *x, float *y)
{
	float tw,th;
	nametext.GetTextSize(text,&tw,&th);
	if (x) *x=WINDOW_POS_X1+(WINDOW_WIDTH-tw)*0.5f;
	if (y) *y=WINDOW_POS_Y2-MARGIN_HEIGHT-th;
}

void CInfo::GetInfoCoords(int linenum, float *x, float *y)
{
	float namey;
	GetNameCoords("",NULL,&namey);
	float nameadd;
	nametext.GetTextSize("",NULL,&nameadd);
	nameadd*=(SPACING_COEF*LINES_AFTER_NAME);

	float th;
	infotext.GetTextSize("",NULL,&th);
	th*=SPACING_COEF*(float)(linenum-1);

	if (x) *x=WINDOW_POS_X1+MARGIN_WIDTH;
	if (y) *y=namey-nameadd-th;
}

void CInfo::MakeName(int list, char *targetname)
{
	if (!targetname) return;
	if (*targetname==' ') targetname++;
	float x,y;
	GetNameCoords(targetname,&x,&y);
	int xi=(int)x,yi=(int)y;
	glNewList(list,GL_COMPILE);
	{
		glEnable(GL_TEXTURE_2D);
		glLoadIdentity();
		glTranslatef(xi,yi,0);
		nametext.Print(targetname);
	}
	glEndList();
}

void CInfo::MakeInfoLine(int linenum, char *line)
{
	float x,y;
	GetInfoCoords(linenum,&x,&y);
	int xi=(int)x,yi=(int)y;
	glPushMatrix();
	glTranslatef(xi,yi,0);
	infotext.Print(line);
	glPopMatrix();
}

void CInfo::MakeInfo(int list, CBody *targetbody)
{
	bool star=(targetbody==NULL);
	if (star) targetbody=CBody::bodycache[0];
	glNewList(list,GL_COMPILE);
	{
		int n=0;
		glEnable(GL_TEXTURE_2D);
		glLoadIdentity();
		if (star)
		{
			char line[64];
			n++;
			sprintf(line,"star name: %s",targetbody->name);
			MakeInfoLine(n,line);
		}
		for (int i=0;i<targetbody->info.numlines;i++)
		{
			if (targetbody->info.textlines[i][0]=='/') continue;
			n++;
			MakeInfoLine(n,targetbody->info.textlines[i]);
		}
	}
	glEndList();
}

void CInfo::Start(float seconds, float duration, char *targetname, CBody *targetbody)
{
	if (!loaded)
		return;
	char name[32];
	strcpy(name,targetname);
	int l=strlen(name);
	for (int i=0;i<l;i++)
		if (name[i]=='_')
			name[i]=' ';
	starttime=seconds;
	endtime=starttime+duration;
	fadetime=FADE_TIME(duration);
	MakeName(namelist,name);
	MakeInfo(infolist,targetbody);
}

void CInfo::Update(float seconds)
{
	time=seconds;
	if (time<(endtime-fadetime))
		alpha=min(1,(time-starttime)/fadetime);
	else
		alpha=max(0,(endtime-time)/fadetime);
}

void CInfo::Restart()
{
	starttime-=time;
	endtime-=time;
	time=0;
}

void CInfo::Draw()
{
	if (!alpha || !loaded)
		return;

	glPushAttrib(GL_ENABLE_BIT);

	glDisable(GL_LIGHTING);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);
	glDisable(GL_NORMALIZE);
	glEnable(GL_BLEND);

	glColor4f(WINDOW_COLOR_R,WINDOW_COLOR_G,WINDOW_COLOR_B,WINDOW_COLOR_A*alpha);
	glCallList(winlist);

	glColor4f(NAME_TEXT_COLOR_R,NAME_TEXT_COLOR_G,NAME_TEXT_COLOR_B,NAME_TEXT_COLOR_A*alpha);
	glCallList(namelist);

	glColor4f(INFO_TEXT_COLOR_R,INFO_TEXT_COLOR_G,INFO_TEXT_COLOR_B,INFO_TEXT_COLOR_A*alpha);
	glCallList(infolist);

	glPopAttrib();
}
<commit_msg>Removed some unnecessary OpenGL state machine calls.<commit_after>#include <windows.h>

#include <gl\gl.h>

#ifdef _MSC_VER
#define _USE_MATH_DEFINES
#endif
#include <math.h>

#include "Window.h"
#include "Body.h"
#include "Error.h"
#include "Info.h"

#define NAME_FONT_NAME "Arial"
#define NAME_FONT_SIZE_AT_H600 24
#define NAME_FONT_SIZE (NAME_FONT_SIZE_AT_H600*scrheight/600)

#define NAME_TEXT_COLOR_R 1.00f
#define NAME_TEXT_COLOR_G 1.00f
#define NAME_TEXT_COLOR_B 1.00f
#define NAME_TEXT_COLOR_A 0.50f

#define INFO_FONT_NAME "Arial"
#define INFO_FONT_SIZE_AT_H600 16
#define INFO_FONT_SIZE (INFO_FONT_SIZE_AT_H600*scrheight/600)

#define INFO_TEXT_COLOR_R 1.00f
#define INFO_TEXT_COLOR_G 1.00f
#define INFO_TEXT_COLOR_B 1.00f
#define INFO_TEXT_COLOR_A 0.50f

#define SPACING_COEF 1.75f
#define LINES_AFTER_NAME 1.00f

#define WINDOW_COLOR_R 0.50f
#define WINDOW_COLOR_G 0.50f
#define WINDOW_COLOR_B 0.50f
#define WINDOW_COLOR_A 0.25f

#define MAX_FADE_TIME 3.0f
#define FADE_TIME_RATIO 0.10f
#define FADE_TIME(totaltime) min(MAX_FADE_TIME, (totaltime)*FADE_TIME_RATIO)

#define WINDOW_BORDER_REL 0.0125f
#define WINDOW_BORDER (WINDOW_BORDER_REL*scrheight)
#define WINDOW_WIDTH_REL_Y (0.3075f*4.0f/3.0f)
#define WINDOW_WIDTH (WINDOW_WIDTH_REL_Y*scrheight)
#define WINDOW_HEIGHT_REL 0.2575f
#define WINDOW_HEIGHT (WINDOW_HEIGHT_REL*scrheight)

#define WINDOW_POS_X1 (WINDOW_BORDER)
#define WINDOW_POS_Y1 (WINDOW_BORDER)
#define WINDOW_POS_X2 (WINDOW_POS_X1+WINDOW_WIDTH)
#define WINDOW_POS_Y2 (WINDOW_POS_Y1+WINDOW_HEIGHT)

#define MARGIN_TOP_REL 0.100f
#define MARGIN_LEFT_REL 0.075f
#define MARGIN_WIDTH (WINDOW_WIDTH*MARGIN_LEFT_REL)
#define MARGIN_HEIGHT (WINDOW_HEIGHT*MARGIN_TOP_REL)

CInfo::CInfo()
{
	Init();
}

CInfo::~CInfo()
{
	Free();
}

void CInfo::Init()
{
	loaded=false;
	scrwidth=0;
	scrheight=0;
	winlist=0;
	namelist=infolist=0;
	time=0;
	starttime=endtime=0;
	fadetime=1;
	alpha=0;
}

void CInfo::Free()
{
	nametext.Free();
	infotext.Free();
	if (winlist)
	{
		if (glIsList(winlist))
			glDeleteLists(winlist,3);
	}
	Init();
}

bool CInfo::Load()
{
	Free();

	scrwidth=(float)CWindow::GetWidth();
	scrheight=(float)CWindow::GetHeight();

	winlist=glGenLists(3);
	if (!winlist)
	{
		CError::LogError(WARNING_CODE,"Unable to load planet info - failed to generate display lists.");
		Free();
		return false;
	}
	namelist=winlist+1;
	infolist=namelist+1;

	MakeWindow(winlist);

	loaded=true;
	loaded&=nametext.BuildFTFont(NAME_FONT_NAME,NAME_FONT_SIZE);
	loaded&=infotext.BuildFTFont(INFO_FONT_NAME,INFO_FONT_SIZE);
	if (!loaded)
	{
		CError::LogError(WARNING_CODE,"Unable to load planet info - failed to load font.");
		Free();
	}

	return loaded;
}

void CInfo::MakeWindow(int list)
{
	glNewList(list,GL_COMPILE);
	{
		int l=(int)WINDOW_POS_X1;
		int r=(int)WINDOW_POS_X2;
		int b=(int)WINDOW_POS_Y1;
		int t=(int)WINDOW_POS_Y2;
		glDisable(GL_TEXTURE_2D);
		glLoadIdentity();
		glBegin(GL_QUADS);
		{
			glVertex2f(l,b);
			glVertex2f(r,b);
			glVertex2f(r,t);
			glVertex2f(l,t);
		}
		glEnd();
	}
	glEndList();
}

void CInfo::GetNameCoords(const char *text, float *x, float *y)
{
	float tw,th;
	nametext.GetTextSize(text,&tw,&th);
	if (x) *x=WINDOW_POS_X1+(WINDOW_WIDTH-tw)*0.5f;
	if (y) *y=WINDOW_POS_Y2-MARGIN_HEIGHT-th;
}

void CInfo::GetInfoCoords(int linenum, float *x, float *y)
{
	float namey;
	GetNameCoords("",NULL,&namey);
	float nameadd;
	nametext.GetTextSize("",NULL,&nameadd);
	nameadd*=(SPACING_COEF*LINES_AFTER_NAME);

	float th;
	infotext.GetTextSize("",NULL,&th);
	th*=SPACING_COEF*(float)(linenum-1);

	if (x) *x=WINDOW_POS_X1+MARGIN_WIDTH;
	if (y) *y=namey-nameadd-th;
}

void CInfo::MakeName(int list, char *targetname)
{
	if (!targetname) return;
	if (*targetname==' ') targetname++;
	float x,y;
	GetNameCoords(targetname,&x,&y);
	int xi=(int)x,yi=(int)y;
	glNewList(list,GL_COMPILE);
	{
		glEnable(GL_TEXTURE_2D);
		glLoadIdentity();
		glTranslatef(xi,yi,0);
		nametext.Print(targetname);
	}
	glEndList();
}

void CInfo::MakeInfoLine(int linenum, char *line)
{
	float x,y;
	GetInfoCoords(linenum,&x,&y);
	int xi=(int)x,yi=(int)y;
	glPushMatrix();
	glTranslatef(xi,yi,0);
	infotext.Print(line);
	glPopMatrix();
}

void CInfo::MakeInfo(int list, CBody *targetbody)
{
	bool star=(targetbody==NULL);
	if (star) targetbody=CBody::bodycache[0];
	glNewList(list,GL_COMPILE);
	{
		int n=0;
		glEnable(GL_TEXTURE_2D);
		glLoadIdentity();
		if (star)
		{
			char line[64];
			n++;
			sprintf(line,"star name: %s",targetbody->name);
			MakeInfoLine(n,line);
		}
		for (int i=0;i<targetbody->info.numlines;i++)
		{
			if (targetbody->info.textlines[i][0]=='/') continue;
			n++;
			MakeInfoLine(n,targetbody->info.textlines[i]);
		}
	}
	glEndList();
}

void CInfo::Start(float seconds, float duration, char *targetname, CBody *targetbody)
{
	if (!loaded)
		return;
	char name[32];
	strcpy(name,targetname);
	int l=strlen(name);
	for (int i=0;i<l;i++)
		if (name[i]=='_')
			name[i]=' ';
	starttime=seconds;
	endtime=starttime+duration;
	fadetime=FADE_TIME(duration);
	MakeName(namelist,name);
	MakeInfo(infolist,targetbody);
}

void CInfo::Update(float seconds)
{
	time=seconds;
	if (time<(endtime-fadetime))
		alpha=min(1,(time-starttime)/fadetime);
	else
		alpha=max(0,(endtime-time)/fadetime);
}

void CInfo::Restart()
{
	starttime-=time;
	endtime-=time;
	time=0;
}

void CInfo::Draw()
{
	if (!alpha || !loaded)
		return;

	glDisable(GL_LIGHTING);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);
	glEnable(GL_BLEND);

	glColor4f(WINDOW_COLOR_R,WINDOW_COLOR_G,WINDOW_COLOR_B,WINDOW_COLOR_A*alpha);
	glCallList(winlist);

	glColor4f(NAME_TEXT_COLOR_R,NAME_TEXT_COLOR_G,NAME_TEXT_COLOR_B,NAME_TEXT_COLOR_A*alpha);
	glCallList(namelist);

	glColor4f(INFO_TEXT_COLOR_R,INFO_TEXT_COLOR_G,INFO_TEXT_COLOR_B,INFO_TEXT_COLOR_A*alpha);
	glCallList(infolist);
}
<|endoftext|>


<commit_before>#include "utest.h"
#include "function.h"
#include "math/epsilon.h"
#include "layers/conv3d.h"
#include "layers/conv4d.h"

using namespace nano;

auto make_default_params(const tensor_size_t kconn = 1)
{
        const auto imaps = 6;
        const auto irows = 11;
        const auto icols = 15;
        const auto omaps = 4;
        const auto krows = 3;
        const auto kcols = 5;
        const auto kdrow = 2;
        const auto kdcol = 1;

        return conv_params_t{imaps, irows, icols, omaps, kconn, krows, kcols, kdrow, kdcol};
}

auto make_buffers(const conv_params_t& params, const tensor_size_t count)
{
        auto bdata = params.make_bdata(); bdata.setRandom();
        auto kdata = params.make_kdata(); kdata.vector().setRandom();
        auto idata = params.make_idata(count); idata.vector().setRandom();
        auto odata = params.make_odata(count); odata.vector().setRandom();
        return std::make_tuple(bdata, idata, kdata, odata);
}

template <typename top>
struct wrt_params_function_t final : public function_t
{
        explicit wrt_params_function_t(const top& op) :
                function_t("conv", op.params().psize(), op.params().psize(), op.params().psize(), convexity::no, 1e+6),
                m_op(op)
        {
                std::tie(m_bdata, m_idata, m_kdata, m_odata) = make_buffers(op.params(), 3);
        }

        scalar_t vgrad(const vector_t& x, vector_t* gx) const override
        {
                m_kdata = map_tensor(x.data(), m_kdata.dims());
                m_bdata = map_vector(x.data() + m_kdata.size(), m_bdata.size());
                m_op.output(m_idata, m_kdata, m_bdata, m_odata);
                if (gx)
                {
                        gx->resize(x.size());
                        auto kdata = map_tensor(gx->data(), m_kdata.dims());
                        auto bdata = map_vector(gx->data() + m_kdata.size(), m_bdata.size());
                        m_op.gparam(m_idata, kdata, bdata, m_odata);
                }
                return m_odata.array().square().sum() / 2;
        }

        mutable top             m_op;
        tensor4d_t              m_idata;
        mutable tensor4d_t      m_kdata;
        mutable vector_t        m_bdata;
        mutable tensor4d_t      m_odata;
};

template <typename top>
struct wrt_inputs_function_t final : public function_t
{
        explicit wrt_inputs_function_t(const top& op) :
                function_t("conv", op.params().isize(), op.params().isize(), op.params().isize(), convexity::no, 1e+6),
                m_op(op)
        {
                std::tie(m_bdata, m_idata, m_kdata, m_odata) = make_buffers(op.params(), 1);
        }

        scalar_t vgrad(const vector_t& x, vector_t* gx) const override
        {
                m_idata = map_tensor(x.data(), m_idata.dims());
                m_op.output(m_idata, m_kdata, m_bdata, m_odata);
                if (gx)
                {
                        gx->resize(x.size());
                        auto idata = map_tensor(gx->data(), m_idata.dims());
                        m_op.ginput(idata, m_kdata, m_bdata, m_odata);
                }
                return m_odata.array().square().sum() / 2;
        }

        mutable top             m_op;
        mutable tensor4d_t      m_idata;
        tensor4d_t              m_kdata;
        vector_t                m_bdata;
        mutable tensor4d_t      m_odata;
};

template <typename top>
auto make_wrt_params_function(const conv_params_t& params)
{
        return wrt_params_function_t<top>(top{params});
}

template <typename top>
auto make_wrt_inputs_function(const conv_params_t& params)
{
        return wrt_inputs_function_t<top>(top{params});
}

NANO_BEGIN_MODULE(test_conv)

NANO_CASE(params_valid)
{
        const auto imaps = 8;
        const auto irows = 11;
        const auto icols = 15;
        const auto omaps = 4;
        const auto kconn = 2;
        const auto krows = 3;
        const auto kcols = 5;
        const auto kdrow = 2;
        const auto kdcol = 1;

        const auto params = conv_params_t{imaps, irows, icols, omaps, kconn, krows, kcols, kdrow, kdcol};

        NANO_CHECK(params.valid_kernel());
        NANO_CHECK(params.valid_connectivity());
        NANO_CHECK(params.valid());

        NANO_CHECK_EQUAL(params.imaps(), imaps);
        NANO_CHECK_EQUAL(params.irows(), irows);
        NANO_CHECK_EQUAL(params.icols(), icols);

        NANO_CHECK_EQUAL(params.omaps(), omaps);
        NANO_CHECK_EQUAL(params.orows(), (irows - krows + 1) / kdrow);
        NANO_CHECK_EQUAL(params.ocols(), (icols - kcols + 1) / kdcol);

        NANO_CHECK_EQUAL(params.bdims(), omaps);
}

NANO_CASE(params_invalid)
{
        const auto imaps = 8;
        const auto irows = 11;
        const auto icols = 15;
        const auto omaps = 6;
        const auto kconn = 3;
        const auto krows = 13;
        const auto kcols = 5;
        const auto kdrow = 2;
        const auto kdcol = 7;

        const auto params = conv_params_t{imaps, irows, icols, omaps, kconn, krows, kcols, kdrow, kdcol};

        NANO_CHECK(!params.valid_kernel());
        NANO_CHECK(!params.valid_connectivity());
        NANO_CHECK(!params.valid());
}

NANO_CASE(gparam_accuracy)
{
        const auto params = make_default_params();
        NANO_REQUIRE(params.valid());

        const auto pfunct = make_wrt_params_function<conv3d_t>(params);
        for (int i = 0; i < 8; ++ i)
        {
                vector_t px(pfunct.size()); px.setRandom();
                NANO_CHECK_LESS(pfunct.grad_accuracy(px), epsilon1<scalar_t>());
        }
}

NANO_CASE(ginput_accuracy)
{
        const auto params = make_default_params();
        NANO_REQUIRE(params.valid());

        const auto ifunct = make_wrt_inputs_function<conv3d_t>(params);
        for (int i = 0; i < 8; ++ i)
        {
                vector_t ix(ifunct.size()); ix.setRandom();
                NANO_CHECK_LESS(ifunct.grad_accuracy(ix), epsilon1<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_output_kconn1)
{
        const auto params = make_default_params(1);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata, kdata, odata3, odata4;
                vector_t bdata;

                std::tie(bdata, idata, kdata, odata3) = make_buffers(params, i + 2);
                std::tie(bdata, idata, kdata, odata4) = make_buffers(params, i + 2);

                NANO_REQUIRE(op3d.output(idata, kdata, bdata, odata3));
                NANO_REQUIRE(op4d.output(idata, kdata, bdata, odata4));

                NANO_CHECK_EIGEN_CLOSE(odata3.array(), odata4.array(), 10 * epsilon0<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_output_kconn2)
{
        const auto params = make_default_params(2);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata, kdata, odata3, odata4;
                vector_t bdata;

                std::tie(bdata, idata, kdata, odata3) = make_buffers(params, i + 2);
                std::tie(bdata, idata, kdata, odata4) = make_buffers(params, i + 2);

                NANO_REQUIRE(op3d.output(idata, kdata, bdata, odata3));
                NANO_REQUIRE(op4d.output(idata, kdata, bdata, odata4));

                NANO_CHECK_EIGEN_CLOSE(odata3.array(), odata4.array(), 10 * epsilon0<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_gparam_kconn1)
{
        const auto params = make_default_params(1);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata, kdata3, kdata4, odata;
                vector_t bdata3, bdata4;

                std::tie(bdata3, idata, kdata3, odata) = make_buffers(params, i + 2);
                std::tie(bdata4, idata, kdata4, odata) = make_buffers(params, i + 2);

                NANO_REQUIRE(op4d.output(idata, kdata4, bdata4, odata));// NB: needed to update the internal buffers!
                NANO_REQUIRE(op3d.gparam(idata, kdata3, bdata3, odata));
                NANO_REQUIRE(op4d.gparam(idata, kdata4, bdata4, odata));

                NANO_CHECK_EIGEN_CLOSE(bdata3.array(), bdata4.array(), 10 * epsilon0<scalar_t>());
                NANO_CHECK_EIGEN_CLOSE(kdata3.array(), kdata4.array(), 10 * epsilon0<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_gparam_kconn2)
{
        const auto params = make_default_params(2);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata, kdata3, kdata4, odata;
                vector_t bdata3, bdata4;

                std::tie(bdata3, idata, kdata3, odata) = make_buffers(params, i + 2);
                std::tie(bdata4, idata, kdata4, odata) = make_buffers(params, i + 2);

                NANO_REQUIRE(op4d.output(idata, kdata4, bdata4, odata));// NB: needed to update the internal buffers!
                NANO_REQUIRE(op3d.gparam(idata, kdata3, bdata3, odata));
                NANO_REQUIRE(op4d.gparam(idata, kdata4, bdata4, odata));

                NANO_CHECK_EIGEN_CLOSE(bdata3.array(), bdata4.array(), 10 * epsilon0<scalar_t>());
                NANO_CHECK_EIGEN_CLOSE(kdata3.array(), kdata4.array(), 10 * epsilon0<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_ginput_kconn1)
{
        const auto params = make_default_params(1);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata3, idata4, kdata, odata;
                vector_t bdata;

                std::tie(bdata, idata3, kdata, odata) = make_buffers(params, i + 2);
                std::tie(bdata, idata4, kdata, odata) = make_buffers(params, i + 2);

                NANO_REQUIRE(op4d.output(idata4, kdata, bdata, odata));// NB: needed to update the internal buffers!
                NANO_REQUIRE(op3d.ginput(idata3, kdata, bdata, odata));
                NANO_REQUIRE(op4d.ginput(idata4, kdata, bdata, odata));

                NANO_CHECK_EIGEN_CLOSE(idata3.array(), idata4.array(), 10 * epsilon0<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_ginput_kconn2)
{
        const auto params = make_default_params(2);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata3, idata4, kdata, odata;
                vector_t bdata;

                std::tie(bdata, idata3, kdata, odata) = make_buffers(params, i + 2);
                std::tie(bdata, idata4, kdata, odata) = make_buffers(params, i + 2);

                NANO_REQUIRE(op4d.output(idata4, kdata, bdata, odata));// NB: needed to update the internal buffers!
                NANO_REQUIRE(op3d.ginput(idata3, kdata, bdata, odata));
                NANO_REQUIRE(op4d.ginput(idata4, kdata, bdata, odata));

                NANO_CHECK_EIGEN_CLOSE(idata3.array(), idata4.array(), 10 * epsilon0<scalar_t>());
        }
}

NANO_END_MODULE()
<commit_msg>numerically more robust unit test<commit_after>#include "utest.h"
#include "function.h"
#include "math/epsilon.h"
#include "layers/conv3d.h"
#include "layers/conv4d.h"

using namespace nano;

auto make_default_params(const tensor_size_t kconn = 1)
{
        const auto imaps = 6;
        const auto irows = 9;
        const auto icols = 8;
        const auto omaps = 4;
        const auto krows = 2;
        const auto kcols = 3;
        const auto kdrow = 2;
        const auto kdcol = 1;

        return conv_params_t{imaps, irows, icols, omaps, kconn, krows, kcols, kdrow, kdcol};
}

auto make_buffers(const conv_params_t& params, const tensor_size_t count)
{
        auto bdata = params.make_bdata(); bdata.setRandom();
        auto kdata = params.make_kdata(); kdata.vector().setRandom();
        auto idata = params.make_idata(count); idata.vector().setRandom();
        auto odata = params.make_odata(count); odata.vector().setRandom();
        return std::make_tuple(bdata, idata, kdata, odata);
}

template <typename top>
struct wrt_params_function_t final : public function_t
{
        explicit wrt_params_function_t(const top& op) :
                function_t("conv", op.params().psize(), op.params().psize(), op.params().psize(), convexity::no, 1e+6),
                m_op(op)
        {
                std::tie(m_bdata, m_idata, m_kdata, m_odata) = make_buffers(op.params(), 3);
        }

        scalar_t vgrad(const vector_t& x, vector_t* gx) const override
        {
                m_kdata = map_tensor(x.data(), m_kdata.dims());
                m_bdata = map_vector(x.data() + m_kdata.size(), m_bdata.size());
                m_op.output(m_idata, m_kdata, m_bdata, m_odata);
                if (gx)
                {
                        gx->resize(x.size());
                        auto kdata = map_tensor(gx->data(), m_kdata.dims());
                        auto bdata = map_vector(gx->data() + m_kdata.size(), m_bdata.size());
                        m_op.gparam(m_idata, kdata, bdata, m_odata);
                }
                return m_odata.array().square().sum() / 2;
        }

        mutable top             m_op;
        tensor4d_t              m_idata;
        mutable tensor4d_t      m_kdata;
        mutable vector_t        m_bdata;
        mutable tensor4d_t      m_odata;
};

template <typename top>
struct wrt_inputs_function_t final : public function_t
{
        explicit wrt_inputs_function_t(const top& op) :
                function_t("conv", op.params().isize(), op.params().isize(), op.params().isize(), convexity::no, 1e+6),
                m_op(op)
        {
                std::tie(m_bdata, m_idata, m_kdata, m_odata) = make_buffers(op.params(), 1);
        }

        scalar_t vgrad(const vector_t& x, vector_t* gx) const override
        {
                m_idata = map_tensor(x.data(), m_idata.dims());
                m_op.output(m_idata, m_kdata, m_bdata, m_odata);
                if (gx)
                {
                        gx->resize(x.size());
                        auto idata = map_tensor(gx->data(), m_idata.dims());
                        m_op.ginput(idata, m_kdata, m_bdata, m_odata);
                }
                return m_odata.array().square().sum() / 2;
        }

        mutable top             m_op;
        mutable tensor4d_t      m_idata;
        tensor4d_t              m_kdata;
        vector_t                m_bdata;
        mutable tensor4d_t      m_odata;
};

template <typename top>
auto make_wrt_params_function(const conv_params_t& params)
{
        return wrt_params_function_t<top>(top{params});
}

template <typename top>
auto make_wrt_inputs_function(const conv_params_t& params)
{
        return wrt_inputs_function_t<top>(top{params});
}

NANO_BEGIN_MODULE(test_conv)

NANO_CASE(params_valid)
{
        const auto imaps = 8;
        const auto irows = 11;
        const auto icols = 15;
        const auto omaps = 4;
        const auto kconn = 2;
        const auto krows = 3;
        const auto kcols = 5;
        const auto kdrow = 2;
        const auto kdcol = 1;

        const auto params = conv_params_t{imaps, irows, icols, omaps, kconn, krows, kcols, kdrow, kdcol};

        NANO_CHECK(params.valid_kernel());
        NANO_CHECK(params.valid_connectivity());
        NANO_CHECK(params.valid());

        NANO_CHECK_EQUAL(params.imaps(), imaps);
        NANO_CHECK_EQUAL(params.irows(), irows);
        NANO_CHECK_EQUAL(params.icols(), icols);

        NANO_CHECK_EQUAL(params.omaps(), omaps);
        NANO_CHECK_EQUAL(params.orows(), (irows - krows + 1) / kdrow);
        NANO_CHECK_EQUAL(params.ocols(), (icols - kcols + 1) / kdcol);

        NANO_CHECK_EQUAL(params.bdims(), omaps);
}

NANO_CASE(params_invalid)
{
        const auto imaps = 8;
        const auto irows = 11;
        const auto icols = 15;
        const auto omaps = 6;
        const auto kconn = 3;
        const auto krows = 13;
        const auto kcols = 5;
        const auto kdrow = 2;
        const auto kdcol = 7;

        const auto params = conv_params_t{imaps, irows, icols, omaps, kconn, krows, kcols, kdrow, kdcol};

        NANO_CHECK(!params.valid_kernel());
        NANO_CHECK(!params.valid_connectivity());
        NANO_CHECK(!params.valid());
}

NANO_CASE(gparam_accuracy)
{
        const auto params = make_default_params();
        NANO_REQUIRE(params.valid());

        const auto pfunct = make_wrt_params_function<conv3d_t>(params);
        for (int i = 0; i < 8; ++ i)
        {
                vector_t px(pfunct.size()); px.setRandom();
                NANO_CHECK_LESS(pfunct.grad_accuracy(px), epsilon1<scalar_t>());
        }
}

NANO_CASE(ginput_accuracy)
{
        const auto params = make_default_params();
        NANO_REQUIRE(params.valid());

        const auto ifunct = make_wrt_inputs_function<conv3d_t>(params);
        for (int i = 0; i < 8; ++ i)
        {
                vector_t ix(ifunct.size()); ix.setRandom();
                NANO_CHECK_LESS(ifunct.grad_accuracy(ix), epsilon1<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_output_kconn1)
{
        const auto params = make_default_params(1);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata, kdata, odata3, odata4;
                vector_t bdata;

                std::tie(bdata, idata, kdata, odata3) = make_buffers(params, i + 2);
                std::tie(bdata, idata, kdata, odata4) = make_buffers(params, i + 2);

                NANO_REQUIRE(op3d.output(idata, kdata, bdata, odata3));
                NANO_REQUIRE(op4d.output(idata, kdata, bdata, odata4));

                NANO_CHECK_EIGEN_CLOSE(odata3.array(), odata4.array(), epsilon1<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_output_kconn2)
{
        const auto params = make_default_params(2);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata, kdata, odata3, odata4;
                vector_t bdata;

                std::tie(bdata, idata, kdata, odata3) = make_buffers(params, i + 2);
                std::tie(bdata, idata, kdata, odata4) = make_buffers(params, i + 2);

                NANO_REQUIRE(op3d.output(idata, kdata, bdata, odata3));
                NANO_REQUIRE(op4d.output(idata, kdata, bdata, odata4));

                NANO_CHECK_EIGEN_CLOSE(odata3.array(), odata4.array(), epsilon1<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_gparam_kconn1)
{
        const auto params = make_default_params(1);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata, kdata3, kdata4, odata;
                vector_t bdata3, bdata4;

                std::tie(bdata3, idata, kdata3, odata) = make_buffers(params, i + 2);
                std::tie(bdata4, idata, kdata4, odata) = make_buffers(params, i + 2);

                NANO_REQUIRE(op4d.output(idata, kdata4, bdata4, odata));// NB: needed to update the internal buffers!
                NANO_REQUIRE(op3d.gparam(idata, kdata3, bdata3, odata));
                NANO_REQUIRE(op4d.gparam(idata, kdata4, bdata4, odata));

                NANO_CHECK_EIGEN_CLOSE(bdata3.array(), bdata4.array(), epsilon1<scalar_t>());
                NANO_CHECK_EIGEN_CLOSE(kdata3.array(), kdata4.array(), epsilon1<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_gparam_kconn2)
{
        const auto params = make_default_params(2);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata, kdata3, kdata4, odata;
                vector_t bdata3, bdata4;

                std::tie(bdata3, idata, kdata3, odata) = make_buffers(params, i + 2);
                std::tie(bdata4, idata, kdata4, odata) = make_buffers(params, i + 2);

                NANO_REQUIRE(op4d.output(idata, kdata4, bdata4, odata));// NB: needed to update the internal buffers!
                NANO_REQUIRE(op3d.gparam(idata, kdata3, bdata3, odata));
                NANO_REQUIRE(op4d.gparam(idata, kdata4, bdata4, odata));

                NANO_CHECK_EIGEN_CLOSE(bdata3.array(), bdata4.array(), epsilon1<scalar_t>());
                NANO_CHECK_EIGEN_CLOSE(kdata3.array(), kdata4.array(), epsilon1<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_ginput_kconn1)
{
        const auto params = make_default_params(1);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata3, idata4, kdata, odata;
                vector_t bdata;

                std::tie(bdata, idata3, kdata, odata) = make_buffers(params, i + 2);
                std::tie(bdata, idata4, kdata, odata) = make_buffers(params, i + 2);

                NANO_REQUIRE(op4d.output(idata4, kdata, bdata, odata));// NB: needed to update the internal buffers!
                NANO_REQUIRE(op3d.ginput(idata3, kdata, bdata, odata));
                NANO_REQUIRE(op4d.ginput(idata4, kdata, bdata, odata));

                NANO_CHECK_EIGEN_CLOSE(idata3.array(), idata4.array(), epsilon1<scalar_t>());
        }
}

NANO_CASE(3d_vs_4d_ginput_kconn2)
{
        const auto params = make_default_params(2);
        NANO_REQUIRE(params.valid());

        auto op3d = conv3d_t{params};
        auto op4d = conv4d_t{params};

        for (int i = 0; i < 8; ++ i)
        {
                tensor4d_t idata3, idata4, kdata, odata;
                vector_t bdata;

                std::tie(bdata, idata3, kdata, odata) = make_buffers(params, i + 2);
                std::tie(bdata, idata4, kdata, odata) = make_buffers(params, i + 2);

                NANO_REQUIRE(op4d.output(idata4, kdata, bdata, odata));// NB: needed to update the internal buffers!
                NANO_REQUIRE(op3d.ginput(idata3, kdata, bdata, odata));
                NANO_REQUIRE(op4d.ginput(idata4, kdata, bdata, odata));

                NANO_CHECK_EIGEN_CLOSE(idata3.array(), idata4.array(), epsilon1<scalar_t>());
        }
}

NANO_END_MODULE()
<|endoftext|>


<commit_before>/* Copyright 2009-2016 Francesco Biscani (bluescarni@gmail.com)

This file is part of the mp++ library.

The mp++ library is free software; you can redistribute it and/or modify
it under the terms of either:

  * the GNU Lesser General Public License as published by the Free
    Software Foundation; either version 3 of the License, or (at your
    option) any later version.

or

  * the GNU General Public License as published by the Free Software
    Foundation; either version 3 of the License, or (at your option) any
    later version.

or both in parallel, as here.

The mp++ library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the mp++ library.  If not,
see https://www.gnu.org/licenses/. */

#include <cstddef>
#include <gmp.h>
#include <random>
#include <tuple>
#include <type_traits>

#include <mp++.hpp>

#include "test_utils.hpp"

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

static int ntries = 1000;

using namespace mppp;
using namespace mppp_test;

using sizes = std::tuple<std::integral_constant<std::size_t, 1>, std::integral_constant<std::size_t, 2>,
                         std::integral_constant<std::size_t, 3>, std::integral_constant<std::size_t, 6>,
                         std::integral_constant<std::size_t, 10>>;

static std::mt19937 rng;

struct hash_tester {
    template <typename S>
    inline void operator()(const S &) const
    {
        using integer = mp_integer<S::value>;
        integer n1, n2;
        REQUIRE((hash(n1) == 0u));
        n1.promote();
        REQUIRE((hash(n1) == 0u));
        n1 = integer{12};
        n2 = n1;
        REQUIRE(n2.is_static());
        n1.promote();
        REQUIRE(n1.is_dynamic());
        REQUIRE((hash(n1) == hash(n1)));
#if 0
        ::mpz_abs(&m1.m_mpz, &m2.m_mpz);
        abs(n1, n2);
        REQUIRE((lex_cast(n1) == lex_cast(m1)));
        REQUIRE(n1.is_static());
        // Test the other variants.
        n1.abs();
        REQUIRE((lex_cast(n1) == lex_cast(m1)));
        REQUIRE(n1.is_static());
        REQUIRE((lex_cast(abs(n1)) == lex_cast(m1)));
        mpz_raii tmp;
        std::uniform_int_distribution<int> sdist(0, 1);
        // Run a variety of tests with operands with x number of limbs.
        auto random_xy = [&](unsigned x) {
            for (int i = 0; i < ntries; ++i) {
                if (sdist(rng) && sdist(rng) && sdist(rng)) {
                    // Reset rop every once in a while.
                    n1 = integer{};
                }
                random_integer(tmp, x, rng);
                ::mpz_set(&m2.m_mpz, &tmp.m_mpz);
                n2 = integer(mpz_to_str(&tmp.m_mpz));
                if (sdist(rng)) {
                    ::mpz_neg(&m2.m_mpz, &m2.m_mpz);
                    n2.neg();
                }
                ::mpz_abs(&m1.m_mpz, &m2.m_mpz);
                abs(n1, n2);
                REQUIRE((lex_cast(n1) == lex_cast(m1)));
                REQUIRE((n1 == abs(n2)));
                n2.abs();
                REQUIRE((n1 == n2));
            }
        };

        random_xy(0);
        random_xy(1);
        random_xy(2);
        random_xy(3);
        random_xy(4);
#endif
    }
};

TEST_CASE("hash")
{
    tuple_for_each(sizes{}, hash_tester{});
}
<commit_msg>More hash tests.<commit_after>/* Copyright 2009-2016 Francesco Biscani (bluescarni@gmail.com)

This file is part of the mp++ library.

The mp++ library is free software; you can redistribute it and/or modify
it under the terms of either:

  * the GNU Lesser General Public License as published by the Free
    Software Foundation; either version 3 of the License, or (at your
    option) any later version.

or

  * the GNU General Public License as published by the Free Software
    Foundation; either version 3 of the License, or (at your option) any
    later version.

or both in parallel, as here.

The mp++ library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the mp++ library.  If not,
see https://www.gnu.org/licenses/. */

#include <cstddef>
#include <gmp.h>
#include <random>
#include <tuple>
#include <type_traits>

#include <mp++.hpp>

#include "test_utils.hpp"

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

static int ntries = 1000;

using namespace mppp;
using namespace mppp_test;

using sizes = std::tuple<std::integral_constant<std::size_t, 1>, std::integral_constant<std::size_t, 2>,
                         std::integral_constant<std::size_t, 3>, std::integral_constant<std::size_t, 6>,
                         std::integral_constant<std::size_t, 10>>;

static std::mt19937 rng;

struct hash_tester {
    template <typename S>
    inline void operator()(const S &) const
    {
        using integer = mp_integer<S::value>;
        integer n1, n2;
        REQUIRE((hash(n1) == 0u));
        n1.promote();
        REQUIRE((hash(n1) == 0u));
        n1 = integer{12};
        n2 = n1;
        REQUIRE(n2.is_static());
        n1.promote();
        REQUIRE(n1.is_dynamic());
        REQUIRE((hash(n1) == hash(n2)));
        n1 = integer{-12};
        n2 = n1;
        REQUIRE(n2.is_static());
        n1.promote();
        REQUIRE(n1.is_dynamic());
        REQUIRE((hash(n1) == hash(n2)));
        mpz_raii tmp;
        std::uniform_int_distribution<int> sdist(0, 1);
        // Run a variety of tests with operands with x number of limbs.
        auto random_xy = [&](unsigned x) {
            for (int i = 0; i < ntries; ++i) {
                random_integer(tmp, x, rng);
                n1 = integer(mpz_to_str(&tmp.m_mpz));
                if (sdist(rng)) {
                    n1.neg();
                }
                n2 = n1;
                if (n2.is_static()) {
                    n1.promote();
                }
                REQUIRE((hash(n1) == hash(n2)));
            }
        };

        random_xy(0);
        random_xy(1);
        random_xy(2);
        random_xy(3);
        random_xy(4);
    }
};

TEST_CASE("hash")
{
    tuple_for_each(sizes{}, hash_tester{});
}
<|endoftext|>


<commit_before>#include <SDL.h>
#include <SDL_ttf.h>
#include <iostream>

SDL_Window* m_window;
SDL_Renderer* m_renderer;

int main(){

  if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) != 0){
    std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
    return false;
  }

  m_window = SDL_CreateWindow("GCW0 - SDL2", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, SDL_WINDOW_SHOWN);
  if (m_window == nullptr){
    std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
    return false;
  }

  m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
  if (m_renderer == nullptr){
    std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
    return false;
  }

  if (TTF_Init() != 0){
    std::cout << "TTF_Init Error: " << TTF_GetError() << std::endl;
    return false;
  }

  SDL_RenderSetLogicalSize(m_renderer, 320, 240);
  SDL_SetRenderDrawColor(m_renderer, 0, 0, 0, 255);
  SDL_ShowCursor(SDL_DISABLE);

  bool run = true;

  SDL_Event event;
  while(run){
    while (SDL_PollEvent(&event)) {
      if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE){
        run = false;
      } else if(event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE){
        run = false;
      }
    }
    SDL_RenderClear(m_renderer);
    SDL_RenderPresent(m_renderer);
  }

  TTF_Quit();
  SDL_DestroyRenderer(m_renderer);
  SDL_DestroyWindow(m_window);
  SDL_Quit();

  return 0;
}
<commit_msg>Load and display image full screen<commit_after>#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <iostream>

SDL_Window* m_window;
SDL_Renderer* m_renderer;

int main(){

    if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) != 0){
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return false;
    }

    m_window = SDL_CreateWindow("GCW0 - SDL2", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, SDL_WINDOW_SHOWN);
    if (m_window == nullptr){
        std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
        return false;
    }

    m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (m_renderer == nullptr){
        std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
        return false;
    }

    if (TTF_Init() != 0){
        std::cout << "TTF_Init Error: " << TTF_GetError() << std::endl;
        return false;
    }

    if(!(IMG_Init( IMG_INIT_PNG ) & IMG_INIT_PNG )){
        std::cout << "IMG_Init Error: " << IMG_GetError() << std::endl;
        return false;
    }

    SDL_Surface * image = IMG_Load("data/image.png");
    SDL_Texture * texture = SDL_CreateTextureFromSurface(m_renderer, image);

    SDL_RenderSetLogicalSize(m_renderer, 320, 240);
    SDL_SetRenderDrawColor(m_renderer, 0, 0, 0, 255);
    SDL_ShowCursor(SDL_DISABLE);

    bool run = true;

    SDL_Event event;
    while(run){
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE){
                run = false;
            } else if(event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE){
                run = false;
            }
        }
        SDL_RenderClear(m_renderer);
        SDL_RenderCopy(m_renderer, texture, NULL, NULL);
        SDL_RenderPresent(m_renderer);
    }

    SDL_DestroyTexture(texture);
    SDL_FreeSurface(image);
    IMG_Quit();
    TTF_Quit();
    SDL_DestroyRenderer(m_renderer);
    SDL_DestroyWindow(m_window);
    SDL_Quit();

    return 0;
}
<|endoftext|>


<commit_before>//=============================================================================
//File Name: Main.cpp
//Description: Handles processing Kinect input
//Author: Tyler Veness
//=============================================================================

/*
 * TODO Add support for multiple monitors
 */

#include "TestScreen.hpp"

#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

typedef struct tagINPUT INPUT, *PINPUT;

enum {
    IDC_RECALIBRATE_BUTTON = 101,
    IDC_STREAM_TOGGLE_BUTTON = 102
};

#include "Kinect.hpp"

// global because the drawing is set up to be continuous in CALLBACK OnEvent
HWND mainWindow = NULL;
HWND depthWindow = NULL;
HICON kinectON = NULL;
HICON kinectOFF = NULL;
Kinect* projectorKinectPtr = NULL;

LRESULT CALLBACK OnEvent( HWND Handle , UINT Message , WPARAM WParam , LPARAM LParam );

BOOL CALLBACK MonitorEnumProc(
    HMONITOR hMonitor,
    HDC hdcMonitor,
    LPRECT lprcMonitor,
    LPARAM dwData
);

INT WINAPI WinMain( HINSTANCE Instance , HINSTANCE , LPSTR , INT ) {
    const char* mainClassName = "KinectBoard";

    kinectON = LoadIcon( Instance , "kinect1-ON" );
    kinectOFF = LoadIcon( Instance , "kinect2-OFF" );

    HBRUSH mainBrush = CreateSolidBrush( RGB( 0 , 0 , 0 ) );

    // Define a class for our main window
    WNDCLASSEX WindowClass;
    ZeroMemory( &WindowClass , sizeof(WNDCLASSEX) );
    WindowClass.cbSize        = sizeof(WNDCLASSEX);
    WindowClass.style         = 0;
    WindowClass.lpfnWndProc   = &OnEvent;
    WindowClass.cbClsExtra    = 0;
    WindowClass.cbWndExtra    = 0;
    WindowClass.hInstance     = Instance;
    WindowClass.hIcon         = kinectOFF;
    WindowClass.hCursor       = NULL;
    WindowClass.hbrBackground = mainBrush;
    WindowClass.lpszMenuName  = NULL;
    WindowClass.lpszClassName = mainClassName;
    RegisterClassEx(&WindowClass);

    MSG Message;

    /* ===== Make a new window that isn't fullscreen ===== */
    RECT winSize = { 0 , 0 , static_cast<int>(ImageVars::width) , static_cast<int>(ImageVars::height) }; // set the size, but not the position
    AdjustWindowRect(
            &winSize ,
            WS_SYSMENU | WS_CAPTION | WS_VISIBLE | WS_MINIMIZEBOX | WS_CLIPCHILDREN ,
            FALSE ); // adjust the size

    // Create a new window to be used for the lifetime of the application
    mainWindow = CreateWindowEx( 0 ,
            mainClassName ,
            "KinectBoard - Video" ,
            WS_SYSMENU | WS_CAPTION | WS_VISIBLE | WS_MINIMIZEBOX | WS_CLIPCHILDREN ,
            ( GetSystemMetrics(SM_CXSCREEN) - ( winSize.right - winSize.left ) ) / 2 ,
            ( GetSystemMetrics(SM_CYSCREEN) - ( winSize.bottom - winSize.top ) ) / 2 ,
            winSize.right - winSize.left , // returns image width (resized as window)
            winSize.bottom - winSize.top , // returns image height (resized as window)
            NULL ,
            NULL ,
            Instance ,
            NULL );

    depthWindow = CreateWindowEx( 0 ,
            mainClassName ,
            "KinectBoard - Depth" ,
            WS_SYSMENU | WS_CAPTION | WS_VISIBLE | WS_MINIMIZEBOX | WS_CLIPCHILDREN ,
            ( GetSystemMetrics(SM_CXSCREEN) - ( winSize.right - winSize.left ) ) / 2 ,
            ( GetSystemMetrics(SM_CYSCREEN) - ( winSize.bottom - winSize.top ) ) / 2 ,
            winSize.right - winSize.left , // returns image width (resized as window)
            winSize.bottom - winSize.top , // returns image height (resized as window)
            NULL ,
            NULL ,
            Instance ,
            NULL );
    /* =================================================== */

    Kinect projectorKinect;
    projectorKinectPtr = &projectorKinect;

    // Make windows receive stream events from Kinect instance
    projectorKinect.registerVideoWindow( mainWindow );
    projectorKinect.registerDepthWindow( depthWindow );

    projectorKinect.startVideoStream();
    //projectorKinect.startDepthStream();
    projectorKinect.enableColor( Processing::Red );
    projectorKinect.enableColor( Processing::Blue );

    // Calibrate Kinect
    SendMessage( mainWindow , WM_COMMAND , IDC_RECALIBRATE_BUTTON , 0 );

    while ( GetMessage( &Message , NULL , 0 , 0 ) > 0 ) {
        // If a message was waiting in the message queue, process it
        TranslateMessage( &Message );
        DispatchMessage( &Message );
    }

    UnregisterClass( mainClassName , Instance );

    return Message.wParam;
}

LRESULT CALLBACK OnEvent( HWND Handle , UINT Message , WPARAM WParam , LPARAM LParam ) {
    switch ( Message ) {
    case WM_CREATE: {
        HWND recalibButton = CreateWindowEx( 0,
                "BUTTON",
                "Recalibrate",
                WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                9,
                ImageVars::height - 9 - 24,
                100,
                24,
                Handle,
                reinterpret_cast<HMENU>( IDC_RECALIBRATE_BUTTON ),
                GetModuleHandle( NULL ),
                NULL);

        SendMessage( recalibButton,
                WM_SETFONT,
                reinterpret_cast<WPARAM>( GetStockObject( DEFAULT_GUI_FONT ) ),
                MAKELPARAM( FALSE , 0 ) );

        HWND toggleStreamButton = CreateWindowEx( 0,
                "BUTTON",
                "Start/Stop",
                WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                ImageVars::width - 9 - 100,
                ImageVars::height - 9 - 24,
                100,
                24,
                Handle,
                reinterpret_cast<HMENU>( IDC_STREAM_TOGGLE_BUTTON ),
                GetModuleHandle( NULL ),
                NULL);

        SendMessage( toggleStreamButton,
                WM_SETFONT,
                reinterpret_cast<WPARAM>( GetStockObject( DEFAULT_GUI_FONT ) ),
                MAKELPARAM( FALSE , 0 ) );

        break;
    }

    case WM_COMMAND: {
        switch( LOWORD(WParam) ) {
            case IDC_RECALIBRATE_BUTTON: {
                if ( projectorKinectPtr != NULL ) {
                    // if there is no Kinect connected, don't bother trying to retrieve images
                    if ( projectorKinectPtr->isVideoStreamRunning() ) {
                        sf::TestScreen testWin( "KinectBoard" , Handle , NULL );

                        testWin.setColor( Processing::Red );
                        testWin.display();
                        Sleep( 600 ); // give Kinect time to get image w/ test pattern
                        projectorKinectPtr->setCalibImage( Processing::Red );

                        testWin.setColor( Processing::Blue );
                        testWin.display();
                        Sleep( 600 ); // give Kinect time to get image w/ test pattern
                        projectorKinectPtr->setCalibImage( Processing::Blue );

                        projectorKinectPtr->calibrate();

                        testWin.close();
                    }
                }

                break;
            }

            case IDC_STREAM_TOGGLE_BUTTON: {
                if ( projectorKinectPtr != NULL ) {
                    // If button was pressed from video display window
                    if ( Handle == mainWindow ) {
                        if ( projectorKinectPtr->isVideoStreamRunning() ) {
                            projectorKinectPtr->stopVideoStream();
                        }
                        else {
                            projectorKinectPtr->startVideoStream();
                        }
                    }

                    // If button was pressed from depth image display window
                    else if ( Handle == depthWindow ) {
                        if ( projectorKinectPtr->isDepthStreamRunning() ) {
                            projectorKinectPtr->stopDepthStream();
                        }
                        else {
                            projectorKinectPtr->startDepthStream();
                        }
                    }
                }

                break;
            }
        }

        break;
    }

    case WM_PAINT: {
        PAINTSTRUCT ps;
        HDC hdc;

        hdc = BeginPaint( Handle , &ps );

        // If we're painting the video display window
        if ( Handle == mainWindow ) {
            projectorKinectPtr->displayVideo( mainWindow , 0 , 0 , hdc );
        }

        // If we're painting the depth image display window
        else if ( Handle == depthWindow ) {
            projectorKinectPtr->displayDepth( depthWindow , 0 , 0 , hdc );
        }

        EndPaint( Handle , &ps );

        break;
    }

    case WM_DESTROY: {
        // If a display window is being closed, exit the application
        if ( Handle == mainWindow || Handle == depthWindow ) {
            PostQuitMessage( 0 );
        }

        break;
    }

    case WM_KINECT_VIDEOSTART: {
        // Change video window icon to green because the stream started
        PostMessage( Handle , WM_SETICON , ICON_SMALL , (LPARAM)kinectON );
        PostMessage( Handle , WM_SETICON , ICON_BIG , (LPARAM)kinectON );

        break;
    }

    case WM_KINECT_VIDEOSTOP: {
        // Change video window icon to red because the stream stopped
        PostMessage( Handle , WM_SETICON , ICON_SMALL , (LPARAM)kinectOFF );
        PostMessage( Handle , WM_SETICON , ICON_BIG , (LPARAM)kinectOFF );

        break;
    }

    case WM_KINECT_DEPTHSTART: {
        // Change depth window icon to green because the stream started
        PostMessage( Handle , WM_SETICON , ICON_SMALL , (LPARAM)kinectON );
        PostMessage( Handle , WM_SETICON , ICON_BIG , (LPARAM)kinectON );

        break;
    }

    case WM_KINECT_DEPTHSTOP: {
        // Change depth window icon to red because the stream stopped
        PostMessage( Handle , WM_SETICON , ICON_SMALL , (LPARAM)kinectOFF );
        PostMessage( Handle , WM_SETICON , ICON_BIG , (LPARAM)kinectOFF );

        break;
    }

    default: {
        return DefWindowProc( Handle , Message , WParam , LParam );
    }
    }

    return 0;
}

BOOL CALLBACK MonitorEnumProc(
    HMONITOR hMonitor,
    HDC hdcMonitor,
    LPRECT lprcMonitor,
    LPARAM dwData
) {
    return FALSE;
}
<commit_msg>Removed unecessary #define in Main.cpp ; renamed HWND mainWindow to videoWindow because it doesn't have any more significance than HWND depthWindow<commit_after>//=============================================================================
//File Name: Main.cpp
//Description: Handles processing Kinect input
//Author: Tyler Veness
//=============================================================================

/*
 * TODO Add support for multiple monitors
 */

#include "TestScreen.hpp"

#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

enum {
    IDC_RECALIBRATE_BUTTON = 101,
    IDC_STREAM_TOGGLE_BUTTON = 102
};

#include "Kinect.hpp"

// global because the drawing is set up to be continuous in CALLBACK OnEvent
HWND videoWindow = NULL;
HWND depthWindow = NULL;
HICON kinectON = NULL;
HICON kinectOFF = NULL;
Kinect* projectorKinectPtr = NULL;

LRESULT CALLBACK OnEvent( HWND Handle , UINT Message , WPARAM WParam , LPARAM LParam );

BOOL CALLBACK MonitorEnumProc(
    HMONITOR hMonitor,
    HDC hdcMonitor,
    LPRECT lprcMonitor,
    LPARAM dwData
);

INT WINAPI WinMain( HINSTANCE Instance , HINSTANCE , LPSTR , INT ) {
    const char* mainClassName = "KinectBoard";

    kinectON = LoadIcon( Instance , "kinect1-ON" );
    kinectOFF = LoadIcon( Instance , "kinect2-OFF" );

    HBRUSH mainBrush = CreateSolidBrush( RGB( 0 , 0 , 0 ) );

    // Define a class for our main window
    WNDCLASSEX WindowClass;
    ZeroMemory( &WindowClass , sizeof(WNDCLASSEX) );
    WindowClass.cbSize        = sizeof(WNDCLASSEX);
    WindowClass.style         = 0;
    WindowClass.lpfnWndProc   = &OnEvent;
    WindowClass.cbClsExtra    = 0;
    WindowClass.cbWndExtra    = 0;
    WindowClass.hInstance     = Instance;
    WindowClass.hIcon         = kinectOFF;
    WindowClass.hCursor       = NULL;
    WindowClass.hbrBackground = mainBrush;
    WindowClass.lpszMenuName  = NULL;
    WindowClass.lpszClassName = mainClassName;
    WindowClass.hIconSm       = kinectOFF;
    RegisterClassEx(&WindowClass);

    MSG Message;

    /* ===== Make a new window that isn't fullscreen ===== */
    RECT winSize = { 0 , 0 , static_cast<int>(ImageVars::width) , static_cast<int>(ImageVars::height) }; // set the size, but not the position
    AdjustWindowRect(
            &winSize ,
            WS_SYSMENU | WS_CAPTION | WS_VISIBLE | WS_MINIMIZEBOX | WS_CLIPCHILDREN ,
            FALSE ); // adjust the size

    // Create a new window to be used for the lifetime of the application
    videoWindow = CreateWindowEx( 0 ,
            mainClassName ,
            "KinectBoard - Video" ,
            WS_SYSMENU | WS_CAPTION | WS_VISIBLE | WS_MINIMIZEBOX | WS_CLIPCHILDREN ,
            ( GetSystemMetrics(SM_CXSCREEN) - ( winSize.right - winSize.left ) ) / 2 ,
            ( GetSystemMetrics(SM_CYSCREEN) - ( winSize.bottom - winSize.top ) ) / 2 ,
            winSize.right - winSize.left , // returns image width (resized as window)
            winSize.bottom - winSize.top , // returns image height (resized as window)
            NULL ,
            NULL ,
            Instance ,
            NULL );

    depthWindow = CreateWindowEx( 0 ,
            mainClassName ,
            "KinectBoard - Depth" ,
            WS_SYSMENU | WS_CAPTION | WS_VISIBLE | WS_MINIMIZEBOX | WS_CLIPCHILDREN ,
            ( GetSystemMetrics(SM_CXSCREEN) - ( winSize.right - winSize.left ) ) / 2 ,
            ( GetSystemMetrics(SM_CYSCREEN) - ( winSize.bottom - winSize.top ) ) / 2 ,
            winSize.right - winSize.left , // returns image width (resized as window)
            winSize.bottom - winSize.top , // returns image height (resized as window)
            NULL ,
            NULL ,
            Instance ,
            NULL );
    /* =================================================== */

    Kinect projectorKinect;
    projectorKinectPtr = &projectorKinect;

    // Make windows receive stream events from Kinect instance
    projectorKinect.registerVideoWindow( videoWindow );
    projectorKinect.registerDepthWindow( depthWindow );

    projectorKinect.startVideoStream();
    //projectorKinect.startDepthStream();
    projectorKinect.enableColor( Processing::Red );
    projectorKinect.enableColor( Processing::Blue );

    // Calibrate Kinect
    SendMessage( videoWindow , WM_COMMAND , IDC_RECALIBRATE_BUTTON , 0 );

    while ( GetMessage( &Message , NULL , 0 , 0 ) > 0 ) {
        // If a message was waiting in the message queue, process it
        TranslateMessage( &Message );
        DispatchMessage( &Message );
    }

    UnregisterClass( mainClassName , Instance );

    return Message.wParam;
}

LRESULT CALLBACK OnEvent( HWND Handle , UINT Message , WPARAM WParam , LPARAM LParam ) {
    switch ( Message ) {
    case WM_CREATE: {
        HWND recalibButton = CreateWindowEx( 0,
                "BUTTON",
                "Recalibrate",
                WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                9,
                ImageVars::height - 9 - 24,
                100,
                24,
                Handle,
                reinterpret_cast<HMENU>( IDC_RECALIBRATE_BUTTON ),
                GetModuleHandle( NULL ),
                NULL);

        SendMessage( recalibButton,
                WM_SETFONT,
                reinterpret_cast<WPARAM>( GetStockObject( DEFAULT_GUI_FONT ) ),
                MAKELPARAM( FALSE , 0 ) );

        HWND toggleStreamButton = CreateWindowEx( 0,
                "BUTTON",
                "Start/Stop",
                WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                ImageVars::width - 9 - 100,
                ImageVars::height - 9 - 24,
                100,
                24,
                Handle,
                reinterpret_cast<HMENU>( IDC_STREAM_TOGGLE_BUTTON ),
                GetModuleHandle( NULL ),
                NULL);

        SendMessage( toggleStreamButton,
                WM_SETFONT,
                reinterpret_cast<WPARAM>( GetStockObject( DEFAULT_GUI_FONT ) ),
                MAKELPARAM( FALSE , 0 ) );

        break;
    }

    case WM_COMMAND: {
        switch( LOWORD(WParam) ) {
            case IDC_RECALIBRATE_BUTTON: {
                if ( projectorKinectPtr != NULL ) {
                    // if there is no Kinect connected, don't bother trying to retrieve images
                    if ( projectorKinectPtr->isVideoStreamRunning() ) {
                        sf::TestScreen testWin( "KinectBoard" , Handle , NULL );

                        testWin.setColor( Processing::Red );
                        testWin.display();
                        Sleep( 600 ); // give Kinect time to get image w/ test pattern
                        projectorKinectPtr->setCalibImage( Processing::Red );

                        testWin.setColor( Processing::Blue );
                        testWin.display();
                        Sleep( 600 ); // give Kinect time to get image w/ test pattern
                        projectorKinectPtr->setCalibImage( Processing::Blue );

                        projectorKinectPtr->calibrate();

                        testWin.close();
                    }
                }

                break;
            }

            case IDC_STREAM_TOGGLE_BUTTON: {
                if ( projectorKinectPtr != NULL ) {
                    // If button was pressed from video display window
                    if ( Handle == videoWindow ) {
                        if ( projectorKinectPtr->isVideoStreamRunning() ) {
                            projectorKinectPtr->stopVideoStream();
                        }
                        else {
                            projectorKinectPtr->startVideoStream();
                        }
                    }

                    // If button was pressed from depth image display window
                    else if ( Handle == depthWindow ) {
                        if ( projectorKinectPtr->isDepthStreamRunning() ) {
                            projectorKinectPtr->stopDepthStream();
                        }
                        else {
                            projectorKinectPtr->startDepthStream();
                        }
                    }
                }

                break;
            }
        }

        break;
    }

    case WM_PAINT: {
        PAINTSTRUCT ps;
        HDC hdc;

        hdc = BeginPaint( Handle , &ps );

        // If we're painting the video display window
        if ( Handle == videoWindow ) {
            projectorKinectPtr->displayVideo( videoWindow , 0 , 0 , hdc );
        }

        // If we're painting the depth image display window
        else if ( Handle == depthWindow ) {
            projectorKinectPtr->displayDepth( depthWindow , 0 , 0 , hdc );
        }

        EndPaint( Handle , &ps );

        break;
    }

    case WM_DESTROY: {
        // If a display window is being closed, exit the application
        if ( Handle == videoWindow || Handle == depthWindow ) {
            PostQuitMessage( 0 );
        }

        break;
    }

    case WM_KINECT_VIDEOSTART: {
        // Change video window icon to green because the stream started
        PostMessage( Handle , WM_SETICON , ICON_SMALL , (LPARAM)kinectON );
        PostMessage( Handle , WM_SETICON , ICON_BIG , (LPARAM)kinectON );

        break;
    }

    case WM_KINECT_VIDEOSTOP: {
        // Change video window icon to red because the stream stopped
        PostMessage( Handle , WM_SETICON , ICON_SMALL , (LPARAM)kinectOFF );
        PostMessage( Handle , WM_SETICON , ICON_BIG , (LPARAM)kinectOFF );

        break;
    }

    case WM_KINECT_DEPTHSTART: {
        // Change depth window icon to green because the stream started
        PostMessage( Handle , WM_SETICON , ICON_SMALL , (LPARAM)kinectON );
        PostMessage( Handle , WM_SETICON , ICON_BIG , (LPARAM)kinectON );

        break;
    }

    case WM_KINECT_DEPTHSTOP: {
        // Change depth window icon to red because the stream stopped
        PostMessage( Handle , WM_SETICON , ICON_SMALL , (LPARAM)kinectOFF );
        PostMessage( Handle , WM_SETICON , ICON_BIG , (LPARAM)kinectOFF );

        break;
    }

    default: {
        return DefWindowProc( Handle , Message , WParam , LParam );
    }
    }

    return 0;
}

BOOL CALLBACK MonitorEnumProc(
    HMONITOR hMonitor,
    HDC hdcMonitor,
    LPRECT lprcMonitor,
    LPARAM dwData
) {
    return FALSE;
}
<|endoftext|>