<commit_before>// Copyright (c) 2011-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#endif

#include "clientversion.h"

#include "intro.h"
#include "ui_intro.h"

#include "guiutil.h"

#include "util.h"

#include <boost/filesystem.hpp>

#include <QFileDialog>
#include <QSettings>
#include <QMessageBox>

#include <cmath>

static const uint64_t GB_BYTES = 1000000000LL;
/* Minimum free space (in GB) needed for data directory */
static const uint64_t BLOCK_CHAIN_SIZE = 120;
/* Minimum free space (in GB) needed for data directory when pruned; Does not include prune target */
static const uint64_t CHAIN_STATE_SIZE = 2;
/* Total required space (in GB) depending on user choice (prune, not prune) */
static uint64_t requiredSpace;

/* Check free space asynchronously to prevent hanging the UI thread.

   Up to one request to check a path is in flight to this thread; when the check()
   function runs, the current path is requested from the associated Intro object.
   The reply is sent back through a signal.

   This ensures that no queue of checking requests is built up while the user is
   still entering the path, and that always the most recently entered path is checked as
   soon as the thread becomes available.
*/
class FreespaceChecker : public QObject
{
    Q_OBJECT

public:
    FreespaceChecker(Intro *intro);

    enum Status {
        ST_OK,
        ST_ERROR
    };

public Q_SLOTS:
    void check();

Q_SIGNALS:
    void reply(int status, const QString &message, quint64 available);

private:
    Intro *intro;
};

#include "intro.moc"

FreespaceChecker::FreespaceChecker(Intro *_intro)
{
    this->intro = _intro;
}

void FreespaceChecker::check()
{
    namespace fs = boost::filesystem;
    QString dataDirStr = intro->getPathToCheck();
    fs::path dataDir = GUIUtil::qstringToBoostPath(dataDirStr);
    uint64_t freeBytesAvailable = 0;
    int replyStatus = ST_OK;
    QString replyMessage = tr("A new data directory will be created.");

    /* Find first parent that exists, so that fs::space does not fail */
    fs::path parentDir = dataDir;
    fs::path parentDirOld = fs::path();
    while(parentDir.has_parent_path() && !fs::exists(parentDir))
    {
        parentDir = parentDir.parent_path();

        /* Check if we make any progress, break if not to prevent an infinite loop here */
        if (parentDirOld == parentDir)
            break;

        parentDirOld = parentDir;
    }

    try {
        freeBytesAvailable = fs::space(parentDir).available;
        if(fs::exists(dataDir))
        {
            if(fs::is_directory(dataDir))
            {
                QString separator = "" + QDir::toNativeSeparators("/") + tr("name") + "";
                replyStatus = ST_OK;
                replyMessage = tr("Directory already exists. Add %1 if you intend to create a new directory here.").arg(separator);
            } else {
                replyStatus = ST_ERROR;
                replyMessage = tr("Path already exists, and is not a directory.");
            }
        }
    } catch (const fs::filesystem_error&)
    {
        /* Parent directory does not exist or is not accessible */
        replyStatus = ST_ERROR;
        replyMessage = tr("Cannot create data directory here.");
    }
    Q_EMIT reply(replyStatus, replyMessage, freeBytesAvailable);
}

Intro::Intro(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Intro),
    thread(0),
    signalled(false)
{
    ui->setupUi(this);
    ui->welcomeLabel->setText(ui->welcomeLabel->text().arg(tr(PACKAGE_NAME)));
    ui->storageLabel->setText(ui->storageLabel->text().arg(tr(PACKAGE_NAME)));
    uint64_t pruneTarget = std::max<int64_t>(0, GetArg("-prune", 0));
    requiredSpace = BLOCK_CHAIN_SIZE;
    if (pruneTarget) {
        uint64_t prunedGBs = std::ceil(pruneTarget * 1024 * 1024.0 / GB_BYTES);
        if (prunedGBs <= requiredSpace) {
            requiredSpace = prunedGBs;
        }
    }
    requiredSpace += CHAIN_STATE_SIZE;
    ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(tr(PACKAGE_NAME)).arg(requiredSpace));
    startThread();
}

Intro::~Intro()
{
    delete ui;
    /* Ensure thread is finished before it is deleted */
    Q_EMIT stopThread();
    thread->wait();
}

QString Intro::getDataDirectory()
{
    return ui->dataDirectory->text();
}

void Intro::setDataDirectory(const QString &dataDir)
{
    ui->dataDirectory->setText(dataDir);
    if(dataDir == getDefaultDataDirectory())
    {
        ui->dataDirDefault->setChecked(true);
        ui->dataDirectory->setEnabled(false);
        ui->ellipsisButton->setEnabled(false);
    } else {
        ui->dataDirCustom->setChecked(true);
        ui->dataDirectory->setEnabled(true);
        ui->ellipsisButton->setEnabled(true);
    }
}

QString Intro::getDefaultDataDirectory()
{
    return GUIUtil::boostPathToQString(GetDefaultDataDir());
}

bool Intro::pickDataDirectory()
{
    namespace fs = boost::filesystem;
    QSettings settings;
    /* If data directory provided on command line, no need to look at settings
       or show a picking dialog */
    if(!GetArg("-datadir", "").empty())
        return true;
    /* 1) Default data directory for operating system */
    QString dataDir = getDefaultDataDirectory();
    /* 2) Allow QSettings to override default dir */
    dataDir = settings.value("strDataDir", dataDir).toString();

    if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR) || settings.value("fReset", false).toBool() || GetBoolArg("-resetguisettings", false))
    {
        /* If current default data directory does not exist, let the user choose one */
        Intro intro;
        intro.setDataDirectory(dataDir);
        intro.setWindowIcon(QIcon(":icons/bitcoin"));

        while(true)
        {
            if(!intro.exec())
            {
                /* Cancel clicked */
                return false;
            }
            dataDir = intro.getDataDirectory();
            try {
                TryCreateDirectory(GUIUtil::qstringToBoostPath(dataDir));
                break;
            } catch (const fs::filesystem_error&) {
                QMessageBox::critical(0, tr(PACKAGE_NAME),
                    tr("Error: Specified data directory \"%1\" cannot be created.").arg(dataDir));
                /* fall through, back to choosing screen */
            }
        }

        settings.setValue("strDataDir", dataDir);
        settings.setValue("fReset", false);
    }
    /* Only override -datadir if different from the default, to make it possible to
     * override -datadir in the bitcoin.conf file in the default data directory
     * (to be consistent with bitcoind behavior)
     */
    if(dataDir != getDefaultDataDirectory())
        SoftSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting
    return true;
}

void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable)
{
    switch(status)
    {
    case FreespaceChecker::ST_OK:
        ui->errorMessage->setText(message);
        ui->errorMessage->setStyleSheet("");
        break;
    case FreespaceChecker::ST_ERROR:
        ui->errorMessage->setText(tr("Error") + ": " + message);
        ui->errorMessage->setStyleSheet("QLabel { color: #800000 }");
        break;
    }
    /* Indicate number of bytes available */
    if(status == FreespaceChecker::ST_ERROR)
    {
        ui->freeSpace->setText("");
    } else {
        QString freeString = tr("%n GB of free space available", "", bytesAvailable/GB_BYTES);
        if(bytesAvailable < requiredSpace * GB_BYTES)
        {
            freeString += " " + tr("(of %n GB needed)", "", requiredSpace);
            ui->freeSpace->setStyleSheet("QLabel { color: #800000 }");
        } else {
            ui->freeSpace->setStyleSheet("");
        }
        ui->freeSpace->setText(freeString + ".");
    }
    /* Don't allow confirm in ERROR state */
    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(status != FreespaceChecker::ST_ERROR);
}

void Intro::on_dataDirectory_textChanged(const QString &dataDirStr)
{
    /* Disable OK button until check result comes in */
    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
    checkPath(dataDirStr);
}

void Intro::on_ellipsisButton_clicked()
{
    QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(0, "Choose data directory", ui->dataDirectory->text()));
    if(!dir.isEmpty())
        ui->dataDirectory->setText(dir);
}

void Intro::on_dataDirDefault_clicked()
{
    setDataDirectory(getDefaultDataDirectory());
}

void Intro::on_dataDirCustom_clicked()
{
    ui->dataDirectory->setEnabled(true);
    ui->ellipsisButton->setEnabled(true);
}

void Intro::startThread()
{
    thread = new QThread(this);
    FreespaceChecker *executor = new FreespaceChecker(this);
    executor->moveToThread(thread);

    connect(executor, SIGNAL(reply(int,QString,quint64)), this, SLOT(setStatus(int,QString,quint64)));
    connect(this, SIGNAL(requestCheck()), executor, SLOT(check()));
    /*  make sure executor object is deleted in its own thread */
    connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater()));
    connect(this, SIGNAL(stopThread()), thread, SLOT(quit()));

    thread->start();
}

void Intro::checkPath(const QString &dataDir)
{
    mutex.lock();
    pathToCheck = dataDir;
    if(!signalled)
    {
        signalled = true;
        Q_EMIT requestCheck();
    }
    mutex.unlock();
}

QString Intro::getPathToCheck()
{
    QString retval;
    mutex.lock();
    retval = pathToCheck;
    signalled = false; /* new request can be queued now */
    mutex.unlock();
    return retval;
}
<commit_msg>change blockchain size, bitcoin to c0ban.<commit_after>// Copyright (c) 2011-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#endif

#include "clientversion.h"

#include "intro.h"
#include "ui_intro.h"

#include "guiutil.h"

#include "util.h"

#include <boost/filesystem.hpp>

#include <QFileDialog>
#include <QSettings>
#include <QMessageBox>

#include <cmath>

static const uint64_t GB_BYTES = 1000000000LL;
/* Minimum free space (in GB) needed for data directory */
static const uint64_t BLOCK_CHAIN_SIZE = 1;
/* Minimum free space (in GB) needed for data directory when pruned; Does not include prune target */
static const uint64_t CHAIN_STATE_SIZE = 2;
/* Total required space (in GB) depending on user choice (prune, not prune) */
static uint64_t requiredSpace;

/* Check free space asynchronously to prevent hanging the UI thread.

   Up to one request to check a path is in flight to this thread; when the check()
   function runs, the current path is requested from the associated Intro object.
   The reply is sent back through a signal.

   This ensures that no queue of checking requests is built up while the user is
   still entering the path, and that always the most recently entered path is checked as
   soon as the thread becomes available.
*/
class FreespaceChecker : public QObject
{
    Q_OBJECT

public:
    FreespaceChecker(Intro *intro);

    enum Status {
        ST_OK,
        ST_ERROR
    };

public Q_SLOTS:
    void check();

Q_SIGNALS:
    void reply(int status, const QString &message, quint64 available);

private:
    Intro *intro;
};

#include "intro.moc"

FreespaceChecker::FreespaceChecker(Intro *_intro)
{
    this->intro = _intro;
}

