示例#1
0
int main(void) {
    Seawolf_loadConfig("../conf/seawolf.conf");
    Seawolf_init("Pitch PID");

    PID* pid;
    char data[64];
    double mv;
    bool paused = Var_get("PitchPID.Paused");

    Notify_filter(FILTER_MATCH, "UPDATED PitchPID.Coefficients");
    Notify_filter(FILTER_MATCH, "UPDATED PitchPID.Heading");
    Notify_filter(FILTER_MATCH, "UPDATED PitchPID.Paused");
    Notify_filter(FILTER_MATCH, "UPDATED IMU");

    pid = PID_new(Var_get("PitchPID.Heading"),
                  Var_get("PitchPID.p"),
                  Var_get("PitchPID.i"),
                  Var_get("PitchPID.d"));
    dataOut(0.0);

    while(true) {
        Notify_get(NULL, data);

        double pitch = Var_get("SEA.Pitch");
        if(strcmp(data, "PitchPID.Coefficients") == 0) {
            PID_setCoefficients(pid,
                                Var_get("PitchPID.p"),
                                Var_get("PitchPID.i"),
                                Var_get("PitchPID.d"));
            PID_resetIntegral(pid);
        } else if(strcmp(data, "PitchPID.Heading") == 0) {
            PID_setSetPoint(pid, Var_get("PitchPID.Heading"));
            mv = PID_update(pid, pitch);
            if(paused) {
                Var_set("PitchPID.Paused", 0.0);
            }
        } else if(strcmp(data, "PitchPID.Paused") == 0) {
            bool p = Var_get("PitchPID.Paused");
            if(p == paused) {
                continue;
            }

            paused = p;
            if(paused) {
                dataOut(0.0);
                Notify_send("PIDPAUSED", "Pitch");
            }
        } else if(strcmp(data, "IMU") == 0 && paused == false) {
            mv = PID_update(pid, pitch);
        }

        if(paused == false) {
            dataOut(mv);
        }
    }

    Seawolf_close();
    return 0;
}
void LibretroRunner::dataIn( DataType type, QMutex *mutex, void *data, size_t bytes, qint64 timeStamp ) {
    emit dataOut( type, mutex, data, bytes, timeStamp );

    switch( type ) {
        // Make a copy of the data into our own gamepad list
        case DataType::Input: {
            mutex->lock();
            GamepadState gamepad = *static_cast<GamepadState *>( data );
            mutex->unlock();
            int instanceID = gamepad.instanceID;
            libretroCore.gamepads[ instanceID ] = gamepad;
            break;
        }

        // Make a copy of the incoming data and store it
        case DataType::MouseInput: {
            mutex->lock();
            libretroCore.mouse = *static_cast<MouseState *>( data );
            mutex->unlock();
            break;
        }

        default:
            break;
    }
}
JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNClient_streamFileContent
(JNIEnv *env, jobject jthis, jstring jpath, jobject jrevision,
 jobject jpegRevision, jobject jstream)
{
  JNIEntry(SVNClient, streamFileContent);
  SVNClient *cl = SVNClient::getCppObject(jthis);
  if (cl == NULL)
    {
      JNIUtil::throwError(_("bad C++ this"));
      return;
    }
  JNIStringHolder path(jpath);
  if (JNIUtil::isExceptionThrown())
    return;

  Revision revision(jrevision);
  if (JNIUtil::isExceptionThrown())
    return;

  Revision pegRevision(jpegRevision);
  if (JNIUtil::isExceptionThrown())
    return;

  OutputStream dataOut(jstream);
  if (JNIUtil::isExceptionThrown())
    return;

  cl->streamFileContent(path, revision, pegRevision, dataOut);
}
示例#4
0
    void CsvFormatter::finishObject()
    {
        --_level;

        log_debug("finishObject, level=" << _level);

        if (_level == 1)
            dataOut();
    }
示例#5
0
文件: yx32b.c 项目: plumbum/lcd32m
inline static lcd_data_t readLcdOnce(void)
{
    dataIn();
    palClearPad(GPIOC, GPIOC_LCD_CS);
    // __asm__ volatile ("nop");
    lcd_data_t r = palReadPort(GPIOB);
    r = palReadPort(GPIOB); // Read two times for correct
    palSetPad(GPIOC, GPIOC_LCD_CS);
    dataOut();
    return r;
}
示例#6
0
	UString convert(iconv_t &ctx, byte *data, size_t n, size_t growth, size_t termSize) {
		if (ctx == ((iconv_t) -1))
			return "[!!!]";

		size_t size;
		ScopedArray<byte> dataOut(doConvert(ctx, data, n, n * growth + termSize, size));
		if (!dataOut)
			return "[!?!]";

		while (termSize-- > 0)
			dataOut[size++] = '\0';

		return UString(reinterpret_cast<const char *>(dataOut.get()));
	}
JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNClient_diff__Ljava_lang_String_2Lorg_apache_subversion_javahl_types_Revision_2Lorg_apache_subversion_javahl_types_Revision_2Lorg_apache_subversion_javahl_types_Revision_2Ljava_lang_String_2Ljava_io_OutputStream_2Lorg_apache_subversion_javahl_types_Depth_2Ljava_util_Collection_2ZZZZZ
(JNIEnv *env, jobject jthis, jstring jtarget, jobject jpegRevision,
 jobject jstartRevision, jobject jendRevision, jstring jrelativeToDir,
 jobject jstream, jobject jdepth, jobject jchangelists,
 jboolean jignoreAncestry, jboolean jnoDiffDeleted, jboolean jforce,
 jboolean jcopiesAsAdds, jboolean jignoreProps)
{
  JNIEntry(SVNClient, diff);
  SVNClient *cl = SVNClient::getCppObject(jthis);
  if (cl == NULL)
    {
      JNIUtil::throwError(_("bad C++ this"));
      return;
    }
  JNIStringHolder target(jtarget);
  if (JNIUtil::isExceptionThrown())
    return;

  Revision pegRevision(jpegRevision);
  if (JNIUtil::isExceptionThrown())
    return;

  Revision startRevision(jstartRevision);
  if (JNIUtil::isExceptionThrown())
    return;

  Revision endRevision(jendRevision);
  if (JNIUtil::isExceptionThrown())
    return;

  OutputStream dataOut(jstream);
  if (JNIUtil::isExceptionThrown())
    return;

  JNIStringHolder relativeToDir(jrelativeToDir);
  if (JNIUtil::isExceptionThrown())
    return;

  StringArray changelists(jchangelists);
  if (JNIUtil::isExceptionThrown())
    return;

  cl->diff(target, pegRevision, startRevision, endRevision, relativeToDir,
           dataOut, EnumMapper::toDepth(jdepth), changelists,
           jignoreAncestry ? true:false,
           jnoDiffDeleted ? true:false, jforce ? true:false,
           jcopiesAsAdds ? true:false, jignoreProps ? true:false);
}
示例#8
0
	MemoryReadStream *convert(iconv_t &ctx, const UString &str, size_t growth, size_t termSize) {
		if (ctx == ((iconv_t) -1))
			return 0;

		byte  *dataIn = const_cast<byte *>(reinterpret_cast<const byte *>(str.c_str()));
		size_t nIn    = std::strlen(str.c_str());
		size_t nOut   = nIn * growth + termSize;

		size_t size;
		ScopedArray<byte> dataOut(doConvert(ctx, dataIn, nIn, nOut, size));
		if (!dataOut)
			return 0;

		while (termSize-- > 0)
			dataOut[size++] = '\0';

		return new MemoryReadStream(dataOut.release(), size, true);
	}
