Skip to content
This repository was archived by the owner on Jul 16, 2020. It is now read-only.

Commit 1876946

Browse files
committed
sample: screen control sample
1 parent 5c48b0d commit 1876946

9 files changed

+604
-0
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<ItemGroup Label="ProjectConfigurations">
4+
<ProjectConfiguration Include="Debug|Win32">
5+
<Configuration>Debug</Configuration>
6+
<Platform>Win32</Platform>
7+
</ProjectConfiguration>
8+
<ProjectConfiguration Include="Release|Win32">
9+
<Configuration>Release</Configuration>
10+
<Platform>Win32</Platform>
11+
</ProjectConfiguration>
12+
<ProjectConfiguration Include="Debug|x64">
13+
<Configuration>Debug</Configuration>
14+
<Platform>x64</Platform>
15+
</ProjectConfiguration>
16+
<ProjectConfiguration Include="Release|x64">
17+
<Configuration>Release</Configuration>
18+
<Platform>x64</Platform>
19+
</ProjectConfiguration>
20+
</ItemGroup>
21+
<PropertyGroup Label="Globals">
22+
<VCProjectVersion>15.0</VCProjectVersion>
23+
<ProjectGuid>{C5D30411-CECD-48B1-9B9C-3C86A1ACD2FA}</ProjectGuid>
24+
<Keyword>Win32Proj</Keyword>
25+
<RootNamespace>InteractiveSample</RootNamespace>
26+
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
27+
<ProjectName>InteractiveScreenControlSample</ProjectName>
28+
</PropertyGroup>
29+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
30+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
31+
<ConfigurationType>Application</ConfigurationType>
32+
<UseDebugLibraries>true</UseDebugLibraries>
33+
<PlatformToolset>v141</PlatformToolset>
34+
<CharacterSet>Unicode</CharacterSet>
35+
</PropertyGroup>
36+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
37+
<ConfigurationType>Application</ConfigurationType>
38+
<UseDebugLibraries>false</UseDebugLibraries>
39+
<PlatformToolset>v141</PlatformToolset>
40+
<WholeProgramOptimization>true</WholeProgramOptimization>
41+
<CharacterSet>Unicode</CharacterSet>
42+
</PropertyGroup>
43+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
44+
<ConfigurationType>Application</ConfigurationType>
45+
<UseDebugLibraries>true</UseDebugLibraries>
46+
<PlatformToolset>v141</PlatformToolset>
47+
<CharacterSet>NotSet</CharacterSet>
48+
</PropertyGroup>
49+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
50+
<ConfigurationType>Application</ConfigurationType>
51+
<UseDebugLibraries>false</UseDebugLibraries>
52+
<PlatformToolset>v141</PlatformToolset>
53+
<WholeProgramOptimization>true</WholeProgramOptimization>
54+
<CharacterSet>Unicode</CharacterSet>
55+
</PropertyGroup>
56+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
57+
<ImportGroup Label="ExtensionSettings">
58+
</ImportGroup>
59+
<ImportGroup Label="Shared">
60+
</ImportGroup>
61+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
62+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
63+
</ImportGroup>
64+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
65+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
66+
</ImportGroup>
67+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
68+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
69+
</ImportGroup>
70+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
71+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
72+
</ImportGroup>
73+
<PropertyGroup Label="UserMacros" />
74+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
75+
<LinkIncremental>true</LinkIncremental>
76+
</PropertyGroup>
77+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
78+
<LinkIncremental>true</LinkIncremental>
79+
</PropertyGroup>
80+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
81+
<LinkIncremental>false</LinkIncremental>
82+
</PropertyGroup>
83+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
84+
<LinkIncremental>false</LinkIncremental>
85+
</PropertyGroup>
86+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
87+
<ClCompile>
88+
<PrecompiledHeader>NotUsing</PrecompiledHeader>
89+
<WarningLevel>Level3</WarningLevel>
90+
<Optimization>Disabled</Optimization>
91+
<SDLCheck>true</SDLCheck>
92+
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
93+
<ConformanceMode>true</ConformanceMode>
94+
</ClCompile>
95+
<Link>
96+
<SubSystem>Console</SubSystem>
97+
<GenerateDebugInformation>true</GenerateDebugInformation>
98+
</Link>
99+
</ItemDefinitionGroup>
100+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
101+
<ClCompile>
102+
<PrecompiledHeader>NotUsing</PrecompiledHeader>
103+
<WarningLevel>Level3</WarningLevel>
104+
<Optimization>Disabled</Optimization>
105+
<SDLCheck>true</SDLCheck>
106+
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
107+
<ConformanceMode>true</ConformanceMode>
108+
</ClCompile>
109+
<Link>
110+
<SubSystem>Console</SubSystem>
111+
<GenerateDebugInformation>true</GenerateDebugInformation>
112+
</Link>
113+
</ItemDefinitionGroup>
114+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
115+
<ClCompile>
116+
<PrecompiledHeader>NotUsing</PrecompiledHeader>
117+
<WarningLevel>Level3</WarningLevel>
118+
<Optimization>MaxSpeed</Optimization>
119+
<FunctionLevelLinking>true</FunctionLevelLinking>
120+
<IntrinsicFunctions>true</IntrinsicFunctions>
121+
<SDLCheck>true</SDLCheck>
122+
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
123+
<ConformanceMode>true</ConformanceMode>
124+
</ClCompile>
125+
<Link>
126+
<SubSystem>Console</SubSystem>
127+
<EnableCOMDATFolding>true</EnableCOMDATFolding>
128+
<OptimizeReferences>true</OptimizeReferences>
129+
<GenerateDebugInformation>true</GenerateDebugInformation>
130+
</Link>
131+
</ItemDefinitionGroup>
132+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
133+
<ClCompile>
134+
<PrecompiledHeader>NotUsing</PrecompiledHeader>
135+
<WarningLevel>Level3</WarningLevel>
136+
<Optimization>MaxSpeed</Optimization>
137+
<FunctionLevelLinking>true</FunctionLevelLinking>
138+
<IntrinsicFunctions>true</IntrinsicFunctions>
139+
<SDLCheck>true</SDLCheck>
140+
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
141+
<ConformanceMode>true</ConformanceMode>
142+
</ClCompile>
143+
<Link>
144+
<SubSystem>Console</SubSystem>
145+
<EnableCOMDATFolding>true</EnableCOMDATFolding>
146+
<OptimizeReferences>true</OptimizeReferences>
147+
<GenerateDebugInformation>true</GenerateDebugInformation>
148+
</Link>
149+
</ItemDefinitionGroup>
150+
<ItemGroup>
151+
<ClInclude Include="stdafx.h" />
152+
<ClInclude Include="targetver.h" />
153+
</ItemGroup>
154+
<ItemGroup>
155+
<ClCompile Include="..\..\source\interactivity.cpp" />
156+
<ClCompile Include="InteractiveScreenControlSample.cpp" />
157+
<ClCompile Include="stdafx.cpp">
158+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
159+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
160+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
161+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
162+
</ClCompile>
163+
</ItemGroup>
164+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
165+
<ImportGroup Label="ExtensionTargets">
166+
</ImportGroup>
167+
</Project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<ItemGroup>
4+
<Filter Include="Source Files">
5+
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
6+
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
7+
</Filter>
8+
<Filter Include="Header Files">
9+
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
10+
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
11+
</Filter>
12+
<Filter Include="Resource Files">
13+
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
14+
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
15+
</Filter>
16+
</ItemGroup>
17+
<ItemGroup>
18+
<ClInclude Include="stdafx.h">
19+
<Filter>Header Files</Filter>
20+
</ClInclude>
21+
<ClInclude Include="targetver.h">
22+
<Filter>Header Files</Filter>
23+
</ClInclude>
24+
</ItemGroup>
25+
<ItemGroup>
26+
<ClCompile Include="stdafx.cpp">
27+
<Filter>Source Files</Filter>
28+
</ClCompile>
29+
<ClCompile Include="..\..\source\interactivity.cpp">
30+
<Filter>Source Files</Filter>
31+
</ClCompile>
32+
<ClCompile Include="InteractiveScreenControlSample.cpp">
33+
<Filter>Source Files</Filter>
34+
</ClCompile>
35+
</ItemGroup>
36+
</Project>
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#include "stdafx.h"
2+
#include "../../source/interactivity.h"
3+
#include "../../source/internal/rapidjson/Document.h"
4+
5+
#include <windows.h>
6+
#include <shellapi.h>
7+
8+
// STL includes
9+
#include <chrono>
10+
#include <thread>
11+
#include <iostream>
12+
#include <map>
13+
#include <string>
14+
15+
#define CLIENT_ID "f0d20e2d263b75894f5cdaabc8a344b99b1ea6f9ecb7fa4f"
16+
#define INTERACTIVE_ID "247834"
17+
#define SHARE_CODE "v8t3hlaa"
18+
19+
#define MIXER_DEBUG 0
20+
21+
std::map<std::string, std::string> controlsByTransaction;
22+
23+
// Display an OAuth consent page to the user.
24+
int authorize(std::string& authorization);
25+
26+
// Handle interactive input.
27+
void handle_interactive_input(void* context, interactive_session session, const interactive_input* input);
28+
29+
int main()
30+
{
31+
int err = 0;
32+
33+
#if MIXER_DEBUG
34+
interactive_config_debug(interactive_debug_trace, [](const interactive_debug_level dbgMsgType, const char* dbgMsg, size_t dbgMsgSize)
35+
{
36+
std::cout << dbgMsg << std::endl;
37+
});
38+
#endif
39+
40+
// Get an authorization token for the user to pass to the connect function.
41+
std::string authorization;
42+
err = authorize(authorization);
43+
if (err) return err;
44+
45+
// Connect to the user's interactive channel, using the interactive project specified by the version ID.
46+
interactive_session session;
47+
err = interactive_open_session(authorization.c_str(), INTERACTIVE_ID, SHARE_CODE, false, &session);
48+
if (err) return err;
49+
50+
// Register a callback for button presses.
51+
err = interactive_set_input_handler(session, handle_interactive_input);
52+
if (err) return err;
53+
54+
// Now notify participants that interactive is ready.
55+
err = interactive_set_ready(session, true);
56+
if (err) return err;
57+
58+
// Simulate game update loop. All previously registered session callbacks will be called from this thread.
59+
for (;;)
60+
{
61+
// This call processes any waiting messages from the interactive service. If there are no messages this returns immediately.
62+
err = interactive_run(session, 1);
63+
if (err) break;
64+
std::this_thread::sleep_for(std::chrono::milliseconds(16));
65+
}
66+
67+
interactive_close_session(session);
68+
69+
return err;
70+
}
71+
72+
int authorize(std::string& authorization)
73+
{
74+
int err = 0;
75+
char shortCode[7];
76+
size_t shortCodeLength = _countof(shortCode);
77+
char shortCodeHandle[1024];
78+
size_t shortCodeHandleLength = _countof(shortCodeHandle);
79+
80+
// Get an OAuth short code from the user. For more information about OAuth see: https://oauth.net/2/
81+
err = interactive_auth_get_short_code(CLIENT_ID, nullptr, shortCode, &shortCodeLength, shortCodeHandle, &shortCodeHandleLength);
82+
if (err) return err;
83+
84+
// Pop the browser for the user to approve access.
85+
std::string authUrl = std::string("https://www.mixer.com/go?code=") + shortCode;
86+
ShellExecuteA(0, 0, authUrl.c_str(), nullptr, nullptr, SW_SHOW);
87+
88+
// Wait for OAuth token response.
89+
char refreshTokenBuffer[1024];
90+
size_t refreshTokenLength = _countof(refreshTokenBuffer);
91+
err = interactive_auth_wait_short_code(CLIENT_ID, nullptr, shortCodeHandle, refreshTokenBuffer, &refreshTokenLength);
92+
if (err)
93+
{
94+
if (MIXER_ERROR_TIMED_OUT == err)
95+
{
96+
std::cout << "Authorization timed out, user did not approve access within the time limit." << std::endl;
97+
}
98+
else if (MIXER_ERROR_AUTH_DENIED == err)
99+
{
100+
std::cout << "User denied access." << std::endl;
101+
}
102+
103+
return err;
104+
}
105+
106+
/*
107+
* TODO: This is where you would serialize the refresh token locally or on your own service for future use in a way that is associated with the current user.
108+
* Future calls would then only need to check if the token is stale, refresh it if so, and then parse the new authorization header.
109+
*/
110+
111+
// Extract the authorization header from the refresh token.
112+
char authBuffer[1024];
113+
size_t authBufferLength = _countof(authBuffer);
114+
err = interactive_auth_parse_refresh_token(refreshTokenBuffer, authBuffer, &authBufferLength);
115+
if (err) return err;
116+
117+
// Set the authorization out parameter.
118+
authorization = std::string(authBuffer, authBufferLength);
119+
return 0;
120+
}
121+
122+
int get_participant_name(interactive_session session, const char* participantId, std::string& participantName)
123+
{
124+
// Get the participant's name.
125+
size_t participantNameLength = 0;
126+
127+
// First call with a nullptr to get the required size for the user's name, MIXER_ERROR_BUFFER_SIZE is the expected return value.
128+
int err = interactive_participant_get_user_name(session, participantId, nullptr, &participantNameLength);
129+
if (MIXER_ERROR_BUFFER_SIZE != err)
130+
{
131+
return err;
132+
}
133+
134+
// Resize the string to the correct size and call it again.
135+
participantName.resize(participantNameLength);
136+
err = interactive_participant_get_user_name(session, participantId, (char*)participantName.data(), &participantNameLength);
137+
// STL strings don't need a trailing null character.
138+
participantName = participantName.erase(participantNameLength - 1);
139+
140+
return 0;
141+
}
142+
143+
void handle_interactive_input(void* context, interactive_session session, const interactive_input* input)
144+
{
145+
// Get the participant's Mixer name to give them attribution.
146+
std::string participantName;
147+
int err = get_participant_name(session, input->participantId, participantName);
148+
if (err)
149+
{
150+
std::cerr << "Failed to get participant user name (" << std::to_string(err) << ")" << std::endl;
151+
return;
152+
}
153+
154+
// Now handle the input based on input type.
155+
if ((input_type_key == input->type || input_type_click == input->type) && interactive_button_action_down == input->buttonData.action)
156+
{
157+
float x = input->coordinateData.x;
158+
float y = input->coordinateData.y;
159+
std::cout << participantName << " clicked x: " + std::to_string(x) << " y: " << std::to_string(y) << std::endl;
160+
}
161+
else if (input_type_move == input->type)
162+
{
163+
// Show which user moved the joystick.
164+
float x = input->coordinateData.x;
165+
float y = input->coordinateData.y;
166+
std::cout << participantName << " moved pointer to x: " + std::to_string(x) << " y: " << std::to_string(y) << std::endl;
167+
}
168+
}

0 commit comments

Comments
 (0)