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); }
void CsvFormatter::finishObject() { --_level; log_debug("finishObject, level=" << _level); if (_level == 1) dataOut(); }
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; }
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); }
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; }
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 ? ¬ifyCallback : NULL); }
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; }
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(); }
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, ¬eData, 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, ¬eData, strErr); DBG_PRINT(("res = %d", res)); if (res != SUCCESS) { return res; } return SUCCESS; }
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; }
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; }
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; } } }