bool saveThemeToBlob(const QString &themeBlob,
                     const QHash<QString, QPicture> &partPictures,
                     const QHash<QPair<QString, int>, QColor> &colors)
{
    QFile blob(themeBlob);
    if (!blob.open(QIODevice::WriteOnly)) {
        qWarning() << __FUNCTION__ << ": Could not create blob: " << themeBlob;
        return false;
    }

    QByteArray data;
    QBuffer dataBuffer(&data);
    dataBuffer.open(QIODevice::WriteOnly);
    QDataStream dataOut(&dataBuffer);

    const int colorsCount = colors.count();
    dataOut << colorsCount;
    const QList<QPair<QString, int> > colorKeys = colors.keys();
    for (int i = 0; i < colorsCount; ++i) {
        const QPair<QString, int> &key = colorKeys.at(i);
        dataOut << key;
        const QColor color = colors.value(key);
        dataOut << color;
    }

    dataOut << partPictures.count();
    QHashIterator<QString, QPicture> i(partPictures);
    while (i.hasNext()) {
        i.next();
        dataOut << i.key();
        dataOut << i.value(); // the QPicture
    }

    QDataStream blobOut(&blob);
    blobOut << blobVersion;
    blobOut << qCompress(data);
    return blobOut.status() == QDataStream::Ok;
}
示例#10
0
bool TrainingData::save(const QString &filename) {
    bool doCompress = ConfigData::instance().doCompressSdlFile();
    QString result;
    QXmlStreamWriter xmlWriter(&result);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();

    xmlWriter.writeStartElement("traininglog");
    weekMap->writeXML(xmlWriter);
    myRoutesModel->writeXML(xmlWriter);
    xmlWriter.writeEndDocument();

    QFile file(filename);
    // write string to file
    if (doCompress) {
        qDebug() << "writing compressed file";
        if ( ! file.open(QFile::WriteOnly)) {
            // TODO warn
            qDebug() << "Warning: can not write" << filename;
            return false;
        }
        QByteArray ba = qCompress(result.toUtf8());
        QDataStream dataOut(&file);
        dataOut << ba;
        file.close();
    } else {
        qDebug() << "writing UNcompressed file";
        if ( ! file.open(QFile::WriteOnly)) {
            // TODO warn
            qDebug() << "Warning: can not write" << filename;
            return false;
        }
        QTextStream txtStream(&file);
        txtStream << result;       
    }
    file.close();
    return true;
}
JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_dump
(JNIEnv *env, jobject jthis, jobject jpath, jobject jdataout,
 jobject jrevisionStart, jobject jrevisionEnd, jboolean jincremental,
 jboolean juseDeltas, jobject jnotifyCallback)
{
  JNIEntry(SVNRepos, dump);
  SVNRepos *cl = SVNRepos::getCppObject(jthis);
  if (cl == NULL)
    {
      JNIUtil::throwError(_("bad C++ this"));
      return;
    }

  File path(jpath);
  if (JNIUtil::isExceptionThrown())
    return;

  OutputStream dataOut(jdataout);
  if (JNIUtil::isExceptionThrown())
    return;

  Revision revisionStart(jrevisionStart);
  if (JNIUtil::isExceptionThrown())
    return;

  Revision revisionEnd(jrevisionEnd);
  if (JNIUtil::isExceptionThrown())
    return;

  ReposNotifyCallback notifyCallback(jnotifyCallback);

  cl->dump(path, dataOut, revisionStart, revisionEnd,
           jincremental ? true : false, juseDeltas ? true : false,
           jnotifyCallback != NULL ? &notifyCallback : NULL);
}
示例#12
0
long outOfMoneyOption(vector<Asset*>& assets, double startMoney){ //based on what

	Asset* calls;
	Asset* puts;
	Asset* underlyer;
	double tCRatio = 0.01; //records the transaction cost ratio
	if (assets.size() != 3){
		cerr << " Wrong number of objects to test outOfMoneyOption" << endl;
		exit (EXIT_FAILURE);
	}

	if (assets.at(0)->getIsEquity() == 1){ //first object is Equity
		underlyer = assets.at(0);
		if(assets.at(1)->getIsCall() == 1){ //second object is calls
			calls = assets.at(1);
			puts = assets.at(2);
		}
		else{
			calls = assets.at(2);
			puts = assets.at(1);
		}
	}
	else if (assets.at(0)->getIsOption() == 1){
		if(assets.at(0)->getIsCall() == 1){
			calls = assets.at(0);
			if(assets.at(1)->getIsEquity() == 1){
				underlyer = assets.at(1);
				puts = assets.at(2);
			}
			else{
				underlyer = assets.at(2);
				puts = assets.at(1);
			}

		}
		else{
			puts = assets.at(0);
			if(assets.at(1)->getIsEquity() == 1){
				underlyer = assets.at(1);
				calls = assets.at(2);
			}
			else{
				underlyer = assets.at(2);
				calls = assets.at(1);
			}
		}
	}

	//we have the required types of data: perform back-test.
	//Simple strat that just keeps cash adn trades 20% of portfolio in out of the money straddle.
	//Equity information is contained is separate object.

	struct stat fStatus; //where all the output will be in for further analysis
	string outputFile = assets.at(0)->getWriteTo()+ "/" + "outOfMoneyOption.csv";
	int thereOrNot = stat(outputFile.c_str(), &fStatus);
	ofstream dataOut(outputFile.c_str(), ios_base::out | ios_base::app); //append to file only will create file if not there
	if (thereOrNot == -1) //file not already created.
		dataOut << "Date," << "Capital," << "Cash," << "calls," << "puts" << endl;
	else{}//do nothing


	double currCash = startMoney;
	deque<double>results;
	results.push_back(startMoney);
	double nbrCalls = 0; //in practice, very hard to get a perfect straddle, so numbers will vary.
	double nbrPuts = 0;
	double callID = 0; //ID of currently held call contracts
	double putID = 0; //ID of currently held put contracts
	size_t equityIndex = 0;
	long currDate = underlyer->getDate(equityIndex);
	dataOut << currDate << "," << currCash
			<< "," << currCash << "," << nbrCalls << "," << nbrPuts << endl;

	size_t callsPos = 0;
	size_t putsPos = 0;
	double oufOfMoneyRatio = 0.2; // certainly need to data mine this value.

	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	//////////////////// find option closest to outOfMoneyRatio ////////////////////////
	while (calls->getDate(callsPos) == currDate){

		callsDailyVol += calls->getVolume(callsPos);
		callsDailyOoi += calls->getOoi(callsPos);
		++callsPos;
		if(callsPos == calls->getNbrRows()) break;
	}

	//get puts daily volume and open interest for all options on given day.
	while (puts->getDate(putsPos) == currDate){ //while I am on one date
		putsDailyVol += puts->getVolume(putsPos);
		putsDailyOoi += puts->getOoi(putsPos);
		++putsPos;
		if(putsPos == puts->getNbrRows()) break;
	}

	prevPcVolRatio = putsDailyVol/(callsDailyVol + putsDailyVol);
	prevPcOoiRatio = putsDailyOoi/(callsDailyOoi + putsDailyOoi);

	//////////////////////// get first day data on volumes /////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////


	while(++equityIndex < underlyer->getNbrRows()){ //increment before comparing, to start comparing from row 1.

		currDate = underlyer->getDate(equityIndex);

		if (nbrToLong - currLongPos > 0){ //I have to buy some stock

			if(currCash - (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex) >= 0){ // I've go enough cash to commit
				currCash -= (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex);
				currLongPos = nbrToLong;
			}
			else{
				nbrToLong = currLongPos + floor(currCash/((1+tCRatio)*underlyer->getOpen(equityIndex))); //buy as much as I can
				currCash -= (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex);
				currLongPos = nbrToLong;
			}

		}
		else if (nbrToLong - currLongPos < 0){ // I have to sell some stock, currently only doing long only.
			currCash += (1-tCRatio)*(currLongPos - nbrToLong)*underlyer->getOpen(equityIndex);
			currLongPos = nbrToLong;
		}
		else{} // do nothing.

		//re-initialize values on new date
		callsDailyVol = 0;
		callsDailyOoi = 0;
		putsDailyVol = 0;
		putsDailyOoi = 0;
		//get calls daily volume and open interest for all options on given day.
		while (calls->getDate(callsPos) == currDate){ //while I am on one date
			callsDailyVol += calls->getVolume(callsPos);
			callsDailyOoi += calls->getOoi(callsPos);
			++callsPos;
			if(callsPos == calls->getNbrRows()) break;
		}

		//get puts daily volume and open interest for all options on given day.
		while (puts->getDate(putsPos) == currDate){ //while I am on one date
			putsDailyVol += puts->getVolume(putsPos);
			putsDailyOoi += puts->getOoi(putsPos);
			++putsPos;
			if(putsPos == puts->getNbrRows()) break;
		}

		currPcVolRatio = putsDailyVol/(callsDailyVol + putsDailyVol); //update pcVolRatio, wrong, actually want difference in volumes from one day to the other.
		currPcOoiRatio = putsDailyOoi/(callsDailyOoi + putsDailyOoi);

		//make trade decision based on pcVolRatio
		//start easy, only long, cannot short.

		if (currPcVolRatio - prevPcVolRatio < RATIODIFF){
			nbrToLong += floor((1-currPcVolRatio)*(currCash/((1+tCRatio)*underlyer->getClose(equityIndex))));
		}
		else if (currPcVolRatio - prevPcVolRatio > RATIODIFF)
			if(currLongPos > 0)
				nbrToLong = floor((currPcVolRatio)*currLongPos); //diminish part of stocks
			else{}
		else{
			if(currLongPos*underlyer->getClose(equityIndex) > currCash) //no clear sign and lots of cash in stocks
				nbrToLong = nbrToLong * 0.9; //diminish part of equity. 0.9 picked random
			else{} //do nothing.
		}


		results.push_back(currCash + currLongPos * underlyer->getClose(equityIndex));
		dataOut << currDate << "," << currCash + currLongPos* underlyer->getClose(equityIndex)
				<< "," << currCash << "," << currLongPos << "," << 0 << endl;
	}

	plotResults(underlyer->getDateColumnPtr(), &results);
	plotLogResults(underlyer->getDateColumnPtr(), &results);
	return 0;


	return 0;
}
示例#13
0
long optionsVolumeComp1(vector<Asset*>& assets, double startMoney){

	Asset* calls;
	Asset* puts;
	Asset* underlyer;
	const double RATIODIFF = 0.05;
	double tCRatio = 0.01; //records the transaction cost ratio
	if (assets.size() != 3){
		cerr << " Wrong number of objects to test optionsVolumeComp1" << endl;
		exit (EXIT_FAILURE);
	}

	if (assets.at(0)->getIsEquity() == 1){ //first object is Equity
		underlyer = assets.at(0);
		if(assets.at(1)->getIsCall() == 1){ //second object is calls
			calls = assets.at(1);
			puts = assets.at(2);
		}
		else{
			calls = assets.at(2);
			puts = assets.at(1);
		}
	}
	else if (assets.at(0)->getIsOption() == 1){
		if(assets.at(0)->getIsCall() == 1){
			calls = assets.at(0);
			if(assets.at(1)->getIsEquity() == 1){
				underlyer = assets.at(1);
				puts = assets.at(2);
			}
			else{
				underlyer = assets.at(2);
				puts = assets.at(1);
			}

		}
		else{
			puts = assets.at(0);
			if(assets.at(1)->getIsEquity() == 1){
				underlyer = assets.at(1);
				calls = assets.at(2);
			}
			else{
				underlyer = assets.at(2);
				calls = assets.at(1);
			}
		}
	}

	else{
		cerr << " Functions requires an equity, a  put and a call dataset to do analysis."
				"At least one is missing." << endl; //write using exception throwing rather than exit.
		exit (EXIT_FAILURE);
	}



	//we have the required types of data: perform back-test.
	//ooi is lagged by one day. Do not forget, that for any day. we get the
	//info on the following day, thus trading strategy must rely on
	//one day old information.
	//Equity information is contained in separate object.

	struct stat fStatus; //where all the output will be i for further analysis
	string outputFile = assets.at(0)->getWriteTo()+ "/" + "optionsVolumeComp1.csv";
	int thereOrNot = stat(outputFile.c_str(), &fStatus);
	ofstream dataOut(outputFile.c_str(), ios_base::out | ios_base::app); //append to file only will create file if not there
	if (thereOrNot == -1) //file not already created.
		dataOut << "Date," << "Capital," << "Cash," << "LongPos," << "ShortPos" << endl;
	else{}//do nothing


	double currCash = startMoney;
	deque<double>results;
	results.push_back(startMoney);
	double currLongPos = 0; //number of short positions
	double nbrToLong = 0; //number of shares to buy first thing in morning.
	double currShortPos = 0; //number of long positions (trying long only for now)
	double nbrToShort = 0; //number of shares to short first thing in morning.
	size_t equityIndex = 0;
	long currDate = underlyer->getDate(equityIndex);
	dataOut << currDate << "," << currCash + currLongPos* underlyer->getClose(equityIndex)
			<< "," << currCash << "," << currLongPos << "," << 0 << endl;

	size_t callsPos = 0;
	size_t putsPos = 0;
	double callsDailyVol = 0;
	double callsDailyOoi = 0;
	double putsDailyVol = 0;
	double putsDailyOoi = 0;
	double prevPcVolRatio = 0;
	double currPcVolRatio = 0;
	double prevPcOoiRatio = 0;
	double currPcOoiRatio = 0;

	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	//////////////////////// get first day data on volumes /////////////////////////////
	while (calls->getDate(callsPos) == currDate){
		callsDailyVol += calls->getVolume(callsPos);
		callsDailyOoi += calls->getOoi(callsPos);
		++callsPos;
		if(callsPos == calls->getNbrRows()) break;
	}

	//get puts daily volume and open interest for all options on given day.
	while (puts->getDate(putsPos) == currDate){ //while I am on one date
		putsDailyVol += puts->getVolume(putsPos);
		putsDailyOoi += puts->getOoi(putsPos);
		++putsPos;
		if(putsPos == puts->getNbrRows()) break;
	}

	prevPcVolRatio = putsDailyVol/(callsDailyVol + putsDailyVol);
	prevPcOoiRatio = putsDailyOoi/(callsDailyOoi + putsDailyOoi);

	//////////////////////// get first day data on volumes /////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////


	while(++equityIndex < underlyer->getNbrRows()){ //increment before comparing, to start comparing from row 1.

		currDate = underlyer->getDate(equityIndex);

		if (nbrToLong - currLongPos > 0){ //I have to buy some stock

			if(currCash - (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex) >= 0){ // I've go enough cash to commit
				currCash -= (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex);
				currLongPos = nbrToLong;
			}
			else{
				nbrToLong = currLongPos + floor(currCash/((1+tCRatio)*underlyer->getOpen(equityIndex))); //buy as much as I can
				currCash -= (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex);
				currLongPos = nbrToLong;
			}

		}
		else if (nbrToLong - currLongPos < 0){ // I have to sell some stock, currently only doing long only.
			currCash += (1-tCRatio)*(currLongPos - nbrToLong)*underlyer->getOpen(equityIndex);
			currLongPos = nbrToLong;
		}
		else{} // do nothing.

		//re-initialize values on new date
		callsDailyVol = 0;
		callsDailyOoi = 0;
		putsDailyVol = 0;
		putsDailyOoi = 0;
		//get calls daily volume and open interest for all options on given day.
		while (calls->getDate(callsPos) == currDate){ //while I am on one date
			callsDailyVol += calls->getVolume(callsPos);
			callsDailyOoi += calls->getOoi(callsPos);
			++callsPos;
			if(callsPos == calls->getNbrRows()) break;
		}

		//get puts daily volume and open interest for all options on given day.
		while (puts->getDate(putsPos) == currDate){ //while I am on one date
			putsDailyVol += puts->getVolume(putsPos);
			putsDailyOoi += puts->getOoi(putsPos);
			++putsPos;
			if(putsPos == puts->getNbrRows()) break;
		}

		currPcVolRatio = putsDailyVol/(callsDailyVol + putsDailyVol); //update pcVolRatio, wrong, actually want difference in volumes from one day to the other.
		currPcOoiRatio = putsDailyOoi/(callsDailyOoi + putsDailyOoi);

		//make trade decision based on pcVolRatio
		//start easy, only long, cannot short.

		if (currPcVolRatio - prevPcVolRatio < RATIODIFF){
			nbrToLong += floor((1-currPcVolRatio)*(currCash/((1+tCRatio)*underlyer->getClose(equityIndex))));
		}
		else if (currPcVolRatio - prevPcVolRatio > RATIODIFF)
			if(currLongPos > 0)
				nbrToLong = floor((currPcVolRatio)*currLongPos); //diminish part of stocks
			else{}
		else{
			if(currLongPos*underlyer->getClose(equityIndex) > currCash) //no clear sign and lots of cash in stocks
				nbrToLong = nbrToLong * 0.9; //diminish part of equity. 0.9 picked random
			else{} //do nothing.
		}


		results.push_back(currCash + currLongPos * underlyer->getClose(equityIndex));
		dataOut << currDate << "," << currCash + currLongPos* underlyer->getClose(equityIndex)
				<< "," << currCash << "," << currLongPos << "," << 0 << endl;
	}

	plotResults(underlyer->getDateColumnPtr(), &results);
	plotLogResults(underlyer->getDateColumnPtr(), &results);
	return 0;
}
int main(int argc, char ** argv) {

	MPI_Init(&argc, &argv);

	NcError error(NcError::silent_nonfatal);

try {

	// Input filename
	std::string strInputFile;

	// Output filename
	std::string strOutputFile;

	// Separate topography file
	std::string strTopographyFile;

	// List of variables to extract
	std::string strVariables;

	// Extract geopotential height
	bool fGeopotentialHeight;

	// Pressure levels to extract
	std::string strPressureLevels;

	// Height levels to extract
	std::string strHeightLevels;

	// Extract variables at the surface
	bool fExtractSurface;

	// Extract total energy
	bool fExtractTotalEnergy;

	// Parse the command line
	BeginCommandLine()
		CommandLineString(strInputFile, "in", "");
		CommandLineString(strOutputFile, "out", "");
		CommandLineString(strVariables, "var", "");
		CommandLineBool(fGeopotentialHeight, "output_z");
		CommandLineBool(fExtractTotalEnergy, "output_energy");
		CommandLineString(strPressureLevels, "p", "");
		CommandLineString(strHeightLevels, "z", "");
		CommandLineBool(fExtractSurface, "surf");

		ParseCommandLine(argc, argv);
	EndCommandLine(argv)

	AnnounceBanner();

	// Check command line arguments
	if (strInputFile == "") {
		_EXCEPTIONT("No input file specified");
	}
	if (strOutputFile == "") {
		_EXCEPTIONT("No output file specified");
	}
	if (strVariables == "") {
		_EXCEPTIONT("No variables specified");
	}

	// Parse variable string
	std::vector< std::string > vecVariableStrings;

	ParseVariableList(strVariables, vecVariableStrings);

	// Check variables
	if (vecVariableStrings.size() == 0) {
		_EXCEPTIONT("No variables specified");
	}

	// Parse pressure level string
	std::vector<double> vecPressureLevels;

	ParseLevelArray(strPressureLevels, vecPressureLevels);

	int nPressureLevels = (int)(vecPressureLevels.size());

	for (int k = 0; k < nPressureLevels; k++) {
		if (vecPressureLevels[k] <= 0.0) {
			_EXCEPTIONT("Non-positive pressure values not allowed");
		}
	}

	// Parse height level string
	std::vector<double> vecHeightLevels;

	ParseLevelArray(strHeightLevels, vecHeightLevels);

	int nHeightLevels = (int)(vecHeightLevels.size());

	// Check pressure levels
	if ((nPressureLevels == 0) &&
		(nHeightLevels == 0) &&
		(!fExtractSurface)
	) {
		_EXCEPTIONT("No pressure / height levels to process");
	}

	// Open input file
	AnnounceStartBlock("Loading input file");
	NcFile ncdf_in(strInputFile.c_str(), NcFile::ReadOnly);
	if (!ncdf_in.is_valid()) {
		_EXCEPTION1("Unable to open file \"%s\" for reading",
			strInputFile.c_str());
	}

	// Load time array
	Announce("Time");
	NcVar * varTime = ncdf_in.get_var("time");
	if (varTime == NULL) {
		_EXCEPTION1("File \"%s\" does not contain variable \"time\"",
			strInputFile.c_str());
	}
	int nTime = varTime->get_dim(0)->size();

	DataArray1D<double> dTime(nTime);
	varTime->set_cur((long)0);
	varTime->get(&(dTime[0]), nTime);

	// Load latitude array
	Announce("Latitude");
	NcVar * varLat = ncdf_in.get_var("lat");
	if (varLat == NULL) {
		_EXCEPTION1("File \"%s\" does not contain variable \"lat\"",
			strInputFile.c_str());
	}
	int nLat = varLat->get_dim(0)->size();

	DataArray1D<double> dLat(nLat);
	varLat->set_cur((long)0);
	varLat->get(&(dLat[0]), nLat);

	// Load longitude array
	Announce("Longitude");
	NcVar * varLon = ncdf_in.get_var("lon");
	if (varLon == NULL) {
		_EXCEPTION1("File \"%s\" does not contain variable \"lon\"",
			strInputFile.c_str());
	}
	int nLon = varLon->get_dim(0)->size();

	DataArray1D<double> dLon(nLon);
	varLon->set_cur((long)0);
	varLon->get(&(dLon[0]), nLon);

	// Load level array
	Announce("Level");
	NcVar * varLev = ncdf_in.get_var("lev");
	if (varLev == NULL) {
		_EXCEPTION1("File \"%s\" does not contain variable \"lev\"",
			strInputFile.c_str());
	}
	int nLev = varLev->get_dim(0)->size();

	DataArray1D<double> dLev(nLev);
	varLev->set_cur((long)0);
	varLev->get(&(dLev[0]), nLev);

	// Load level interface array
	Announce("Interface");
	NcVar * varILev = ncdf_in.get_var("ilev");
	int nILev = 0;
	DataArray1D<double> dILev;
	if (varILev == NULL) {
		Announce("Warning: Variable \"ilev\" not found");
	} else {
		nILev = varILev->get_dim(0)->size();
		if (nILev != nLev + 1) {
			_EXCEPTIONT("Variable \"ilev\" must have size lev+1");
		}
		dILev.Allocate(nILev);
		varILev->set_cur((long)0);
		varILev->get(&(dILev[0]), nILev);
	}

	// Load topography
	Announce("Topography");
	NcVar * varZs = ncdf_in.get_var("Zs");
	if (varZs == NULL) {
		_EXCEPTION1("File \"%s\" does not contain variable \"Zs\"",
			strInputFile.c_str());
	}

	DataArray2D<double> dZs(nLat, nLon);
	varZs->set_cur((long)0, (long)0);
	varZs->get(&(dZs[0][0]), nLat, nLon);

	AnnounceEndBlock("Done");

	// Open output file
	AnnounceStartBlock("Constructing output file");

	NcFile ncdf_out(strOutputFile.c_str(), NcFile::Replace);
	if (!ncdf_out.is_valid()) {
		_EXCEPTION1("Unable to open file \"%s\" for writing",
			strOutputFile.c_str());
	}

	CopyNcFileAttributes(&ncdf_in, &ncdf_out);

	// Output time array
	Announce("Time");
	NcDim * dimOutTime = ncdf_out.add_dim("time");
	NcVar * varOutTime = ncdf_out.add_var("time", ncDouble, dimOutTime);
	varOutTime->set_cur((long)0);
	varOutTime->put(&(dTime[0]), nTime);

	CopyNcVarAttributes(varTime, varOutTime);

	// Output pressure array
	NcDim * dimOutP = NULL;
	NcVar * varOutP = NULL;
	if (nPressureLevels > 0) {
		Announce("Pressure");
		dimOutP = ncdf_out.add_dim("p", nPressureLevels);
		varOutP = ncdf_out.add_var("p", ncDouble, dimOutP);
		varOutP->set_cur((long)0);
		varOutP->put(&(vecPressureLevels[0]), nPressureLevels);
	}

	// Output height array
	NcDim * dimOutZ = NULL;
	NcVar * varOutZ = NULL;
	if (nHeightLevels > 0) {
		Announce("Height");
		dimOutZ = ncdf_out.add_dim("z", nHeightLevels);
		varOutZ = ncdf_out.add_var("z", ncDouble, dimOutZ);
		varOutZ->set_cur((long)0);
		varOutZ->put(&(vecHeightLevels[0]), nHeightLevels);
	}

	// Output latitude and longitude array
	Announce("Latitude");
	NcDim * dimOutLat = ncdf_out.add_dim("lat", nLat);
	NcVar * varOutLat = ncdf_out.add_var("lat", ncDouble, dimOutLat);
	varOutLat->set_cur((long)0);
	varOutLat->put(&(dLat[0]), nLat);

	CopyNcVarAttributes(varLat, varOutLat);

	Announce("Longitude");
	NcDim * dimOutLon = ncdf_out.add_dim("lon", nLon);
	NcVar * varOutLon = ncdf_out.add_var("lon", ncDouble, dimOutLon);
	varOutLon->set_cur((long)0);
	varOutLon->put(&(dLon[0]), nLon);

	CopyNcVarAttributes(varLon, varOutLon);

	// Output topography
	Announce("Topography");
	NcVar * varOutZs = ncdf_out.add_var(
		"Zs", ncDouble, dimOutLat, dimOutLon);

	varOutZs->set_cur((long)0, (long)0);
	varOutZs->put(&(dZs[0][0]), nLat, nLon);

	AnnounceEndBlock("Done");

	// Done
	AnnounceEndBlock("Done");

	// Load all variables
	Announce("Loading variables");

	std::vector<NcVar *> vecNcVar;
	for (int v = 0; v < vecVariableStrings.size(); v++) {
		vecNcVar.push_back(ncdf_in.get_var(vecVariableStrings[v].c_str()));
		if (vecNcVar[v] == NULL) {
			_EXCEPTION1("Unable to load variable \"%s\" from file",
				vecVariableStrings[v].c_str());
		}
	}

	// Physical constants
	Announce("Initializing thermodynamic variables");

	NcAtt * attEarthRadius = ncdf_in.get_att("earth_radius");
	double dEarthRadius = attEarthRadius->as_double(0);

	NcAtt * attRd = ncdf_in.get_att("Rd");
	double dRd = attRd->as_double(0);

	NcAtt * attCp = ncdf_in.get_att("Cp");
	double dCp = attCp->as_double(0);

	double dGamma = dCp / (dCp - dRd);

	NcAtt * attP0 = ncdf_in.get_att("P0");
	double dP0 = attP0->as_double(0);

	double dPressureScaling = dP0 * std::pow(dRd / dP0, dGamma);

	NcAtt * attZtop = ncdf_in.get_att("Ztop");
	double dZtop = attZtop->as_double(0);

	// Input data
	DataArray3D<double> dataIn(nLev, nLat, nLon);
	DataArray3D<double> dataInt(nILev, nLat, nLon);

	// Output data
	DataArray2D<double> dataOut(nLat, nLon);

	// Pressure in column
	DataArray1D<double> dataColumnP(nLev);

	// Height in column
	DataArray1D<double> dataColumnZ(nLev);
	DataArray1D<double> dataColumnIZ(nILev);

	// Column weights
	DataArray1D<double> dW(nLev);
	DataArray1D<double> dIW(nILev);

	// Loop through all times, pressure levels and variables
	AnnounceStartBlock("Interpolating");

	// Add energy variable
	NcVar * varEnergy;
	if (fExtractTotalEnergy) {
		varEnergy = ncdf_out.add_var("TE", ncDouble, dimOutTime);
	}

	// Create output pressure variables
	std::vector<NcVar *> vecOutNcVarP;
	if (nPressureLevels > 0) {
		for (int v = 0; v < vecVariableStrings.size(); v++) {
			vecOutNcVarP.push_back(
				ncdf_out.add_var(
					vecVariableStrings[v].c_str(), ncDouble,
						dimOutTime, dimOutP, dimOutLat, dimOutLon));

			// Copy attributes
			CopyNcVarAttributes(vecNcVar[v], vecOutNcVarP[v]);
		}
	}

	// Create output height variables
	std::vector<NcVar *> vecOutNcVarZ;
	if (nHeightLevels > 0) {
		for (int v = 0; v < vecVariableStrings.size(); v++) {
			std::string strVarName = vecVariableStrings[v];
			if (nPressureLevels > 0) {
				strVarName += "z";
			}
			vecOutNcVarZ.push_back(
				ncdf_out.add_var(
					strVarName.c_str(), ncDouble,
						dimOutTime, dimOutZ, dimOutLat, dimOutLon));

			// Copy attributes
			CopyNcVarAttributes(vecNcVar[v], vecOutNcVarZ[v]);
		}
	}

	// Create output surface variable
	std::vector<NcVar *> vecOutNcVarS;
	if (fExtractSurface) {
		for (int v = 0; v < vecVariableStrings.size(); v++) {
			std::string strVarName = vecVariableStrings[v];
			strVarName += "S";

			vecOutNcVarS.push_back(
				ncdf_out.add_var(
					strVarName.c_str(), ncDouble,
						dimOutTime, dimOutLat, dimOutLon));

			// Copy attributes
			CopyNcVarAttributes(vecNcVar[v], vecOutNcVarS[v]);
		}
	}

	// Loop over all times
	for (int t = 0; t < nTime; t++) {

		char szAnnounce[256];
		sprintf(szAnnounce, "Time %i", t); 
		AnnounceStartBlock(szAnnounce);

		// Rho
		DataArray3D<double> dataRho(nLev, nLat, nLon);

		NcVar * varRho = ncdf_in.get_var("Rho");
		if (varRho == NULL) {
			_EXCEPTIONT("Unable to load variable \"Rho\" from file");
		}
		varRho->set_cur(t, 0, 0, 0);
		varRho->get(&(dataRho[0][0][0]), 1, nLev, nLat, nLon);

		// Pressure
		DataArray3D<double> dataP(nLev, nLat, nLon);

		if (nPressureLevels != 0) {
			NcVar * varP = ncdf_in.get_var("P");
			if (varP == NULL) {
				_EXCEPTIONT("Unable to load variable \"P\" from file");
			}
			varP->set_cur(t, 0, 0, 0);
			varP->get(&(dataP[0][0][0]), 1, nLev, nLat, nLon);
		}
/*
		// Populate pressure array
		if (nPressureLevels > 0) {

			// Calculate pointwise pressure
			for (int k = 0; k < nLev; k++) {
			for (int i = 0; i < nLat; i++) {
			for (int j = 0; j < nLon; j++) {
				dataP[k][i][j] = dPressureScaling
					* exp(log(dataRho[k][i][j] * dataP[k][i][j]) * dGamma);
			}
			}
			}
		}
*/
		// Height everywhere
		DataArray3D<double> dataZ(nLev, nLat, nLon);
		DataArray3D<double> dataIZ;
		if (nILev != 0) {
			dataIZ.Allocate(nILev, nLat, nLon);
		}

		// Populate height array
		if ((nHeightLevels > 0) || (fGeopotentialHeight)) {
			for (int k = 0; k < nLev; k++) {
			for (int i = 0; i < nLat; i++) {
			for (int j = 0; j < nLon; j++) {
				dataZ[k][i][j] = dZs[i][j] + dLev[k] * (dZtop - dZs[i][j]);
			}
			}
			}

			for (int k = 0; k < nILev; k++) {
			for (int i = 0; i < nLat; i++) {
			for (int j = 0; j < nLon; j++) {
				dataIZ[k][i][j] = dZs[i][j] + dILev[k] * (dZtop - dZs[i][j]);
			}
			}
			}
		}

		// Loop through all pressure levels and variables
		for (int v = 0; v < vecNcVar.size(); v++) {

			bool fOnInterfaces = false;

			// Load in the data array
			vecNcVar[v]->set_cur(t, 0, 0, 0);

			if (vecNcVar[v]->get_dim(1)->size() == nLev) {
				vecNcVar[v]->get(&(dataIn[0][0][0]), 1, nLev, nLat, nLon);

				Announce("%s (n)", vecVariableStrings[v].c_str());

			} else if (vecNcVar[v]->get_dim(1)->size() == nILev) {
				vecNcVar[v]->get(&(dataInt[0][0][0]), 1, nILev, nLat, nLon);
				fOnInterfaces = true;

				Announce("%s (i)", vecVariableStrings[v].c_str());
			} else {
				_EXCEPTION1("Variable \"%s\" has invalid level dimension",
					vecVariableStrings[v].c_str());
			}

			// At the physical surface
			if (fExtractSurface) {

				if (fOnInterfaces) {
					for (int i = 0; i < nLat; i++) {
					for (int j = 0; j < nLon; j++) {
						dataOut[i][j] = dataInt[0][i][j];
					}
					}

				} else {

					int kBegin = 0;
					int kEnd = 3;

					PolynomialInterp::LagrangianPolynomialCoeffs(
						3, dLev, dW, 0.0);

					// Loop thorugh all latlon indices
					for (int i = 0; i < nLat; i++) {
					for (int j = 0; j < nLon; j++) {

						// Interpolate in the vertical
						dataOut[i][j] = 0.0;
						for (int k = kBegin; k < kEnd; k++) {
							dataOut[i][j] += dW[k] * dataIn[k][i][j];
						}
					}
					}
				}

				// Write variable
				vecOutNcVarS[v]->set_cur(t, 0, 0);
				vecOutNcVarS[v]->put(&(dataOut[0][0]), 1, nLat, nLon);

			}

			// Loop through all pressure levels
			for (int p = 0; p < nPressureLevels; p++) {

				// Loop thorugh all latlon indices
				for (int i = 0; i < nLat; i++) {
				for (int j = 0; j < nLon; j++) {

					// Store column pressure
					for (int k = 0; k < nLev; k++) {
						dataColumnP[k] = dataP[k][i][j];
					}

					// Find weights
					int kBegin = 0;
					int kEnd = 0;

					// On a pressure surface
					InterpolationWeightsLinear(
						vecPressureLevels[p],
						dataColumnP,
						kBegin,
						kEnd,
						dW);

					// Interpolate in the vertical
					dataOut[i][j] = 0.0;
					for (int k = kBegin; k < kEnd; k++) {
						dataOut[i][j] += dW[k] * dataIn[k][i][j];
					}

				}
				}

				// Write variable
				vecOutNcVarP[v]->set_cur(t, p, 0, 0);
				vecOutNcVarP[v]->put(&(dataOut[0][0]), 1, 1, nLat, nLon);
			}

			// Loop through all height levels
			for (int z = 0; z < nHeightLevels; z++) {

				// Loop thorugh all latlon indices
				for (int i = 0; i < nLat; i++) {
				for (int j = 0; j < nLon; j++) {

					// Find weights
					int kBegin = 0;
					int kEnd = 0;

					// Interpolate from levels to z surfaces
					if (!fOnInterfaces) {
						for (int k = 0; k < nLev; k++) {
							dataColumnZ[k] = dataZ[k][i][j];
						}

						InterpolationWeightsLinear(
							vecHeightLevels[z],
							dataColumnZ,
							kBegin,
							kEnd,
							dW);

						dataOut[i][j] = 0.0;
						for (int k = kBegin; k < kEnd; k++) {
							dataOut[i][j] += dW[k] * dataIn[k][i][j];
						}

					// Interpolate from interfaces to z surfaces
					} else {
						for (int k = 0; k < nILev; k++) {
							dataColumnIZ[k] = dataIZ[k][i][j];
						}

						InterpolationWeightsLinear(
							vecHeightLevels[z],
							dataColumnIZ,
							kBegin,
							kEnd,
							dIW);

						dataOut[i][j] = 0.0;
						for (int k = kBegin; k < kEnd; k++) {
							dataOut[i][j] += dIW[k] * dataInt[k][i][j];
						}
					}
				}
				}

				// Write variable
				vecOutNcVarZ[v]->set_cur(t, z, 0, 0);
				vecOutNcVarZ[v]->put(&(dataOut[0][0]), 1, 1, nLat, nLon);
			}
		}

		// Output geopotential height
		if (fGeopotentialHeight) {

			Announce("Geopotential height");

			// Output variables
			NcVar * varOutZ;
			NcVar * varOutZs;

			if (nPressureLevels > 0) {
				varOutZ = ncdf_out.add_var(
					"PHIZ", ncDouble, dimOutTime, dimOutP, dimOutLat, dimOutLon);
			}
			if (fExtractSurface) {
				varOutZs = ncdf_out.add_var(
					"PHIZS", ncDouble, dimOutTime, dimOutLat, dimOutLon);
			}

			// Interpolate onto pressure levels
			for (int p = 0; p < nPressureLevels; p++) {

				// Loop thorugh all latlon indices
				for (int i = 0; i < nLat; i++) {
				for (int j = 0; j < nLon; j++) {

					int kBegin = 0;
					int kEnd = 0;

					for (int k = 0; k < nLev; k++) {
						dataColumnP[k] = dataP[k][i][j];
					}

					InterpolationWeightsLinear(
						vecPressureLevels[p],
						dataColumnP,
						kBegin,
						kEnd,
						dW);

					// Interpolate in the vertical
					dataOut[i][j] = 0.0;
					for (int k = kBegin; k < kEnd; k++) {
						dataOut[i][j] += dW[k] * dataZ[k][i][j];
					}
				}
				}

				// Write variable
				varOutZ->set_cur(t, p, 0, 0);
				varOutZ->put(&(dataOut[0][0]), 1, 1, nLat, nLon);

			}

			// Interpolate onto the physical surface
			if (fExtractSurface) {

				int kBegin = 0;
				int kEnd = 3;

				PolynomialInterp::LagrangianPolynomialCoeffs(
					3, dLev, dW, 0.0);

				// Loop thorugh all latlon indices
				for (int i = 0; i < nLat; i++) {
				for (int j = 0; j < nLon; j++) {

					// Interpolate in the vertical
					dataOut[i][j] = 0.0;
					for (int k = kBegin; k < kEnd; k++) {
						dataOut[i][j] += dW[k] * dataZ[k][i][j];
					}
				}
				}

				// Write variable
				varOutZs->set_cur(t, 0, 0);
				varOutZs->put(&(dataOut[0][0]), 1, nLat, nLon);

			}
		}

		// Extract total energy
		if (fExtractTotalEnergy) {
			Announce("Total Energy");

			// Zonal velocity
			DataArray3D<double> dataU(nLev, nLat, nLon);

			NcVar * varU = ncdf_in.get_var("U");
			varU->set_cur(t, 0, 0, 0);
			varU->get(&(dataU[0][0][0]), 1, nLev, nLat, nLon);

			// Meridional velocity
			DataArray3D<double> dataV(nLev, nLat, nLon);

			NcVar * varV = ncdf_in.get_var("V");
			varV->set_cur(t, 0, 0, 0);
			varV->get(&(dataV[0][0][0]), 1, nLev, nLat, nLon);

			// Vertical velocity
			DataArray3D<double> dataW(nLev, nLat, nLon);

			NcVar * varW = ncdf_in.get_var("W");
			varW->set_cur(t, 0, 0, 0);
			varW->get(&(dataW[0][0][0]), 1, nLev, nLat, nLon);

			// Calculate total energy
			double dTotalEnergy = 0.0;

			double dElementRefArea =
				dEarthRadius * dEarthRadius
				* M_PI / static_cast<double>(nLat)
				* 2.0 * M_PI / static_cast<double>(nLon);

			for (int k = 0; k < nLev; k++) {
			for (int i = 0; i < nLat; i++) {
			for (int j = 0; j < nLon; j++) {
				double dKineticEnergy =
					0.5 * dataRho[k][i][j] *
						( dataU[k][i][j] * dataU[k][i][j]
						+ dataV[k][i][j] * dataV[k][i][j]
						+ dataW[k][i][j] * dataW[k][i][j]);

				double dInternalEnergy =
					dataP[k][i][j] / (dGamma - 1.0);

				dTotalEnergy +=
					(dKineticEnergy + dInternalEnergy)
						* std::cos(M_PI * dLat[i] / 180.0) * dElementRefArea
						* (dZtop - dZs[i][j]) / static_cast<double>(nLev);
			}
			}
			}

			// Put total energy into file
			varEnergy->set_cur(t);
			varEnergy->put(&dTotalEnergy, 1);
		}

		AnnounceEndBlock("Done");
	}

	AnnounceEndBlock("Done");

} catch(Exception & e) {
	Announce(e.ToString().c_str());
}

	// Finalize MPI
	MPI_Finalize();
}
示例#15
0
文件: yx32b.c 项目: plumbum/lcd32m
int lcdInit(void)
{
    setRS(0);
    lcd_data_t status = readLcdOnce();
    if (status != 0x8989) {
        return (1<<31) | status; // unknow lcd
    }

    dataOut();

    // power supply setting
    // set R07h at 0021h (GON=1,DTE=0,D[1:0]=01)
    writeReg(0x0007,0x0021);
    // set R00h at 0001h (OSCEN=1)
    writeReg(0x0000,0x0001);
    // set R07h at 0023h (GON=1,DTE=0,D[1:0]=11)
    writeReg(0x0007,0x0023);
    // set R10h at 0000h (Exit sleep mode)
    writeReg(0x0010,0x0000);
    // Wait 30ms
    chThdSleepMilliseconds(30);
    // set R07h at 0033h (GON=1,DTE=1,D[1:0]=11)
    writeReg(0x0007,0x0033);
    // Entry mode setting (R11h)
    // R11H Entry mode
    // vsmode DFM1 DFM0 TRANS OEDef WMode DMode1 DMode0 TY1 TY0 ID1 ID0 AM LG2 LG2 LG0
    //   0     1    1     0     0     0     0      0     0   1   1   1  *   0   0   0
    writeReg(0x0011, 0x6078); // 0x6070
    // LCD driver AC setting (R02h)
    writeReg(0x0002,0x0600);
    // power control 1
    // DCT3 DCT2 DCT1 DCT0 BT2 BT1 BT0 0 DC3 DC2 DC1 DC0 AP2 AP1 AP0 0
    // 1     0    1    0    1   0   0  0  1   0   1   0   0   1   0  0
    // DCT[3:0] fosc/4 BT[2:0]  DC{3:0] fosc/4
    writeReg(0x0003,0x0804);//0xA8A4
    writeReg(0x000C,0x0000);//
    writeReg(0x000D,0x0808);// 0x080C --> 0x0808
    // power control 4
    // 0 0 VCOMG VDV4 VDV3 VDV2 VDV1 VDV0 0 0 0 0 0 0 0 0
    // 0 0   1    0    1    0    1    1   0 0 0 0 0 0 0 0
    writeReg(0x000E, 0x2900);
    writeReg(0x001E, 0x00B8);
    writeReg(0x0001, 0x293F); // 0x2B3F); // Driver output control 320*240  0x6B3F
    writeReg(0x0010, 0x0000);
    writeReg(0x0005, 0x0000);
    writeReg(0x0006, 0x0000);
    writeReg(0x0016, 0xEF1C);
    writeReg(0x0017, 0x0003);
    writeReg(0x0007, 0x0233); // 0x0233
    writeReg(0x000B, 0x0000|(3<<6));
    writeReg(0x000F, 0x0000); // Gate scan start position
    writeReg(0x0041, 0x0000);
    writeReg(0x0042, 0x0000);
    writeReg(0x0048, 0x0000);
    writeReg(0x0049, 0x013F);
    writeReg(0x004A, 0x0000);
    writeReg(0x004B, 0x0000);
    writeReg(0x0044, 0xEF00);
    writeReg(0x0045, 0x0000);
    writeReg(0x0046, 0x013F);
    writeReg(0x0030, 0x0707);
    writeReg(0x0031, 0x0204);
    writeReg(0x0032, 0x0204);
    writeReg(0x0033, 0x0502);
    writeReg(0x0034, 0x0507);
    writeReg(0x0035, 0x0204);
    writeReg(0x0036, 0x0204);
    writeReg(0x0037, 0x0502);
    writeReg(0x003A, 0x0302);
    writeReg(0x003B, 0x0302);
    writeReg(0x0023, 0x0000);
    writeReg(0x0024, 0x0000);
    writeReg(0x0025, 0x8000);   // 65hz
    writeReg(0x004f, 0); // Set GDDRAM X address counter 
    writeReg(0x004e, 0); // Set GDDRAM Y address counter 

    lcdFill(COLOR_BLACK);

    return 0;
}
INT32 CInvUpload::CommunicationProc(void* pDataIn, void* pDataOut, string &strErr)
{
	INT32 res = 0;

	NoteData_Para noteData;
	noteData.m_appType = NET_FPSC;	//此处设置业务类型
	DataOutType dataOut(g_Xml_OutBuf_Inv, PROTOCOL_OUT_BUFF_LEN);
	res = BuildXml(pDataIn, &dataOut, &noteData, strErr);
	DBG_PRINT(("res = %u", res));
	if (res != SUCCESS)
	{
		return res;
	}
	
	DBG_PRINT(("outLen = %d", dataOut.outLen));

	//////////////////////////////////////////////////////////////////////////
	//此处为处理流程,将上面组织的数据发送给库SSL接口,接收到的数据放入g_Xml_OutBuf_Inv中。
	//////////////////////////////////////////////////////////////////////////
#if SSL_USE_TYPE == 1
	int rec_len = PROTOCOL_OUT_BUFF_LEN;
	CTechnologyMsg pTechMsg;
	string strTechMsg("");

	pTechMsg.m_nsrsbh = g_gNetArg->m_nsrsbh;
	pTechMsg.m_servIP = g_gNetArg->m_servIP;
	pTechMsg.m_servPort = g_gNetArg->m_servPort;
	pTechMsg.m_passWord = g_gNetArg->m_strzskl;
	pTechMsg.m_certPwd = g_gNetArg->m_strzskl;
	pTechMsg.m_servId = TECH_MSG_SERV_ID_INV;
	if(g_gNetArg->m_servId != "")
	{
		pTechMsg.m_servId = g_gNetArg->m_servId;
	}
	GetTechMsgStr(&pTechMsg, strTechMsg);
	UINT8 errBuf[1024];
	memset(errBuf, 0, sizeof(errBuf));

// 	printf("------------------------send-------------------------------------\n");
// 	DBG_PRINT(("dataOut.outLen = %d", dataOut.outLen));
// 	printf("%s\n", g_Xml_OutBuf_Inv);
// 	printf("\n----------------------send---------------------------------------\n");

	int retval = 0;
#if NET_LOCK_FLAG == 1
	CJSKInfoFunc::MutexLock();
#endif
	retval=aisino_ssl_transfer_call(SSL_AUTH_CODE,(char*)strTechMsg.c_str(),strTechMsg.size(),
		(unsigned char*)g_Xml_OutBuf_Inv,dataOut.outLen,(unsigned char*)g_Xml_ExchangeBuf_Inv,&rec_len,errBuf);
#if NET_LOCK_FLAG == 1
	CJSKInfoFunc::MutexUnlock();
#endif
	DBG_PRINT(("retval = %d", retval));
	if( retval != 0)
	{
		DBG_PRINT(("errBuf = %s", errBuf));
		//strErr = (INT8 *)errBuf;
		strErr = "网络通信错误!";
		return retval;
	}

	DBG_PRINT(("rec_len = %d", rec_len));
	dataOut.fill(g_Xml_ExchangeBuf_Inv, rec_len);
	memset(g_Xml_ExchangeBuf_Inv, 0, PROTOCOL_OUT_BUFF_LEN);

#ifdef XML_DEBUG_OUT
	printf("--------------------------CInvUpload rec begin-----------------------------------\n");
	DBG_PRINT(("rec_len = %d", rec_len));
	printf("%s\n", g_Xml_OutBuf_Inv);
	printf("\n------------------------CInvUpload rec end-------------------------------------\n");
#endif
#endif

	res = ParseXml(pDataOut, &dataOut, &noteData, strErr);
	DBG_PRINT(("res = %d", res));
	if (res != SUCCESS)
	{
		return res;
	}
	
	return SUCCESS;
}
示例#17
0
int main(void)
{
	printf( "Testing output and speed of MersenneTwister.h\n" );
	printf( "\nTest of random integer generation:\n" );
	MTRand mtrand1( 4357U );
	for( int i = 0; i < 1000; ++i )
	{
		printf( "%10lu ", mtrand1.randInt() );
		if( i % 5 == 4 ) printf("\n");
	}
	
	printf( "\nTest of random real number [0,1] generation:\n" );
	MTRand mtrand2( 4357U );
	for( int i = 0; i < 1000; ++i )
	{
		printf( "%10.8f ", mtrand2.rand() );
		if( i % 5 == 4 ) printf("\n");
	}
	
	printf( "\nTest of random real number [0,1) generation:\n" );
	MTRand mtrand3( 4357U );
	for( int i = 0; i < 1000; ++i )
	{
		printf( "%10.8f ", mtrand3.randExc() );
		if( i % 5 == 4 ) printf("\n");
	}
	
	printf( "\nTest of time to generate 300 million random integers:\n" );
	MTRand mtrand4( 4357U );
	unsigned long junk;
	clock_t startClock = clock();
	for( long i = 0; i < 3e+8; ++i )
	{
		junk = mtrand4.randInt();
	}
	clock_t stopClock = clock();
	printf( "Time elapsed = " );
	printf( "%8.3f", double( stopClock - startClock ) / CLOCKS_PER_SEC );
	printf( " s\n" );
	
	
	printf( "\nTests of functionality:\n" );
	
	// Array save/load test
	bool saveArrayFailure = false;
	MTRand mtrand5;
	unsigned long pass1[5], pass2[5];
	MTRand::uint32 saveArray[ MTRand::SAVE ];
	mtrand5.save( saveArray );
	for( int i = 0; i < 5; ++i )
		pass1[i] = mtrand5.randInt();
	mtrand5.load( saveArray );
	for( int i = 0; i < 5; ++i )
	{
		pass2[i] = mtrand5.randInt();
		if( pass2[i] != pass1[i] )
			saveArrayFailure = true;
	}
	if( saveArrayFailure )
		printf( "Error - Failed array save/load test\n" );
	else
		printf( "Passed array save/load test\n" );
	
	
	// Stream save/load test
	bool saveStreamFailure = false;
	std::ofstream dataOut( "state.data" );
	if( dataOut )
	{
		dataOut << mtrand5;  // comment out if compiler does not support
		dataOut.close();
	} 
	for( int i = 0; i < 5; ++i )
		pass1[i] = mtrand5.randInt();
	std::ifstream dataIn( "state.data" );
	if( dataIn )
	{
		dataIn >> mtrand5;  // comment out if compiler does not support
		dataIn.close();
	}
	for( int i = 0; i < 5; ++i )
	{
		pass2[i] = mtrand5.randInt();
		if( pass2[i] != pass1[i] )
			saveStreamFailure = true;
	}
	if( saveStreamFailure )
		printf( "Error - Failed stream save/load test\n" );
	else
		printf( "Passed stream save/load test\n" );
	
	
	// Integer range test
	MTRand mtrand6;
	bool integerRangeFailure = false;
	bool gotMax = false;
	for( int i = 0; i < 10000; ++i )
	{
		int r = mtrand6.randInt(17);
		if( r < 0 || r > 17 )
			integerRangeFailure = true;
		if( r == 17 )
			gotMax = true;
	}
	if( !gotMax )
		integerRangeFailure = true;
	if( integerRangeFailure )
		printf( "Error - Failed integer range test\n" );
	else
		printf( "Passed integer range test\n" );
	
	
	// Float range test
	MTRand mtrand7;
	bool floatRangeFailure = false;
	for( int i = 0; i < 10000; ++i )
	{
		float r = mtrand7.rand(0.3183);
		if( r < 0.0 || r > 0.3183 )
			floatRangeFailure = true;
	}
	if( floatRangeFailure )
		printf( "Error - Failed float range test\n" );
	else
		printf( "Passed float range test\n" );
	
	
	// Auto-seed uniqueness test
	MTRand mtrand8a, mtrand8b, mtrand8c;
	double r8a = mtrand8a();
	double r8b = mtrand8b();
	double r8c = mtrand8c();
	if( r8a == r8b || r8a == r8c || r8b == r8c )
		printf( "Error - Failed auto-seed uniqueness test\n" );
	else
		printf( "Passed auto-seed uniqueness test\n" );
	
	return 0;
}
示例#18
0
ErrCode Crossover::get_crossedIndividuals(Individuals& crossedIndividuals, Individuals& individuals, const Device& device)
{
	ErrCode err = 0;

	// Параметры
	int nThread_in_Warp = device.nMaxThread_in_Warp;
	int nThread_in_Group = nThread_in_Warp * nWarp_in_Group;
	int nThread = nThread_in_Group * nGroup_in_CU * device.max_compute_units;

	// Локальные
	int loc_sample_ByteSize = sampleIndividual.nByte_in_Chromoset;
	int loc_sampleInvert_ByteSize = sampleIndividual.nByte_in_Chromoset;
	int nIndividual_in_Loc = (device.LDS_ByteSize / nGroup_in_CU - loc_sample_ByteSize - loc_sampleInvert_ByteSize) / (sizeof(int)+sampleIndividual.nByte_in_Chromoset);
	int loc_indexes_ByteSize = nIndividual_in_Loc * sizeof(int);
	int loc_Individuals_ByteSize = nIndividual_in_Loc * sampleIndividual.nByte_in_Chromoset;
	int loc_ByteSize = loc_sample_ByteSize + loc_sampleInvert_ByteSize + loc_indexes_ByteSize + loc_Individuals_ByteSize;

	Editor editor;

	err = editor.import_(kernel_filePath);
	if (err != 0) return err;
	editor.replace("$$EXPRESSION", expression);
	calc_nParent();
	editor.replace("$$N_PARENT", intToString(nParent));
	editor.replace("$$N_CHROMOSECTOR_IN_CHROMOSET", intToString(sampleIndividual.chromoSectors.size()));
	editor.replace("$$N_CHROMOSET_IN_LOC", intToString(nIndividual_in_Loc));
	editor.replace("$$N_CHROMOSET_IN_GLOB", intToString(individuals.size()-10));
	int min_rating = (*(--individuals.end())).second.rating;
	editor.replace("$$START_RATING", intToString(min_rating));
	editor.replace("$$N_GLOBAL_CICLES", intToString(nGlobal_Cicles));
	editor.replace("$$N_LOCAL_CICLES", intToString(nLocal_Cicles));
	editor.replace("$$K_RATING", floatToString(kRating));
	editor.replace("$$KOEF_A", intToString(15678));
	editor.replace("$$KOEF_C", intToString(34302));

	editor.expand("$$EXTRACT_N_PARENT", nParent);
			
	editor.export_(kernel_filePath + KERNEL_FILE_SUFFIX);

	std::string kernel_Source;
	editor.get_string(kernel_Source);
	editor.clear();

	Computer computer;

	computer.set_Device(device);
	computer.set_Kernel_Name("crossing");
	computer.set_Kernel_Source(kernel_Source);
	computer.set_nThread_in_Group(nThread_in_Group);
	computer.set_nThread(nThread);

	// Строим (компиляция ядра, создание контекста...) 
	err = computer.build_kernel();
	if (err != 0) return err;

	DataIn dataIn;
	err = get_DataIn_from_Individuals(dataIn, individuals);

	// Входа
	computer.add_In(dataIn.chromoSectors);
	computer.add_In(sampleIndividual.chromoSectors);
	computer.add_In(sampleIndividual.invertChromoSectors);

	computer.add_Local(loc_ByteSize);

	DataOut dataOut(nThread, nParent);

	// Выхода
	computer.add_Out(dataOut.glob_indexes);
	computer.add_Out(dataOut.ratings);
	computer.add_Out(dataOut.c11s);
	computer.add_Out(dataOut.c01s);

	// Запускаем
	computer.compute();

	// Восстанавливаем особей
	err = get_Individuals_from_DataOut(crossedIndividuals, dataOut);

	computeTime = computer.get_computeTime();

	// Освобождение ресурсов
	computer.clear();

	return 0;
}
示例#19
0
void Remapper::dataIn( Node::DataType type, QMutex *mutex, void *data, size_t bytes, qint64 timeStamp ) {
    switch( type ) {
        case DataType::Input: {
            // Copy incoming data to our own buffer
            GamepadState gamepad;
            {
                mutex->lock();
                gamepad = *reinterpret_cast<GamepadState *>( data );
                mutex->unlock();
            }

            int instanceID = gamepad.instanceID;
            int joystickID = gamepad.joystickID;
            QString GUID( QByteArray( reinterpret_cast<const char *>( gamepad.GUID.data ), 16 ).toHex() );

            // Do initial calibration if not done yet
            {
                if( deadzoneFlag[ GUID ] ) {
                    deadzoneFlag[ GUID ] = false;

                    // Apply default value
                    for( int i = 0; i < gamepad.joystickNumAxes; i++ ) {
                        deadzones[ GUID ][ i ] = 10000;

                        // Check analog value at this moment. If its magnitude is less than 30000 then it's most likely
                        // an analog stick. Otherwise, it might be a trigger (with a centered value of -32768)
                        deadzoneModes[ GUID ][ i ] = ( qAbs( static_cast<int>( gamepad.joystickAxis[ i ] ) ) < 30000 );
                    }

                    // TODO: Replace with stored value from disk
                }
            }

            // Inject deadzone settings into gamepad
            {
                for( int i = 0; i < gamepad.joystickNumAxes; i++ ) {
                    gamepad.deadzone[ i ] = deadzones[ GUID ][ i ];
                    gamepad.deadzoneMode[ i ] = deadzoneModes[ GUID ][ i ];
                }
            }

            // Send raw joystick data to the model
            // Do this before we apply joystick deadzones so the user sees completely unprocessed data
            {
                // Copy current gamepad into buffer
                this->mutex.lock();
                gamepadBuffer[ gamepadBufferIndex ] = gamepad;
                this->mutex.unlock();

                // Send buffer on its way
                emit rawJoystickData( &( this->mutex ), reinterpret_cast<void *>( &gamepadBuffer[ gamepadBufferIndex ] ) );

                // Increment the index
                gamepadBufferIndex = ( gamepadBufferIndex + 1 ) % 100;
            }

            // Apply deadzones to each stick and both triggers independently
            {
                qreal deadzone = 0.0;
                bool deadzoneMode = false;

                for( int i = 0; i < 4; i++ ) {
                    int xAxis;
                    int yAxis;

                    // For the analog sticks, average the underlying joystick axes together to get the final deadzone value
                    // If either axis has deadzone mode set to true, it'll apply to both
                    // FIXME: If users complain about this, expand the code to handle this case (one axis true and one axis false) and treat axes indepenently
                    switch( i ) {
                        case 0: {
                            xAxis = SDL_CONTROLLER_AXIS_LEFTX;
                            yAxis = SDL_CONTROLLER_AXIS_LEFTY;

                            Val val = gameControllerToJoystick[ GUID ][ Key( AXIS, SDL_CONTROLLER_AXIS_LEFTX ) ];
                            int axisID = val.second.first;

                            if( val.first == AXIS ) {
                                deadzone = deadzones[ GUID ][ axisID ];
                                deadzoneMode = deadzoneModes[ GUID ][ axisID ];
                            }

                            Val val2 = gameControllerToJoystick[ GUID ][ Key( AXIS, SDL_CONTROLLER_AXIS_LEFTY ) ];
                            axisID = val2.second.first;

                            if( val2.first == AXIS ) {
                                deadzone += deadzones[ GUID ][ axisID ];
                                deadzone /= 2.0;
                                deadzoneMode = deadzoneMode || deadzoneModes[ GUID ][ axisID ];
                            }

                            break;
                        }

                        case 1: {
                            xAxis = SDL_CONTROLLER_AXIS_RIGHTX;
                            yAxis = SDL_CONTROLLER_AXIS_RIGHTY;

                            Val val = gameControllerToJoystick[ GUID ][ Key( AXIS, SDL_CONTROLLER_AXIS_RIGHTX ) ];
                            int axisID = val.second.first;

                            if( val.first == AXIS ) {
                                deadzone = deadzones[ GUID ][ axisID ];
                                deadzoneMode = deadzoneModes[ GUID ][ axisID ];
                            }

                            Val val2 = gameControllerToJoystick[ GUID ][ Key( AXIS, SDL_CONTROLLER_AXIS_RIGHTY ) ];
                            axisID = val2.second.first;

                            if( val2.first == AXIS ) {
                                deadzone += deadzones[ GUID ][ axisID ];
                                deadzone /= 2.0;
                                deadzoneMode = deadzoneMode || deadzoneModes[ GUID ][ axisID ];
                            }

                            break;
                        }

                        // For simplicity, just map the triggers to the line y = x
                        case 2: {
                            xAxis = SDL_CONTROLLER_AXIS_TRIGGERLEFT;
                            yAxis = SDL_CONTROLLER_AXIS_TRIGGERLEFT;
                            Val val = gameControllerToJoystick[ GUID ][ Key( AXIS, SDL_CONTROLLER_AXIS_TRIGGERLEFT ) ];
                            int axisID = val.second.first;

                            if( val.first == AXIS ) {
                                deadzone = deadzones[ GUID ][ axisID ];
                                deadzoneMode = deadzoneModes[ GUID ][ axisID ];
                            }

                            break;
                        }

                        case 3: {
                            xAxis = SDL_CONTROLLER_AXIS_TRIGGERRIGHT;
                            yAxis = SDL_CONTROLLER_AXIS_TRIGGERRIGHT;
                            Val val = gameControllerToJoystick[ GUID ][ Key( AXIS, SDL_CONTROLLER_AXIS_TRIGGERRIGHT ) ];
                            int axisID = val.second.first;

                            if( val.first == AXIS ) {
                                deadzone = deadzones[ GUID ][ axisID ];
                                deadzoneMode = deadzoneModes[ GUID ][ axisID ];
                            }

                            break;
                        }
                    }

                    // Map from [-32768, 32767] to [0, 32767]
                    if( !deadzoneMode ) {
                        gamepad.axis[ xAxis ] /= 2;
                        gamepad.axis[ yAxis ] /= 2;
                        gamepad.axis[ xAxis ] += 16384;
                        gamepad.axis[ yAxis ] += 16384;
                    }

                    // Get axis coords in cartesian coords
                    // Bottom right is positive -> top right is positive
                    qreal xCoord = gamepad.axis[ xAxis ];
                    qreal yCoord = -gamepad.axis[ yAxis ];

                    // Get radius from center
                    QVector2D position( static_cast<float>( xCoord ), static_cast<float>( yCoord ) );
                    qreal radius = static_cast<qreal>( position.length() );

                    if( !( radius > deadzone ) ) {
                        gamepad.axis[ xAxis ] = 0;
                        gamepad.axis[ yAxis ] = 0;

                        if( xAxis == SDL_CONTROLLER_AXIS_TRIGGERLEFT ) {
                            gamepad.digitalL2 = false;
                        }

                        if( xAxis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT ) {
                            gamepad.digitalR2 = false;
                        }
                    } else {
                        if( xAxis == SDL_CONTROLLER_AXIS_TRIGGERLEFT ) {
                            gamepad.digitalL2 = true;
                        }

                        if( xAxis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT ) {
                            gamepad.digitalR2 = true;
                        }
                    }
                }
            }

            // Apply deadzones to all joystick axes
            // Used only when detecting input for remapping
            {
                for( int i = 0; i < 16; i++ ) {
                    qreal deadzoneRadius = deadzones[ GUID ][ i ];
                    qreal coord = gamepad.joystickAxis[ i ];

                    if( !deadzoneModes[ GUID ][ i ] ) {
                        coord += 32768;
                    }

                    if( !( qAbs( coord ) > deadzoneRadius ) ) {
                        gamepad.joystickAxis[ i ] = 0;
                    }
                }
            }

            // If ignoreMode is set, the user hasn't let go of the button they were remapping to
            // Do not let the button go through until they let go
            {
                if( ignoreMode && ignoreModeGUID == GUID && ignoreModeInstanceID == gamepad.instanceID ) {
                    if( ignoreModeVal.first == BUTTON ) {
                        if( gamepad.joystickButton[ ignoreModeVal.second.first ] == SDL_PRESSED ) {
                            gamepad.joystickButton[ ignoreModeVal.second.first ] = SDL_RELEASED;
                        } else {
                            ignoreMode = false;
                        }
                    } else if( ignoreModeVal.first == HAT ) {
                        if( gamepad.joystickHat[ ignoreModeVal.second.first ] != SDL_HAT_CENTERED ) {
                            gamepad.joystickHat[ ignoreModeVal.second.first ] = SDL_HAT_CENTERED;
                        } else {
                            ignoreMode = false;
                        }
                    } else if( ignoreModeVal.first == AXIS ) {
                        if( gamepad.joystickAxis[ ignoreModeVal.second.first ] != 0 ) {
                            gamepad.joystickAxis[ ignoreModeVal.second.first ] = 0;
                        } else {
                            ignoreMode = false;
                        }
                    }
                }
            }

            // If we opened an SDL2 Game controller handle from this class, keep it and inject it into all gamepads we send out
            {
                if( gameControllerHandles[ instanceID ] ) {
                    gamepad.gamecontrollerHandle = gameControllerHandles[ instanceID ];
                }
            }

            // If we are in remap mode, check for a button press from the stored GUID, and remap the stored button to that button
            // All game controller states are cleared past this point if in remap mode
            {
                if( remapMode && GUID == remapModeGUID ) {
                    // Find a button press, the first one we encounter will be the new remapping
                    bool foundInput = false;
                    Key key = remapModeKey;
                    Val value = Val( INVALID, VHat( -1, -1 ) );

                    // Prioritize buttons and hats over analog sticks
                    for( int joystickButton = 0; joystickButton < 256; joystickButton++ ) {
                        if( gamepad.joystickButton[ joystickButton ] == SDL_PRESSED ) {
                            qCDebug( phxInput ).nospace() << "Button b" << joystickButton
                                                          << " from GUID " << GUID << " now activates " << keyToMappingString( key );

                            foundInput = true;
                            value.first = BUTTON;
                            value.second = VHat( joystickButton, -1 );
                            break;
                        }
                    }

                    for( int joystickHat = 0; joystickHat < 16; joystickHat++ ) {
                        if( gamepad.joystickHat[ joystickHat ] != SDL_HAT_CENTERED ) {
                            qCDebug( phxInput ).nospace() << "Hat h" << joystickHat << "." << gamepad.joystickHat[ joystickHat ]
                                                          << " from GUID " << GUID << " now activates " << keyToMappingString( key );
                            foundInput = true;
                            value.first = HAT;
                            value.second = VHat( joystickHat, gamepad.joystickHat[ joystickHat ] );
                            break;
                        }
                    }

                    for( int joystickAxis = 0; joystickAxis < 16; joystickAxis++ ) {
                        if( gamepad.joystickAxis[ joystickAxis ] != 0 ) {
                            qCDebug( phxInput ).nospace() << "Axis a" << joystickAxis
                                                          << " from GUID " << GUID << " now activates " << keyToMappingString( key );
                            foundInput = true;
                            value.first = AXIS;
                            value.second = VHat( joystickAxis, -1 );
                            break;
                        }
                    }

                    if( foundInput ) {
                        // Store the new remapping internally
                        gameControllerToJoystick[ GUID ][ remapModeKey ] = value;

                        // Tell SDL2 about it
                        QString mappingString;
                        QString platform( SDL_GetPlatform() );
                        {
                            QString friendlyName = QString( SDL_JoystickName( gamepad.joystickHandle ) );

                            mappingString.append( GUID ).append( "," ).append( friendlyName ).append( "," );

                            for( Key key : gameControllerToJoystick[ GUID ].keys() ) {
                                if( gameControllerToJoystick[ GUID ][ key ].first != INVALID ) {
                                    mappingString.append( keyToMappingString( key ) ).append( ':' )
                                    .append( valToMappingString( gameControllerToJoystick[ GUID ][ key ] ) ).append( ',' );
                                }
                            }


                            mappingString.append( "platform:" ).append( platform ).append( "," );
                            qDebug().nospace() << mappingString;

                            // Give SDL the new mapping string
                            SDL_GameControllerAddMapping( mappingString.toUtf8().constData() );

                            // If this is not a game controller, reopen as one
                            SDL_GameController *gamecontrollerHandle = nullptr;

                            if( !gameControllerHandles[ instanceID ] ) {
                                gamecontrollerHandle = SDL_GameControllerOpen( joystickID );
                                gamepad.gamecontrollerHandle = gamecontrollerHandle;
                                // Store internally so we can inject it into all future events from this instanceID
                                gameControllerHandles[ instanceID ] = gamecontrollerHandle;
                                qDebug() << "Opened newly remapped joystick as a game controller:" << gamecontrollerHandle;
                            }
                        }

                        // Store this mapping to disk
                        {
                            if( !userDataPath.isEmpty() ) {
                                QFile mappingFile( userDataPath + "/gamecontrollerdb.txt" );

                                mappingFile.open( QIODevice::ReadWrite | QIODevice::Text );
                                QByteArray mappingFileData = mappingFile.readAll();

                                if( !mappingFile.isOpen() ) {
                                    qWarning() << "Unable to open mapping file for reading" << mappingFile.errorString();
                                }

                                mappingFile.close();

                                QTextStream mappingFileStreamIn( &mappingFileData );
                                mappingFileStreamIn.setCodec( "UTF-8" );

                                mappingFile.open( QIODevice::WriteOnly | QIODevice::Text );

                                if( !mappingFile.isOpen() ) {
                                    qWarning() << "Unable to open mapping file for writing" << mappingFile.errorString();
                                }

                                QTextStream mappingFileStreamOut( &mappingFile );
                                mappingFileStreamOut.setCodec( "UTF-8" );

                                QString line = "";

                                while( !line.isNull() ) {
                                    line = mappingFileStreamIn.readLine();

                                    // We want to replace the line (any line) for our platform that contains our GUID
                                    // We'll also filter out empty lines
                                    if( line.isEmpty() || ( line.contains( GUID ) && line.contains( platform ) ) ) {
                                        continue;
                                    }

                                    mappingFileStreamOut << line << endl;
                                }

                                mappingFileStreamOut << mappingString << endl;
                                mappingFile.close();
                            } else {
                                qWarning() << "Unable to open controller mapping file, user data path not set";
                            }
                        }

                        // End remap mode, start ignore mode
                        {
                            remapMode = false;
                            ignoreMode = true;
                            ignoreModeGUID = GUID;
                            ignoreModeVal = value;
                            ignoreModeInstanceID = gamepad.instanceID;
                        }

                        // Tell the model we're done
                        {
                            emit setMapping( GUID, keyToMappingString( key ), valToFriendlyString( value ) );
                            emit remappingEnded();
                        }
                    }

                    // Clear all game controller states (joystick states are untouched)
                    for( int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) {
                        gamepad.button[ i ] = 0;
                    }

                    for( int i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++ ) {
                        gamepad.axis[ i ] = 0;
                    }
                } else if( remapMode ) {
                    // Clear all gamepad states
                    for( int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) {
                        gamepad.button[ i ] = 0;
                    }

                    for( int i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++ ) {
                        gamepad.axis[ i ] = 0;
                    }
                }
            }

            // OR all joystick button, hat and analog states together by GUID for RemapperModel to indicate presses
            {
                for( int i = 0; i < 256; i++ ) {
                    pressed[ GUID ] |= gamepad.joystickButton[ i ];
                }

                for( int i = 0; i < 16; i++ ) {
                    pressed[ GUID ] |= ( gamepad.joystickHat[ i ] != SDL_HAT_CENTERED );
                }

                for( int i = 0; i < 16; i++ ) {
                    pressed[ GUID ] |= ( gamepad.joystickAxis[ i ] != 0 );
                }
            }

            // Apply axis to d-pad, if enabled
            // This will always be enabled if we're not currently playing so GlobalGamepad can use the analog stick
            {
                if( analogToDpad[ GUID ] || !playing ) {
                    // TODO: Support other axes?
                    int xAxis = SDL_CONTROLLER_AXIS_LEFTX;
                    int yAxis = SDL_CONTROLLER_AXIS_LEFTY;

                    // TODO: Let user configure these

                    qreal threshold = 16384.0;

                    // Size in degrees of the arc covering and centered around each cardinal direction
                    // If <90, there will be gaps in the diagonals
                    // If >180, this code will always produce diagonal inputs
                    qreal rangeDegrees = 180.0 - 45.0;

                    // Get axis coords in cartesian coords
                    // Bottom right is positive -> top right is positive
                    qreal xCoord = gamepad.axis[ xAxis ];
                    qreal yCoord = -gamepad.axis[ yAxis ];

                    // Get radius from center
                    QVector2D position( static_cast<float>( xCoord ), static_cast<float>( yCoord ) );
                    qreal radius = static_cast<qreal>( position.length() );

                    // Get angle in degrees
                    qreal angle = qRadiansToDegrees( qAtan2( yCoord, xCoord ) );

                    if( angle < 0.0 ) {
                        angle += 360.0;
                    }

                    if( radius > threshold ) {
                        qreal halfRange = rangeDegrees / 2.0;

                        if( angle > 90.0 - halfRange && angle < 90.0 + halfRange ) {
                            gamepad.button[ SDL_CONTROLLER_BUTTON_DPAD_UP ] = true;
                        }

                        if( angle > 270.0 - halfRange && angle < 270.0 + halfRange ) {
                            gamepad.button[ SDL_CONTROLLER_BUTTON_DPAD_DOWN ] = true;
                        }

                        if( angle > 180.0 - halfRange && angle < 180.0 + halfRange ) {
                            gamepad.button[ SDL_CONTROLLER_BUTTON_DPAD_LEFT ] = true;
                        }

                        if( angle > 360.0 - halfRange || angle < 0.0 + halfRange ) {
                            gamepad.button[ SDL_CONTROLLER_BUTTON_DPAD_RIGHT ] = true;
                        }
                    }
                }
            }

            // Apply d-pad to axis, if enabled
            {
                if( dpadToAnalog[ GUID ] ) {
                    gamepad = mapDpadToAnalog( gamepad );
                }
            }

            // Send updated data out
            {
                // Copy current gamepad into buffer
                this->mutex.lock();
                gamepadBuffer[ gamepadBufferIndex ] = gamepad;
                this->mutex.unlock();

                // Send buffer on its way
                emit dataOut( DataType::Input, &( this->mutex ),
                              reinterpret_cast<void *>( &gamepadBuffer[ gamepadBufferIndex ] ), 0,
                              nodeCurrentTime() );

                // Increment the index
                gamepadBufferIndex = ( gamepadBufferIndex + 1 ) % 100;
            }
            break;
        }

        case DataType::KeyboardInput: {
            // Unpack keyboard states and write to gamepad according to remap data
            {
                mutex->lock();
                KeyboardState keyboard = *reinterpret_cast<KeyboardState *>( data );

                for( int i = keyboard.head; i < keyboard.tail; i = ( i + 1 ) % 128 ) {
                    int key = keyboard.key[ i ];
                    bool pressed = keyboard.pressed[ i ];

                    if( keyboardKeyToSDLButton.contains( key ) ) {
                        keyboardGamepad.button[ keyboardKeyToSDLButton[ key ] ] = pressed ? SDL_PRESSED : SDL_RELEASED;
                    }
                }

                mutex->unlock();
            }

            // OR all key states together and store that value
            for( int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) {
                keyboardKeyPressed |= keyboardGamepad.button[ i ];
            }

            // Apply d-pad to axis, if enabled
            if( dpadToAnalogKeyboard ) {
                keyboardGamepad = mapDpadToAnalog( keyboardGamepad, true );
            }

            // Send gamepad on its way
            {
                // Copy current gamepad into buffer
                this->mutex.lock();
                gamepadBuffer[ gamepadBufferIndex ] = keyboardGamepad;
                this->mutex.unlock();

                // Send buffer on its way
                emit dataOut( DataType::Input, &( this->mutex ),
                              reinterpret_cast< void * >( &gamepadBuffer[ gamepadBufferIndex ] ), 0,
                              nodeCurrentTime() );

                // Increment the index
                gamepadBufferIndex = ( gamepadBufferIndex + 1 ) % 100;
            }
            break;
        }

        default: {
            emit dataOut( type, mutex, data, bytes, timeStamp );
            break;
        }
    }
}