void FreespaceChecker::check()
{
    namespace fs = boost::filesystem;
    QString dataDirStr = intro->getPathToCheck();
    fs::path dataDir = GUIUtil::qstringToBoostPath(dataDirStr);
    uint64_t freeBytesAvailable = 0;
    int replyStatus = ST_OK;
    QString replyMessage = tr("A new data directory will be created.");

    /* Find first parent that exists, so that fs::space does not fail */
    fs::path parentDir = dataDir;
    fs::path parentDirOld = fs::path();
    while(parentDir.has_parent_path() && !fs::exists(parentDir))
    {
        parentDir = parentDir.parent_path();

        /* Check if we make any progress, break if not to prevent an infinite loop here */
        if (parentDirOld == parentDir)
            break;

        parentDirOld = parentDir;
    }

    try {
        freeBytesAvailable = fs::space(parentDir).available;
        if(fs::exists(dataDir))
        {
            if(fs::is_directory(dataDir))
            {
                QString separator = "" + QDir::toNativeSeparators("/") + tr("name") + "";
                replyStatus = ST_OK;
                replyMessage = tr("Directory already exists. Add %1 if you intend to create a new directory here.").arg(separator);
            } else {
                replyStatus = ST_ERROR;
                replyMessage = tr("Path already exists, and is not a directory.");
            }
        }
    } catch (const fs::filesystem_error&)
    {
        /* Parent directory does not exist or is not accessible */
        replyStatus = ST_ERROR;
        replyMessage = tr("Cannot create data directory here.");
    }
    Q_EMIT reply(replyStatus, replyMessage, freeBytesAvailable);
}

Intro::Intro(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Intro),
    thread(0),
    signalled(false)
{
    ui->setupUi(this);
    ui->welcomeLabel->setText(ui->welcomeLabel->text().arg(tr(PACKAGE_NAME)));
    ui->storageLabel->setText(ui->storageLabel->text().arg(tr(PACKAGE_NAME)));
    uint64_t pruneTarget = std::max<int64_t>(0, GetArg("-prune", 0));
    requiredSpace = BLOCK_CHAIN_SIZE;
    if (pruneTarget) {
        uint64_t prunedGBs = std::ceil(pruneTarget * 1024 * 1024.0 / GB_BYTES);
        if (prunedGBs <= requiredSpace) {
            requiredSpace = prunedGBs;
        }
    }
    requiredSpace += CHAIN_STATE_SIZE;
    ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(tr(PACKAGE_NAME)).arg(requiredSpace));
    startThread();
}

Intro::~Intro()
{
    delete ui;
    /* Ensure thread is finished before it is deleted */
    Q_EMIT stopThread();
    thread->wait();
}

QString Intro::getDataDirectory()
{
    return ui->dataDirectory->text();
}

void Intro::setDataDirectory(const QString &dataDir)
{
    ui->dataDirectory->setText(dataDir);
    if(dataDir == getDefaultDataDirectory())
    {
        ui->dataDirDefault->setChecked(true);
        ui->dataDirectory->setEnabled(false);
        ui->ellipsisButton->setEnabled(false);
    } else {
        ui->dataDirCustom->setChecked(true);
        ui->dataDirectory->setEnabled(true);
        ui->ellipsisButton->setEnabled(true);
    }
}

QString Intro::getDefaultDataDirectory()
{
    return GUIUtil::boostPathToQString(GetDefaultDataDir());
}

bool Intro::pickDataDirectory()
{
    namespace fs = boost::filesystem;
    QSettings settings;
    /* If data directory provided on command line, no need to look at settings
       or show a picking dialog */
    if(!GetArg("-datadir", "").empty())
        return true;
    /* 1) Default data directory for operating system */
    QString dataDir = getDefaultDataDirectory();
    /* 2) Allow QSettings to override default dir */
    dataDir = settings.value("strDataDir", dataDir).toString();

    if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR) || settings.value("fReset", false).toBool() || GetBoolArg("-resetguisettings", false))
    {
        /* If current default data directory does not exist, let the user choose one */
        Intro intro;
        intro.setDataDirectory(dataDir);
        intro.setWindowIcon(QIcon(":icons/bitcoin"));

        while(true)
        {
            if(!intro.exec())
            {
                /* Cancel clicked */
                return false;
            }
            dataDir = intro.getDataDirectory();
            try {
                TryCreateDirectory(GUIUtil::qstringToBoostPath(dataDir));
                break;
            } catch (const fs::filesystem_error&) {
                QMessageBox::critical(0, tr(PACKAGE_NAME),
                    tr("Error: Specified data directory \"%1\" cannot be created.").arg(dataDir));
                /* fall through, back to choosing screen */
            }
        }

        settings.setValue("strDataDir", dataDir);
        settings.setValue("fReset", false);
    }
    /* Only override -datadir if different from the default, to make it possible to
     * override -datadir in the bitcoin.conf file in the default data directory
     * (to be consistent with bitcoind behavior)
     */
    if(dataDir != getDefaultDataDirectory())
        SoftSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting
    return true;
}

void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable)
{
    switch(status)
    {
    case FreespaceChecker::ST_OK:
        ui->errorMessage->setText(message);
        ui->errorMessage->setStyleSheet("");
        break;
    case FreespaceChecker::ST_ERROR:
        ui->errorMessage->setText(tr("Error") + ": " + message);
        ui->errorMessage->setStyleSheet("QLabel { color: #800000 }");
        break;
    }
    /* Indicate number of bytes available */
    if(status == FreespaceChecker::ST_ERROR)
    {
        ui->freeSpace->setText("");
    } else {
        QString freeString = tr("%n GB of free space available", "", bytesAvailable/GB_BYTES);
        if(bytesAvailable < requiredSpace * GB_BYTES)
        {
            freeString += " " + tr("(of %n GB needed)", "", requiredSpace);
            ui->freeSpace->setStyleSheet("QLabel { color: #800000 }");
        } else {
            ui->freeSpace->setStyleSheet("");
        }
        ui->freeSpace->setText(freeString + ".");
    }
    /* Don't allow confirm in ERROR state */
    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(status != FreespaceChecker::ST_ERROR);
}

void Intro::on_dataDirectory_textChanged(const QString &dataDirStr)
{
    /* Disable OK button until check result comes in */
    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
    checkPath(dataDirStr);
}

void Intro::on_ellipsisButton_clicked()
{
    QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(0, "Choose data directory", ui->dataDirectory->text()));
    if(!dir.isEmpty())
        ui->dataDirectory->setText(dir);
}

void Intro::on_dataDirDefault_clicked()
{
    setDataDirectory(getDefaultDataDirectory());
}

void Intro::on_dataDirCustom_clicked()
{
    ui->dataDirectory->setEnabled(true);
    ui->ellipsisButton->setEnabled(true);
}

void Intro::startThread()
{
    thread = new QThread(this);
    FreespaceChecker *executor = new FreespaceChecker(this);
    executor->moveToThread(thread);

    connect(executor, SIGNAL(reply(int,QString,quint64)), this, SLOT(setStatus(int,QString,quint64)));
    connect(this, SIGNAL(requestCheck()), executor, SLOT(check()));
    /*  make sure executor object is deleted in its own thread */
    connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater()));
    connect(this, SIGNAL(stopThread()), thread, SLOT(quit()));

    thread->start();
}

void Intro::checkPath(const QString &dataDir)
{
    mutex.lock();
    pathToCheck = dataDir;
    if(!signalled)
    {
        signalled = true;
        Q_EMIT requestCheck();
    }
    mutex.unlock();
}

QString Intro::getPathToCheck()
{
    QString retval;
    mutex.lock();
    retval = pathToCheck;
    signalled = false; /* new request can be queued now */
    mutex.unlock();
    return retval;
}
<|endoftext|>


