void FILEFile::init() { // Open mode for file's open const char *omode = "rb"; if (OpenFlags & Open_Truncate) { if (OpenFlags & Open_Read) omode = "w+b"; else omode = "wb"; } else if (OpenFlags & Open_Create) { if (OpenFlags & Open_Read) omode = "a+b"; else omode = "ab"; } else if (OpenFlags & Open_Write) omode = "r+b"; #ifdef OVR_OS_WIN32 SysErrorModeDisabler disabler(FileName.ToCStr()); #endif #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) wchar_t womode[16]; wchar_t *pwFileName = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(FileName.ToCStr())+1) * sizeof(wchar_t)); UTF8Util::DecodeString(pwFileName, FileName.ToCStr()); OVR_ASSERT(strlen(omode) < sizeof(womode)/sizeof(womode[0])); UTF8Util::DecodeString(womode, omode); _wfopen_s(&fs, pwFileName, womode); OVR_FREE(pwFileName); #else fs = fopen(FileName.ToCStr(), omode); #endif if (fs) rewind (fs); Opened = (fs != NULL); // Set error code if (!Opened) ErrorCode = SFerror(); else { // If we are testing file seek correctness, pre-load the entire file so // that we can do comparison tests later. #ifdef OVR_FILE_VERIFY_SEEK_ERRORS TestPos = 0; fseek(fs, 0, SEEK_END); FileTestLength = ftell(fs); fseek(fs, 0, SEEK_SET); pFileTestBuffer = (UByte*)OVR_ALLOC(FileTestLength); if (pFileTestBuffer) { OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength)); Seek(0, Seek_Set); } #endif ErrorCode = 0; } LastOp = 0; }
bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor) { if (!initializeManager()) { return false; } CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager); if (!deviceSet) return false; CFIndex deviceCount = CFSetGetCount(deviceSet); // Allocate a block of memory and read the set into it. IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount); CFSetGetValues(deviceSet, (const void **) devices); // Iterate over devices. for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) { IOHIDDeviceRef hidDev = devices[deviceIndex]; if (!hidDev) { continue; } HIDDeviceDesc devDesc; if (getPath(hidDev, &(devDesc.Path)) && initVendorProductVersion(hidDev, &devDesc) && enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId) && initUsage(hidDev, &devDesc)) { initStrings(hidDev, &devDesc); initSerialNumber(hidDev, &devDesc); // Look for the device to check if it is already opened. Ptr<DeviceCreateDesc> existingDevice = DevManager->FindHIDDevice(devDesc, true); // if device exists and it is opened then most likely the CreateHIDFile // will fail; therefore, we just set Enumerated to 'true' and continue. if (existingDevice && existingDevice->pDevice) { existingDevice->Enumerated = true; continue; } // open the device temporarily for startup communication if (IOHIDDeviceOpen(hidDev, kIOHIDOptionsTypeSeizeDevice) == kIOReturnSuccess) { // Construct minimal device that the visitor callback can get feature reports from. OSX::HIDDevice device(this, hidDev); enumVisitor->Visit(device, devDesc); IOHIDDeviceClose(hidDev, kIOHIDOptionsTypeSeizeDevice); } } } OVR_FREE(devices); CFRelease(deviceSet); return true; }
bool HIDDevice::openDevice() { // Have to iterate through devices again to generate paths. CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager->HIDManager); CFIndex deviceCount = CFSetGetCount(deviceSet); // Allocate a block of memory and read the set into it. IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount); CFSetGetValues(deviceSet, (const void **) devices); // Iterate over devices. IOHIDDeviceRef device = NULL; for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) { IOHIDDeviceRef tmpDevice = devices[deviceIndex]; if (!tmpDevice) { continue; } String path; if (!HIDManager->getPath(tmpDevice, &path)) { continue; } if (path == DevDesc.Path) { device = tmpDevice; break; } } OVR_FREE(devices); if (!device) { CFRelease(deviceSet); return false; } // Attempt to open device. if (IOHIDDeviceOpen(device, kIOHIDOptionsTypeSeizeDevice) != kIOReturnSuccess) { CFRelease(deviceSet); return false; } // Retain the device before we release the set. CFRetain(device); CFRelease(deviceSet); Device = device; if (!initInfo()) { IOHIDDeviceClose(Device, kIOHIDOptionsTypeSeizeDevice); CFRelease(Device); Device = NULL; return false; } // Setup the Run Loop and callbacks. IOHIDDeviceScheduleWithRunLoop(Device, HIDManager->getRunLoop(), kCFRunLoopDefaultMode); IOHIDDeviceRegisterInputReportCallback(Device, ReadBuffer, ReadBufferSize, staticHIDReportCallback, this); IOHIDDeviceRegisterRemovalCallback(Device, staticDeviceRemovedCallback, this); return true; }
Texture* RenderDevice::CreateTexture(int format, int width, int height, const void* data, int mipcount) { OVR_UNUSED(mipcount); DXGI_FORMAT d3dformat; int bpp; switch(format & Texture_TypeMask) { case Texture_RGBA: bpp = 4; d3dformat = DXGI_FORMAT_R8G8B8A8_UNORM; break; case Texture_Depth: bpp = 0; d3dformat = DXGI_FORMAT_D32_FLOAT; break; default: return NULL; } int samples = (format & Texture_SamplesMask); if (samples < 1) { samples = 1; } Texture* NewTex = new Texture(this, format, width, height); NewTex->Samples = samples; D3D1x_(TEXTURE2D_DESC) dsDesc; dsDesc.Width = width; dsDesc.Height = height; dsDesc.MipLevels = (format == (Texture_RGBA | Texture_GenMipmaps) && data) ? GetNumMipLevels(width, height) : 1; dsDesc.ArraySize = 1; dsDesc.Format = d3dformat; dsDesc.SampleDesc.Count = samples; dsDesc.SampleDesc.Quality = 0; dsDesc.Usage = D3D1x_(USAGE_DEFAULT); dsDesc.BindFlags = D3D1x_(BIND_SHADER_RESOURCE); dsDesc.CPUAccessFlags = 0; dsDesc.MiscFlags = 0; if (format & Texture_RenderTarget) { if ((format & Texture_TypeMask) == Texture_Depth) { // We don't use depth textures, and creating them in d3d10 requires different options. dsDesc.BindFlags = D3D1x_(BIND_DEPTH_STENCIL); } else { dsDesc.BindFlags |= D3D1x_(BIND_RENDER_TARGET); } } HRESULT hr = Device->CreateTexture2D(&dsDesc, NULL, &NewTex->Tex.GetRawRef()); if (FAILED(hr)) { OVR_DEBUG_LOG_TEXT(("Failed to create 2D D3D texture.")); NewTex->Release(); return NULL; } if (dsDesc.BindFlags & D3D1x_(BIND_SHADER_RESOURCE)) { Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef()); } if (data) { Context->UpdateSubresource(NewTex->Tex, 0, NULL, data, width * bpp, width * height * bpp); if (format == (Texture_RGBA | Texture_GenMipmaps)) { int srcw = width, srch = height; int level = 0; UByte* mipmaps = NULL; do { level++; int mipw = srcw >> 1; if (mipw < 1) { mipw = 1; } int miph = srch >> 1; if (miph < 1) { miph = 1; } if (mipmaps == NULL) { mipmaps = (UByte*)OVR_ALLOC(mipw * miph * 4); } FilterRgba2x2(level == 1 ? (const UByte*)data : mipmaps, srcw, srch, mipmaps); Context->UpdateSubresource(NewTex->Tex, level, NULL, mipmaps, mipw * bpp, miph * bpp); srcw = mipw; srch = miph; } while(srcw > 1 || srch > 1); if (mipmaps != NULL) { OVR_FREE(mipmaps); } } }
//----------------------------------------------------------------------------- // Render an object to text. The returned string must be freed char* JSON::PrintObject(int depth, bool fmt) { char** entries = 0, **names = 0; char* out = 0; char* ptr, *ret, *str; intptr_t len = 7, i = 0, j; bool fail = false; // Count the number of entries. int numentries = GetItemCount(); // Explicitly handle empty object case if (numentries == 0) { out=(char*)OVR_ALLOC(fmt?depth+4:4); if (!out) return 0; ptr=out; *ptr++='{'; if (fmt) { *ptr++='\n'; for (i=0;i<depth-1;i++) *ptr++='\t'; } *ptr++='}'; *ptr++=0; return out; } // Allocate space for the names and the objects entries=(char**)OVR_ALLOC(numentries*sizeof(char*)); if (!entries) return 0; names=(char**)OVR_ALLOC(numentries*sizeof(char*)); if (!names) { OVR_FREE(entries); return 0; } memset(entries,0,sizeof(char*)*numentries); memset(names,0,sizeof(char*)*numentries); // Collect all the results into our arrays: depth++; if (fmt) len+=depth; JSON* child = Children.GetFirst(); while (!Children.IsNull(child)) { names[i] = str = PrintString(child->Name); entries[i++] = ret = child->PrintValue(depth, fmt); if (str && ret) { len += OVR_strlen(ret)+OVR_strlen(str)+2+(fmt?3+depth:0); } else { fail = true; break; } child = Children.GetNext(child); } // Try to allocate the output string if (!fail) out=(char*)OVR_ALLOC(len); if (!out) fail=true; // Handle failure if (fail) { for (i=0;i<numentries;i++) { if (names[i]) OVR_FREE(names[i]); if (entries[i]) OVR_FREE(entries[i]);} OVR_FREE(names); OVR_FREE(entries); return 0; } // Compose the output: *out = '{'; ptr = out+1; if (fmt) { #ifdef OVR_OS_WIN32 *ptr++ = '\r'; #endif *ptr++ = '\n'; } *ptr = 0; for (i=0; i<numentries; i++) { if (fmt) { for (j = 0; j < depth; j++) { *ptr++ = '\t'; } } OVR_strcpy(ptr, len - (ptr-out), names[i]); ptr += OVR_strlen(names[i]); *ptr++ =':'; if (fmt) { *ptr++ = '\t'; } OVR_strcpy(ptr, len - (ptr-out), entries[i]); ptr+=OVR_strlen(entries[i]); if (i != numentries - 1) { *ptr++ = ','; } if (fmt) { #ifdef OVR_OS_WIN32 *ptr++ = '\r'; #endif *ptr++ = '\n'; } *ptr = 0; OVR_FREE(names[i]); OVR_FREE(entries[i]); } OVR_FREE(names); OVR_FREE(entries); if (fmt) { for (i = 0; i < depth - 1; i++) { *ptr++ = '\t'; } } *ptr++='}'; *ptr++=0; return out; }
//----------------------------------------------------------------------------- // Render an array to text. The returned text must be freed char* JSON::PrintArray(int depth, bool fmt) { char ** entries; char * out = 0, *ptr,*ret; intptr_t len = 5; bool fail = false; // How many entries in the array? int numentries = GetItemCount(); if (!numentries) { out=(char*)OVR_ALLOC(3); if (out) OVR_strcpy(out, 3, "[]"); return out; } // Allocate an array to hold the values for each entries=(char**)OVR_ALLOC(numentries*sizeof(char*)); if (!entries) return 0; memset(entries,0,numentries*sizeof(char*)); //// Retrieve all the results: JSON* child = Children.GetFirst(); for (int i=0; i<numentries; i++) { //JSON* child = Children[i]; ret=child->PrintValue(depth+1, fmt); entries[i]=ret; if (ret) len+=OVR_strlen(ret)+2+(fmt?1:0); else { fail = true; break; } child = Children.GetNext(child); } // If we didn't fail, try to malloc the output string if (!fail) out=(char*)OVR_ALLOC(len); // If that fails, we fail. if (!out) fail = true; // Handle failure. if (fail) { for (int i=0; i<numentries; i++) { if (entries[i]) OVR_FREE(entries[i]); } OVR_FREE(entries); return 0; } // Compose the output array. *out='['; ptr=out+1; *ptr=0; for (int i=0; i<numentries; i++) { OVR_strcpy(ptr, len - (ptr-out), entries[i]); ptr+=OVR_strlen(entries[i]); if (i!=numentries-1) { *ptr++=','; if (fmt) *ptr++=' '; *ptr=0; } OVR_FREE(entries[i]); } OVR_FREE(entries); *ptr++=']'; *ptr++=0; return out; }
//----------------------------------------------------------------------------- // Parses the input text into a string item and returns the text position after // the parsed string const char* JSON::parseString(const char* str, const char** perror) { const char* ptr = str+1; const char* p; char* ptr2; char* out; int len=0; unsigned uc, uc2; if (*str!='\"') { return AssignError(perror, "Syntax Error: Missing quote"); } while (*ptr!='\"' && *ptr && ++len) { if (*ptr++ == '\\') ptr++; // Skip escaped quotes. } // This is how long we need for the string, roughly. out=(char*)OVR_ALLOC(len+1); if (!out) return 0; ptr = str+1; ptr2= out; while (*ptr!='\"' && *ptr) { if (*ptr!='\\') { *ptr2++ = *ptr++; } else { ptr++; switch (*ptr) { case 'b': *ptr2++ = '\b'; break; case 'f': *ptr2++ = '\f'; break; case 'n': *ptr2++ = '\n'; break; case 'r': *ptr2++ = '\r'; break; case 't': *ptr2++ = '\t'; break; // Transcode utf16 to utf8. case 'u': // Get the unicode char. p = ParseHex(&uc, 4, ptr + 1); if (ptr != p) ptr = p - 1; if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; // Check for invalid. // UTF16 surrogate pairs. if (uc>=0xD800 && uc<=0xDBFF) { if (ptr[1]!='\\' || ptr[2]!='u') break; // Missing second-half of surrogate. p= ParseHex(&uc2, 4, ptr + 3); if (ptr != p) ptr = p - 1; if (uc2<0xDC00 || uc2>0xDFFF) break; // Invalid second-half of surrogate. uc = 0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); } len=4; if (uc<0x80) len=1; else if (uc<0x800) len=2; else if (uc<0x10000) len=3; ptr2+=len; switch (len) { case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; //no break, fall through case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; //no break case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; //no break case 1: *--ptr2 = (char)(uc | firstByteMark[len]); //no break } ptr2+=len; break; default: *ptr2++ = *ptr; break; } ptr++; } } *ptr2 = 0; if (*ptr=='\"') ptr++; // Make a copy of the string Value=out; OVR_FREE(out); Type=JSON_String; return ptr; }
void DistortionMeshInit(unsigned distortionCaps, ovrHmd HMD, ovrEyeRenderDesc eyeRenderDesc[2], ovrSizei textureSize, ovrRecti viewports[2], RenderDevice* pRender) { //Generate distortion mesh for each eye for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) { // Allocate & generate distortion mesh vertices. ovrDistortionMesh meshData; ovrHmd_CreateDistortionMesh(HMD, eyeRenderDesc[eyeNum].Eye, eyeRenderDesc[eyeNum].Fov, distortionCaps, &meshData); ovrHmd_GetRenderScaleAndOffset(eyeRenderDesc[eyeNum].Fov, textureSize, viewports[eyeNum], (ovrVector2f*) DistortionData.UVScaleOffset[eyeNum]); // Now parse the vertex data and create a render ready vertex buffer from it DistortionVertex * pVBVerts = (DistortionVertex*)OVR_ALLOC( sizeof(DistortionVertex) * meshData.VertexCount ); DistortionVertex * v = pVBVerts; ovrDistortionVertex * ov = meshData.pVertexData; for ( unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++ ) { v->Pos.x = ov->Pos.x; v->Pos.y = ov->Pos.y; v->TexR = (*(Vector2f*)&ov->TexR); v->TexG = (*(Vector2f*)&ov->TexG); v->TexB = (*(Vector2f*)&ov->TexB); v->Col.R = v->Col.G = v->Col.B = (OVR::UByte)( ov->VignetteFactor * 255.99f ); v->Col.A = (OVR::UByte)( ov->TimeWarpFactor * 255.99f ); v++; ov++; } //Register this mesh with the renderer DistortionData.MeshVBs[eyeNum] = *pRender->CreateBuffer(); DistortionData.MeshVBs[eyeNum]->Data ( Buffer_Vertex, pVBVerts, sizeof(DistortionVertex) * meshData.VertexCount ); DistortionData.MeshIBs[eyeNum] = *pRender->CreateBuffer(); DistortionData.MeshIBs[eyeNum]->Data ( Buffer_Index, meshData.pIndexData, sizeof(unsigned short) * meshData.IndexCount ); OVR_FREE ( pVBVerts ); ovrHmd_DestroyDistortionMesh( &meshData ); } // Pixel shader for the mesh //------------------------------------------------------------------------------------------- const char* pixelShader = "Texture2D Texture : register(t0); \n" "SamplerState Linear : register(s0); \n" "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR, \n" " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, \n" " in float2 oTexCoord2 : TEXCOORD2) : SV_Target \n" "{ \n" // 3 samples for fixing chromatic aberrations " float ResultR = Texture.Sample(Linear, oTexCoord0.xy).r; \n" " float ResultG = Texture.Sample(Linear, oTexCoord1.xy).g; \n" " float ResultB = Texture.Sample(Linear, oTexCoord2.xy).b; \n" " return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0); \n" "}"; // Choose the vertex shader, according to if you have timewarp enabled if (distortionCaps & ovrDistortionCap_TimeWarp) { // TIMEWARP //-------------------------------------------------------------------------------------------- const char* vertexShader = "float2 EyeToSourceUVScale; \n" "float2 EyeToSourceUVOffset; \n" "float4x4 EyeRotationStart; \n" "float4x4 EyeRotationEnd; \n" "float2 TimewarpTexCoord(float2 TexCoord, float4x4 rotMat) \n" "{ \n" // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic // aberration and distortion). These are now "real world" vectors in direction (x,y,1) // relative to the eye of the HMD. Apply the 3x3 timewarp rotation to these vectors. " float3 transformed = float3( mul ( rotMat, float4(TexCoord.xy, 1, 1) ).xyz); \n" // Project them back onto the Z=1 plane of the rendered images. " float2 flattened = (transformed.xy / transformed.z); \n" // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) " return(EyeToSourceUVScale * flattened + EyeToSourceUVOffset); \n" "} \n" "void main(in float2 Position : POSITION, in float4 Color : COLOR0, \n" " in float2 TexCoord0 : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, \n" " in float2 TexCoord2 : TEXCOORD2, \n" " out float4 oPosition : SV_Position, out float4 oColor : COLOR, \n" " out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, \n" " out float2 oTexCoord2 : TEXCOORD2) \n" "{ \n" " float timewarpLerpFactor = Color.a; \n" " float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, timewarpLerpFactor);\n" " oTexCoord0 = TimewarpTexCoord(TexCoord0,lerpedEyeRot); \n" " oTexCoord1 = TimewarpTexCoord(TexCoord1,lerpedEyeRot); \n" " oTexCoord2 = TimewarpTexCoord(TexCoord2,lerpedEyeRot); \n" " oPosition = float4(Position.xy, 0.5, 1.0); \n" " oColor = Color.r; /*For vignette fade*/ \n" "}"; pRender->InitShaders(vertexShader, pixelShader, &DistortionData.Shaders, &DistortionData.VertexIL,DistortionMeshVertexDesc,5); } else { //------------------------------------------------------------------------------------------- const char* vertexShader = "float2 EyeToSourceUVScale; \n" "float2 EyeToSourceUVOffset; \n" "void main(in float2 Position : POSITION, in float4 Color : COLOR0, \n" " in float2 TexCoord0 : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, \n" " in float2 TexCoord2 : TEXCOORD2, \n" " out float4 oPosition : SV_Position, out float4 oColor : COLOR, \n" " out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, \n" " out float2 oTexCoord2 : TEXCOORD2) \n" "{ \n" // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) " oTexCoord0 = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset; \n" " oTexCoord1 = EyeToSourceUVScale * TexCoord1 + EyeToSourceUVOffset; \n" " oTexCoord2 = EyeToSourceUVScale * TexCoord2 + EyeToSourceUVOffset; \n" " oPosition = float4(Position.xy, 0.5, 1.0); \n" " oColor = Color.r; /*For vignette fade*/ \n" "}"; pRender->InitShaders(vertexShader, pixelShader, &DistortionData.Shaders, &DistortionData.VertexIL,DistortionMeshVertexDesc,5); } }