void setBloodPress(CircularBuffer *spbuf, CircularBuffer *dpbuf) { // This is written to lab spec, with a flag to indicate "complete". // Right now, it does nothing, but I imagine it should probably be a global // variable to indicate to the compute task that the pressure measurement // is ready, since this measurement takes a nontrivial amount of time static unsigned int i = 0; static tBoolean sysComplete = false; static tBoolean diaComplete = false; int syspress = *(int *)cbGet(spbuf); // Restart systolic measurement if diastolic is complete if (syspress > 100) sysComplete = true; if (! sysComplete) { if (i%2==0) syspress+=3; else syspress--; } int diapress = *(int *)cbGet(dpbuf); // Restart diastolic measurement if systolic is complete if (diapress < 40) diaComplete = true; if (!diaComplete) { if (i%2==0) diapress-=2; else diapress++; } if (diaComplete && sysComplete) { sysComplete = false; diaComplete = false; syspress = SYS_RAW_INIT; diapress = DIA_RAW_INIT; } cbAdd(spbuf, &syspress); cbAdd(dpbuf, &diapress); i++; }
s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellGameDataStatCallback> funcStat, u32 container) { cellGame.Warning("cellGameDataCheckCreate2(version=0x%x, dirName=*0x%x, errDialog=0x%x, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container); if (version != CELL_GAMEDATA_VERSION_CURRENT || errDialog > 1) { cellGame.Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_PARAM"); return CELL_GAMEDATA_ERROR_PARAM; } // TODO: output errors (errDialog) const std::string dir = std::string("/dev_hdd0/game/") + dirName.get_ptr(); if (!Emu.GetVFS().ExistsDir(dir)) { cellGame.Todo("cellGameDataCheckCreate2(): creating directory '%s'", dir.c_str()); // TODO: create data return CELL_GAMEDATA_RET_OK; } vfsFile f("/app_home/../PARAM.SFO"); const PSFLoader psf(f); if (!psf) { cellGame.Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_BROKEN (cannot read PARAM.SFO)"); return CELL_GAMEDATA_ERROR_BROKEN; } vm::stackvar<CellGameDataCBResult> cbResult(CPU); vm::stackvar<CellGameDataStatGet> cbGet(CPU); vm::stackvar<CellGameDataStatSet> cbSet(CPU); cbGet.value() = {}; // TODO: Use the free space of the computer's HDD where RPCS3 is being run. cbGet->hddFreeSizeKB = 40000000; //40 GB cbGet->isNewData = CELL_GAMEDATA_ISNEWDATA_NO; strcpy_trunc(cbGet->contentInfoPath, dir); strcpy_trunc(cbGet->gameDataPath, dir + "/USRDIR"); // TODO: set correct time cbGet->st_atime_ = 0; cbGet->st_ctime_ = 0; cbGet->st_mtime_ = 0; // TODO: calculate data size, if necessary cbGet->sizeKB = CELL_GAMEDATA_SIZEKB_NOTCALC; cbGet->sysSizeKB = 0; cbGet->getParam.attribute = CELL_GAMEDATA_ATTR_NORMAL; cbGet->getParam.parentalLevel = psf.GetInteger("PARENTAL_LEVEL"); strcpy_trunc(cbGet->getParam.dataVersion, psf.GetString("APP_VER")); strcpy_trunc(cbGet->getParam.titleId, psf.GetString("TITLE_ID")); strcpy_trunc(cbGet->getParam.title, psf.GetString("TITLE")); // TODO: write lang titles funcStat(CPU, cbResult, cbGet, cbSet); if (cbSet->setParam) { // TODO: write PARAM.SFO from cbSet cellGame.Todo("cellGameDataCheckCreate2(): writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam); } switch ((s32)cbResult->result) { case CELL_GAMEDATA_CBRESULT_OK_CANCEL: // TODO: do not process game data cellGame.Warning("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL"); case CELL_GAMEDATA_CBRESULT_OK: return CELL_GAMEDATA_RET_OK; case CELL_GAMEDATA_CBRESULT_ERR_NOSPACE: // TODO: process errors, error message and needSizeKB result cellGame.Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE"); return CELL_GAMEDATA_ERROR_CBRESULT; case CELL_GAMEDATA_CBRESULT_ERR_BROKEN: cellGame.Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_BROKEN"); return CELL_GAMEDATA_ERROR_CBRESULT; case CELL_GAMEDATA_CBRESULT_ERR_NODATA: cellGame.Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NODATA"); return CELL_GAMEDATA_ERROR_CBRESULT; case CELL_GAMEDATA_CBRESULT_ERR_INVALID: cellGame.Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_INVALID"); return CELL_GAMEDATA_ERROR_CBRESULT; default: cellGame.Error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x)"); return CELL_GAMEDATA_ERROR_CBRESULT; } }
void displayRunFunction(void *dataptr) { static tBoolean onFirstRun = true; if (onFirstRun) { initializeDisplayTask(); onFirstRun = false; } DisplayData *dData = (DisplayData *) dataptr; tBoolean selection = *(dData->select); int scroll = *(dData->scroll); #if !DISPLAY_OFF char num[40]; //char buf1[30]; char buf2[30]; if(0 == *(dData->mode)) { if(false == selection) { RIT128x96x4StringDraw("Make Selection ", 0, 0, 15); RIT128x96x4StringDraw(" Blood Pressure ", 0, 10, 15); RIT128x96x4StringDraw(" Temperature ", 0, 20, 15); RIT128x96x4StringDraw(" Pulse Rate ", 0, 30, 15); RIT128x96x4StringDraw(" EKG ", 0, 40, 15); RIT128x96x4StringDraw(" Battery ", 0, 50, 15); RIT128x96x4StringDraw(" ", 0, 60, 15); RIT128x96x4StringDraw(" ", 0, 70, 15); RIT128x96x4StringDraw("->", 0, 10*((scroll%5+1)), 15); } else { RIT128x96x4StringDraw(" ", 0, 0, 15); if(0 == scroll%5) RIT128x96x4StringDraw("Blood Pressure:", 0, 0, 15); else if(1 == scroll%5) RIT128x96x4StringDraw("Temperature:", 0, 0, 15); else if(2 == scroll%5) RIT128x96x4StringDraw("Pulse Rate:", 0, 0, 15); else if(3 == scroll%5) RIT128x96x4StringDraw("EKG:", 0, 0, 15); else if(4 == scroll%5) RIT128x96x4StringDraw("Battery:", 0, 0, 15); else RIT128x96x4StringDraw("oops", 0, 0, 15);//just in case if(0 == scroll%5) usnprintf(buf2,30, "Systolic: %d mm Hg ", (int) *( (float*) cbGet(dData->systolicPressCorrected))); else if(1 == scroll%5) usnprintf(buf2,30,"%d C ", (int) *( (float*) cbGet(dData->temperatureCorrected))); else if(2 == scroll%5) usnprintf(buf2,30, "%d BPM ", (int) *( (float*) cbGet(dData->pulseRateCorrected))); else if(3 == scroll%5) usnprintf(buf2,30, "%d Hz ", (int) *( (float*) cbGet(dData->ekgFrequencyResult))); else if(4 == scroll%5) usnprintf(buf2,30, "%d %% ", (int) *(dData->batteryState)/2); //else buf2 = "oops"; //just in case RIT128x96x4StringDraw(" ", 0, 10, 15); RIT128x96x4StringDraw(buf2, 0, 10, 15); if(0 == scroll%5) { usnprintf(buf2,30, "Diastolic: %d mm Hg ", (int)*( (float*) cbGet(dData->diastolicPressCorrected))); RIT128x96x4StringDraw(buf2, 0, 20, 15); } else RIT128x96x4StringDraw(" ", 0, 20, 15); RIT128x96x4StringDraw(" ", 0, 30, 15); RIT128x96x4StringDraw(" ", 0, 40, 15); RIT128x96x4StringDraw(" ", 0, 50, 15); RIT128x96x4StringDraw(" ", 0, 60, 15); RIT128x96x4StringDraw(" ", 0, 70, 15); } } else//(1 == *(data->mode) { usnprintf(num,40,"Temperature: %d C ", (int) *( (float*) cbGet(dData->temperatureCorrected))); RIT128x96x4StringDraw(num, 0, 0, 15); usnprintf(num,40, "Systolic Pressure: "); RIT128x96x4StringDraw(num, 0, 10, 15); usnprintf(num,40, "%d mm Hg ", (int) *( (float*) cbGet(dData->systolicPressCorrected))); RIT128x96x4StringDraw(num, 0, 20, 15); usnprintf(num,40, "Diastolic Pressure: "); RIT128x96x4StringDraw(num, 0, 30, 15); usnprintf(num,40, "%d mm Hg ",(int) *( (float*) cbGet(dData->diastolicPressCorrected))); RIT128x96x4StringDraw(num, 0, 40, 15); usnprintf(num,40, "Pulse rate: %d BPM ",(int) *( (float*) cbGet(dData->pulseRateCorrected))); RIT128x96x4StringDraw(num, 0, 50, 15); usnprintf(num,40, "EKG: %d Hz ", *((int *) cbGet(dData->ekgFrequencyResult))); RIT128x96x4StringDraw(num, 0, 60, 15); usnprintf(num,40, "Battery: %d %% ",(int) *(dData->batteryState)/2); RIT128x96x4StringDraw(num,0, 70,15); } #endif }
void measureRunFunction(void *dataptr) { static tBoolean onFirstRun = true; static int rate; MeasureData *mData = (MeasureData *) dataptr; if (onFirstRun) { initializeMeasureTask(); rate = *(int*) cbGet(mData->pulseRateRaw); onFirstRun = false; } // capture pulse rate if (IS_PULSE_CYCLE) { // Divide by two so raw pulse rate matches frequency rate = pulseRate/2; pulseRate = 0; } // only run on major cycle short measureSelect = *(mData->measureSelect); if(measureSelect == 0 || measureSelect == 1) { setTemp(mData->temperatureRaw); } if(measureSelect == 0 || measureSelect == 2) { setBloodPress(mData->systolicPressRaw, mData->diastolicPressRaw); } if(measureSelect == 0 || measureSelect == 3) { int prev = *(int*) cbGet(mData->pulseRateRaw); // Only save if +- 15% if (rate < prev*0.85 || rate > prev*1.15) { cbAdd(mData->pulseRateRaw, (void *)&rate); } } if(measureSelect == 0 || measureSelect == 4) { vTaskResume(ekgCaptureHandle); } else { vTaskSuspend(ekgCaptureHandle); } vTaskResume(computeHandle); // run the compute task #if DEBUG_MEASURE char num[30]; int temp = *(int *)cbGet(mData->temperatureRaw); int sys = *(int *)cbGet(mData->systolicPressRaw); int dia = *(int *)cbGet(mData->diastolicPressRaw); int pulse = *(int *)cbGet(mData->pulseRateRaw); int batt = global.batteryState; usnprintf(num, 30, "<-- MEASURE DEBUG -->"); RIT128x96x4StringDraw(num, 0, 0, 15); usnprintf(num, 30, "Raw temp: %d ", temp); RIT128x96x4StringDraw(num, 0, 10, 15); usnprintf(num, 30, "Raw Syst: %d ", sys); RIT128x96x4StringDraw(num, 0, 20, 15); usnprintf(num, 30, "Raw Dia: %d ", dia); RIT128x96x4StringDraw(num, 0, 30, 15); usnprintf(num, 30, "Raw Pulse: %d ", pulse); RIT128x96x4StringDraw(num, 0, 40, 15); usnprintf(num, 30, "Raw Batt: %d ", batt); RIT128x96x4StringDraw(num, 0, 50, 15); #endif }