├── .gitignore ├── LICENSE ├── README.md ├── RTSSDemo ├── App.config ├── ExitHandler.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── RTSSDemo.csproj ├── RTSSSharedMemoryNET.sln └── RTSSSharedMemoryNET ├── AssemblyInfo.cpp ├── BestRules.ruleset ├── OSD.cpp ├── OSD.h ├── RTSSSharedMemory.h ├── RTSSSharedMemoryNET.vcxproj ├── RTSSSharedMemoryNET.vcxproj.filters ├── Stdafx.cpp ├── Stdafx.h ├── Structs.h └── Utilities.h /.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | *.user 3 | *.opensdf 4 | *.sdf 5 | *.suo 6 | *.ncb 7 | *.sln.docstates 8 | *.bak 9 | *.cache 10 | *.vsp 11 | *.vsmdi 12 | /ipch 13 | [Tt]est[Rr]esult* 14 | [Bb]in*/ 15 | [Oo]bj/ 16 | [Dd]ebug*/ 17 | [Rr]elease*/ 18 | 19 | packages/* 20 | !packages/repositories.config -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RTSSSharedMemoryNET 2 | =================== 3 | 4 | .NET implementation for the RivaTuner Statistics Server shared memory feature 5 | -------------------------------------------------------------------------------- /RTSSDemo/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /RTSSDemo/ExitHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace RTSSDemo 5 | { 6 | public class ExitHandler 7 | { 8 | [DllImport("kernel32.dll")] 9 | private static extern IntPtr GetConsoleWindow(); 10 | 11 | [DllImport("user32.dll")] 12 | private static extern bool EnableMenuItem(IntPtr hMenu, uint uIdEnableItem, uint uEnable); 13 | 14 | [DllImport("user32.dll")] 15 | private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); 16 | 17 | [DllImport ("user32.dll" )] 18 | private static extern IntPtr RemoveMenu(IntPtr hMenu, uint nPosition, uint wFlags); 19 | 20 | [DllImport("kernel32.dll")] 21 | private static extern bool SetConsoleCtrlHandler(HandlerRountine handlerRountine, bool add); 22 | 23 | private const uint SC_CLOSE = 0xF060; 24 | private const uint MF_GRAYED = 0x00000001; 25 | private const uint MF_BYCOMMAND = 0x00000000; 26 | 27 | public delegate bool HandlerRountine(CtrlType sig); 28 | private static HandlerRountine _handlerRountine; 29 | 30 | public enum CtrlType 31 | { 32 | CtrlCEvent = 0, 33 | CtrlBreakEvent = 1, 34 | CtrlCloseEvent = 2, 35 | CtrlLogoffEvent = 5, 36 | CtrlShutdownEvent = 6 37 | } 38 | 39 | public static void Init(HandlerRountine handlerRountine) 40 | { 41 | _handlerRountine = handlerRountine; 42 | SetConsoleCtrlHandler(_handlerRountine, true); 43 | DisableConsoleClose(); 44 | } 45 | 46 | private static void DisableConsoleClose() 47 | { 48 | var hMenu = GetSystemMenu(GetConsoleWindow(), false); 49 | EnableMenuItem(hMenu, SC_CLOSE, MF_GRAYED); //disables the upper-right Close (X) button in the titlebar 50 | RemoveMenu(hMenu, SC_CLOSE, MF_BYCOMMAND); //removes the Close option in the Alt-Space menu 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /RTSSDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using RTSSSharedMemoryNET; 4 | 5 | namespace RTSSDemo 6 | { 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | //enforces a nice cleanup 12 | //just hitting X or Ctrl+C normally won't actually dispose the using() below 13 | ExitHandler.Init(ctrlType => { 14 | Console.WriteLine("\nCleaning up and exiting..."); 15 | return true; //cancel event 16 | }); 17 | 18 | /////////////////////////////////////////////////////////////////// 19 | 20 | Console.WriteLine("Current OSD entries:"); 21 | var osdEntries = OSD.GetOSDEntries(); 22 | foreach( var osd in osdEntries ) 23 | { 24 | Console.ForegroundColor = ConsoleColor.Cyan; 25 | Console.WriteLine(osd.Owner); 26 | Console.ResetColor(); 27 | Console.WriteLine("{0}\n", osd.Text); 28 | } 29 | 30 | /////////////////////////////////////////////////////////////////// 31 | 32 | Console.WriteLine("Current app entries with GPU contexts:"); 33 | var appEntries = OSD.GetAppEntries().Where( x => (x.Flags & AppFlags.MASK) != AppFlags.None ).ToArray(); 34 | foreach( var app in appEntries ) 35 | { 36 | Console.ForegroundColor = ConsoleColor.Magenta; 37 | Console.WriteLine("{0}:{1}", app.ProcessId, app.Name); 38 | Console.ResetColor(); 39 | Console.WriteLine("{0}, {1}FPS", app.Flags, app.InstantaneousFrames); 40 | } 41 | Console.WriteLine(); 42 | 43 | /////////////////////////////////////////////////////////////////// 44 | 45 | using( var osd = new OSD("RTSSDemo") ) 46 | while( true ) 47 | { 48 | Console.WriteLine("Enter some text:"); 49 | var text = Console.ReadLine(); 50 | 51 | //if we hit Ctrl+C while waiting for ReadLine, it returns null 52 | if( text == null ) 53 | break; 54 | 55 | osd.Update(text); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /RTSSDemo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RTSSDemo")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RTSSDemo")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("716747b9-8120-4ddb-adb2-9d434c3ef5d1")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /RTSSDemo/RTSSDemo.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {2D164B3F-2CC0-4F43-A89D-1199AA2B4EFC} 8 | Exe 9 | Properties 10 | RTSSDemo 11 | RTSSDemo 12 | v4.0 13 | 512 14 | Client 15 | 16 | 17 | true 18 | bin\x86\Debug\ 19 | DEBUG;TRACE 20 | full 21 | x86 22 | prompt 23 | MinimumRecommendedRules.ruleset 24 | true 25 | false 26 | 27 | 28 | bin\x86\Release\ 29 | TRACE 30 | true 31 | pdbonly 32 | x86 33 | prompt 34 | MinimumRecommendedRules.ruleset 35 | true 36 | false 37 | 38 | 39 | true 40 | bin\x64\Debug\ 41 | DEBUG;TRACE 42 | full 43 | x64 44 | false 45 | prompt 46 | MinimumRecommendedRules.ruleset 47 | true 48 | 49 | 50 | bin\x64\Release\ 51 | TRACE 52 | true 53 | pdbonly 54 | x64 55 | false 56 | prompt 57 | MinimumRecommendedRules.ruleset 58 | true 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | {53939d64-d853-4b4c-a4f9-2fce48502725} 80 | RTSSSharedMemoryNET 81 | 82 | 83 | 84 | 91 | -------------------------------------------------------------------------------- /RTSSSharedMemoryNET.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTSSSharedMemoryNET", "RTSSSharedMemoryNET\RTSSSharedMemoryNET.vcxproj", "{53939D64-D853-4B4C-A4F9-2FCE48502725}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RTSSDemo", "RTSSDemo\RTSSDemo.csproj", "{2D164B3F-2CC0-4F43-A89D-1199AA2B4EFC}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{46CA24F3-8E56-4FA6-A43D-4F0E08266FA3}" 9 | ProjectSection(SolutionItems) = preProject 10 | LICENSE = LICENSE 11 | README.md = README.md 12 | EndProjectSection 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|x64 = Debug|x64 17 | Debug|x86 = Debug|x86 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {53939D64-D853-4B4C-A4F9-2FCE48502725}.Debug|x64.ActiveCfg = Debug|x64 23 | {53939D64-D853-4B4C-A4F9-2FCE48502725}.Debug|x64.Build.0 = Debug|x64 24 | {53939D64-D853-4B4C-A4F9-2FCE48502725}.Debug|x86.ActiveCfg = Debug|Win32 25 | {53939D64-D853-4B4C-A4F9-2FCE48502725}.Debug|x86.Build.0 = Debug|Win32 26 | {53939D64-D853-4B4C-A4F9-2FCE48502725}.Release|x64.ActiveCfg = Release|x64 27 | {53939D64-D853-4B4C-A4F9-2FCE48502725}.Release|x64.Build.0 = Release|x64 28 | {53939D64-D853-4B4C-A4F9-2FCE48502725}.Release|x86.ActiveCfg = Release|Win32 29 | {53939D64-D853-4B4C-A4F9-2FCE48502725}.Release|x86.Build.0 = Release|Win32 30 | {2D164B3F-2CC0-4F43-A89D-1199AA2B4EFC}.Debug|x64.ActiveCfg = Debug|x64 31 | {2D164B3F-2CC0-4F43-A89D-1199AA2B4EFC}.Debug|x64.Build.0 = Debug|x64 32 | {2D164B3F-2CC0-4F43-A89D-1199AA2B4EFC}.Debug|x86.ActiveCfg = Debug|x86 33 | {2D164B3F-2CC0-4F43-A89D-1199AA2B4EFC}.Debug|x86.Build.0 = Debug|x86 34 | {2D164B3F-2CC0-4F43-A89D-1199AA2B4EFC}.Release|x64.ActiveCfg = Release|x64 35 | {2D164B3F-2CC0-4F43-A89D-1199AA2B4EFC}.Release|x64.Build.0 = Release|x64 36 | {2D164B3F-2CC0-4F43-A89D-1199AA2B4EFC}.Release|x86.ActiveCfg = Release|x86 37 | {2D164B3F-2CC0-4F43-A89D-1199AA2B4EFC}.Release|x86.Build.0 = Release|x86 38 | EndGlobalSection 39 | GlobalSection(SolutionProperties) = preSolution 40 | HideSolutionNode = FALSE 41 | EndGlobalSection 42 | EndGlobal 43 | -------------------------------------------------------------------------------- /RTSSSharedMemoryNET/AssemblyInfo.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | using namespace System; 4 | using namespace System::Reflection; 5 | using namespace System::Runtime::CompilerServices; 6 | using namespace System::Runtime::InteropServices; 7 | using namespace System::Security::Permissions; 8 | 9 | // 10 | // General Information about an assembly is controlled through the following 11 | // set of attributes. Change these attribute values to modify the information 12 | // associated with an assembly. 13 | // 14 | [assembly:AssemblyTitleAttribute("RTSSSharedMemoryNET")]; 15 | [assembly:AssemblyDescriptionAttribute("")]; 16 | [assembly:AssemblyConfigurationAttribute("")]; 17 | [assembly:AssemblyCompanyAttribute("")]; 18 | [assembly:AssemblyProductAttribute("RTSSSharedMemoryNET")]; 19 | [assembly:AssemblyCopyrightAttribute("Copyright (c) Spencer Hakim 2014")]; 20 | [assembly:AssemblyTrademarkAttribute("")]; 21 | [assembly:AssemblyCultureAttribute("")]; 22 | 23 | // 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the value or you can default the Revision and Build Numbers 32 | // by using the '*' as shown below: 33 | 34 | [assembly:AssemblyVersionAttribute("1.0.*")]; 35 | 36 | [assembly:ComVisible(false)]; 37 | 38 | [assembly:CLSCompliantAttribute(true)]; 39 | 40 | [assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)]; 41 | -------------------------------------------------------------------------------- /RTSSSharedMemoryNET/BestRules.ruleset: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RTSSSharedMemoryNET/OSD.cpp: -------------------------------------------------------------------------------- 1 | // This is the main DLL file. 2 | 3 | #include "stdafx.h" 4 | 5 | #include "OSD.h" 6 | 7 | #define TICKS_PER_MICROSECOND 10 8 | #define RTSS_VERSION(x, y) ((x << 16) + y) 9 | 10 | namespace RTSSSharedMemoryNET { 11 | 12 | /// 13 | ///The name of the OSD entry. Should be unique and not more than 255 chars once converted to ANSI. 14 | /// 15 | OSD::OSD(String^ entryName) 16 | { 17 | if( String::IsNullOrWhiteSpace(entryName) ) 18 | throw gcnew ArgumentException("Entry name cannot be null, empty, or whitespace", "entryName"); 19 | 20 | m_entryName = (LPCSTR)Marshal::StringToHGlobalAnsi(entryName).ToPointer(); 21 | if( strlen(m_entryName) > 255 ) 22 | throw gcnew ArgumentException("Entry name exceeds max length of 255 when converted to ANSI", "entryName"); 23 | 24 | //just open/close to make sure RTSS is working 25 | HANDLE hMapFile = NULL; 26 | LPRTSS_SHARED_MEMORY pMem = NULL; 27 | openSharedMemory(&hMapFile, &pMem); 28 | closeSharedMemory(hMapFile, pMem); 29 | 30 | m_osdSlot = 0; 31 | m_disposed = false; 32 | } 33 | 34 | OSD::~OSD() 35 | { 36 | if( m_disposed ) 37 | return; 38 | 39 | 40 | 41 | //delete managed, if any 42 | 43 | this->!OSD(); 44 | m_disposed = true; 45 | } 46 | 47 | OSD::!OSD() 48 | { 49 | HANDLE hMapFile = NULL; 50 | LPRTSS_SHARED_MEMORY pMem = NULL; 51 | openSharedMemory(&hMapFile, &pMem); 52 | 53 | //find entries and zero them out 54 | for(DWORD i=1; i < pMem->dwOSDArrSize; i++) 55 | { 56 | //calc offset of entry 57 | auto pEntry = (RTSS_SHARED_MEMORY::LPRTSS_SHARED_MEMORY_OSD_ENTRY)( (LPBYTE)pMem + pMem->dwOSDArrOffset + (i * pMem->dwOSDEntrySize) ); 58 | 59 | if( STRMATCHES(strcmp(pEntry->szOSDOwner, m_entryName)) ) 60 | { 61 | SecureZeroMemory(pEntry, pMem->dwOSDEntrySize); //won't get optimized away 62 | pMem->dwOSDFrame++; //forces OSD update 63 | } 64 | } 65 | 66 | closeSharedMemory(hMapFile, pMem); 67 | Marshal::FreeHGlobal(IntPtr((LPVOID)m_entryName)); 68 | } 69 | 70 | System::Version^ OSD::Version::get() 71 | { 72 | HANDLE hMapFile = NULL; 73 | LPRTSS_SHARED_MEMORY pMem = NULL; 74 | openSharedMemory(&hMapFile, &pMem); 75 | 76 | auto ver = gcnew System::Version(pMem->dwVersion >> 16, pMem->dwVersion & 0xFFFF); 77 | 78 | closeSharedMemory(hMapFile, pMem); 79 | return ver; 80 | } 81 | 82 | /// 83 | ///Text should be no longer than 4095 chars once converted to ANSI. Lower case looks awful. 84 | /// 85 | void OSD::Update(String^ text) 86 | { 87 | if( text == nullptr ) 88 | throw gcnew ArgumentNullException("text"); 89 | 90 | LPCSTR lpText = (LPCSTR)Marshal::StringToHGlobalAnsi(text).ToPointer(); 91 | if( strlen(lpText) > 4095 ) 92 | throw gcnew ArgumentException("Text exceeds max length of 4095 when converted to ANSI", "text"); 93 | 94 | HANDLE hMapFile = NULL; 95 | LPRTSS_SHARED_MEMORY pMem = NULL; 96 | openSharedMemory(&hMapFile, &pMem); 97 | 98 | //start at either our previously used slot, or the top 99 | for(DWORD i=(m_osdSlot == 0 ? 1 : m_osdSlot); i < pMem->dwOSDArrSize; i++) 100 | { 101 | auto pEntry = (RTSS_SHARED_MEMORY::LPRTSS_SHARED_MEMORY_OSD_ENTRY)( (LPBYTE)pMem + pMem->dwOSDArrOffset + (i * pMem->dwOSDEntrySize) ); 102 | 103 | //if we need a new slot and this one is unused, claim it 104 | if( m_osdSlot == 0 && !strlen(pEntry->szOSDOwner) ) 105 | { 106 | m_osdSlot = i; 107 | strcpy_s(pEntry->szOSDOwner, m_entryName); 108 | } 109 | 110 | //if this is our slot 111 | if( STRMATCHES(strcmp(pEntry->szOSDOwner, m_entryName)) ) 112 | { 113 | //use extended text slot for v2.7 and higher shared memory, it allows displaying 4096 symbols instead of 256 for regular text slot 114 | if( pMem->dwVersion >= RTSS_VERSION(2,7) ) 115 | strncpy_s(pEntry->szOSDEx, lpText, sizeof(pEntry->szOSDEx)-1); 116 | else 117 | strncpy_s(pEntry->szOSD, lpText, sizeof(pEntry->szOSD)-1); 118 | 119 | pMem->dwOSDFrame++; //forces OSD update 120 | break; 121 | } 122 | 123 | //in case we lost our previously used slot or something, let's start over 124 | if( m_osdSlot != 0 ) 125 | { 126 | m_osdSlot = 0; 127 | i = 1; 128 | } 129 | } 130 | 131 | closeSharedMemory(hMapFile, pMem); 132 | Marshal::FreeHGlobal(IntPtr((LPVOID)lpText)); 133 | } 134 | 135 | array^ OSD::GetOSDEntries() 136 | { 137 | HANDLE hMapFile = NULL; 138 | LPRTSS_SHARED_MEMORY pMem = NULL; 139 | openSharedMemory(&hMapFile, &pMem); 140 | 141 | auto list = gcnew List; 142 | 143 | //include all slots 144 | for(DWORD i=0; i < pMem->dwOSDArrSize; i++) 145 | { 146 | auto pEntry = (RTSS_SHARED_MEMORY::LPRTSS_SHARED_MEMORY_OSD_ENTRY)( (LPBYTE)pMem + pMem->dwOSDArrOffset + (i * pMem->dwOSDEntrySize) ); 147 | if( strlen(pEntry->szOSDOwner) ) 148 | { 149 | auto entry = gcnew OSDEntry; 150 | entry->Owner = Marshal::PtrToStringAnsi(IntPtr(pEntry->szOSDOwner)); 151 | 152 | if( pMem->dwVersion >= RTSS_VERSION(2,7) ) 153 | entry->Text = Marshal::PtrToStringAnsi(IntPtr(pEntry->szOSDEx)); 154 | else 155 | entry->Text = Marshal::PtrToStringAnsi(IntPtr(pEntry->szOSD)); 156 | 157 | list->Add(entry); 158 | } 159 | } 160 | 161 | closeSharedMemory(hMapFile, pMem); 162 | return list->ToArray(); 163 | } 164 | 165 | array^ OSD::GetAppEntries() 166 | { 167 | HANDLE hMapFile = NULL; 168 | LPRTSS_SHARED_MEMORY pMem = NULL; 169 | openSharedMemory(&hMapFile, &pMem); 170 | 171 | auto list = gcnew List; 172 | 173 | //include all slots 174 | for(DWORD i=0; i < pMem->dwAppArrSize; i++) 175 | { 176 | auto pEntry = (RTSS_SHARED_MEMORY::LPRTSS_SHARED_MEMORY_APP_ENTRY)( (LPBYTE)pMem + pMem->dwAppArrOffset + (i * pMem->dwAppEntrySize) ); 177 | if( pEntry->dwProcessID ) 178 | { 179 | auto entry = gcnew AppEntry; 180 | 181 | //basic fields 182 | entry->ProcessId = pEntry->dwProcessID; 183 | entry->Name = Marshal::PtrToStringAnsi(IntPtr(pEntry->szName)); 184 | entry->Flags = (AppFlags)pEntry->dwFlags; 185 | 186 | //instantaneous framerate fields 187 | entry->InstantaneousTimeStart = timeFromTickcount(pEntry->dwTime0); 188 | entry->InstantaneousTimeEnd = timeFromTickcount(pEntry->dwTime1); 189 | entry->InstantaneousFrames = pEntry->dwFrames; 190 | entry->InstantaneousFrameTime = TimeSpan::FromTicks(pEntry->dwFrameTime * TICKS_PER_MICROSECOND); 191 | 192 | //framerate stats fields 193 | entry->StatFlags = (StatFlags)pEntry->dwStatFlags; 194 | entry->StatTimeStart = timeFromTickcount(pEntry->dwStatTime0); 195 | entry->StatTimeEnd = timeFromTickcount(pEntry->dwStatTime1); 196 | entry->StatFrames = pEntry->dwStatFrames; 197 | entry->StatCount = pEntry->dwStatCount; 198 | entry->StatFramerateMin = pEntry->dwStatFramerateMin; 199 | entry->StatFramerateAvg = pEntry->dwStatFramerateAvg; 200 | entry->StatFramerateMax = pEntry->dwStatFramerateMax; 201 | if( pMem->dwVersion >= RTSS_VERSION(2,5) ) 202 | { 203 | entry->StatFrameTimeMin = pEntry->dwStatFrameTimeMin; 204 | entry->StatFrameTimeAvg = pEntry->dwStatFrameTimeAvg; 205 | entry->StatFrameTimeMax = pEntry->dwStatFrameTimeMax; 206 | entry->StatFrameTimeCount = pEntry->dwStatFrameTimeCount; 207 | //TODO - frametime buffer? 208 | } 209 | 210 | //OSD fields 211 | entry->OSDCoordinateX = pEntry->dwOSDX; 212 | entry->OSDCoordinateY = pEntry->dwOSDY; 213 | entry->OSDZoom = pEntry->dwOSDPixel; 214 | entry->OSDFrameId = pEntry->dwOSDFrame; 215 | entry->OSDColor = Color::FromArgb(pEntry->dwOSDColor); 216 | if( pMem->dwVersion >= RTSS_VERSION(2,1) ) 217 | entry->OSDBackgroundColor = Color::FromArgb(pEntry->dwOSDBgndColor); 218 | 219 | //screenshot fields 220 | entry->ScreenshotFlags = (ScreenshotFlags)pEntry->dwScreenCaptureFlags; 221 | entry->ScreenshotPath = Marshal::PtrToStringAnsi(IntPtr(pEntry->szScreenCapturePath)); 222 | if( pMem->dwVersion >= RTSS_VERSION(2,2) ) 223 | { 224 | entry->ScreenshotQuality = pEntry->dwScreenCaptureQuality; 225 | entry->ScreenshotThreads = pEntry->dwScreenCaptureThreads; 226 | } 227 | 228 | //video capture fields 229 | if( pMem->dwVersion >= RTSS_VERSION(2,2) ) 230 | { 231 | entry->VideoCaptureFlags = (VideoCaptureFlags)pEntry->dwVideoCaptureFlags; 232 | entry->VideoCapturePath = Marshal::PtrToStringAnsi(IntPtr(pEntry->szVideoCapturePath)); 233 | entry->VideoFramerate = pEntry->dwVideoFramerate; 234 | entry->VideoFramesize = pEntry->dwVideoFramesize; 235 | entry->VideoFormat = pEntry->dwVideoFormat; 236 | entry->VideoQuality = pEntry->dwVideoQuality; 237 | entry->VideoCaptureThreads = pEntry->dwVideoCaptureThreads; 238 | } 239 | if( pMem->dwVersion >= RTSS_VERSION(2,4) ) 240 | entry->VideoCaptureFlagsEx = pEntry->dwVideoCaptureFlagsEx; 241 | 242 | //audio capture fields 243 | if( pMem->dwVersion >= RTSS_VERSION(2,3) ) 244 | entry->AudioCaptureFlags = pEntry->dwAudioCaptureFlags; 245 | if( pMem->dwVersion >= RTSS_VERSION(2,5) ) 246 | entry->AudioCaptureFlags2 = pEntry->dwAudioCaptureFlags2; 247 | if( pMem->dwVersion >= RTSS_VERSION(2,6) ) 248 | { 249 | entry->AudioCapturePTTEventPush = pEntry->qwAudioCapturePTTEventPush.QuadPart; 250 | entry->AudioCapturePTTEventRelease = pEntry->qwAudioCapturePTTEventRelease.QuadPart; 251 | entry->AudioCapturePTTEventPush2 = pEntry->qwAudioCapturePTTEventPush2.QuadPart; 252 | entry->AudioCapturePTTEventRelease2 = pEntry->qwAudioCapturePTTEventRelease2.QuadPart; 253 | } 254 | 255 | list->Add(entry); 256 | } 257 | } 258 | 259 | closeSharedMemory(hMapFile, pMem); 260 | return list->ToArray(); 261 | } 262 | 263 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 264 | 265 | void OSD::openSharedMemory(HANDLE* phMapFile, LPRTSS_SHARED_MEMORY* ppMem) 266 | { 267 | HANDLE hMapFile = NULL; 268 | LPRTSS_SHARED_MEMORY pMem = NULL; 269 | try 270 | { 271 | hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"RTSSSharedMemoryV2"); 272 | if( !hMapFile ) 273 | THROW_LAST_ERROR(); 274 | 275 | pMem = (LPRTSS_SHARED_MEMORY)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0); 276 | if( !pMem ) 277 | THROW_LAST_ERROR(); 278 | 279 | if( !(pMem->dwSignature == 'RTSS' && pMem->dwVersion >= RTSS_VERSION(2,0)) ) 280 | throw gcnew System::IO::InvalidDataException("Failed to validate RTSS Shared Memory structure"); 281 | 282 | *phMapFile = hMapFile; 283 | *ppMem = pMem; 284 | } 285 | catch(...) 286 | { 287 | closeSharedMemory(hMapFile, pMem); 288 | throw; 289 | } 290 | } 291 | 292 | void OSD::closeSharedMemory(HANDLE hMapFile, LPRTSS_SHARED_MEMORY pMem) 293 | { 294 | if( pMem ) 295 | UnmapViewOfFile(pMem); 296 | 297 | if( hMapFile ) 298 | CloseHandle(hMapFile); 299 | 300 | } 301 | 302 | DateTime OSD::timeFromTickcount(DWORD ticks) 303 | { 304 | return DateTime::Now - TimeSpan::FromMilliseconds(ticks); 305 | } 306 | } -------------------------------------------------------------------------------- /RTSSSharedMemoryNET/OSD.h: -------------------------------------------------------------------------------- 1 | // OSD.h 2 | 3 | #pragma once 4 | 5 | #include "Structs.h" 6 | 7 | using namespace System; 8 | using namespace System::Collections::Generic; 9 | using namespace System::Runtime::InteropServices; 10 | 11 | namespace RTSSSharedMemoryNET { 12 | 13 | public ref class OSD 14 | { 15 | private: 16 | LPCSTR m_entryName; 17 | DWORD m_osdSlot; 18 | bool m_disposed; 19 | 20 | public: 21 | OSD(String^ entryName); 22 | ~OSD(); 23 | !OSD(); 24 | 25 | static property System::Version^ Version 26 | { 27 | System::Version^ get(); 28 | } 29 | 30 | void Update(String^ text); 31 | static array^ GetOSDEntries(); 32 | static array^ GetAppEntries(); 33 | 34 | private: 35 | static void openSharedMemory(HANDLE* phMapFile, LPRTSS_SHARED_MEMORY* ppMem); 36 | static void closeSharedMemory(HANDLE hMapFile, LPRTSS_SHARED_MEMORY pMem); 37 | static DateTime timeFromTickcount(DWORD ticks); 38 | }; 39 | 40 | LPCWSTR MBtoWC(const char* str); 41 | } 42 | -------------------------------------------------------------------------------- /RTSSSharedMemoryNET/RTSSSharedMemory.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////// 2 | // 3 | // This header file defines statistics server's shared memory format 4 | // 5 | ///////////////////////////////////////////////////////////////////////////// 6 | #ifndef _RTSS_SHARED_MEMORY_INCLUDED_ 7 | #define _RTSS_SHARED_MEMORY_INCLUDED_ 8 | ///////////////////////////////////////////////////////////////////////////// 9 | // v1.0 memory structure 10 | typedef struct RTSS_SHARED_MEMORY_V_1_0 11 | { 12 | DWORD dwSignature; 13 | //signature allows applications to verify status of shared memory 14 | 15 | //The signature can be set to: 16 | //'RTSS' - statistics server's memory is initialized and contains 17 | // valid data 18 | //0xDEAD - statistics server's memory is marked for deallocation and 19 | // no longer contain valid data 20 | //otherwise the memory is not initialized 21 | DWORD dwVersion; 22 | //structure version ((major<<16) + minor) 23 | //must be set to 0x00010000 for v1.0 structure 24 | DWORD dwTime0; 25 | //start time of framerate measurement period (in milliseconds) 26 | 27 | //Take a note that this field must contain non-zero value to calculate 28 | //framerate properly! 29 | DWORD dwTime1; 30 | //end time of framerate measurement period (in milliseconds) 31 | DWORD dwFrames; 32 | //amount of frames rendered during (dwTime1 - dwTime0) period 33 | 34 | //to calculate framerate use the following formula: 35 | //1000.0f * dwFrames / (dwTime1 - dwTime0) 36 | 37 | } RTSS_SHARED_MEMORY_V_1_0, *LPRTSS_SHARED_MEMORY_V_1_0; 38 | ///////////////////////////////////////////////////////////////////////////// 39 | #define OSDFLAG_UPDATED 0x00000001 40 | //use this flag to force the server to update OSD 41 | ///////////////////////////////////////////////////////////////////////////// 42 | // v1.1 memory structure 43 | typedef struct RTSS_SHARED_MEMORY_V_1_1 44 | { 45 | DWORD dwSignature; 46 | //signature allows applications to verify status of shared memory 47 | 48 | //The signature can be set to: 49 | //'RTSS' - statistics server's memory is initialized and contains 50 | // valid data 51 | //0xDEAD - statistics server's memory is marked for deallocation and 52 | // no longer contain valid data 53 | //otherwise the memory is not initialized 54 | DWORD dwVersion; 55 | //structure version ((major<<16) + minor) 56 | //must be set to 0x00010001 for v1.1 structure 57 | DWORD dwTime0; 58 | //start time of framerate measurement period (in milliseconds) 59 | 60 | //Take a note that this field must contain non-zero value to calculate 61 | //framerate properly! 62 | DWORD dwTime1; 63 | //end time of framerate measurement period (in milliseconds) 64 | DWORD dwFrames; 65 | //amount of frames rendered during (dwTime1 - dwTime0) period 66 | 67 | //to calculate framerate use the following formula: 68 | //1000.0f * dwFrames / (dwTime1 - dwTime0) 69 | 70 | DWORD dwOSDFlags; 71 | //bitmask, containing combination of OSDFLAG_... flags 72 | 73 | //Note: set OSDFLAG_UPDATED flag as soon as you change any OSD related 74 | //field 75 | DWORD dwOSDX; 76 | //OSD X-coordinate (coordinate wrapping is allowed, i.e. -5 defines 5 77 | //pixel offset from the right side of the screen) 78 | DWORD dwOSDY; 79 | //OSD Y-coordinate (coordinate wrapping is allowed, i.e. -5 defines 5 80 | //pixel offset from the bottom side of the screen) 81 | DWORD dwOSDPixel; 82 | //OSD pixel zooming ratio 83 | DWORD dwOSDColor; 84 | //OSD color in RGB format 85 | char szOSD[256]; 86 | //OSD text 87 | char szOSDOwner[32]; 88 | //OSD owner ID 89 | 90 | //Use this field to capture OSD and prevent other applications from 91 | //using OSD when it is already in use by your application. 92 | //You should change this field only if it is empty (i.e. when OSD is 93 | //not owned by any application) or if it is set to your own application's 94 | //ID (i.e. when you own OSD) 95 | //You shouldn't change any OSD related feilds until you own OSD 96 | 97 | } RTSS_SHARED_MEMORY_V_1_1, *LPRTSS_SHARED_MEMORY_V_1_1; 98 | ///////////////////////////////////////////////////////////////////////////// 99 | // v1.2 memory structure 100 | typedef struct RTSS_SHARED_MEMORY_V_1_2 101 | { 102 | DWORD dwSignature; 103 | //signature allows applications to verify status of shared memory 104 | 105 | //The signature can be set to: 106 | //'RTSS' - statistics server's memory is initialized and contains 107 | // valid data 108 | //0xDEAD - statistics server's memory is marked for deallocation and 109 | // no longer contain valid data 110 | //otherwise the memory is not initialized 111 | DWORD dwVersion; 112 | //structure version ((major<<16) + minor) 113 | //must be set to 0x00010002 for v1.2 structure 114 | DWORD dwTime0; 115 | //start time of framerate measurement period (in milliseconds) 116 | 117 | //Take a note that this field must contain non-zero value to calculate 118 | //framerate properly! 119 | DWORD dwTime1; 120 | //end time of framerate measurement period (in milliseconds) 121 | DWORD dwFrames; 122 | //amount of frames rendered during (dwTime1 - dwTime0) period 123 | 124 | //to calculate framerate use the following formula: 125 | //1000.0f * dwFrames / (dwTime1 - dwTime0) 126 | 127 | DWORD dwOSDFlags; 128 | //bitmask, containing combination of OSDFLAG_... flags 129 | 130 | //Note: set OSDFLAG_UPDATED flag as soon as you change any OSD related 131 | //field 132 | DWORD dwOSDX; 133 | //OSD X-coordinate (coordinate wrapping is allowed, i.e. -5 defines 5 134 | //pixel offset from the right side of the screen) 135 | DWORD dwOSDY; 136 | //OSD Y-coordinate (coordinate wrapping is allowed, i.e. -5 defines 5 137 | //pixel offset from the bottom side of the screen) 138 | DWORD dwOSDPixel; 139 | //OSD pixel zooming ratio 140 | DWORD dwOSDColor; 141 | //OSD color in RGB format 142 | char szOSD[256]; 143 | //primary OSD slot text 144 | char szOSDOwner[32]; 145 | //primary OSD slot owner ID 146 | 147 | //Use this field to capture OSD slot and prevent other applications from 148 | //using OSD when it is already in use by your application. 149 | //You should change this field only if it is empty (i.e. when OSD slot is 150 | //not owned by any application) or if it is set to your own application's 151 | //ID (i.e. when you own OSD slot) 152 | //You shouldn't change any OSD related feilds until you own OSD slot 153 | 154 | char szOSD1[256]; 155 | //OSD slot 1 text 156 | char szOSD1Owner[32]; 157 | //OSD slot 1 owner ID 158 | char szOSD2[256]; 159 | //OSD slot 2 text 160 | char szOSD2Owner[32]; 161 | //OSD slot 2 owner ID 162 | char szOSD3[256]; 163 | //OSD slot 3 text 164 | char szOSD3Owner[32]; 165 | //OSD slot 3 owner ID 166 | } RTSS_SHARED_MEMORY_V_1_2, *LPRTSS_SHARED_MEMORY_V_1_2; 167 | ///////////////////////////////////////////////////////////////////////////// 168 | #define STATFLAG_RECORD 0x00000001 169 | ///////////////////////////////////////////////////////////////////////////// 170 | // v1.3 memory structure 171 | typedef struct RTSS_SHARED_MEMORY_V_1_3 172 | { 173 | DWORD dwSignature; 174 | //signature allows applications to verify status of shared memory 175 | 176 | //The signature can be set to: 177 | //'RTSS' - statistics server's memory is initialized and contains 178 | // valid data 179 | //0xDEAD - statistics server's memory is marked for deallocation and 180 | // no longer contain valid data 181 | //otherwise the memory is not initialized 182 | DWORD dwVersion; 183 | //structure version ((major<<16) + minor) 184 | //must be set to 0x00010003 for v1.3 structure 185 | DWORD dwTime0; 186 | //start time of framerate measurement period (in milliseconds) 187 | 188 | //Take a note that this field must contain non-zero value to calculate 189 | //framerate properly! 190 | DWORD dwTime1; 191 | //end time of framerate measurement period (in milliseconds) 192 | DWORD dwFrames; 193 | //amount of frames rendered during (dwTime1 - dwTime0) period 194 | 195 | //to calculate framerate use the following formula: 196 | //1000.0f * dwFrames / (dwTime1 - dwTime0) 197 | 198 | DWORD dwOSDFlags; 199 | //bitmask, containing combination of OSDFLAG_... flags 200 | 201 | //Note: set OSDFLAG_UPDATED flag as soon as you change any OSD related 202 | //field 203 | DWORD dwOSDX; 204 | //OSD X-coordinate (coordinate wrapping is allowed, i.e. -5 defines 5 205 | //pixel offset from the right side of the screen) 206 | DWORD dwOSDY; 207 | //OSD Y-coordinate (coordinate wrapping is allowed, i.e. -5 defines 5 208 | //pixel offset from the bottom side of the screen) 209 | DWORD dwOSDPixel; 210 | //OSD pixel zooming ratio 211 | DWORD dwOSDColor; 212 | //OSD color in RGB format 213 | char szOSD[256]; 214 | //primary OSD slot text 215 | char szOSDOwner[32]; 216 | //primary OSD slot owner ID 217 | 218 | //Use this field to capture OSD slot and prevent other applications from 219 | //using OSD when it is already in use by your application. 220 | //You should change this field only if it is empty (i.e. when OSD slot is 221 | //not owned by any application) or if it is set to your own application's 222 | //ID (i.e. when you own OSD slot) 223 | //You shouldn't change any OSD related feilds until you own OSD slot 224 | 225 | char szOSD1[256]; 226 | //OSD slot 1 text 227 | char szOSD1Owner[32]; 228 | //OSD slot 1 owner ID 229 | char szOSD2[256]; 230 | //OSD slot 2 text 231 | char szOSD2Owner[32]; 232 | //OSD slot 2 owner ID 233 | char szOSD3[256]; 234 | //OSD slot 3 text 235 | char szOSD3Owner[32]; 236 | //OSD slot 3 owner ID 237 | 238 | DWORD dwStatFlags; 239 | //bitmask containing combination of STATFLAG_... flags 240 | DWORD dwStatTime0; 241 | //statistics record period start time 242 | DWORD dwStatTime1; 243 | //statistics record period end time 244 | DWORD dwStatFrames; 245 | //total amount of frames rendered during statistics record period 246 | DWORD dwStatCount; 247 | //amount of min/avg/max measurements during statistics record period 248 | DWORD dwStatFramerateMin; 249 | //minimum instantaneous framerate measured during statistics record period 250 | DWORD dwStatFramerateAvg; 251 | //average instantaneous framerate measured during statistics record period 252 | DWORD dwStatFramerateMax; 253 | //maximum instantaneous framerate measured during statistics record period 254 | } RTSS_SHARED_MEMORY_V_1_3, *LPRTSS_SHARED_MEMORY_V_1_3; 255 | ///////////////////////////////////////////////////////////////////////////// 256 | #define APPFLAG_DD 0x00000010 257 | #define APPFLAG_D3D8 0x00000100 258 | #define APPFLAG_D3D9 0x00001000 259 | #define APPFLAG_D3D9EX 0x00002000 260 | #define APPFLAG_OGL 0x00010000 261 | #define APPFLAG_D3D10 0x00100000 262 | #define APPFLAG_D3D11 0x01000000 263 | 264 | #define APPFLAG_API_USAGE_MASK (APPFLAG_DD | APPFLAG_D3D8 | APPFLAG_D3D9 | APPFLAG_D3D9EX | APPFLAG_OGL | APPFLAG_D3D10 | APPFLAG_D3D11) 265 | 266 | #define APPFLAG_PROFILE_UPDATE_REQUESTED 0x10000000 267 | ///////////////////////////////////////////////////////////////////////////// 268 | #define SCREENCAPTUREFLAG_REQUEST_CAPTURE 0x00000001 269 | #define SCREENCAPTUREFLAG_REQUEST_CAPTURE_OSD 0x00000010 270 | ///////////////////////////////////////////////////////////////////////////// 271 | #define VIDEOCAPTUREFLAG_REQUEST_CAPTURE_START 0x00000001 272 | #define VIDEOCAPTUREFLAG_REQUEST_CAPTURE_PROGRESS 0x00000002 273 | #define VIDEOCAPTUREFLAG_REQUEST_CAPTURE_STOP 0x00000004 274 | #define VIDEOCAPTUREFLAG_REQUEST_CAPTURE_MASK 0x00000007 275 | #define VIDEOCAPTUREFLAG_REQUEST_CAPTURE_OSD 0x00000010 276 | 277 | #define VIDEOCAPTUREFLAG_INTERNAL_RESIZE 0x00010000 278 | ///////////////////////////////////////////////////////////////////////////// 279 | 280 | // v2.0 memory structure 281 | typedef struct RTSS_SHARED_MEMORY 282 | { 283 | DWORD dwSignature; 284 | //signature allows applications to verify status of shared memory 285 | 286 | //The signature can be set to: 287 | //'RTSS' - statistics server's memory is initialized and contains 288 | // valid data 289 | //0xDEAD - statistics server's memory is marked for deallocation and 290 | // no longer contain valid data 291 | //otherwise the memory is not initialized 292 | DWORD dwVersion; 293 | //structure version ((major<<16) + minor) 294 | //must be set to 0x0002xxxx for v2.x structure 295 | 296 | DWORD dwAppEntrySize; 297 | //size of RTSS_SHARED_MEMORY_OSD_ENTRY for compatibility with future versions 298 | DWORD dwAppArrOffset; 299 | //offset of arrOSD array for compatibility with future versions 300 | DWORD dwAppArrSize; 301 | //size of arrOSD array for compatibility with future versions 302 | 303 | DWORD dwOSDEntrySize; 304 | //size of RTSS_SHARED_MEMORY_APP_ENTRY for compatibility with future versions 305 | DWORD dwOSDArrOffset; 306 | //offset of arrApp array for compatibility with future versions 307 | DWORD dwOSDArrSize; 308 | //size of arrOSD array for compatibility with future versions 309 | 310 | DWORD dwOSDFrame; 311 | //Global OSD frame ID. Increment it to force the server to update OSD for all currently active 3D 312 | //applications. 313 | 314 | //OSD slot descriptor structure 315 | 316 | typedef struct RTSS_SHARED_MEMORY_OSD_ENTRY 317 | { 318 | char szOSD[256]; 319 | //OSD slot text 320 | char szOSDOwner[256]; 321 | //OSD slot owner ID 322 | 323 | //next fields are valid for v2.7 and newer shared memory format only 324 | 325 | char szOSDEx[4096]; 326 | //extended OSD slot text 327 | 328 | } RTSS_SHARED_MEMORY_OSD_ENTRY, *LPRTSS_SHARED_MEMORY_OSD_ENTRY; 329 | 330 | //application descriptor structure 331 | 332 | typedef struct RTSS_SHARED_MEMORY_APP_ENTRY 333 | { 334 | //application identification related fields 335 | 336 | DWORD dwProcessID; 337 | //process ID 338 | char szName[MAX_PATH]; 339 | //process executable name 340 | DWORD dwFlags; 341 | //application specific flags 342 | 343 | //instantaneous framerate related fields 344 | 345 | DWORD dwTime0; 346 | //start time of framerate measurement period (in milliseconds) 347 | 348 | //Take a note that this field must contain non-zero value to calculate 349 | //framerate properly! 350 | DWORD dwTime1; 351 | //end time of framerate measurement period (in milliseconds) 352 | DWORD dwFrames; 353 | //amount of frames rendered during (dwTime1 - dwTime0) period 354 | DWORD dwFrameTime; 355 | //frame time (in microseconds) 356 | 357 | 358 | //to calculate framerate use the following formulas: 359 | 360 | //1000.0f * dwFrames / (dwTime1 - dwTime0) for framerate calculated once per second 361 | //or 362 | //1000000.0f / dwFrameTime for framerate calculated once per frame 363 | 364 | //framerate statistics related fields 365 | 366 | DWORD dwStatFlags; 367 | //bitmask containing combination of STATFLAG_... flags 368 | DWORD dwStatTime0; 369 | //statistics record period start time 370 | DWORD dwStatTime1; 371 | //statistics record period end time 372 | DWORD dwStatFrames; 373 | //total amount of frames rendered during statistics record period 374 | DWORD dwStatCount; 375 | //amount of min/avg/max measurements during statistics record period 376 | DWORD dwStatFramerateMin; 377 | //minimum instantaneous framerate measured during statistics record period 378 | DWORD dwStatFramerateAvg; 379 | //average instantaneous framerate measured during statistics record period 380 | DWORD dwStatFramerateMax; 381 | //maximum instantaneous framerate measured during statistics record period 382 | 383 | //OSD related fields 384 | 385 | DWORD dwOSDX; 386 | //OSD X-coordinate (coordinate wrapping is allowed, i.e. -5 defines 5 387 | //pixel offset from the right side of the screen) 388 | DWORD dwOSDY; 389 | //OSD Y-coordinate (coordinate wrapping is allowed, i.e. -5 defines 5 390 | //pixel offset from the bottom side of the screen) 391 | DWORD dwOSDPixel; 392 | //OSD pixel zooming ratio 393 | DWORD dwOSDColor; 394 | //OSD color in RGB format 395 | DWORD dwOSDFrame; 396 | //application specific OSD frame ID. Don't change it directly! 397 | 398 | DWORD dwScreenCaptureFlags; 399 | char szScreenCapturePath[MAX_PATH]; 400 | 401 | //next fields are valid for v2.1 and newer shared memory format only 402 | 403 | DWORD dwOSDBgndColor; 404 | //OSD background color in RGB format 405 | 406 | //next fields are valid for v2.2 and newer shared memory format only 407 | 408 | DWORD dwVideoCaptureFlags; 409 | char szVideoCapturePath[MAX_PATH]; 410 | DWORD dwVideoFramerate; 411 | DWORD dwVideoFramesize; 412 | DWORD dwVideoFormat; 413 | DWORD dwVideoQuality; 414 | DWORD dwVideoCaptureThreads; 415 | 416 | DWORD dwScreenCaptureQuality; 417 | DWORD dwScreenCaptureThreads; 418 | 419 | //next fields are valid for v2.3 and newer shared memory format only 420 | 421 | DWORD dwAudioCaptureFlags; 422 | 423 | //next fields are valid for v2.4 and newer shared memory format only 424 | 425 | DWORD dwVideoCaptureFlagsEx; 426 | 427 | //next fields are valid for v2.5 and newer shared memory format only 428 | 429 | DWORD dwAudioCaptureFlags2; 430 | 431 | DWORD dwStatFrameTimeMin; 432 | DWORD dwStatFrameTimeAvg; 433 | DWORD dwStatFrameTimeMax; 434 | DWORD dwStatFrameTimeCount; 435 | 436 | DWORD dwStatFrameTimeBuf[1024]; 437 | DWORD dwStatFrameTimeBufPos; 438 | DWORD dwStatFrameTimeBufFramerate; 439 | 440 | //next fields are valid for v2.6 and newer shared memory format only 441 | 442 | LARGE_INTEGER qwAudioCapturePTTEventPush; 443 | LARGE_INTEGER qwAudioCapturePTTEventRelease; 444 | 445 | LARGE_INTEGER qwAudioCapturePTTEventPush2; 446 | LARGE_INTEGER qwAudioCapturePTTEventRelease2; 447 | 448 | } RTSS_SHARED_MEMORY_APP_ENTRY, *LPRTSS_SHARED_MEMORY_APP_ENTRY; 449 | 450 | RTSS_SHARED_MEMORY_OSD_ENTRY arrOSD[8]; 451 | //array of OSD slots 452 | RTSS_SHARED_MEMORY_APP_ENTRY arrApp[256]; 453 | //array of application descriptors 454 | 455 | } RTSS_SHARED_MEMORY, *LPRTSS_SHARED_MEMORY; 456 | ///////////////////////////////////////////////////////////////////////////// 457 | #endif //_RTSS_SHARED_MEMORY_INCLUDED_ -------------------------------------------------------------------------------- /RTSSSharedMemoryNET/RTSSSharedMemoryNET.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {53939D64-D853-4B4C-A4F9-2FCE48502725} 23 | v4.0 24 | ManagedCProj 25 | RTSSSharedMemoryNET 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v110 32 | true 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | true 38 | v110 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | false 45 | v110 46 | true 47 | Unicode 48 | 49 | 50 | DynamicLibrary 51 | false 52 | v110 53 | true 54 | Unicode 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | $(ProjectDir)\$(PlatformShortName)\bin\$(Configuration)\ 75 | $(ProjectDir)\$(PlatformShortName)\obj\$(Configuration)\ 76 | true 77 | BestRules.ruleset 78 | 79 | 80 | true 81 | BestRules.ruleset 82 | true 83 | $(ProjectDir)\$(PlatformShortName)\bin\$(Configuration)\ 84 | $(ProjectDir)\$(PlatformShortName)\obj\$(Configuration)\ 85 | 86 | 87 | false 88 | $(ProjectDir)\$(PlatformShortName)\bin\$(Configuration)\ 89 | $(ProjectDir)\$(PlatformShortName)\obj\$(Configuration)\ 90 | true 91 | BestRules.ruleset 92 | 93 | 94 | true 95 | BestRules.ruleset 96 | false 97 | $(ProjectDir)\$(PlatformShortName)\bin\$(Configuration)\ 98 | $(ProjectDir)\$(PlatformShortName)\obj\$(Configuration)\ 99 | 100 | 101 | 102 | Level4 103 | Disabled 104 | WIN32;_DEBUG;%(PreprocessorDefinitions) 105 | Use 106 | true 107 | CodeAnalysis\SourceAnnotations.h;%(ForcedIncludeFiles) 108 | true 109 | 110 | 111 | true 112 | 113 | 114 | 115 | 116 | 117 | Level4 118 | Disabled 119 | WIN32;_DEBUG;%(PreprocessorDefinitions) 120 | Use 121 | true 122 | CodeAnalysis\SourceAnnotations.h;%(ForcedIncludeFiles) 123 | true 124 | 125 | 126 | true 127 | 128 | 129 | 130 | 131 | 132 | 133 | Level4 134 | WIN32;NDEBUG;%(PreprocessorDefinitions) 135 | Use 136 | true 137 | CodeAnalysis\SourceAnnotations.h;%(ForcedIncludeFiles) 138 | true 139 | 140 | 141 | true 142 | 143 | 144 | 145 | 146 | 147 | Level4 148 | WIN32;NDEBUG;%(PreprocessorDefinitions) 149 | Use 150 | true 151 | CodeAnalysis\SourceAnnotations.h;%(ForcedIncludeFiles) 152 | true 153 | 154 | 155 | true 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | Create 178 | Create 179 | Create 180 | Create 181 | 182 | 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /RTSSSharedMemoryNET/RTSSSharedMemoryNET.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | -------------------------------------------------------------------------------- /RTSSSharedMemoryNET/Stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // RTSSSharedMemoryNET.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | -------------------------------------------------------------------------------- /RTSSSharedMemoryNET/Stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, 3 | // but are changed infrequently 4 | 5 | #pragma once 6 | 7 | #define WIN32_LEAN_AND_MEAN 8 | #include 9 | #include 10 | #include "RTSSSharedMemory.h" 11 | #include "Utilities.h" -------------------------------------------------------------------------------- /RTSSSharedMemoryNET/Structs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | using namespace System; 4 | using namespace System::Drawing; 5 | using namespace System::Diagnostics; 6 | 7 | namespace RTSSSharedMemoryNET { 8 | [Flags] 9 | public enum class AppFlags 10 | { 11 | None = 0, 12 | OpenGL = APPFLAG_OGL, 13 | DirectDraw = APPFLAG_DD, 14 | Direct3D8 = APPFLAG_D3D8, 15 | Direct3D9 = APPFLAG_D3D9, 16 | Direct3D9Ex = APPFLAG_D3D9EX, 17 | Direct3D10 = APPFLAG_D3D10, 18 | Direct3D11 = APPFLAG_D3D11, 19 | 20 | ProfileUpdateRequested = APPFLAG_PROFILE_UPDATE_REQUESTED, 21 | MASK = (APPFLAG_DD | APPFLAG_D3D8 | APPFLAG_D3D9 | APPFLAG_D3D9EX | APPFLAG_OGL | APPFLAG_D3D10 | APPFLAG_D3D11), 22 | }; 23 | 24 | [Flags] 25 | public enum class StatFlags 26 | { 27 | None = 0, 28 | Record = STATFLAG_RECORD, 29 | }; 30 | 31 | [Flags] 32 | public enum class ScreenshotFlags 33 | { 34 | None = 0, 35 | RequestCapture = SCREENCAPTUREFLAG_REQUEST_CAPTURE, 36 | RequestCaptureOSD = SCREENCAPTUREFLAG_REQUEST_CAPTURE_OSD, 37 | }; 38 | 39 | [Flags] 40 | public enum class VideoCaptureFlags 41 | { 42 | None = 0, 43 | RequestCaptureStart = VIDEOCAPTUREFLAG_REQUEST_CAPTURE_START, 44 | RequestCaptureProgress = VIDEOCAPTUREFLAG_REQUEST_CAPTURE_PROGRESS, 45 | RequestCaptureStop = VIDEOCAPTUREFLAG_REQUEST_CAPTURE_STOP, 46 | RequestCaptureOSD = VIDEOCAPTUREFLAG_REQUEST_CAPTURE_OSD, 47 | 48 | INTERNAL_RESIZE = VIDEOCAPTUREFLAG_INTERNAL_RESIZE, 49 | MASK = (VIDEOCAPTUREFLAG_REQUEST_CAPTURE_START | VIDEOCAPTUREFLAG_REQUEST_CAPTURE_PROGRESS | VIDEOCAPTUREFLAG_REQUEST_CAPTURE_STOP), 50 | }; 51 | 52 | /////////////////////////////////////////////////////////////////////////// 53 | 54 | [DebuggerDisplay("{Owner}, {Text}")] 55 | public ref struct OSDEntry 56 | { 57 | public: 58 | String^ Owner; 59 | String^ Text; 60 | }; 61 | 62 | [DebuggerDisplay("{ProcessId}:{Name}, {Flags}")] 63 | public ref struct AppEntry 64 | { 65 | public: 66 | int ProcessId; 67 | String^ Name; 68 | AppFlags Flags; 69 | 70 | //instantaneous framerate fields 71 | DateTime InstantaneousTimeStart; 72 | DateTime InstantaneousTimeEnd; 73 | DWORD InstantaneousFrames; 74 | TimeSpan InstantaneousFrameTime; 75 | 76 | //framerate stats fields 77 | StatFlags StatFlags; 78 | DateTime StatTimeStart; 79 | DateTime StatTimeEnd; 80 | DWORD StatFrames; 81 | DWORD StatCount; 82 | DWORD StatFramerateMin; 83 | DWORD StatFramerateAvg; 84 | DWORD StatFramerateMax; 85 | 86 | //framerate stats 2.5+ 87 | DWORD StatFrameTimeMin; 88 | DWORD StatFrameTimeAvg; 89 | DWORD StatFrameTimeMax; 90 | DWORD StatFrameTimeCount; 91 | /* TODO 92 | DWORD StatFrameTimeBuf[1024]; 93 | DWORD StatFrameTimeBufPos; 94 | DWORD StatFrameTimeBufFramerate; 95 | */ 96 | 97 | //OSD fields 98 | int OSDCoordinateX; 99 | int OSDCoordinateY; 100 | DWORD OSDZoom; 101 | Color OSDColor; 102 | DWORD OSDFrameId; 103 | Color OSDBackgroundColor; //2.1+ 104 | 105 | //screenshot fields 106 | ScreenshotFlags ScreenshotFlags; 107 | String^ ScreenshotPath; 108 | DWORD ScreenshotQuality; //2.2+ 109 | DWORD ScreenshotThreads; //2.2+ 110 | 111 | //video capture fields - 2.2+ 112 | VideoCaptureFlags VideoCaptureFlags; 113 | String^ VideoCapturePath; 114 | DWORD VideoFramerate; 115 | DWORD VideoFramesize; 116 | DWORD VideoFormat; 117 | DWORD VideoQuality; 118 | DWORD VideoCaptureThreads; 119 | DWORD VideoCaptureFlagsEx; //2.4+ 120 | 121 | //audio capture fields 122 | DWORD AudioCaptureFlags; //2.3+ 123 | DWORD AudioCaptureFlags2; //2.5+ 124 | Int64 AudioCapturePTTEventPush; //2.6+ 125 | Int64 AudioCapturePTTEventRelease; //2.6+ 126 | Int64 AudioCapturePTTEventPush2; //2.6+ 127 | Int64 AudioCapturePTTEventRelease2; //2.6+ 128 | }; 129 | } -------------------------------------------------------------------------------- /RTSSSharedMemoryNET/Utilities.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //http://stackoverflow.com/a/673336/489071 4 | template 5 | public ref class using_auto_ptr 6 | { 7 | public: 8 | using_auto_ptr(T^ p) : m_p(p), m_used(true) 9 | { 10 | //type check, since C#'s using is only for IDisposable 11 | static_cast(p); 12 | } 13 | 14 | ~using_auto_ptr() { delete m_p; } 15 | 16 | T^ operator->() { return m_p; } 17 | static T^ operator*(using_auto_ptr% p) { return p->m_p; } //C4383 says I should do it this way 18 | 19 | bool m_used; 20 | 21 | private: 22 | T^ m_p; 23 | }; 24 | 25 | // USING( [TYPE], [VARIABLE NAME], [CONSTRUCTOR] ) 26 | #define USING(CLASS, VAR, ALLOC) \ 27 | for( using_auto_ptr VAR(ALLOC); VAR.m_used; VAR.m_used=0) 28 | 29 | //for easily handling unmanaged shit 30 | #define SAFE_RELEASE(p) if( NULL != (p) ){ (p)->Release(); (p) = NULL; } 31 | #define SAFE_DELETE(p) if( NULL != (p) ){ delete (p); (p) = NULL; } 32 | #define GOTO_FAIL_IF_FAILED(hr) if( FAILED(hr) ){ goto fail; } 33 | 34 | //for easily handling unmanaged to managed errors 35 | #define THROW_HR(hr) System::Runtime::InteropServices::Marshal::ThrowExceptionForHR(hr) 36 | #define THROW_ERROR(error) THROW_HR(HRESULT_FROM_WIN32(error)) 37 | #define THROW_LAST_ERROR() THROW_HR(System::Runtime::InteropServices::Marshal::GetHRForLastWin32Error()) 38 | 39 | //for strcmp and co 40 | #define STRMATCHES(x) (x) == 0 41 | #define STRLESSTHAN(x) (x) < 0 42 | #define STRMORETHAN(x) (x) > 0 43 | --------------------------------------------------------------------------------