<commit_before>/**
 * Wrapper for QWebPage
 *
 * @package ad-reger
 * @author Azat Khuzhin <dohardgopro@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#include "qwebpage.h"
#include "connector.h"

#include <QDebug>

namespace Wrapper {
	QString QWebPage::userAgent = "qt";

	QWebPage::QWebPage(QObject *parent) : ::QWebPage(parent) {
		// Set cache settings
		settings()->setMaximumPagesInCache(0);
		settings()->setObjectCacheCapacities(0,0,0);
	}

	void QWebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) {
		qDebug() << message << " @ no. " << lineNumber << " sourceid: " << sourceID;
	}

	void QWebPage::javaScriptAlert(QWebFrame *frame, const QString &msg) {
		Q_UNUSED(frame);

		qDebug() << msg;
	}

	bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString &msg, const QString &defaultValue, QString *result) {
		Q_UNUSED(frame);

		qDebug() << msg << " @ default is '" << defaultValue << "' : " << (result ? *result : "canceled");

		return result == NULL;
	}

	bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString &msg) {
		Q_UNUSED(frame);

		qDebug() << msg;

		return msg == "";
	}

	QString QWebPage::userAgentForUrl(const QUrl &url) const {
		Q_UNUSED(url);

		return userAgent;
	}

	bool QWebPage::moveMouseTo(QWebElement elementMoveTo) const {
		if (elementMoveTo.isNull()) {
			return false;
		}

		qDebug() << "Cursor position" << QCursor::pos();

		QRect geometry = elementMoveTo.geometry();
		// TODO : some randomize
		QPoint moveTo;
		// Calculate real center, not the upper border
		{
			moveTo = geometry.bottomLeft();
			moveTo.setX(moveTo.x() + (geometry.width() / 2));
			moveTo.setY(moveTo.y() + (geometry.height() / 2));
		}
		QPoint moveFrom = QCursor::pos();

		Module::Connector connector;

		// TODO : move more granular
		// Move
		while (moveFrom != moveTo) {
			if (moveTo.x() != moveFrom.x()) {
				moveFrom.setX((moveFrom.x() > moveTo.x()) ? (moveFrom.x() - 1) : (moveFrom.x() + 1));
			}

			if (moveTo.y() != moveFrom.y()) {
				moveFrom.setY((moveFrom.y() > moveTo.y()) ? (moveFrom.y() - 1) : (moveFrom.y() + 1));
			}

			QCursor::setPos(moveFrom);

			connector.waitWithoutGuiBlock(OPTIMAL_MSECS_BETWEEN_CHANGE_POSITION);
		}

		return true;
	}
}

<commit_msg>Add TODO : add detecting global position, not position on current monitor<commit_after>/**
 * Wrapper for QWebPage
 *
 * @package ad-reger
 * @author Azat Khuzhin <dohardgopro@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#include "qwebpage.h"
#include "connector.h"

#include <QDebug>

namespace Wrapper {
	QString QWebPage::userAgent = "qt";

	QWebPage::QWebPage(QObject *parent) : ::QWebPage(parent) {
		// Set cache settings
		settings()->setMaximumPagesInCache(0);
		settings()->setObjectCacheCapacities(0,0,0);
	}

	void QWebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) {
		qDebug() << message << " @ no. " << lineNumber << " sourceid: " << sourceID;
	}

	void QWebPage::javaScriptAlert(QWebFrame *frame, const QString &msg) {
		Q_UNUSED(frame);

		qDebug() << msg;
	}

	bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString &msg, const QString &defaultValue, QString *result) {
		Q_UNUSED(frame);

		qDebug() << msg << " @ default is '" << defaultValue << "' : " << (result ? *result : "canceled");

		return result == NULL;
	}

	bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString &msg) {
		Q_UNUSED(frame);

		qDebug() << msg;

		return msg == "";
	}

	QString QWebPage::userAgentForUrl(const QUrl &url) const {
		Q_UNUSED(url);

		return userAgent;
	}

	bool QWebPage::moveMouseTo(QWebElement elementMoveTo) const {
		if (elementMoveTo.isNull()) {
			return false;
		}

		qDebug() << "Cursor position" << QCursor::pos();

		// TODO : add detecting global position, not position on current monitor
		QRect geometry = elementMoveTo.geometry();
		// TODO : some randomize
		QPoint moveTo;
		// Calculate real center, not the upper border
		{
			moveTo = geometry.bottomLeft();
			moveTo.setX(moveTo.x() + (geometry.width() / 2));
			moveTo.setY(moveTo.y() + (geometry.height() / 2));
		}
		QPoint moveFrom = QCursor::pos();

		Module::Connector connector;

		// TODO : move more granular
		// Move
		while (moveFrom != moveTo) {
			if (moveTo.x() != moveFrom.x()) {
				moveFrom.setX((moveFrom.x() > moveTo.x()) ? (moveFrom.x() - 1) : (moveFrom.x() + 1));
			}

			if (moveTo.y() != moveFrom.y()) {
				moveFrom.setY((moveFrom.y() > moveTo.y()) ? (moveFrom.y() - 1) : (moveFrom.y() + 1));
			}

			QCursor::setPos(moveFrom);

			connector.waitWithoutGuiBlock(OPTIMAL_MSECS_BETWEEN_CHANGE_POSITION);
		}

		return true;
	}
}

<|endoftext|>


<commit_before>#pragma once
#include <Prerequisites.hpp>
#include <Intersector.hpp>

#include <BSDF.hpp>
#include <AreaLights.hpp>
#include <Materials.hpp>
#include <Cameras.hpp>

#include <SurfacePoint.hpp>

namespace haste {

using namespace glm;

template <class T> using shared = std::shared_ptr<T>;
using std::make_shared;

using std::vector;
using std::string;
using std::size_t;
using std::move;

struct Ray;

struct Mesh {
    string name;
    unsigned materialID;
    vector<int> indices;
    vector<vec3> vertices;
    vector<vec3> normals;
    vector<vec3> tangents;
    vector<vec3> bitangents;
};

class Scene : public Intersector {
public:
    Scene(
        Cameras&& cameras,
        Materials&& materials,
        vector<Mesh>&& meshes,
        AreaLights&& areaLights);

    Cameras _cameras;
    const vector<Mesh> meshes;
    AreaLights lights;
    const Materials materials;

    const Cameras& cameras() const { return _cameras; }

    void buildAccelStructs(RTCDevice device);

    const BSDF& queryBSDF(const RayIsect& isect) const;
    const BSDF& queryBSDF(const SurfacePoint& surface) const;
    vec3 lightExitance(const RayIsect& hit) const;
    vec3 lerpNormal(const RayIsect& hit) const;

    vec3 queryRadiance(const RayIsect& isect) const;
    SurfacePoint querySurface(const RayIsect& isect) const;

    LightSample sampleLight(
        RandomEngine& engine,
        const vec3& position) const;

    LightSampleEx sampleLightEx(
        RandomEngine& engine,
        const vec3& position) const;

    vec3 queryRadiance(
        const RayIsect& isect,
        const vec3& omega) const;

    const LSDFQuery queryLSDF(
        const RayIsect& isect,
        const vec3& omega) const;

    const LSDFQuery queryLSDF(
        const SurfacePoint& surface,
        const vec3& omega) const;

    const RayIsect intersect(
        const vec3& origin,
        const vec3& direction) const override;

    const RayIsect intersect(
        const Ray& ray) const;

    const float occluded(const vec3& origin,
        const vec3& target) const override;

    const RayIsect intersectLight(
        const vec3& origin,
        const vec3& direction) const override;

    const size_t numNormalRays() const;
    const size_t numShadowRays() const;
    const size_t numRays() const;

    mutable UniformSampler sampler;

    const LightSampleEx sampleLight(
        RandomEngine& engine) const;

    const BSDFSample sampleBSDF(
        RandomEngine& engine,
        const SurfacePoint& surface,
        const vec3& omega) const;

    const BSDFSample sampleAdjointBSDF(
        RandomEngine& engine,
        const SurfacePoint& surface,
        const vec3& omega) const;

    const BSDFQuery queryBSDF(
        const SurfacePoint& surface,
        const vec3& incident,
        const vec3& outgoing) const;

    const BSDFQuery queryAdjointBSDF(
        const SurfacePoint& surface,
        const vec3& incident,
        const vec3& outgoing) const;

    const vec3 sampleDirectLightAngle(
        RandomEngine& engine,
        const SurfacePoint& point,
        const vec3& omegaR,
        const BSDF& bsdf) const;

    const vec3 sampleDirectLightArea(
        RandomEngine& engine,
        const SurfacePoint& point,
        const vec3& omegaR,
        const BSDF& bsdf) const;

    const vec3 sampleDirectLightMixed(
        RandomEngine& engine,
        const SurfacePoint& surface,
        const vec3& omega,
        const BSDF& bsdf) const;

private:
    mutable std::atomic<size_t> _numIntersectRays;
    mutable std::atomic<size_t> _numOccludedRays;

    mutable RTCScene rtcScene;
};

}
<commit_msg>Remove dead code from scene.<commit_after>#pragma once
#include <Prerequisites.hpp>
#include <Intersector.hpp>

#include <BSDF.hpp>
#include <AreaLights.hpp>
#include <Materials.hpp>
#include <Cameras.hpp>

#include <SurfacePoint.hpp>

namespace haste {

using namespace glm;

template <class T> using shared = std::shared_ptr<T>;
using std::make_shared;

using std::vector;
using std::string;
using std::size_t;
using std::move;

struct Ray;

struct Mesh {
    string name;
    unsigned materialID;
    vector<int> indices;
    vector<vec3> vertices;
    vector<vec3> normals;
    vector<vec3> tangents;
    vector<vec3> bitangents;
};

class Scene : public Intersector {
public:
    Scene(
        Cameras&& cameras,
        Materials&& materials,
        vector<Mesh>&& meshes,
        AreaLights&& areaLights);

    Cameras _cameras;
    const vector<Mesh> meshes;
    AreaLights lights;
    const Materials materials;

    const Cameras& cameras() const { return _cameras; }

    void buildAccelStructs(RTCDevice device);

    const BSDF& queryBSDF(const RayIsect& isect) const;
    const BSDF& queryBSDF(const SurfacePoint& surface) const;
    vec3 lightExitance(const RayIsect& hit) const;
    vec3 lerpNormal(const RayIsect& hit) const;

    vec3 queryRadiance(const RayIsect& isect) const;
    SurfacePoint querySurface(const RayIsect& isect) const;

    LightSample sampleLight(
        RandomEngine& engine,
        const vec3& position) const;

    LightSampleEx sampleLightEx(
        RandomEngine& engine,
        const vec3& position) const;

    vec3 queryRadiance(
        const RayIsect& isect,
        const vec3& omega) const;

    const LSDFQuery queryLSDF(
        const RayIsect& isect,
        const vec3& omega) const;

    const LSDFQuery queryLSDF(
        const SurfacePoint& surface,
        const vec3& omega) const;

    const RayIsect intersect(
        const vec3& origin,
        const vec3& direction) const override;

    const RayIsect intersect(
        const Ray& ray) const;

    const float occluded(const vec3& origin,
        const vec3& target) const override;

    const RayIsect intersectLight(
        const vec3& origin,
        const vec3& direction) const override;

    const size_t numNormalRays() const;
    const size_t numShadowRays() const;
    const size_t numRays() const;

    mutable UniformSampler sampler;

    const LightSampleEx sampleLight(
        RandomEngine& engine) const;

    const BSDFSample sampleBSDF(
        RandomEngine& engine,
        const SurfacePoint& surface,
        const vec3& omega) const;

    const BSDFQuery queryBSDF(
        const SurfacePoint& surface,
        const vec3& incident,
        const vec3& outgoing) const;

    const vec3 sampleDirectLightAngle(
        RandomEngine& engine,
        const SurfacePoint& point,
        const vec3& omegaR,
        const BSDF& bsdf) const;

    const vec3 sampleDirectLightArea(
        RandomEngine& engine,
        const SurfacePoint& point,
        const vec3& omegaR,
        const BSDF& bsdf) const;

    const vec3 sampleDirectLightMixed(
        RandomEngine& engine,
        const SurfacePoint& surface,
        const vec3& omega,
        const BSDF& bsdf) const;

private:
    mutable std::atomic<size_t> _numIntersectRays;
    mutable std::atomic<size_t> _numOccludedRays;

    mutable RTCScene rtcScene;
};

}
<|endoftext|>


<commit_before>#include "Video.h"
#include <map>

RGB Video::CLASSIC_PALLETE[4] = { { 155,188,15 }, { 139,172,15 }, { 48,98,48 }, { 15,56,15 } };
RGB Video::GREY_PALLETE[4] = { { 255,255,255 },{ 0xCC,0xCC,0xCC },{ 0x77,0x77,0x77 }, { 0x0,0x0,0x0 } };

Video::Video(Memory *memory, CPU *cpu) {
    this->memory = memory;
    this->cpu = cpu;
    this->createSDLWindow();
    this->resetFrameBuffer();
    this->renderGame();

	this->videoCycles = 0;
	this->vblankCycles = 0;
	this->mode = Video::Mode::OAM_RAM;
	this->pallete = GREY_PALLETE;
}

void Video::updateGraphics(short cycles) {
    if (isLCDEnabled()) {
		videoCycles += cycles;
		switch (mode) {
			case Video::Mode::H_BLANK:
				handleHBlankMode();
				break;
			case Video::Mode::V_BLANK:
				handleVBlankMode(cycles);
				break;
			case Video::Mode::OAM_RAM:
				handleOAMMode();
				break;
			case Video::Mode::LCD_TRANSFER:
				handleLCDTransferMode();
				break;
		}
    }
}

void Video::handleHBlankMode() {
    if (videoCycles >= MIN_HBLANK_MODE_CYCLES) {
		videoCycles = 0;

		byte scanline = memory->readDirectly(LY_REGISTER);
		memory->writeDirectly(LY_REGISTER, ++scanline);
		if (scanline == VERTICAL_BLANK_SCAN_LINE) {
			mode = Mode::V_BLANK;

			/* Move to mode 1: VBLANK*/
			byte lcdStatus = memory->readDirectly(LCDC_STATUS);
			setBit(&lcdStatus, 1);
			memory->writeDirectly(LCDC_STATUS, lcdStatus);

			//if (isBitSet(lc dStatus, 4)) {
				cpu->requestInterrupt(Interrupts::VBLANK);
			//}
		} else {
			mode = Mode::OAM_RAM;
		}
    }
}

