├── .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 |
--------------------------------------------------------------------------------