void Video::handleVBlankMode(short cycles) {
	vblankCycles += cycles;

    if (vblankCycles >= MAX_VIDEO_CYCLES) {
		vblankCycles = 0;

		byte scanline = memory->readDirectly(LY_REGISTER);
		if (scanline < VERTICAL_BLANK_SCAN_LINE_MAX) {
			memory->writeDirectly(LY_REGISTER, ++scanline);
		}
		compareLYWithLYC();
	}

	if (videoCycles >= VBLANK_CYCLES) {
		videoCycles = 0;
		vblankCycles = 0;

		/* Reset scanlines to zero */
		memory->writeDirectly(LY_REGISTER, 0);
		compareLYWithLYC();

		/* Move to mode 2: OAM Mode*/
		mode = Mode::OAM_RAM;
		byte lcdStatus = memory->readDirectly(LCDC_STATUS);
        setBit(&lcdStatus, 1);
        clearBit(&lcdStatus, 0);
        memory->writeDirectly(LCDC_STATUS, lcdStatus);

        if (isBitSet(lcdStatus, 5)) {
            cpu->requestInterrupt(Interrupts::LCD);
        }
    }
}

void Video::handleOAMMode() {
	if (videoCycles >= MIN_OAM_MODE_CYCLES) {
		videoCycles = 0;

		/* Move to mode 3 */
		mode = Mode::LCD_TRANSFER;
		byte lcdStatus = memory->readDirectly(LCDC_STATUS);
		setBit(&lcdStatus, 1);
		setBit(&lcdStatus, 0);
		memory->writeDirectly(LCDC_STATUS, lcdStatus);
	}
}

void Video::handleLCDTransferMode() {
	if (videoCycles >= MIN_LCD_TRANSFER_CYCLES) {
		videoCycles = 0;

		/* This can be optimize so it is done before we change the mode */
		drawScanline();

		/* Move to mode 0 */
		mode = Mode::H_BLANK;
		byte lcdStatus = memory->readDirectly(LCDC_STATUS);
		clearBit(&lcdStatus,1);
		clearBit(&lcdStatus,0);
		memory->writeDirectly(LCDC_STATUS, lcdStatus);
	}
}

void Video::compareLYWithLYC() {
	byte lcdStatus = memory->readDirectly(LCDC_STATUS);
	byte currentScanline = memory->readDirectly(LY_REGISTER);
	byte lyCompare = memory->readDirectly(LY_COMPARE);
	if (lyCompare == currentScanline) {
		if (isBitSet(lcdStatus, 6)) {
			cpu->requestInterrupt(Interrupts::LCD);
		}
	}
}

void Video::drawScanline() {
    const byte lcdControl = memory->readDirectly(LCD_CONTROL);
	if ( isBitSet(lcdControl, 7) ) {
		renderBackground(lcdControl);
        renderSprites(lcdControl);
    }
}

void Video::renderBackground(byte lcdControl) {
    word tileData;
    word backgroundMemory;
    bool unsig = true;
    bool usingWindow = false;

    byte scrollY = memory->readDirectly(SCROLL_Y);
    byte scrollX = memory->readDirectly(SCROLL_X);
    byte windowY = memory->readDirectly(WINDOWS_Y);
    byte windowX = memory->readDirectly(WINDOWS_X) - 7;

	const int scanline = memory->readDirectly(LY_REGISTER);

    if ( isBitSet(lcdControl, 5) ) {
		usingWindow = windowY <= scanline;
    }

    if ( isBitSet(lcdControl,4) ) {
        tileData = 0x8000;
    } else {
        tileData = 0x8800;
        unsig= false;
    }

    if ( !usingWindow ) {
        if ( isBitSet(lcdControl, 3) ) {
            backgroundMemory = 0x9C00;
        } else {
            backgroundMemory = 0x9800;
        }
    } else {
        if ( isBitSet(lcdControl, 6) ) {
            backgroundMemory = 0x9C00;
        } else {
            backgroundMemory = 0x9800;
        }
    }

    byte yPos = 0;
    if ( !usingWindow ) {
        yPos = scrollY + scanline;
    } else {
        yPos = scanline - windowY;
    }

    word tileRow = (((byte)(yPos/8))*32);

    for ( int pixel = 0 ; pixel < 160; pixel++ ) {
        byte xPos = pixel + scrollX;

        if ( usingWindow && pixel >= windowX ) {
			xPos = pixel - windowX;
        }

        const word tileCol = (xPos/8);
        signed short tileNum;

        if( unsig ) {
            tileNum = (byte)memory->readDirectly(backgroundMemory+tileRow + tileCol);
        } else {
            tileNum = (signed short)memory->readDirectly(backgroundMemory+tileRow + tileCol);
        }

        word tileLocation = tileData;
        if ( unsig ) {
            tileLocation += (tileNum * 16);
        } else {
            tileLocation += ((tileNum+128) *16);
        }

        byte line = yPos % 8;
        line *= 2;
        byte data1 = memory->readDirectly(tileLocation + line);
        byte data2 = memory->readDirectly(tileLocation + line + 1);

        int colourBit = xPos % 8;
        colourBit -= 7;
        colourBit *= -1;

        int colourNum = getBitValue(data2, colourBit);
        colourNum <<= 1;
        colourNum |= getBitValue(data1,colourBit);

        RGB colour = getColour(colourNum);

        frameBuffer[scanline][pixel][0] = colour.red;
        frameBuffer[scanline][pixel][1] = colour.green;
        frameBuffer[scanline][pixel][2] = colour.blue;
    }
}

void Video::renderSprites(byte lcdControl) {
    bool use8x16 = false;

    if ( isBitSet(lcdControl, 2) ) {
        use8x16 = true;
    }

    for (int sprite = 0 ; sprite < 40; sprite++) {
        byte index = sprite*4 ;
        byte yPos = memory->read(0xFE00+index) - 16;
        byte xPos = memory->read(0xFE00+index+1)-8;
        byte tileLocation = memory->read(0xFE00+index+2) ;
        byte attributes = memory->read(0xFE00+index+3) ;

        bool yFlip =  isBitSet(attributes, 6);
        bool xFlip = isBitSet(attributes, 5);

        int scanline = memory->read(LY_REGISTER);

        int ysize = 8;

        if ( use8x16 ) {
            ysize = 16;
        }

        if ( (scanline >= yPos) && (scanline < (yPos+ysize)) ) {
            int line = scanline - yPos;

            if ( yFlip ) {
                line -= ysize;
                line *= -1;
            }

            line *= 2;
            byte data1 = memory->read((0x8000 + (tileLocation * 16)) + line);
            byte data2 = memory->read((0x8000 + (tileLocation * 16)) + line+1);

            for ( int tilePixel = 7; tilePixel >= 0; tilePixel-- ) {
                int colourbit = tilePixel ;
                if ( xFlip ) {
                    colourbit -= 7;
                    colourbit *= -1;
                }

                int colourNum = getBitValue(data2,colourbit) ;
                colourNum <<= 1;
                colourNum |= getBitValue(data1,colourbit) ;

				RGB colour = getColour(colourNum);

                int xPix = 0 - tilePixel;
                xPix += 7;

                int pixel = xPos+xPix;

                frameBuffer[scanline][pixel][0] = colour.red;
                frameBuffer[scanline][pixel][1] = colour.green;
                frameBuffer[scanline][pixel][2] = colour.blue;
 			}
		}
	}
}

Video::Mode Video::getLCDMode() const {
    byte lcdStatus = memory->readDirectly(LCDC_STATUS);
	return Video::Mode(lcdStatus & 0x3);
}

bool Video::createSDLWindow() {
    if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) {
        return false;
    }

    window = SDL_CreateWindow("PatBoy", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                              GAMEBOY_WIDTH, GAMEBOY_HEIGHT, 0);
    renderer = SDL_CreateRenderer(window, -1, 0);
    texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB24,
                                SDL_TEXTUREACCESS_STREAMING, GAMEBOY_WIDTH, GAMEBOY_HEIGHT);
    return true ;
}

void Video::renderGame() {
    SDL_UpdateTexture(texture, NULL, this->frameBuffer, GAMEBOY_WIDTH * sizeof(byte) * 3);
    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, texture, NULL, NULL);
    SDL_RenderPresent(renderer);
}

void Video::switchPallete() {
	if (pallete == CLASSIC_PALLETE) {
		pallete = GREY_PALLETE;
	} else if (pallete == GREY_PALLETE) {
		pallete = CLASSIC_PALLETE;
	}
}

void Video::resetFrameBuffer() {
	memset(frameBuffer, 255, sizeof(frameBuffer));
}

Video::~Video() {
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

<commit_msg>Reset mode when LCD is not enabled<commit_after>#include "Video.h"
#include <map>

RGB Video::CLASSIC_PALLETE[4] = { { 155,188,15 }, { 139,172,15 }, { 48,98,48 }, { 15,56,15 } };
RGB Video::GREY_PALLETE[4] = { { 255,255,255 },{ 0xCC,0xCC,0xCC },{ 0x77,0x77,0x77 }, { 0x0,0x0,0x0 } };

Video::Video(Memory *memory, CPU *cpu) {
    this->memory = memory;
    this->cpu = cpu;
    this->createSDLWindow();
    this->resetFrameBuffer();
    this->renderGame();

	this->videoCycles = 0;
	this->vblankCycles = 0;
	this->mode = Video::Mode::OAM_RAM;
	this->pallete = GREY_PALLETE;
}

void Video::updateGraphics(short cycles) {
    if (isLCDEnabled()) {
		videoCycles += cycles;
		switch (mode) {
			case Video::Mode::H_BLANK:
				handleHBlankMode();
				break;
			case Video::Mode::V_BLANK:
				handleVBlankMode(cycles);
				break;
			case Video::Mode::OAM_RAM:
				handleOAMMode();
				break;
			case Video::Mode::LCD_TRANSFER:
				handleLCDTransferMode();
				break;
		}
	} else {
		videoCycles = 0;
		memory->writeDirectly(LY_REGISTER, 0);

		byte lcdc = memory->readDirectly(LCDC_STATUS);
		lcdc &= 0xFC;
		memory->writeDirectly(LCDC_STATUS, lcdc);
		mode = Video::Mode::H_BLANK;
	}
}

void Video::handleHBlankMode() {
    if (videoCycles >= MIN_HBLANK_MODE_CYCLES) {
		videoCycles = 0;

		byte scanline = memory->readDirectly(LY_REGISTER);
		memory->writeDirectly(LY_REGISTER, ++scanline);
		if (scanline == VERTICAL_BLANK_SCAN_LINE) {
			mode = Mode::V_BLANK;

			/* Move to mode 1: VBLANK*/
			byte lcdStatus = memory->readDirectly(LCDC_STATUS);
			setBit(&lcdStatus, 1);
			memory->writeDirectly(LCDC_STATUS, lcdStatus);
			cpu->requestInterrupt(Interrupts::VBLANK);
		} else {
			mode = Mode::OAM_RAM;
		}
    }
}

void Video::handleVBlankMode(short cycles) {
	vblankCycles += cycles;

    if (vblankCycles >= MAX_VIDEO_CYCLES) {
		vblankCycles = 0;

		byte scanline = memory->readDirectly(LY_REGISTER);
		if (scanline < VERTICAL_BLANK_SCAN_LINE_MAX) {
			memory->writeDirectly(LY_REGISTER, ++scanline);
		}
		compareLYWithLYC();
	}

	if (videoCycles >= VBLANK_CYCLES) {
		videoCycles = 0;
		vblankCycles = 0;

		/* Reset scanlines to zero */
		memory->writeDirectly(LY_REGISTER, 0);
		compareLYWithLYC();

		/* Move to mode 2: OAM Mode*/
		mode = Mode::OAM_RAM;
		byte lcdStatus = memory->readDirectly(LCDC_STATUS);
        setBit(&lcdStatus, 1);
        clearBit(&lcdStatus, 0);
        memory->writeDirectly(LCDC_STATUS, lcdStatus);

        if (isBitSet(lcdStatus, 5)) {
            cpu->requestInterrupt(Interrupts::LCD);
        }
    }
}

void Video::handleOAMMode() {
	if (videoCycles >= MIN_OAM_MODE_CYCLES) {
		videoCycles = 0;

		/* Move to mode 3 */
		mode = Mode::LCD_TRANSFER;
		byte lcdStatus = memory->readDirectly(LCDC_STATUS);
		setBit(&lcdStatus, 1);
		setBit(&lcdStatus, 0);
		memory->writeDirectly(LCDC_STATUS, lcdStatus);
	}
}

void Video::handleLCDTransferMode() {
	if (videoCycles >= MIN_LCD_TRANSFER_CYCLES) {
		videoCycles = 0;

		/* This can be optimize so it is done before we change the mode */
		drawScanline();

		/* Move to mode 0 */
		mode = Mode::H_BLANK;
		byte lcdStatus = memory->readDirectly(LCDC_STATUS);
		clearBit(&lcdStatus,1);
		clearBit(&lcdStatus,0);
		memory->writeDirectly(LCDC_STATUS, lcdStatus);
	}
}

void Video::compareLYWithLYC() {
	byte lcdStatus = memory->readDirectly(LCDC_STATUS);
	byte currentScanline = memory->readDirectly(LY_REGISTER);
	byte lyCompare = memory->readDirectly(LY_COMPARE);
	if (lyCompare == currentScanline) {
		if (isBitSet(lcdStatus, 6)) {
			cpu->requestInterrupt(Interrupts::LCD);
		}
	}
}

void Video::drawScanline() {
    const byte lcdControl = memory->readDirectly(LCD_CONTROL);
	if ( isBitSet(lcdControl, 7) ) {
		renderBackground(lcdControl);
        renderSprites(lcdControl);
    }
}

void Video::renderBackground(byte lcdControl) {
    word tileData;
    word backgroundMemory;
    bool unsig = true;
    bool usingWindow = false;

    byte scrollY = memory->readDirectly(SCROLL_Y);
    byte scrollX = memory->readDirectly(SCROLL_X);
    byte windowY = memory->readDirectly(WINDOWS_Y);
    byte windowX = memory->readDirectly(WINDOWS_X) - 7;

	const int scanline = memory->readDirectly(LY_REGISTER);

    if ( isBitSet(lcdControl, 5) ) {
		usingWindow = windowY <= scanline;
    }

    if ( isBitSet(lcdControl,4) ) {
        tileData = 0x8000;
    } else {
        tileData = 0x8800;
        unsig= false;
    }

    if ( !usingWindow ) {
        if ( isBitSet(lcdControl, 3) ) {
            backgroundMemory = 0x9C00;
        } else {
            backgroundMemory = 0x9800;
        }
    } else {
        if ( isBitSet(lcdControl, 6) ) {
            backgroundMemory = 0x9C00;
        } else {
            backgroundMemory = 0x9800;
        }
    }

    byte yPos = 0;
    if ( !usingWindow ) {
        yPos = scrollY + scanline;
    } else {
        yPos = scanline - windowY;
    }

    word tileRow = (((byte)(yPos/8))*32);

    for ( int pixel = 0 ; pixel < 160; pixel++ ) {
        byte xPos = pixel + scrollX;

        if ( usingWindow && pixel >= windowX ) {
			xPos = pixel - windowX;
        }

        const word tileCol = (xPos/8);
        signed short tileNum;

        if( unsig ) {
            tileNum = (byte)memory->readDirectly(backgroundMemory+tileRow + tileCol);
        } else {
            tileNum = (signed short)memory->readDirectly(backgroundMemory+tileRow + tileCol);
        }

        word tileLocation = tileData;
        if ( unsig ) {
            tileLocation += (tileNum * 16);
        } else {
            tileLocation += ((tileNum+128) *16);
        }

        byte line = yPos % 8;
        line *= 2;
        byte data1 = memory->readDirectly(tileLocation + line);
        byte data2 = memory->readDirectly(tileLocation + line + 1);

        int colourBit = xPos % 8;
        colourBit -= 7;
        colourBit *= -1;

        int colourNum = getBitValue(data2, colourBit);
        colourNum <<= 1;
        colourNum |= getBitValue(data1,colourBit);

        RGB colour = getColour(colourNum);

        frameBuffer[scanline][pixel][0] = colour.red;
        frameBuffer[scanline][pixel][1] = colour.green;
        frameBuffer[scanline][pixel][2] = colour.blue;
    }
}

void Video::renderSprites(byte lcdControl) {
    bool use8x16 = false;

    if ( isBitSet(lcdControl, 2) ) {
        use8x16 = true;
    }

    for (int sprite = 0 ; sprite < 40; sprite++) {
        byte index = sprite*4 ;
        byte yPos = memory->read(0xFE00+index) - 16;
        byte xPos = memory->read(0xFE00+index+1)-8;
        byte tileLocation = memory->read(0xFE00+index+2) ;
        byte attributes = memory->read(0xFE00+index+3) ;

        bool yFlip =  isBitSet(attributes, 6);
        bool xFlip = isBitSet(attributes, 5);

        int scanline = memory->read(LY_REGISTER);

        int ysize = 8;

        if ( use8x16 ) {
            ysize = 16;
        }

        if ( (scanline >= yPos) && (scanline < (yPos+ysize)) ) {
            int line = scanline - yPos;

            if ( yFlip ) {
                line -= ysize;
                line *= -1;
            }

            line *= 2;
            byte data1 = memory->read((0x8000 + (tileLocation * 16)) + line);
            byte data2 = memory->read((0x8000 + (tileLocation * 16)) + line+1);

            for ( int tilePixel = 7; tilePixel >= 0; tilePixel-- ) {
                int colourbit = tilePixel ;
                if ( xFlip ) {
                    colourbit -= 7;
                    colourbit *= -1;
                }

                int colourNum = getBitValue(data2,colourbit) ;
                colourNum <<= 1;
                colourNum |= getBitValue(data1,colourbit) ;

				RGB colour = getColour(colourNum);

                int xPix = 0 - tilePixel;
                xPix += 7;

                int pixel = xPos+xPix;

                frameBuffer[scanline][pixel][0] = colour.red;
                frameBuffer[scanline][pixel][1] = colour.green;
                frameBuffer[scanline][pixel][2] = colour.blue;
 			}
		}
	}
}

Video::Mode Video::getLCDMode() const {
    byte lcdStatus = memory->readDirectly(LCDC_STATUS);
	return Video::Mode(lcdStatus & 0x3);
}

bool Video::createSDLWindow() {
    if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) {
        return false;
    }

    window = SDL_CreateWindow("PatBoy", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                              GAMEBOY_WIDTH, GAMEBOY_HEIGHT, 0);
    renderer = SDL_CreateRenderer(window, -1, 0);
    texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB24,
                                SDL_TEXTUREACCESS_STREAMING, GAMEBOY_WIDTH, GAMEBOY_HEIGHT);
    return true ;
}

void Video::renderGame() {
    SDL_UpdateTexture(texture, NULL, this->frameBuffer, GAMEBOY_WIDTH * sizeof(byte) * 3);
    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, texture, NULL, NULL);
    SDL_RenderPresent(renderer);
}

void Video::switchPallete() {
	if (pallete == CLASSIC_PALLETE) {
		pallete = GREY_PALLETE;
	} else if (pallete == GREY_PALLETE) {
		pallete = CLASSIC_PALLETE;
	}
}

void Video::resetFrameBuffer() {
	memset(frameBuffer, 255, sizeof(frameBuffer));
}

Video::~Video() {
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

<|endoftext|>


<commit_before>#include "stb_image.h"
#include "stb_image_write.h"

#include <array>
#include <cmath>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include <atomic>
#include <thread>

class PRNG
{
  private:
    uint64_t mSeed;

  public:
    PRNG(uint64_t seed = 12118) : mSeed(seed == 0 ? 1 : seed){}; // seed CANNOT be 0!!
    float Extents(float extents)
    {
        mSeed ^= mSeed >> 12;
        mSeed ^= mSeed << 25;
        mSeed ^= mSeed >> 27;
        return -extents + float(mSeed * UINT64_C(2685821657736338717) * 5.4210105e-20) * (2 * extents);
    };
};

int main(int argc, char *argv[])
{
    if (argc != 4)
    {
        std::cout << "# Usage: " << argv[0] << " commands.txt noise.png output.png" << std::endl;
        return 0;
    }

    int width, height, channels;
    unsigned char *noiseTexture = stbi_load(argv[2], &width, &height, &channels, 4);
    printf("# Loaded: %s [%ix%ix%i]\n", argv[2], width, height, channels);

    std::vector<std::pair<float, float>> noiseVector(width * height);
    for (int n = 0; n < (width * height); n++)
    {
        noiseVector[n] = {(float)(noiseTexture[n * channels] - 127) / 127.0f,
                          (float)(noiseTexture[n * channels + 1] - 127) / 127.0f};
    }
    stbi_image_free(noiseTexture);

    std::vector<std::array<float, 3>> hdr(width * height);

    const std::string particleString("PARTICLE");
    const std::string colourString("COLOUR");
    const std::string simulateString("SIMULATE");
    const std::string tonemapString("TONEMAP");

    std::ifstream commands(argv[1]);
    if (!commands.is_open())
    {
        std::cout << "# Failed to open: " << argv[1] << std::endl;
        return -1;
    }
    else
    {
        std::cout << "# Commands: " << argv[1] << std::endl;
    }

    int iterations, stepSampleRate;
    float damping, noisy, fuzz;
    float red, green, blue;
    PRNG prng;

    std::string token;
    while (commands >> token)
    {
        if (token.compare(particleString) == 0)
        {
            float x, y, vx, vy;
            commands >> x >> y >> vx >> vy;
            size_t index = (int)x + (int)y * width;

            bool alive = true;
            for (int i = 0; alive && i < iterations; i++)
            {
                vx = vx * damping + (noiseVector[index].first * 4.0 * noisy) + prng.Extents(0.1) * fuzz;
                vy = vy * damping + (noiseVector[index].second * 4.0 * noisy) + prng.Extents(0.1) * fuzz;
                float step = 1.0f / stepSampleRate;
                for (int j = 0; j < stepSampleRate; j++)
                {
                    x += vx * step;
                    y += vy * step;
                    if ((int)x < 0 || (int)x >= width || (int)y < 0 || (int)y >= height)
                    {
                        alive = false;
                        break;
                    }
                    index = (int)x + (int)y * width;
                    hdr[index][0] += red;
                    hdr[index][1] += green;
                    hdr[index][2] += blue;
                }
            }
        }
        else if (token.compare(colourString) == 0)
        {
            commands >> red >> green >> blue;
        }
        else if (token.compare(simulateString) == 0)
        {
            commands >> iterations >> stepSampleRate >> damping >> noisy >> fuzz;
            prng = PRNG();
            std::cout << "# Simulating" << std::endl;
        }
        else if (token.compare(tonemapString) == 0)
        {
            float exposure;
            commands >> exposure;
            std::cout << "# Tonemapping" << std::endl;

            auto tonemap = [exposure](float n) {
                return (unsigned char)((1.0f - std::pow(2.0f, -n * 0.005f * exposure)) * 255);
            };

            std::unique_ptr<unsigned char[]> output(new unsigned char[width * height * channels]);

            std::vector<std::thread> threads;
            std::atomic<int> x_next{0};
            for (unsigned n = 0; n < 4; n++)
            {
                threads.emplace_back([&]() {
                    for (int x; (x = x_next++) < width; x++)
                    {
                        for (int y = 0; y < height; y++)
                        {
                            size_t index = (x + y * width);
                            output[index * channels] = tonemap(hdr[index][0]);
                            output[index * channels + 1] = tonemap(hdr[index][1]);
                            output[index * channels + 2] = tonemap(hdr[index][2]);
                            output[index * channels + 3] = 255;
                        }
                    }
                });
            }
            for (auto &t : threads)
                t.join();

            stbi_write_png(argv[3], width, height, channels, output.get(), width * channels);
            std::cout << "# Saved: " << argv[3] << std::endl;
        }
    }

    commands.close();
    return 0;
}
<commit_msg>Output timing of tonemapping.<commit_after>#include "stb_image.h"
#include "stb_image_write.h"

#include <array>
#include <cmath>
#include <cstdint>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include <atomic>
#include <thread>

class PRNG
{
  private:
    uint64_t mSeed;

  public:
    PRNG(uint64_t seed = 12118) : mSeed(seed == 0 ? 1 : seed){}; // seed CANNOT be 0!!
    float Extents(float extents)
    {
        mSeed ^= mSeed >> 12;
        mSeed ^= mSeed << 25;
        mSeed ^= mSeed >> 27;
        return -extents + float(mSeed * UINT64_C(2685821657736338717) * 5.4210105e-20) * (2 * extents);
    };
};

int main(int argc, char *argv[])
{
    if (argc != 4)
    {
        std::cout << "# Usage: " << argv[0] << " commands.txt noise.png output.png" << std::endl;
        return 0;
    }

    int width, height, channels;
    unsigned char *noiseTexture = stbi_load(argv[2], &width, &height, &channels, 4);
    printf("# Loaded: %s [%ix%ix%i]\n", argv[2], width, height, channels);

    std::vector<std::pair<float, float>> noiseVector(width * height);
    for (int n = 0; n < (width * height); n++)
    {
        noiseVector[n] = {(float)(noiseTexture[n * channels] - 127) / 127.0f,
                          (float)(noiseTexture[n * channels + 1] - 127) / 127.0f};
    }
    stbi_image_free(noiseTexture);

    std::vector<std::array<float, 3>> hdr(width * height);

    const std::string particleString("PARTICLE");
    const std::string endString("END");
    const std::string colourString("COLOUR");
    const std::string simulateString("SIMULATE");
    const std::string tonemapString("TONEMAP");

    std::ifstream commands(argv[1]);
    if (!commands.is_open())
    {
        std::cout << "# Failed to open: " << argv[1] << std::endl;
        return -1;
    }
    else
    {
        std::cout << "# Commands: " << argv[1] << std::endl;
    }

    int iterations, stepSampleRate;
    float damping, noisy, fuzz;
    float red, green, blue;
    PRNG prng;

    std::string token;
    while (commands >> token)
    {
        if (token.compare(particleString) == 0)
        {
            float x, y, vx, vy;
            commands >> x >> y >> vx >> vy;
            size_t index = (int)x + (int)y * width;

            bool alive = true;
            for (int i = 0; alive && i < iterations; i++)
            {
                vx = vx * damping + (noiseVector[index].first * 4.0 * noisy) + prng.Extents(0.1) * fuzz;
                vy = vy * damping + (noiseVector[index].second * 4.0 * noisy) + prng.Extents(0.1) * fuzz;
                float step = 1.0f / stepSampleRate;
                for (int j = 0; j < stepSampleRate; j++)
                {
                    x += vx * step;
                    y += vy * step;
                    if ((int)x < 0 || (int)x >= width || (int)y < 0 || (int)y >= height)
                    {
                        alive = false;
                        break;
                    }
                    index = (int)x + (int)y * width;
                    hdr[index][0] += red;
                    hdr[index][1] += green;
                    hdr[index][2] += blue;
                }
            }
        }
        else if (token.compare(colourString) == 0)
        {
            commands >> red >> green >> blue;
        }
        else if (token.compare(simulateString) == 0)
        {
            commands >> iterations >> stepSampleRate >> damping >> noisy >> fuzz;
            prng = PRNG();
            std::cout << "# Simulating" << std::endl;
        }
        else if (token.compare(tonemapString) == 0)
        {
            float exposure;
            commands >> exposure;
            std::cout << "# Tonemapping" << std::endl;

            auto tonemap = [exposure](float n) {
                return (unsigned char)((1.0f - std::pow(2.0f, -n * 0.005f * exposure)) * 255);
            };

            std::unique_ptr<unsigned char[]> output(new unsigned char[width * height * channels]);

            const int num_threads = std::thread::hardware_concurrency();
            auto c_start = std::clock();
            auto t_start = std::chrono::high_resolution_clock::now();
#define PARALLEL
#ifdef PARALLEL
            std::vector<std::thread> threads;
            std::atomic<int> x_next{0};
            for (int n = 0; n < num_threads; n++)
            {
                threads.emplace_back([&]() {
                    for (int x; (x = x_next++) < width;)
                    {
                        for (int y = 0; y < height; y++)
                        {
                            size_t index = (x + y * width);
                            output[index * channels] = tonemap(hdr[index][0]);
                            output[index * channels + 1] = tonemap(hdr[index][1]);
                            output[index * channels + 2] = tonemap(hdr[index][2]);
                            output[index * channels + 3] = 255;
                        }
                    }
                });
            }
            for (auto &t : threads)
                t.join();
#else
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    size_t index = (x + y * width);
                    output[index * channels] = tonemap(hdr[index][0]);
                    output[index * channels + 1] = tonemap(hdr[index][1]);
                    output[index * channels + 2] = tonemap(hdr[index][2]);
                    output[index * channels + 3] = 255;
                }
            }
#endif
            auto c_end = std::clock();
            auto t_end = std::chrono::high_resolution_clock::now();
            std::cout << std::fixed << std::setprecision(4)
                      << "# CPU time: " << 1000.0 * (c_end - c_start) / CLOCKS_PER_SEC << "ms\n"
                      << "# Real time: " << std::chrono::duration<double, std::milli>(t_end - t_start).count()
                      << "ms\n";

            stbi_write_png(argv[3], width, height, channels, output.get(), width * channels);
            std::cout << "# Saved: " << argv[3] << std::endl;
        }
    }

    commands.close();
    return 0;
}
<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  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 of the License, or (at your option) any later version.
//
//  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, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "DSHelper.h"

#include "../base/Exception.h"
#include "../base/Logger.h"

#include <stdio.h>
#include <oleauto.h>

#include <string>

using namespace std;

namespace avg {

#pragma warning(disable : 4995)
HRESULT AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
{
    IMoniker * pMoniker;
    IRunningObjectTable *pROT;
    WCHAR wsz[128];
    HRESULT hr;

    if (!pUnkGraph || !pdwRegister) {
        return E_POINTER;
    }

    if (FAILED(GetRunningObjectTable(0, &pROT))) {
        return E_FAIL;
    }

    hr = swprintf(wsz, NUMELMS(wsz), L"FilterGraph %08x pid %08x\0",
            (DWORD_PTR)pUnkGraph, GetCurrentProcessId());

    hr = CreateItemMoniker(L"!", wsz, &pMoniker);
    if (SUCCEEDED(hr)) {
        hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph, pMoniker,
                pdwRegister);
        pMoniker->Release();
    }

    pROT->Release();
    return hr;
}

void RemoveGraphFromRot(DWORD pdwRegister)
{
    IRunningObjectTable *pROT;

    if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
        pROT->Revoke(pdwRegister);
        pROT->Release();
    }
}

string getStringProp(IPropertyBag *pPropBag, LPCOLESTR pszPropName)
{
    VARIANT varName;
    VariantInit(&varName);
    HRESULT hr = pPropBag->Read(pszPropName, &varName, 0);
    if (FAILED(hr)) {
        return "";
    }
//    checkForDShowError(hr, string("DSHelper::getStringProp(")+pszPropName+")::Read PropBag");

    string s;
    int lenWStr = SysStringLen(varName.bstrVal);
    int lenAStr = WideCharToMultiByte(CP_ACP, 0, varName.bstrVal, lenWStr, 0, 0, NULL, NULL);
    if (lenAStr > 0) {
        char* pAStr = new char[lenAStr + 1];
        WideCharToMultiByte(CP_ACP, 0, varName.bstrVal, lenWStr, pAStr, lenAStr, NULL, NULL);
        pAStr[lenAStr] = 0;
        s = pAStr;
        delete[] pAStr;
    }

    VariantClear(&varName);
    return s;
}

PixelFormat mediaSubtypeToPixelFormat(const GUID& subtype)
{
    if (subtype == MEDIASUBTYPE_RGB24) {
        return B8G8R8;
    } else if (subtype == MEDIASUBTYPE_RGB32) {
        return B8G8R8X8;
    } else if (subtype == MEDIASUBTYPE_RGB8) {
        return I8;
    } else if (subtype == MEDIASUBTYPE_UYVY) {
        return YCbCr422;
    } else if (subtype == MEDIASUBTYPE_YUY2) {
        return YUYV422;
    } else if (subtype == MEDIASUBTYPE_RGB565) {
        return B5G6R5;
//    } else if (Subtype == MEDIASUBTYPE_Y800 && DesiredPF == "BY8_GBRG") {
//        return BAYER8_GBRG;
    } else if (subtype == MEDIASUBTYPE_Y800) {
        return I8;
    } else {
        return NO_PIXELFORMAT;
    }
}

std::string mediaTypeToString(const GUID& type)
{
    if (type == MEDIATYPE_Video) {
        return "MEDIATYPE_Video";
    } else if (type == GUID_NULL) {
        return "GUID_NULL";
    } else {
        return "Unknown";
    }
}

string mediaSubtypeToString(const GUID & subtype)
{
    if (subtype == MEDIASUBTYPE_RGB24) {
        return "MEDIASUBTYPE_RGB24";
    } else if (subtype == MEDIASUBTYPE_RGB32) {
        return "MEDIASUBTYPE_RGB32";
    } else if (subtype == MEDIASUBTYPE_RGB8) {
        return "MEDIASUBTYPE_RGB8";
    } else if (subtype == MEDIASUBTYPE_UYVY) {
        return "MEDIASUBTYPE_UYVY";
    } else if (subtype == MEDIASUBTYPE_YUY2) {
        return "MEDIASUBTYPE_YUY2";
    } else if (subtype == MEDIASUBTYPE_MJPG) {
        return "MEDIASUBTYPE_MJPG";
    } else if (subtype == MEDIASUBTYPE_RGB555) {
        return "MEDIASUBTYPE_RGB555";
    } else if (subtype == MEDIASUBTYPE_RGB565) {
        return "MEDIASUBTYPE_RGB565";
    } else if (subtype == MEDIASUBTYPE_Y800) {
        return "MEDIASUBTYPE_Y800";
    } else if (subtype == GUID_NULL) {
        return "GUID_NULL";
    } else {
        return "Unknown";
    }
}

string mediaFormattypeToString(const GUID& formattype)
{
    if (formattype == FORMAT_None) {
        return "FORMAT_None";
    } else if (formattype == FORMAT_VideoInfo) {
        return "FORMAT_VideoInfo";
    } else if (formattype == FORMAT_VideoInfo2) {
        return "FORMAT_VideoInfo2";
    } else if (formattype == GUID_NULL) {
        return "GUID_NULL";
    } else {
        return "Unknown";
    }
}

string camImageFormatToString(const AM_MEDIA_TYPE* pMediaType)
{
    stringstream ss;
    VIDEOINFOHEADER* pVideoInfo = (VIDEOINFOHEADER*)(pMediaType->pbFormat);
    BITMAPINFOHEADER* pBitmapInfo = &pVideoInfo->bmiHeader;
    PixelFormat pf = mediaSubtypeToPixelFormat(pMediaType->subtype);
    ss << "(" << pBitmapInfo->biWidth << "x" << pBitmapInfo->biHeight << "), " << pf
            << ", " << 10000000./pVideoInfo->AvgTimePerFrame << " fps.";
    return ss.str();
}

bool isDSFeatureCamControl(CameraFeature feature)
{
    switch(feature) {
        case CAM_FEATURE_BRIGHTNESS:
        case CAM_FEATURE_SHARPNESS:
        case CAM_FEATURE_WHITE_BALANCE:
        case CAM_FEATURE_HUE:
        case CAM_FEATURE_SATURATION:
        case CAM_FEATURE_GAMMA:
        case CAM_FEATURE_GAIN:
            return false;
        case CAM_FEATURE_EXPOSURE:
        case CAM_FEATURE_IRIS:
        case CAM_FEATURE_FOCUS:
        case CAM_FEATURE_ZOOM:
        case CAM_FEATURE_PAN:
        case CAM_FEATURE_TILT:
            return true;
        case CAM_FEATURE_SHUTTER:
        case CAM_FEATURE_TEMPERATURE:
        case CAM_FEATURE_TRIGGER:
        case CAM_FEATURE_OPTICAL_FILTER:
        case CAM_FEATURE_CAPTURE_SIZE:
        case CAM_FEATURE_CAPTURE_QUALITY:
        case CAM_FEATURE_CONTRAST:
            AVG_TRACE(Logger::WARNING, "isDSFeatureCamControl: "
                    + cameraFeatureToString(feature) + " not supported by DirectShow.");
            return false;
        default:
            AVG_TRACE(Logger::WARNING, "isDSFeatureCamControl: "
                    + cameraFeatureToString(feature) + " unknown.");
            return false;
    }
}

long getDSFeatureID(CameraFeature feature)
{
    switch(feature) {
        case CAM_FEATURE_BRIGHTNESS:
            return VideoProcAmp_Brightness;
        case CAM_FEATURE_SHARPNESS:
            return VideoProcAmp_Sharpness;
        case CAM_FEATURE_WHITE_BALANCE:
            return VideoProcAmp_WhiteBalance;
        case CAM_FEATURE_HUE:
            return VideoProcAmp_Hue;
        case CAM_FEATURE_SATURATION:
            return VideoProcAmp_Saturation;
        case CAM_FEATURE_GAMMA:
            return VideoProcAmp_Gamma;
        case CAM_FEATURE_GAIN:
            return VideoProcAmp_Gain;
        case CAM_FEATURE_EXPOSURE:
            return CameraControl_Exposure;
        case CAM_FEATURE_IRIS:
            return CameraControl_Iris;
        case CAM_FEATURE_FOCUS:
            return CameraControl_Focus;
        case CAM_FEATURE_ZOOM:
            return CameraControl_Zoom;
        case CAM_FEATURE_PAN:
            return CameraControl_Pan;
        case CAM_FEATURE_TILT:
            return CameraControl_Tilt;
        case CAM_FEATURE_SHUTTER:
        case CAM_FEATURE_TEMPERATURE:
        case CAM_FEATURE_TRIGGER:
        case CAM_FEATURE_OPTICAL_FILTER:
        case CAM_FEATURE_CAPTURE_SIZE:
        case CAM_FEATURE_CAPTURE_QUALITY:
        case CAM_FEATURE_CONTRAST:
            AVG_TRACE(Logger::WARNING, "getDSFeatureID: "+cameraFeatureToString(feature)
                    +" not supported by DirectShow.");
            return 0;
        default:
            AVG_TRACE(Logger::WARNING, "getDSFeatureID: "+cameraFeatureToString(feature)+" unknown.");
            return -1;
    }
}

}
<commit_msg>Cosmetics.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  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 of the License, or (at your option) any later version.
//
//  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, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "DSHelper.h"

#include "../base/Exception.h"
#include "../base/Logger.h"

#include <stdio.h>
#include <oleauto.h>

#include <string>

using namespace std;

namespace avg {

#pragma warning(disable : 4995)
HRESULT AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
{
    IMoniker * pMoniker;
    IRunningObjectTable *pROT;
    WCHAR wsz[128];
    HRESULT hr;

    if (!pUnkGraph || !pdwRegister) {
        return E_POINTER;
    }

    if (FAILED(GetRunningObjectTable(0, &pROT))) {
        return E_FAIL;
    }

    hr = swprintf(wsz, NUMELMS(wsz), L"FilterGraph %08x pid %08x\0",
            (DWORD_PTR)pUnkGraph, GetCurrentProcessId());

    hr = CreateItemMoniker(L"!", wsz, &pMoniker);
    if (SUCCEEDED(hr)) {
        hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph, pMoniker,
                pdwRegister);
        pMoniker->Release();
    }

    pROT->Release();
    return hr;
}

void RemoveGraphFromRot(DWORD pdwRegister)
{
    IRunningObjectTable *pROT;

    if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
        pROT->Revoke(pdwRegister);
        pROT->Release();
    }
}

string getStringProp(IPropertyBag *pPropBag, LPCOLESTR pszPropName)
{
    VARIANT varName;
    VariantInit(&varName);
    HRESULT hr = pPropBag->Read(pszPropName, &varName, 0);
    if (FAILED(hr)) {
        return "";
    }
//    checkForDShowError(hr, string("DSHelper::getStringProp(")+pszPropName+")::Read PropBag");

    string s;
    int lenWStr = SysStringLen(varName.bstrVal);
    int lenAStr = WideCharToMultiByte(CP_ACP, 0, varName.bstrVal, lenWStr, 0, 0, NULL, NULL);
    if (lenAStr > 0) {
        char* pAStr = new char[lenAStr + 1];
        WideCharToMultiByte(CP_ACP, 0, varName.bstrVal, lenWStr, pAStr, lenAStr, NULL, NULL);
        pAStr[lenAStr] = 0;
        s = pAStr;
        delete[] pAStr;
    }

    VariantClear(&varName);
    return s;
}

PixelFormat mediaSubtypeToPixelFormat(const GUID& subtype)
{
    if (subtype == MEDIASUBTYPE_RGB24) {
        return B8G8R8;
    } else if (subtype == MEDIASUBTYPE_RGB32) {
        return B8G8R8X8;
    } else if (subtype == MEDIASUBTYPE_RGB8) {
        return I8;
    } else if (subtype == MEDIASUBTYPE_UYVY) {
        return YCbCr422;
    } else if (subtype == MEDIASUBTYPE_YUY2) {
        return YUYV422;
    } else if (subtype == MEDIASUBTYPE_RGB565) {
        return B5G6R5;
//    } else if (Subtype == MEDIASUBTYPE_Y800 && DesiredPF == "BY8_GBRG") {
//        return BAYER8_GBRG;
    } else if (subtype == MEDIASUBTYPE_Y800) {
        return I8;
    } else {
        return NO_PIXELFORMAT;
    }
}

std::string mediaTypeToString(const GUID& type)
{
    if (type == MEDIATYPE_Video) {
        return "MEDIATYPE_Video";
    } else if (type == GUID_NULL) {
        return "GUID_NULL";
    } else {
        return "Unknown";
    }
}

string mediaSubtypeToString(const GUID & subtype)
{
    if (subtype == MEDIASUBTYPE_RGB24) {
        return "MEDIASUBTYPE_RGB24";
    } else if (subtype == MEDIASUBTYPE_RGB32) {
        return "MEDIASUBTYPE_RGB32";
    } else if (subtype == MEDIASUBTYPE_RGB8) {
        return "MEDIASUBTYPE_RGB8";
    } else if (subtype == MEDIASUBTYPE_UYVY) {
        return "MEDIASUBTYPE_UYVY";
    } else if (subtype == MEDIASUBTYPE_YUY2) {
        return "MEDIASUBTYPE_YUY2";
    } else if (subtype == MEDIASUBTYPE_MJPG) {
        return "MEDIASUBTYPE_MJPG";
    } else if (subtype == MEDIASUBTYPE_RGB555) {
        return "MEDIASUBTYPE_RGB555";
    } else if (subtype == MEDIASUBTYPE_RGB565) {
        return "MEDIASUBTYPE_RGB565";
    } else if (subtype == MEDIASUBTYPE_Y800) {
        return "MEDIASUBTYPE_Y800";
    } else if (subtype == GUID_NULL) {
        return "GUID_NULL";
    } else {
        return "Unknown";
    }
}

string mediaFormattypeToString(const GUID& formattype)
{
    if (formattype == FORMAT_None) {
        return "FORMAT_None";
    } else if (formattype == FORMAT_VideoInfo) {
        return "FORMAT_VideoInfo";
    } else if (formattype == FORMAT_VideoInfo2) {
        return "FORMAT_VideoInfo2";
    } else if (formattype == GUID_NULL) {
        return "GUID_NULL";
    } else {
        return "Unknown";
    }
}

string camImageFormatToString(const AM_MEDIA_TYPE* pMediaType)
{
    stringstream ss;
    VIDEOINFOHEADER* pVideoInfo = (VIDEOINFOHEADER*)(pMediaType->pbFormat);
    BITMAPINFOHEADER* pBitmapInfo = &pVideoInfo->bmiHeader;
    PixelFormat pf = mediaSubtypeToPixelFormat(pMediaType->subtype);
    ss << "(" << pBitmapInfo->biWidth << "x" << pBitmapInfo->biHeight << "), " << pf
            << ", " << 10000000./pVideoInfo->AvgTimePerFrame << " fps.";
    return ss.str();
}

bool isDSFeatureCamControl(CameraFeature feature)
{
    switch(feature) {
        case CAM_FEATURE_BRIGHTNESS:
        case CAM_FEATURE_SHARPNESS:
        case CAM_FEATURE_WHITE_BALANCE:
        case CAM_FEATURE_HUE:
        case CAM_FEATURE_SATURATION:
        case CAM_FEATURE_GAMMA:
        case CAM_FEATURE_GAIN:
            return false;
        case CAM_FEATURE_EXPOSURE:
        case CAM_FEATURE_IRIS:
        case CAM_FEATURE_FOCUS:
        case CAM_FEATURE_ZOOM:
        case CAM_FEATURE_PAN:
        case CAM_FEATURE_TILT:
            return true;
        case CAM_FEATURE_SHUTTER:
        case CAM_FEATURE_TEMPERATURE:
        case CAM_FEATURE_TRIGGER:
        case CAM_FEATURE_OPTICAL_FILTER:
        case CAM_FEATURE_CAPTURE_SIZE:
        case CAM_FEATURE_CAPTURE_QUALITY:
        case CAM_FEATURE_CONTRAST:
            AVG_TRACE(Logger::WARNING, "isDSFeatureCamControl: "
                    + cameraFeatureToString(feature) + " not supported by DirectShow.");
            return false;
        default:
            AVG_TRACE(Logger::WARNING, "isDSFeatureCamControl: "
                    + cameraFeatureToString(feature) + " unknown.");
            return false;
    }
}

long getDSFeatureID(CameraFeature feature)
{
    switch(feature) {
        case CAM_FEATURE_BRIGHTNESS:
            return VideoProcAmp_Brightness;
        case CAM_FEATURE_SHARPNESS:
            return VideoProcAmp_Sharpness;
        case CAM_FEATURE_WHITE_BALANCE:
            return VideoProcAmp_WhiteBalance;
        case CAM_FEATURE_HUE:
            return VideoProcAmp_Hue;
        case CAM_FEATURE_SATURATION:
            return VideoProcAmp_Saturation;
        case CAM_FEATURE_GAMMA:
            return VideoProcAmp_Gamma;
        case CAM_FEATURE_GAIN:
            return VideoProcAmp_Gain;
        case CAM_FEATURE_EXPOSURE:
            return CameraControl_Exposure;
        case CAM_FEATURE_IRIS:
            return CameraControl_Iris;
        case CAM_FEATURE_FOCUS:
            return CameraControl_Focus;
        case CAM_FEATURE_ZOOM:
            return CameraControl_Zoom;
        case CAM_FEATURE_PAN:
            return CameraControl_Pan;
        case CAM_FEATURE_TILT:
            return CameraControl_Tilt;
        case CAM_FEATURE_SHUTTER:
        case CAM_FEATURE_TEMPERATURE:
        case CAM_FEATURE_TRIGGER:
        case CAM_FEATURE_OPTICAL_FILTER:
        case CAM_FEATURE_CAPTURE_SIZE:
        case CAM_FEATURE_CAPTURE_QUALITY:
        case CAM_FEATURE_CONTRAST:
            AVG_TRACE(Logger::WARNING, "getDSFeatureID: "+cameraFeatureToString(feature)
                    +" not supported by DirectShow.");
            return 0;
        default:
            AVG_TRACE(Logger::WARNING, "getDSFeatureID: "+cameraFeatureToString(feature)+" unknown.");
            return -1;
    }
}

}
<|endoftext|>


<commit_before>#include "getusername.h"
#include <errno.h>
#include <langinfo.h>
#include <locale.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <scxcorelib/scxstrencodingconv.h>

// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724432(v=vs.85).aspx
// Sets errno to:
//     ERROR_INVALID_PARAMETER - parameter is not valid
//     ERROR_BAD_ENVIRONMENT - locale is not UTF-8
//     ERROR_TOO_MANY_OPEN_FILES - already have the maximum allowed number of open files
//     ERROR_NO_ASSOCIATION - calling process has no controlling terminal
//     ERROR_INSUFFICIENT_BUFFER - buffer not large enough to hold username string
//     ERROR_NO_SUCH_USER - there was no corresponding entry in the utmp-file
//     ERROR_OUTOFMEMORY - insufficient memory to allocate passwd structure
//     ERROR_NO_ASSOCIATION - standard input didn't refer to a terminal
//     ERROR_INVALID_FUNCTION - getlogin_r() returned an unrecognized error code
//
// Returns:
//     1 - succeeded
//     0 - failed
BOOL GetUserName(WCHAR_T *lpBuffer, LPDWORD lpnSize)
{
	const std::string utf8 = "UTF-8";

	errno = 0;

	// Check parameters
	if (!lpBuffer || !lpnSize) {
		errno = ERROR_INVALID_PARAMETER;
		return 0;
	}

	// Select locale from environment
	setlocale(LC_ALL, "");
	// Check that locale is UTF-8
	if (nl_langinfo(CODESET) != utf8) {
		errno = ERROR_BAD_ENVIRONMENT;
		return 0;
	}

	// Get username from system in a thread-safe manner
	std::string username(LOGIN_NAME_MAX, '\0');
	int err = getlogin_r(&username[0], username.size());
	// Map errno to Win32 Error Codes
	if (err != 0) {
		switch (errno) {
		case EMFILE:
		case ENFILE:
			errno = ERROR_TOO_MANY_OPEN_FILES;
			break;
		case ENXIO:
			errno = ERROR_NO_ASSOCIATION;
			break;
		case ERANGE:
			errno = ERROR_INSUFFICIENT_BUFFER;
			break;
		case ENOENT:
			errno = ERROR_NO_SUCH_USER;
			break;
		case ENOMEM:
			errno = ERROR_OUTOFMEMORY;
			break;
		case ENOTTY:
			errno = ERROR_NO_ASSOCIATION;
			break;
		default:
			errno = ERROR_INVALID_FUNCTION;
		}
		return 0;
	}

	// "Trim" the username to the first trailing null because
	// otherwise the std::string with repeated null characters is
	// valid, and the conversion will still include all the null
	// characters. Creating a std::string from the C string of the
	// original effectively trims it to the first null, without
	// the need to manually trim whitespace (nor using Boost).
	username = std::string(username.c_str());

	// Convert to char * to WCHAR_T * (UTF-8 to UTF-16 LE w/o BOM)
	std::vector<unsigned char> output;
	SCXCoreLib::Utf8ToUtf16le(username, output);

	if (output.size()/2 + 1 > *lpnSize) {
		errno = ERROR_INSUFFICIENT_BUFFER;
		*lpnSize = output.size()/2 + 1;
		return 0;
	}

	// Add two null bytes (because it's UTF-16)
	output.push_back('\0');
	output.push_back('\0');

	memcpy(lpBuffer, &output[0], output.size());
	*lpnSize = output.size()/2;

	return 1;
}
<commit_msg>Refactor setting of lpnSize when buffer size is insufficient<commit_after>#include "getusername.h"
#include <errno.h>
#include <langinfo.h>
#include <locale.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <scxcorelib/scxstrencodingconv.h>

// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724432(v=vs.85).aspx
// Sets errno to:
//     ERROR_INVALID_PARAMETER - parameter is not valid
//     ERROR_BAD_ENVIRONMENT - locale is not UTF-8
//     ERROR_TOO_MANY_OPEN_FILES - already have the maximum allowed number of open files
//     ERROR_NO_ASSOCIATION - calling process has no controlling terminal
//     ERROR_INSUFFICIENT_BUFFER - buffer not large enough to hold username string
//     ERROR_NO_SUCH_USER - there was no corresponding entry in the utmp-file
//     ERROR_OUTOFMEMORY - insufficient memory to allocate passwd structure
//     ERROR_NO_ASSOCIATION - standard input didn't refer to a terminal
//     ERROR_INVALID_FUNCTION - getlogin_r() returned an unrecognized error code
//
// Returns:
//     1 - succeeded
//     0 - failed
BOOL GetUserName(WCHAR_T *lpBuffer, LPDWORD lpnSize)
{
	const std::string utf8 = "UTF-8";

	errno = 0;

	// Check parameters
	if (!lpBuffer || !lpnSize) {
		errno = ERROR_INVALID_PARAMETER;
		return 0;
	}

	// Select locale from environment
	setlocale(LC_ALL, "");
	// Check that locale is UTF-8
	if (nl_langinfo(CODESET) != utf8) {
		errno = ERROR_BAD_ENVIRONMENT;
		return 0;
	}

	// Get username from system in a thread-safe manner
	std::string username(LOGIN_NAME_MAX, '\0');
	int err = getlogin_r(&username[0], username.size());
	// Map errno to Win32 Error Codes
	if (err != 0) {
		switch (errno) {
		case EMFILE:
		case ENFILE:
			errno = ERROR_TOO_MANY_OPEN_FILES;
			break;
		case ENXIO:
			errno = ERROR_NO_ASSOCIATION;
			break;
		case ERANGE:
			errno = ERROR_INSUFFICIENT_BUFFER;
			break;
		case ENOENT:
			errno = ERROR_NO_SUCH_USER;
			break;
		case ENOMEM:
			errno = ERROR_OUTOFMEMORY;
			break;
		case ENOTTY:
			errno = ERROR_NO_ASSOCIATION;
			break;
		default:
			errno = ERROR_INVALID_FUNCTION;
		}
		return 0;
	}

	// "Trim" the username to the first trailing null because
	// otherwise the std::string with repeated null characters is
	// valid, and the conversion will still include all the null
	// characters. Creating a std::string from the C string of the
	// original effectively trims it to the first null, without
	// the need to manually trim whitespace (nor using Boost).
	username = std::string(username.c_str());

	// Convert to char * to WCHAR_T * (UTF-8 to UTF-16 LE w/o BOM)
	std::vector<unsigned char> output;
	SCXCoreLib::Utf8ToUtf16le(username, output);

	// The length is the number of characters in the string, which
	// is half the string size because UTF-16 encodes two bytes
	// per character, plus one for the trailing null.
	const DWORD length = output.size()/2 + 1;
	if (length > *lpnSize) {
		errno = ERROR_INSUFFICIENT_BUFFER;
		// Set lpnSize if buffer is too small to inform user
		// of necessary size
		*lpnSize = length;
		return 0;
	}

	// Add two null bytes (because it's UTF-16)
	output.push_back('\0');
	output.push_back('\0');

	memcpy(lpBuffer, &output[0], output.size());
	*lpnSize = output.size()/2;

	return 1;
}
<|endoftext|>