* 2210 GDK
This commit is contained in:
Nathan Iskandar 2022-10-27 12:40:03 -07:00 коммит произвёл GitHub
Родитель 65a698fad8
Коммит 525786e8de
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
62 изменённых файлов: 5043 добавлений и 973 удалений

2
External/Xal/External/libHttpClient поставляемый

@ -1 +1 @@
Subproject commit 6b822f62f3c3286ec2579b4885900bb38fa55591
Subproject commit b8e335836e0c6bc6b83f943b1c9ad3c815c1aab0

Просмотреть файл

@ -20,6 +20,6 @@ extern "C"
/// YYYYMMDD Date string describing the date the build was created
/// rrr QFE number (000 indicates base release)
/// </summary>
#define XAL_VERSION "2022.06.20220603.000"
#define XAL_VERSION "2022.08.20220825.000"
}

Просмотреть файл

@ -165,7 +165,7 @@ enum class XblAchievementRewardType : uint32_t
enum class XblAchievementRarityCategory : uint32_t
{
/// <summary>
/// The rarity is incalculable (e.g. no one has played the title yet, demoninator is 0).
/// The rarity is incalculable (e.g. no one has played the title yet, denominator is 0).
/// </summary>
Unset = 0,

Просмотреть файл

@ -260,7 +260,7 @@ STDAPI XblAchievementsManagerGetAchievementsByState(
/// </summary>
/// <param name="xboxUserId">The Xbox User ID of the player.</param>
/// <param name="achievementId">The UTF-8 encoded achievement ID as defined by Dev Center.</param>
/// <param name="currentProgess">The completion percentage of the achievement to indicate progress.
/// <param name="currentProgress">The completion percentage of the achievement to indicate progress.
/// Valid values are from 1 to 100. Set to 100 to unlock the achievement.
/// Progress will be set by the server to the highest value sent</param>
/// <returns>HRESULT return code for this API operation.</returns>
@ -287,7 +287,7 @@ STDAPI XblAchievementsManagerGetAchievementsByState(
STDAPI XblAchievementsManagerUpdateAchievement(
_In_ uint64_t xboxUserId,
_In_ const char* achievementId,
_In_ uint8_t currentProgess
_In_ uint8_t currentProgress
) XBL_NOEXCEPT;
} //end extern "C"

Просмотреть файл

@ -323,7 +323,7 @@ enum class XblMultiplayerInitializationStage : uint32_t
Evaluating,
/// <summary>
/// Failed stage. If the first initilization episode didn't succeed, the session can't be initialized.
/// Failed stage. If the first initialization episode didn't succeed, the session can't be initialized.
/// </summary>
Failed
};
@ -1138,7 +1138,7 @@ typedef struct XblMultiplayerSessionConstants
XblMultiplayerSessionCapabilities SessionCapabilities;
} XblMultiplayerSessionConstants;
#define XBL_MULTIPLAYER_DEVICE_TOKEN_MAX_LENGTH 40 // TODO confirm max size, not a GUID
#define XBL_MULTIPLAYER_DEVICE_TOKEN_MAX_LENGTH 40
#define XBL_MULTIPLAYER_SESSION_TEMPLATE_NAME_MAX_LENGTH 100
#define XBL_MULTIPLAYER_SESSION_NAME_MAX_LENGTH XBL_MULTIPLAYER_SESSION_TEMPLATE_NAME_MAX_LENGTH
@ -2580,7 +2580,7 @@ STDAPI XblMultiplayerSessionSetMutableRoleSettings(
/// Gets the collection of members that are in the session or entering the session together.
/// </summary>
/// <param name="handle">Handle to the multiplayer session.</param>
/// <param name="members">Passes back a pointer to array of session member ojects.
/// <param name="members">Passes back a pointer to array of session member objects.
/// The memory for the returned pointer will remain valid for the life of the XblMultiplayerSessionHandle object until it is closed.</param>
/// <param name="membersCount">Passes back the size of the returned array.</param>
/// <returns>HRESULT return code for this API operation.</returns>
@ -3243,7 +3243,7 @@ STDAPI XblMultiplayerSearchHandleGetJoinRestriction(
) XBL_NOEXCEPT;
/// <summary>
/// Get whether or not the session associated with the search handle is temporaraly closed for joining.
/// Get whether or not the session associated with the search handle is temporarily closed for joining.
/// </summary>
/// <param name="handle">Handle to the search handle details.</param>
/// <param name="closed">Passes back whether the session is closed or not.</param>
@ -3270,7 +3270,7 @@ STDAPI XblMultiplayerSearchHandleGetMemberCounts(
/// Get the creation time of the search handle.
/// </summary>
/// <param name="handle">Handle to the search handle details.</param>
/// <param name="creationTime">Passes back the time the serach handle was created in MPSD (not the local object).</param>
/// <param name="creationTime">Passes back the time the search handle was created in MPSD (not the local object).</param>
/// <returns>HRESULT return code for this API operation.</returns>
STDAPI XblMultiplayerSearchHandleGetCreationTime(
_In_ XblMultiplayerSearchHandle handle,
@ -3936,7 +3936,7 @@ STDAPI XblMultiplayerGetActivitiesWithPropertiesForUsersResult(
/// <returns>HRESULT return code for this API operation.</returns>
/// <remarks>
/// This method immediately enables the RTA connection, but the in order to receive session changed callbacks, the session
/// must be written again after enabling sunscriptions.
/// must be written again after enabling subscriptions.
/// </remarks>
STDAPI XblMultiplayerSetSubscriptionsEnabled(
_In_ XblContextHandle xblContext,

Просмотреть файл

@ -1098,7 +1098,7 @@ STDAPI XblMultiplayerManagerLobbySessionSetProperties(
/// <remarks>
/// This function sets the value, represented as a JSON string, of a custom property for the lobby session. Custom properties
/// can be changed at any time. If custom properties are shared between devices, or may be updated by several devices
/// at the same time, use this function to ensure atomicity and resolve any conflicts between devices while changing the values of those cusotm properties.
/// at the same time, use this function to ensure atomicity and resolve any conflicts between devices while changing the values of those custom properties.
/// If a custom property isn't shared across devices, use the <see cref="XblMultiplayerManagerLobbySessionSetProperties"/> function instead
/// to change the value of that custom property.
/// <para>The service may reject the request to change the custom property if a race condition occurs due to a conflict.
@ -1363,7 +1363,7 @@ STDAPI XblMultiplayerManagerGameSessionSetProperties(
/// <remarks>
/// This function sets the value, represented as a JSON string, of a custom property for the game session. Custom properties
/// can be changed at any time. If custom properties are shared between devices, or may be updated by several devices
/// at the same time, use this function to ensure atomicity and resolve any conflicts between devices while changing the values of those cusotm properties.
/// at the same time, use this function to ensure atomicity and resolve any conflicts between devices while changing the values of those custom properties.
/// If a custom property isn't shared across devices, use the <see cref="XblMultiplayerManagerGameSessionSetProperties"/> function instead
/// to change the value of that custom property.
/// <para>The service may reject the request to change the custom property if a race condition occurs due to a conflict.

Просмотреть файл

@ -17,7 +17,7 @@ extern "C"
#define XBL_TITLE_STORAGE_BLOB_PATH_MAX_LENGTH (257 * 3)
#define XBL_TITLE_STORAGE_BLOB_DISPLAY_NAME_MAX_LENGTH (129 * 3)
#define XBL_TITLE_STORAGE_BLOB_ETAG_MAX_LENGTH (18 * 3) // TODO confirm with Azure Blob Services team
#define XBL_TITLE_STORAGE_BLOB_ETAG_MAX_LENGTH (18 * 3)
/// <summary>
/// Defines values used to indicate title storage type.

8
NuGet.config Normal file
Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Auto generated file from Gardener Plugin CentralFeedServiceAdoptionPlugin -->
<configuration>
<packageSources>
<clear />
<add key="xbox.services_PublicPackages" value="https://pkgs.dev.azure.com/microsoft/xbox.services/_packaging/xbox.services_PublicPackages/nuget/v3/index.json" />
</packageSources>
</configuration>

Просмотреть файл

@ -254,7 +254,14 @@ LeaderboardResult::SerializeQuery(XblLeaderboardQuery* query, char* buffer)
query->xboxUserId = m_globalQuery->xuid.empty() ? 0 : utils::internal_string_to_uint64(m_globalQuery->xuid);
utils::strcpy(buffer, m_globalQuery->name.size() + 1, m_globalQuery->name.c_str());
query->leaderboardName = static_cast<char*>(buffer);
if (m_globalQuery->isTitleManaged)
{
query->statName = static_cast<char*>(buffer);
}
else
{
query->leaderboardName = static_cast<char*>(buffer);
}
buffer += m_globalQuery->name.size() + 1;
m_additionalColumnleaderboardNamesC.resize(m_globalQuery->columns.size());

Просмотреть файл

@ -1201,11 +1201,22 @@ HRESULT MultiplayerLobbyClient::CreateGameFromLobby() noexcept
}
else if(m_setTransferHandleAttempt++ < MAX_CONNECTION_ATTEMPTS)
{
m_sessionToCommit = writeSessionResult.ExtractPayload();
// Retry setting transfer handle after a small delay
HRESULT hr = m_lobbyClient->m_queue.RunWork([op] {
op->SetTransferHandleToPending();
}, RETRY_DELAY_MS);
std::shared_ptr<XblMultiplayerSession> sessionToCommitTemp = writeSessionResult.ExtractPayload();
HRESULT hr = S_OK;
if (sessionToCommitTemp != nullptr) // handle rare case where an empty body is returned
{
m_sessionToCommit = sessionToCommitTemp;
// Retry setting transfer handle after a small delay
hr = m_lobbyClient->m_queue.RunWork([op] {
op->SetTransferHandleToPending();
}, RETRY_DELAY_MS);
}
else
{
hr = writeSessionResult.Hresult();
}
if (FAILED(hr))
{

Просмотреть файл

@ -9,4 +9,4 @@
//*********************************************************
#pragma once
#define XBOX_SERVICES_API_VERSION_STRING "2022.06.20220915.4"
#define XBOX_SERVICES_API_VERSION_STRING "2022.10.20220915.0"

Просмотреть файл

@ -9,6 +9,8 @@ int XalCleanupAsync_Lua(lua_State *L)
if (Data()->nsalMockCall != nullptr)
{
HCMockRemoveMock(Data()->nsalMockCall);
//Close the handle we're holding onto for API runner state
HCMockCallCloseHandle(Data()->nsalMockCall);
Data()->nsalMockCall = nullptr;
if (Data()->libHttpClientInit) // Set on GDK where XAL is just a wrapper around XUser

Просмотреть файл

@ -83,6 +83,11 @@ int XblMultiplayerSessionCreateHandle_Lua(lua_State *L)
// CODE SNIPPET END
auto state{ MPState() };
auto& session{ state->sessionHandles[static_cast<size_t>(sessionIndex)] };
if (session)
{
XblMultiplayerSessionCloseHandle(session);
}
state->sessionHandles[static_cast<unsigned int>(sessionIndex)] = sessionHandle;
lua_pushinteger(L, static_cast<lua_Integer>(sessionIndex));
@ -1441,6 +1446,13 @@ int XblMultiplayerGetSessionAsync_Lua(lua_State *L)
std::unique_ptr<size_t> sessionIndexPtr{ static_cast<size_t*>(asyncBlock->context) };
auto sessionIndex{ *sessionIndexPtr };
auto& session{ MPState()->sessionHandles[sessionIndex] }; //CODE SNIP SKIP
if (session) //CODE SNIP SKIP
{
XblMultiplayerSessionCloseHandle(session); //CODE SNIP SKIP
MPState()->sessionHandles[sessionIndex] = nullptr; //CODE SNIP SKIP
}
XblMultiplayerSessionHandle sessionHandle = nullptr;
auto hr = XblMultiplayerGetSessionResult(asyncBlock, &sessionHandle);
LogToFile("XblMultiplayerGetSessionResult: hr=%s", ConvertHR(hr).c_str()); // CODE SNIP SKIP
@ -1490,6 +1502,13 @@ int XblMultiplayerGetSessionByHandleAsync_Lua(lua_State *L)
std::unique_ptr<size_t> sessionIndexPtr{ static_cast<size_t*>(asyncBlock->context) };
auto sessionIndex{ *sessionIndexPtr };
auto& session{ MPState()->sessionHandles[sessionIndex] }; //CODE SNIP SKIP
if (session) //CODE SNIP SKIP
{
XblMultiplayerSessionCloseHandle(session); //CODE SNIP SKIP
MPState()->sessionHandles[sessionIndex] = nullptr; //CODE SNIP SKIP
}
XblMultiplayerSessionHandle sessionHandle = nullptr;
auto hr = XblMultiplayerGetSessionByHandleResult(asyncBlock, &sessionHandle);
LogToFile("XblMultiplayerGetSessionByHandleResult: hr=%s", ConvertHR(hr).c_str()); // CODE SNIP SKIP

Просмотреть файл

@ -19,6 +19,7 @@ function OnXblMultiplayerSendInvitesAsync()
end
function OnXblMultiplayerGetSessionByHandleAsync()
XblMultiplayerSessionCloseHandle()
test.stopTest();
end

Просмотреть файл

@ -35,6 +35,7 @@ end
function OnXblMultiplayerDeleteSearchHandleAsync()
XblMultiplayerSearchHandleCloseHandle()
XblMultiplayerSessionCloseHandle()
test.stopTest();
end

Просмотреть файл

@ -22,6 +22,8 @@ function OnXblMultiplayerWriteSessionAsync()
end
function OnXblMultiplayerSetTransferHandleAsync()
XblMultiplayerSessionCloseHandle(session1)
XblMultiplayerSessionCloseHandle(session2)
test.stopTest();
end

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Game configVersion="0">
<Game configVersion="1">
<Identity Name="41336MicrosoftATG.XboxLiveE2E" Publisher="CN=A4954634-DF4B-47C7-AB70-D3215D246AF1" Version="1.7.0.0" />

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Game configVersion="0">
<Game configVersion="1">
<Identity Name="41336MicrosoftATG.XboxLiveE2E" Publisher="CN=A4954634-DF4B-47C7-AB70-D3215D246AF1" Version="1.7.0.0" />

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Game configVersion="0">
<Game configVersion="1">
<Identity Name="41336MicrosoftATG.XboxLiveE2E" Publisher="CN=A4954634-DF4B-47C7-AB70-D3215D246AF1" Version="1.7.0.0" />

Просмотреть файл

@ -1,7 +1,7 @@
//--------------------------------------------------------------------------------------
// File: Keyboard.h
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//
// http://go.microsoft.com/fwlink/?LinkId=248929
@ -10,10 +10,16 @@
#pragma once
#if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) || (defined(_XBOX_ONE) && defined(_TITLE))
#ifndef USING_COREWINDOW
#define USING_COREWINDOW
#endif
#endif
#include <cstdint>
#include <memory>
#if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) || (defined(_XBOX_ONE) && defined(_TITLE))
#ifdef USING_COREWINDOW
namespace ABI { namespace Windows { namespace UI { namespace Core { struct ICoreWindow; } } } }
#endif
@ -29,8 +35,9 @@ namespace DirectX
{
public:
Keyboard() noexcept(false);
Keyboard(Keyboard&& moveFrom) noexcept;
Keyboard& operator= (Keyboard&& moveFrom) noexcept;
Keyboard(Keyboard&&) noexcept;
Keyboard& operator= (Keyboard&&) noexcept;
Keyboard(Keyboard const&) = delete;
Keyboard& operator=(Keyboard const&) = delete;
@ -39,182 +46,184 @@ namespace DirectX
enum Keys : unsigned char
{
None = 0,
None = 0,
Back = 0x8,
Tab = 0x9,
Back = 0x8,
Tab = 0x9,
Enter = 0xd,
Enter = 0xd,
Pause = 0x13,
CapsLock = 0x14,
Kana = 0x15,
Pause = 0x13,
CapsLock = 0x14,
Kana = 0x15,
ImeOn = 0x16,
Kanji = 0x19,
Kanji = 0x19,
Escape = 0x1b,
ImeConvert = 0x1c,
ImeNoConvert = 0x1d,
ImeOff = 0x1a,
Escape = 0x1b,
ImeConvert = 0x1c,
ImeNoConvert = 0x1d,
Space = 0x20,
PageUp = 0x21,
PageDown = 0x22,
End = 0x23,
Home = 0x24,
Left = 0x25,
Up = 0x26,
Right = 0x27,
Down = 0x28,
Select = 0x29,
Print = 0x2a,
Execute = 0x2b,
PrintScreen = 0x2c,
Insert = 0x2d,
Delete = 0x2e,
Help = 0x2f,
D0 = 0x30,
D1 = 0x31,
D2 = 0x32,
D3 = 0x33,
D4 = 0x34,
D5 = 0x35,
D6 = 0x36,
D7 = 0x37,
D8 = 0x38,
D9 = 0x39,
Space = 0x20,
PageUp = 0x21,
PageDown = 0x22,
End = 0x23,
Home = 0x24,
Left = 0x25,
Up = 0x26,
Right = 0x27,
Down = 0x28,
Select = 0x29,
Print = 0x2a,
Execute = 0x2b,
PrintScreen = 0x2c,
Insert = 0x2d,
Delete = 0x2e,
Help = 0x2f,
D0 = 0x30,
D1 = 0x31,
D2 = 0x32,
D3 = 0x33,
D4 = 0x34,
D5 = 0x35,
D6 = 0x36,
D7 = 0x37,
D8 = 0x38,
D9 = 0x39,
A = 0x41,
B = 0x42,
C = 0x43,
D = 0x44,
E = 0x45,
F = 0x46,
G = 0x47,
H = 0x48,
I = 0x49,
J = 0x4a,
K = 0x4b,
L = 0x4c,
M = 0x4d,
N = 0x4e,
O = 0x4f,
P = 0x50,
Q = 0x51,
R = 0x52,
S = 0x53,
T = 0x54,
U = 0x55,
V = 0x56,
W = 0x57,
X = 0x58,
Y = 0x59,
Z = 0x5a,
LeftWindows = 0x5b,
RightWindows = 0x5c,
Apps = 0x5d,
A = 0x41,
B = 0x42,
C = 0x43,
D = 0x44,
E = 0x45,
F = 0x46,
G = 0x47,
H = 0x48,
I = 0x49,
J = 0x4a,
K = 0x4b,
L = 0x4c,
M = 0x4d,
N = 0x4e,
O = 0x4f,
P = 0x50,
Q = 0x51,
R = 0x52,
S = 0x53,
T = 0x54,
U = 0x55,
V = 0x56,
W = 0x57,
X = 0x58,
Y = 0x59,
Z = 0x5a,
LeftWindows = 0x5b,
RightWindows = 0x5c,
Apps = 0x5d,
Sleep = 0x5f,
NumPad0 = 0x60,
NumPad1 = 0x61,
NumPad2 = 0x62,
NumPad3 = 0x63,
NumPad4 = 0x64,
NumPad5 = 0x65,
NumPad6 = 0x66,
NumPad7 = 0x67,
NumPad8 = 0x68,
NumPad9 = 0x69,
Multiply = 0x6a,
Add = 0x6b,
Separator = 0x6c,
Subtract = 0x6d,
Sleep = 0x5f,
NumPad0 = 0x60,
NumPad1 = 0x61,
NumPad2 = 0x62,
NumPad3 = 0x63,
NumPad4 = 0x64,
NumPad5 = 0x65,
NumPad6 = 0x66,
NumPad7 = 0x67,
NumPad8 = 0x68,
NumPad9 = 0x69,
Multiply = 0x6a,
Add = 0x6b,
Separator = 0x6c,
Subtract = 0x6d,
Decimal = 0x6e,
Divide = 0x6f,
F1 = 0x70,
F2 = 0x71,
F3 = 0x72,
F4 = 0x73,
F5 = 0x74,
F6 = 0x75,
F7 = 0x76,
F8 = 0x77,
F9 = 0x78,
F10 = 0x79,
F11 = 0x7a,
F12 = 0x7b,
F13 = 0x7c,
F14 = 0x7d,
F15 = 0x7e,
F16 = 0x7f,
F17 = 0x80,
F18 = 0x81,
F19 = 0x82,
F20 = 0x83,
F21 = 0x84,
F22 = 0x85,
F23 = 0x86,
F24 = 0x87,
Decimal = 0x6e,
Divide = 0x6f,
F1 = 0x70,
F2 = 0x71,
F3 = 0x72,
F4 = 0x73,
F5 = 0x74,
F6 = 0x75,
F7 = 0x76,
F8 = 0x77,
F9 = 0x78,
F10 = 0x79,
F11 = 0x7a,
F12 = 0x7b,
F13 = 0x7c,
F14 = 0x7d,
F15 = 0x7e,
F16 = 0x7f,
F17 = 0x80,
F18 = 0x81,
F19 = 0x82,
F20 = 0x83,
F21 = 0x84,
F22 = 0x85,
F23 = 0x86,
F24 = 0x87,
NumLock = 0x90,
Scroll = 0x91,
NumLock = 0x90,
Scroll = 0x91,
LeftShift = 0xa0,
RightShift = 0xa1,
LeftControl = 0xa2,
RightControl = 0xa3,
LeftAlt = 0xa4,
RightAlt = 0xa5,
BrowserBack = 0xa6,
BrowserForward = 0xa7,
BrowserRefresh = 0xa8,
BrowserStop = 0xa9,
BrowserSearch = 0xaa,
BrowserFavorites = 0xab,
BrowserHome = 0xac,
VolumeMute = 0xad,
VolumeDown = 0xae,
VolumeUp = 0xaf,
MediaNextTrack = 0xb0,
MediaPreviousTrack = 0xb1,
MediaStop = 0xb2,
MediaPlayPause = 0xb3,
LaunchMail = 0xb4,
SelectMedia = 0xb5,
LaunchApplication1 = 0xb6,
LaunchApplication2 = 0xb7,
LeftShift = 0xa0,
RightShift = 0xa1,
LeftControl = 0xa2,
RightControl = 0xa3,
LeftAlt = 0xa4,
RightAlt = 0xa5,
BrowserBack = 0xa6,
BrowserForward = 0xa7,
BrowserRefresh = 0xa8,
BrowserStop = 0xa9,
BrowserSearch = 0xaa,
BrowserFavorites = 0xab,
BrowserHome = 0xac,
VolumeMute = 0xad,
VolumeDown = 0xae,
VolumeUp = 0xaf,
MediaNextTrack = 0xb0,
MediaPreviousTrack = 0xb1,
MediaStop = 0xb2,
MediaPlayPause = 0xb3,
LaunchMail = 0xb4,
SelectMedia = 0xb5,
LaunchApplication1 = 0xb6,
LaunchApplication2 = 0xb7,
OemSemicolon = 0xba,
OemPlus = 0xbb,
OemComma = 0xbc,
OemMinus = 0xbd,
OemPeriod = 0xbe,
OemQuestion = 0xbf,
OemTilde = 0xc0,
OemSemicolon = 0xba,
OemPlus = 0xbb,
OemComma = 0xbc,
OemMinus = 0xbd,
OemPeriod = 0xbe,
OemQuestion = 0xbf,
OemTilde = 0xc0,
OemOpenBrackets = 0xdb,
OemPipe = 0xdc,
OemCloseBrackets = 0xdd,
OemQuotes = 0xde,
Oem8 = 0xdf,
OemOpenBrackets = 0xdb,
OemPipe = 0xdc,
OemCloseBrackets = 0xdd,
OemQuotes = 0xde,
Oem8 = 0xdf,
OemBackslash = 0xe2,
OemBackslash = 0xe2,
ProcessKey = 0xe5,
ProcessKey = 0xe5,
OemCopy = 0xf2,
OemAuto = 0xf3,
OemEnlW = 0xf4,
OemCopy = 0xf2,
OemAuto = 0xf3,
OemEnlW = 0xf4,
Attn = 0xf6,
Crsel = 0xf7,
Exsel = 0xf8,
EraseEof = 0xf9,
Play = 0xfa,
Zoom = 0xfb,
Attn = 0xf6,
Crsel = 0xf7,
Exsel = 0xf8,
EraseEof = 0xf9,
Play = 0xfa,
Zoom = 0xfb,
Pa1 = 0xfd,
OemClear = 0xfe,
Pa1 = 0xfd,
OemClear = 0xfe,
};
struct State
@ -229,10 +238,11 @@ namespace DirectX
bool Pause : 1; // VK_PAUSE, 0x13
bool CapsLock : 1; // VK_CAPITAL, 0x14
bool Kana : 1; // VK_KANA, 0x15
bool Reserved4 : 2;
bool ImeOn : 1; // VK_IME_ON, 0x16
bool Reserved4 : 1;
bool Reserved5 : 1;
bool Kanji : 1; // VK_KANJI, 0x19
bool Reserved6 : 1;
bool ImeOff : 1; // VK_IME_OFF, 0X1A
bool Escape : 1; // VK_ESCAPE, 0x1B
bool ImeConvert : 1; // VK_CONVERT, 0x1C
bool ImeNoConvert : 1; // VK_NONCONVERT, 0x1D
@ -402,14 +412,14 @@ namespace DirectX
bool Reserved25 : 1;
bool Pa1 : 1; // VK_PA1, 0xFD
bool OemClear : 1; // VK_OEM_CLEAR, 0xFE
bool Reserved26: 1;
bool Reserved26 : 1;
bool __cdecl IsKeyDown(Keys key) const noexcept
{
if (key <= 0xfe)
{
auto ptr = reinterpret_cast<const uint32_t*>(this);
unsigned int bf = 1u << (key & 0x1f);
const unsigned int bf = 1u << (key & 0x1f);
return (ptr[(key >> 5)] & bf) != 0;
}
return false;
@ -420,7 +430,7 @@ namespace DirectX
if (key <= 0xfe)
{
auto ptr = reinterpret_cast<const uint32_t*>(this);
unsigned int bf = 1u << (key & 0x1f);
const unsigned int bf = 1u << (key & 0x1f);
return (ptr[(key >> 5)] & bf) == 0;
}
return false;
@ -433,7 +443,7 @@ namespace DirectX
State released;
State pressed;
#pragma prefast(suppress: 26495, "Reset() performs the initialization")
#pragma prefast(suppress: 26495, "Reset() performs the initialization")
KeyboardStateTracker() noexcept { Reset(); }
void __cdecl Update(const State& state) noexcept;
@ -458,11 +468,7 @@ namespace DirectX
// Feature detection
bool __cdecl IsConnected() const;
#if (!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)) && defined(WM_USER)
static void __cdecl ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam);
#endif
#if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) || (defined(_XBOX_ONE) && defined(_TITLE))
#ifdef USING_COREWINDOW
void __cdecl SetWindow(ABI::Windows::UI::Core::ICoreWindow* window);
#ifdef __cplusplus_winrt
void __cdecl SetWindow(Windows::UI::Core::CoreWindow^ window)
@ -478,7 +484,9 @@ namespace DirectX
SetWindow(reinterpret_cast<ABI::Windows::UI::Core::ICoreWindow*>(winrt::get_abi(window)));
}
#endif
#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP
#elif defined(WM_USER)
static void __cdecl ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam);
#endif
// Singleton
static Keyboard& __cdecl Get();

Просмотреть файл

@ -1,7 +1,7 @@
//--------------------------------------------------------------------------------------
// File: Mouse.h
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//
// http://go.microsoft.com/fwlink/?LinkId=248929
@ -10,9 +10,15 @@
#pragma once
#if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) || (defined(_XBOX_ONE) && defined(_TITLE))
#ifndef USING_COREWINDOW
#define USING_COREWINDOW
#endif
#endif
#include <memory>
#if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) || (defined(_XBOX_ONE) && defined(_TITLE) && (_XDK_VER >= 0x42D907D1))
#ifdef USING_COREWINDOW
namespace ABI { namespace Windows { namespace UI { namespace Core { struct ICoreWindow; } } } }
#endif
@ -28,8 +34,9 @@ namespace DirectX
{
public:
Mouse() noexcept(false);
Mouse(Mouse&& moveFrom) noexcept;
Mouse& operator= (Mouse&& moveFrom) noexcept;
Mouse(Mouse&&) noexcept;
Mouse& operator= (Mouse&&) noexcept;
Mouse(Mouse const&) = delete;
Mouse& operator=(Mouse const&) = delete;
@ -72,7 +79,7 @@ namespace DirectX
ButtonState xButton1;
ButtonState xButton2;
#pragma prefast(suppress: 26495, "Reset() performs the initialization")
#pragma prefast(suppress: 26495, "Reset() performs the initialization")
ButtonStateTracker() noexcept { Reset(); }
void __cdecl Update(const State& state) noexcept;
@ -101,17 +108,7 @@ namespace DirectX
bool __cdecl IsVisible() const noexcept;
void __cdecl SetVisible(bool visible);
#ifdef WM_USER
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
void __cdecl SetWindow(HWND window);
static void __cdecl ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam);
#elif (WINAPI_FAMILY == WINAPI_FAMILY_GAMES)
static void __cdecl ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam);
static void __cdecl SetResolution(bool use4k);
#endif
#endif
#if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) || (defined(_XBOX_ONE) && defined(_TITLE) && (_XDK_VER >= 0x42D907D1))
#ifdef USING_COREWINDOW
void __cdecl SetWindow(ABI::Windows::UI::Core::ICoreWindow* window);
#ifdef __cplusplus_winrt
void __cdecl SetWindow(Windows::UI::Core::CoreWindow^ window)
@ -129,7 +126,14 @@ namespace DirectX
#endif
static void __cdecl SetDpi(float dpi);
#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP
#elif defined(WM_USER)
void __cdecl SetWindow(HWND window);
static void __cdecl ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam);
#ifdef _GAMING_XBOX
static void __cdecl SetResolution(float scale);
#endif
#endif
// Singleton
static Mouse& __cdecl Get();

Просмотреть файл

@ -1,7 +1,7 @@
//--------------------------------------------------------------------------------------
// File: Keyboard.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//
// http://go.microsoft.com/fwlink/?LinkId=248929
@ -31,7 +31,7 @@ namespace
auto ptr = reinterpret_cast<uint32_t*>(&state);
unsigned int bf = 1u << (key & 0x1f);
const unsigned int bf = 1u << (key & 0x1f);
ptr[(key >> 5)] |= bf;
}
@ -42,13 +42,14 @@ namespace
auto ptr = reinterpret_cast<uint32_t*>(&state);
unsigned int bf = 1u << (key & 0x1f);
const unsigned int bf = 1u << (key & 0x1f);
ptr[(key >> 5)] &= ~bf;
}
}
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_GAMES)
#pragma region Implementations
#if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_GAMES)) || (defined(_GAMING_DESKTOP) && (_GRDK_EDITION >= 220600))
#include <GameInput.h>
@ -67,7 +68,7 @@ public:
{
if (s_keyboard)
{
throw std::exception("Keyboard is a singleton");
throw std::logic_error("Keyboard is a singleton");
}
s_keyboard = this;
@ -96,10 +97,9 @@ public:
{
if (mGameInput)
{
HRESULT hr = mGameInput->UnregisterCallback(mDeviceToken, UINT64_MAX);
if (FAILED(hr))
if (!mGameInput->UnregisterCallback(mDeviceToken, UINT64_MAX))
{
DebugTrace("ERROR: GameInput::UnregisterCallback [keyboard] failed (%08X)", static_cast<unsigned int>(hr));
DebugTrace("ERROR: GameInput::UnregisterCallback [keyboard] failed");
}
}
@ -120,6 +120,18 @@ public:
for (size_t j = 0; j < readCount; ++j)
{
int vk = static_cast<int>(mKeyState[j].virtualKey);
// Workaround for known issues with VK_RSHIFT and VK_NUMLOCK
if (vk == 0)
{
switch (mKeyState[j].scanCode)
{
case 0xe036: vk = VK_RSHIFT; break;
case 0xe045: vk = VK_NUMLOCK; break;
default: break;
}
}
KeyDown(vk, state);
}
}
@ -172,150 +184,13 @@ private:
Keyboard::Impl* Keyboard::Impl::s_keyboard = nullptr;
#elif !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
//======================================================================================
// Win32 desktop implementation
//======================================================================================
//
// For a Win32 desktop application, call this function from your Window Message Procedure
//
// LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
// {
// switch (message)
// {
//
// case WM_ACTIVATEAPP:
// Keyboard::ProcessMessage(message, wParam, lParam);
// break;
//
// case WM_KEYDOWN:
// case WM_SYSKEYDOWN:
// case WM_KEYUP:
// case WM_SYSKEYUP:
// Keyboard::ProcessMessage(message, wParam, lParam);
// break;
//
// }
// }
//
class Keyboard::Impl
void Keyboard::ProcessMessage(UINT, WPARAM, LPARAM)
{
public:
Impl(Keyboard* owner) :
mState{},
mOwner(owner)
{
if (s_keyboard)
{
throw std::exception("Keyboard is a singleton");
}
s_keyboard = this;
}
Impl(Impl&&) = default;
Impl& operator= (Impl&&) = default;
Impl(Impl const&) = delete;
Impl& operator= (Impl const&) = delete;
~Impl()
{
s_keyboard = nullptr;
}
void GetState(State& state) const
{
memcpy(&state, &mState, sizeof(State));
}
void Reset() noexcept
{
memset(&mState, 0, sizeof(State));
}
bool IsConnected() const
{
return true;
}
State mState;
Keyboard* mOwner;
static Keyboard::Impl* s_keyboard;
};
Keyboard::Impl* Keyboard::Impl::s_keyboard = nullptr;
void Keyboard::ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
auto pImpl = Impl::s_keyboard;
if (!pImpl)
return;
bool down = false;
switch (message)
{
case WM_ACTIVATEAPP:
pImpl->Reset();
return;
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
down = true;
break;
case WM_KEYUP:
case WM_SYSKEYUP:
break;
default:
return;
}
int vk = static_cast<int>(wParam);
switch (vk)
{
case VK_SHIFT:
vk = static_cast<int>(
MapVirtualKey((static_cast<UINT>(lParam) & 0x00ff0000) >> 16u,
MAPVK_VSC_TO_VK_EX));
if (!down)
{
// Workaround to ensure left vs. right shift get cleared when both were pressed at same time
KeyUp(VK_LSHIFT, pImpl->mState);
KeyUp(VK_RSHIFT, pImpl->mState);
}
break;
case VK_CONTROL:
vk = (static_cast<UINT>(lParam) & 0x01000000) ? VK_RCONTROL : VK_LCONTROL;
break;
case VK_MENU:
vk = (static_cast<UINT>(lParam) & 0x01000000) ? VK_RMENU : VK_LMENU;
break;
}
if (down)
{
KeyDown(vk, pImpl->mState);
}
else
{
KeyUp(vk, pImpl->mState);
}
// GameInput for Keyboard doesn't require Win32 messages, but this simplifies integration.
}
#else
#elif defined(USING_COREWINDOW)
//======================================================================================
// Windows Store or Universal Windows Platform (UWP) app implementation
@ -343,7 +218,7 @@ public:
{
if (s_keyboard)
{
throw std::exception("Keyboard is a singleton");
throw std::logic_error("Keyboard is a singleton");
}
s_keyboard = this;
@ -440,19 +315,19 @@ private:
HRESULT hr = mWindow->get_Dispatcher(dispatcher.GetAddressOf());
ThrowIfFailed(hr);
(void)mWindow->remove_Activated(mActivatedToken);
std::ignore = mWindow->remove_Activated(mActivatedToken);
mActivatedToken.value = 0;
ComPtr<ICoreAcceleratorKeys> keys;
hr = dispatcher.As(&keys);
ThrowIfFailed(hr);
(void)keys->remove_AcceleratorKeyActivated(mAcceleratorKeyToken);
std::ignore = keys->remove_AcceleratorKeyActivated(mAcceleratorKeyToken);
mAcceleratorKeyToken.value = 0;
}
}
static HRESULT Activated(IInspectable *, ABI::Windows::UI::Core::IWindowActivatedEventArgs*)
static HRESULT Activated(IInspectable*, ABI::Windows::UI::Core::IWindowActivatedEventArgs*)
{
auto pImpl = Impl::s_keyboard;
@ -464,7 +339,7 @@ private:
return S_OK;
}
static HRESULT AcceleratorKeyEvent(IInspectable *, ABI::Windows::UI::Core::IAcceleratorKeyEventArgs* args)
static HRESULT AcceleratorKeyEvent(IInspectable*, ABI::Windows::UI::Core::IAcceleratorKeyEventArgs* args)
{
using namespace ABI::Windows::System;
using namespace ABI::Windows::UI::Core;
@ -482,17 +357,17 @@ private:
switch (evtType)
{
case CoreAcceleratorKeyEventType_KeyDown:
case CoreAcceleratorKeyEventType_SystemKeyDown:
down = true;
break;
case CoreAcceleratorKeyEventType_KeyDown:
case CoreAcceleratorKeyEventType_SystemKeyDown:
down = true;
break;
case CoreAcceleratorKeyEventType_KeyUp:
case CoreAcceleratorKeyEventType_SystemKeyUp:
break;
case CoreAcceleratorKeyEventType_KeyUp:
case CoreAcceleratorKeyEventType_SystemKeyUp:
break;
default:
return S_OK;
default:
return S_OK;
}
CorePhysicalKeyStatus status;
@ -507,23 +382,23 @@ private:
switch (vk)
{
case VK_SHIFT:
vk = (status.ScanCode == 0x36) ? VK_RSHIFT : VK_LSHIFT;
if (!down)
{
// Workaround to ensure left vs. right shift get cleared when both were pressed at same time
KeyUp(VK_LSHIFT, pImpl->mState);
KeyUp(VK_RSHIFT, pImpl->mState);
}
break;
case VK_SHIFT:
vk = (status.ScanCode == 0x36) ? VK_RSHIFT : VK_LSHIFT;
if (!down)
{
// Workaround to ensure left vs. right shift get cleared when both were pressed at same time
KeyUp(VK_LSHIFT, pImpl->mState);
KeyUp(VK_RSHIFT, pImpl->mState);
}
break;
case VK_CONTROL:
vk = (status.IsExtendedKey) ? VK_RCONTROL : VK_LCONTROL;
break;
case VK_CONTROL:
vk = (status.IsExtendedKey) ? VK_RCONTROL : VK_LCONTROL;
break;
case VK_MENU:
vk = (status.IsExtendedKey) ? VK_RMENU : VK_LMENU;
break;
case VK_MENU:
vk = (status.IsExtendedKey) ? VK_RMENU : VK_LMENU;
break;
}
if (down)
@ -548,7 +423,151 @@ void Keyboard::SetWindow(ABI::Windows::UI::Core::ICoreWindow* window)
pImpl->SetWindow(window);
}
#else
//======================================================================================
// Win32 desktop implementation
//======================================================================================
//
// For a Win32 desktop application, call this function from your Window Message Procedure
//
// LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
// {
// switch (message)
// {
//
// case WM_ACTIVATE:
// case WM_ACTIVATEAPP:
// Keyboard::ProcessMessage(message, wParam, lParam);
// break;
//
// case WM_KEYDOWN:
// case WM_SYSKEYDOWN:
// case WM_KEYUP:
// case WM_SYSKEYUP:
// Keyboard::ProcessMessage(message, wParam, lParam);
// break;
//
// }
// }
//
class Keyboard::Impl
{
public:
Impl(Keyboard* owner) :
mState{},
mOwner(owner)
{
if (s_keyboard)
{
throw std::logic_error("Keyboard is a singleton");
}
s_keyboard = this;
}
Impl(Impl&&) = default;
Impl& operator= (Impl&&) = default;
Impl(Impl const&) = delete;
Impl& operator= (Impl const&) = delete;
~Impl()
{
s_keyboard = nullptr;
}
void GetState(State& state) const
{
memcpy(&state, &mState, sizeof(State));
}
void Reset() noexcept
{
memset(&mState, 0, sizeof(State));
}
bool IsConnected() const
{
return true;
}
State mState;
Keyboard* mOwner;
static Keyboard::Impl* s_keyboard;
};
Keyboard::Impl* Keyboard::Impl::s_keyboard = nullptr;
void Keyboard::ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
auto pImpl = Impl::s_keyboard;
if (!pImpl)
return;
bool down = false;
switch (message)
{
case WM_ACTIVATE:
case WM_ACTIVATEAPP:
pImpl->Reset();
return;
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
down = true;
break;
case WM_KEYUP:
case WM_SYSKEYUP:
break;
default:
return;
}
int vk = LOWORD(wParam);
// We want to distinguish left and right shift/ctrl/alt keys
switch (vk)
{
case VK_SHIFT:
case VK_CONTROL:
case VK_MENU:
{
if (vk == VK_SHIFT && !down)
{
// Workaround to ensure left vs. right shift get cleared when both were pressed at same time
KeyUp(VK_LSHIFT, pImpl->mState);
KeyUp(VK_RSHIFT, pImpl->mState);
}
bool isExtendedKey = (HIWORD(lParam) & KF_EXTENDED) == KF_EXTENDED;
int scanCode = LOBYTE(HIWORD(lParam)) | (isExtendedKey ? 0xe000 : 0);
vk = LOWORD(MapVirtualKeyW(static_cast<UINT>(scanCode), MAPVK_VSC_TO_VK_EX));
}
break;
}
if (down)
{
KeyDown(vk, pImpl->mState);
}
else
{
KeyUp(vk, pImpl->mState);
}
}
#endif
#pragma endregion
#pragma warning( disable : 4355 )
@ -577,9 +596,7 @@ Keyboard& Keyboard::operator= (Keyboard&& moveFrom) noexcept
// Public destructor.
Keyboard::~Keyboard()
{
}
Keyboard::~Keyboard() = default;
Keyboard::State Keyboard::GetState() const
@ -604,7 +621,7 @@ bool Keyboard::IsConnected() const
Keyboard& Keyboard::Get()
{
if (!Impl::s_keyboard || !Impl::s_keyboard->mOwner)
throw std::exception("Keyboard is a singleton");
throw std::logic_error("Keyboard singleton not created");
return *Impl::s_keyboard->mOwner;
}
@ -635,7 +652,6 @@ void Keyboard::KeyboardStateTracker::Update(const State& state) noexcept
lastState = state;
}
void Keyboard::KeyboardStateTracker::Reset() noexcept
{
memset(this, 0, sizeof(KeyboardStateTracker));

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Game configVersion="0">
<Game configVersion="1">
<Identity Name="41336MicrosoftATG.XboxLiveE2E" Publisher="CN=A4954634-DF4B-47C7-AB70-D3215D246AF1" Version="1.7.0.0" />

Двоичные данные
Tests/GDK/ManualTest.GDK/Assets/LargeLogo.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 88 KiB

Двоичные данные
Tests/GDK/ManualTest.GDK/Assets/Logo.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 54 KiB

Просмотреть файл

@ -0,0 +1,10 @@
#ITEM,ID,X,Y,DX,DY,PARAMETERS
OVERLAY,2000,0,0,1920,1080
LEGEND,2001,82,850,525,300,[DPad] or Arrows - Select a scenario|[A] or Enter - Start a scenario|[Menu] or Tab - Sign in|[View] or Esc - Exit
BUTTON,2101,82,300,525,50,AddUser
BUTTON,2102,82,375,525,50,Get Achievement Status ID = 1
BUTTON,2103,82,450,525,50,Complete Achievement ID = 1
BUTTON,2104,82,525,525,50,Get Achievement Status ID = 2
BUTTON,2105,82,600,525,50,Set Achievement ID = 2 -> 25%
BUTTON,2106,82,675,525,50,Set Achievement ID = 2 -> 50%
BUTTON,2107,82,750,525,50,Set Achievement ID = 2 -> 100%
1 #ITEM,ID,X,Y,DX,DY,PARAMETERS
2 OVERLAY,2000,0,0,1920,1080
3 LEGEND,2001,82,850,525,300,[DPad] or Arrows - Select a scenario|[A] or Enter - Start a scenario|[Menu] or Tab - Sign in|[View] or Esc - Exit
4 BUTTON,2101,82,300,525,50,AddUser
5 BUTTON,2102,82,375,525,50,Get Achievement Status ID = 1
6 BUTTON,2103,82,450,525,50,Complete Achievement ID = 1
7 BUTTON,2104,82,525,525,50,Get Achievement Status ID = 2
8 BUTTON,2105,82,600,525,50,Set Achievement ID = 2 -> 25%
9 BUTTON,2106,82,675,525,50,Set Achievement ID = 2 -> 50%
10 BUTTON,2107,82,750,525,50,Set Achievement ID = 2 -> 100%

Двоичные данные
Tests/GDK/ManualTest.GDK/Assets/SmallLogo.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 30 KiB

Двоичные данные
Tests/GDK/ManualTest.GDK/Assets/SplashScreen.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 MiB

Двоичные данные
Tests/GDK/ManualTest.GDK/Assets/StoreLogo.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 19 KiB

Просмотреть файл

@ -0,0 +1,809 @@
//
// DeviceResources.cpp - A wrapper for the Direct3D 12/12.X device and swapchain
//
#include "pch.h"
#include "DeviceResources.h"
using namespace DirectX;
using namespace DX;
using Microsoft::WRL::ComPtr;
#ifdef _GAMING_DESKTOP
#ifdef __clang__
#pragma clang diagnostic ignored "-Wcovered-switch-default"
#pragma clang diagnostic ignored "-Wswitch-enum"
#endif
#pragma warning(disable : 4061)
namespace
{
inline DXGI_FORMAT NoSRGB(DXGI_FORMAT fmt) noexcept
{
switch (fmt)
{
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM;
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM;
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_UNORM;
default: return fmt;
}
}
}
#endif
// Constructor for DeviceResources.
DeviceResources::DeviceResources(
DXGI_FORMAT backBufferFormat,
DXGI_FORMAT depthBufferFormat,
UINT backBufferCount) noexcept(false) :
m_backBufferIndex(0),
m_fenceValues{},
#ifdef _GAMING_XBOX
m_framePipelineToken{},
#endif
m_rtvDescriptorSize(0),
m_screenViewport{},
m_scissorRect{},
m_backBufferFormat(backBufferFormat),
m_depthBufferFormat(depthBufferFormat),
m_backBufferCount(backBufferCount),
m_window(nullptr),
m_d3dFeatureLevel(D3D_FEATURE_LEVEL_11_0),
m_outputSize{ 0, 0, 1, 1 },
m_deviceNotify(nullptr)
{
if (backBufferCount < 2 || backBufferCount > MAX_BACK_BUFFER_COUNT)
{
throw std::out_of_range("invalid backBufferCount");
}
}
// Destructor for DeviceResources.
DeviceResources::~DeviceResources()
{
// Ensure that the GPU is no longer referencing resources that are about to be destroyed.
WaitForGpu();
#ifdef _GAMING_XBOX
// Ensure we present a blank screen before cleaning up resources.
if (m_commandQueue)
{
(void)m_commandQueue->PresentX(0, nullptr, nullptr);
}
#endif
}
// Configures the Direct3D device, and stores handles to it and the device context.
void DeviceResources::CreateDeviceResources()
{
#ifdef _GAMING_XBOX
// Create the DX12 API device object.
D3D12XBOX_CREATE_DEVICE_PARAMETERS params = {};
params.Version = D3D12_SDK_VERSION;
#if defined(_DEBUG)
// Enable the debug layer.
params.ProcessDebugFlags = D3D12_PROCESS_DEBUG_FLAG_DEBUG_LAYER_ENABLED;
#elif defined(PROFILE)
// Enable the instrumented driver.
params.ProcessDebugFlags = D3D12XBOX_PROCESS_DEBUG_FLAG_INSTRUMENTED;
#endif
params.GraphicsCommandQueueRingSizeBytes = static_cast<UINT>(D3D12XBOX_DEFAULT_SIZE_BYTES);
params.GraphicsScratchMemorySizeBytes = static_cast<UINT>(D3D12XBOX_DEFAULT_SIZE_BYTES);
params.ComputeScratchMemorySizeBytes = static_cast<UINT>(D3D12XBOX_DEFAULT_SIZE_BYTES);
HRESULT hr = D3D12XboxCreateDevice(
nullptr,
&params,
IID_GRAPHICS_PPV_ARGS(m_d3dDevice.ReleaseAndGetAddressOf()));
#ifdef _DEBUG
if (hr == D3D12_ERROR_DRIVER_VERSION_MISMATCH)
{
#ifdef _GAMING_XBOX_SCARLETT
OutputDebugStringA("ERROR: Running a d3d12_xs.lib (Xbox Series X|S) linked binary on an Xbox One is not supported\n");
#else
OutputDebugStringA("ERROR: Running a d3d12_x.lib (Xbox One) linked binary on a Xbox Series X|S in 'Scarlett' mode is not supported\n");
#endif
}
#endif
ThrowIfFailed(hr);
m_d3dDevice->SetName(L"DeviceResources");
m_d3dFeatureLevel = D3D_FEATURE_LEVEL_12_0;
#else // _GAMING_DESKTOP
DWORD dxgiFactoryFlags = 0;
#if defined(_DEBUG)
// Enable the debug layer (requires the Graphics Tools "optional feature").
//
// NOTE: Enabling the debug layer after device creation will invalidate the active device.
{
ComPtr<ID3D12Debug> debugController;
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(debugController.GetAddressOf()))))
{
debugController->EnableDebugLayer();
}
else
{
OutputDebugStringA("WARNING: Direct3D Debug Device is not available\n");
}
ComPtr<IDXGIInfoQueue> dxgiInfoQueue;
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(dxgiInfoQueue.GetAddressOf()))))
{
dxgiFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true);
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true);
DXGI_INFO_QUEUE_MESSAGE_ID hide[] =
{
80 /* IDXGISwapChain::GetContainingOutput: The swapchain's adapter does not control the output on which the swapchain's window resides. */,
};
DXGI_INFO_QUEUE_FILTER filter = {};
filter.DenyList.NumIDs = static_cast<UINT>(std::size(hide));
filter.DenyList.pIDList = hide;
dxgiInfoQueue->AddStorageFilterEntries(DXGI_DEBUG_DXGI, &filter);
}
}
#endif
ThrowIfFailed(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(m_dxgiFactory.ReleaseAndGetAddressOf())));
ComPtr<IDXGIAdapter1> adapter;
GetAdapter(adapter.GetAddressOf());
// Create the DX12 API device object.
HRESULT hr = D3D12CreateDevice(
adapter.Get(),
D3D_FEATURE_LEVEL_11_0,
IID_PPV_ARGS(m_d3dDevice.ReleaseAndGetAddressOf())
);
ThrowIfFailed(hr);
m_d3dDevice->SetName(L"DeviceResources");
#ifndef NDEBUG
// Configure debug device (if active).
ComPtr<ID3D12InfoQueue> d3dInfoQueue;
if (SUCCEEDED(m_d3dDevice.As(&d3dInfoQueue)))
{
#ifdef _DEBUG
d3dInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
d3dInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true);
#endif
D3D12_MESSAGE_ID hide[] =
{
D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE,
D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE,
// Workarounds for debug layer issues on hybrid-graphics systems
D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE,
D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_COMMAND_LIST_TYPE,
};
D3D12_INFO_QUEUE_FILTER filter = {};
filter.DenyList.NumIDs = static_cast<UINT>(std::size(hide));
filter.DenyList.pIDList = hide;
d3dInfoQueue->AddStorageFilterEntries(&filter);
}
#endif
// Determine maximum supported feature level for this device
static const D3D_FEATURE_LEVEL s_featureLevels[] =
{
#if defined(NTDDI_WIN10_FE) && (NTDDI_VERSION >= NTDDI_WIN10_FE)
D3D_FEATURE_LEVEL_12_2,
#endif
D3D_FEATURE_LEVEL_12_1,
D3D_FEATURE_LEVEL_12_0,
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
};
D3D12_FEATURE_DATA_FEATURE_LEVELS featLevels =
{
static_cast<UINT>(std::size(s_featureLevels)), s_featureLevels, D3D_FEATURE_LEVEL_11_0
};
hr = m_d3dDevice->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &featLevels, sizeof(featLevels));
if (SUCCEEDED(hr))
{
m_d3dFeatureLevel = featLevels.MaxSupportedFeatureLevel;
}
else
{
m_d3dFeatureLevel = D3D_FEATURE_LEVEL_11_0;
}
#endif
// Create the command queue.
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
ThrowIfFailed(m_d3dDevice->CreateCommandQueue(&queueDesc, IID_GRAPHICS_PPV_ARGS(m_commandQueue.ReleaseAndGetAddressOf())));
m_commandQueue->SetName(L"DeviceResources");
// Create descriptor heaps for render target views and depth stencil views.
D3D12_DESCRIPTOR_HEAP_DESC rtvDescriptorHeapDesc = {};
rtvDescriptorHeapDesc.NumDescriptors = m_backBufferCount;
rtvDescriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&rtvDescriptorHeapDesc, IID_GRAPHICS_PPV_ARGS(m_rtvDescriptorHeap.ReleaseAndGetAddressOf())));
m_rtvDescriptorHeap->SetName(L"DeviceResources");
m_rtvDescriptorSize = m_d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
if (m_depthBufferFormat != DXGI_FORMAT_UNKNOWN)
{
D3D12_DESCRIPTOR_HEAP_DESC dsvDescriptorHeapDesc = {};
dsvDescriptorHeapDesc.NumDescriptors = 1;
dsvDescriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&dsvDescriptorHeapDesc, IID_GRAPHICS_PPV_ARGS(m_dsvDescriptorHeap.ReleaseAndGetAddressOf())));
m_dsvDescriptorHeap->SetName(L"DeviceResources");
}
// Create a command allocator for each back buffer that will be rendered to.
for (UINT n = 0; n < m_backBufferCount; n++)
{
ThrowIfFailed(m_d3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_GRAPHICS_PPV_ARGS(m_commandAllocators[n].ReleaseAndGetAddressOf())));
wchar_t name[25] = {};
swprintf_s(name, L"Render target %u", n);
m_commandAllocators[n]->SetName(name);
}
// Create a command list for recording graphics commands.
ThrowIfFailed(m_d3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocators[0].Get(), nullptr, IID_GRAPHICS_PPV_ARGS(m_commandList.ReleaseAndGetAddressOf())));
ThrowIfFailed(m_commandList->Close());
m_commandList->SetName(L"DeviceResources");
// Create a fence for tracking GPU execution progress.
ThrowIfFailed(m_d3dDevice->CreateFence(m_fenceValues[m_backBufferIndex], D3D12_FENCE_FLAG_NONE, IID_GRAPHICS_PPV_ARGS(m_fence.ReleaseAndGetAddressOf())));
m_fenceValues[m_backBufferIndex]++;
m_fence->SetName(L"DeviceResources");
m_fenceEvent.Attach(CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE));
if (!m_fenceEvent.IsValid())
{
throw std::system_error(std::error_code(static_cast<int>(GetLastError()), std::system_category()), "CreateEventEx");
}
#ifdef _GAMING_XBOX
RegisterFrameEvents();
#endif
}
// These resources need to be recreated every time the window size is changed.
void DeviceResources::CreateWindowSizeDependentResources()
{
if (!m_window)
{
throw std::logic_error("Call SetWindow with a valid Win32 window handle");
}
// Wait until all previous GPU work is complete.
WaitForGpu();
#ifdef _GAMING_XBOX
// Ensure we present a blank screen before cleaning up resources.
ThrowIfFailed(m_commandQueue->PresentX(0, nullptr, nullptr));
#endif
// Release resources that are tied to the swap chain and update fence values.
for (UINT n = 0; n < m_backBufferCount; n++)
{
m_renderTargets[n].Reset();
m_fenceValues[n] = m_fenceValues[m_backBufferIndex];
}
// Determine the render target size in pixels.
const UINT backBufferWidth = std::max<UINT>(static_cast<UINT>(m_outputSize.right - m_outputSize.left), 1u);
const UINT backBufferHeight = std::max<UINT>(static_cast<UINT>(m_outputSize.bottom - m_outputSize.top), 1u);
#ifdef _GAMING_XBOX
// Obtain the back buffers for this window which will be the final render targets
// and create render target views for each of them.
CD3DX12_HEAP_PROPERTIES swapChainHeapProperties(D3D12_HEAP_TYPE_DEFAULT);
D3D12_RESOURCE_DESC swapChainBufferDesc = CD3DX12_RESOURCE_DESC::Tex2D(
m_backBufferFormat,
backBufferWidth,
backBufferHeight,
1, // This resource has only one texture.
1 // Use a single mipmap level.
);
swapChainBufferDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
D3D12_CLEAR_VALUE swapChainOptimizedClearValue = {};
swapChainOptimizedClearValue.Format = m_backBufferFormat;
for (UINT n = 0; n < m_backBufferCount; n++)
{
ThrowIfFailed(m_d3dDevice->CreateCommittedResource(
&swapChainHeapProperties,
D3D12_HEAP_FLAG_ALLOW_DISPLAY,
&swapChainBufferDesc,
D3D12_RESOURCE_STATE_PRESENT,
&swapChainOptimizedClearValue,
IID_GRAPHICS_PPV_ARGS(m_renderTargets[n].GetAddressOf())));
wchar_t name[25] = {};
swprintf_s(name, L"Render target %u", n);
m_renderTargets[n]->SetName(name);
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {};
rtvDesc.Format = m_backBufferFormat;
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvDescriptor(
m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(),
static_cast<INT>(n), m_rtvDescriptorSize);
m_d3dDevice->CreateRenderTargetView(m_renderTargets[n].Get(), &rtvDesc, rtvDescriptor);
}
// Reset the index to the current back buffer.
m_backBufferIndex = 0;
#else // _GAMING_DESKTOP
DXGI_FORMAT backBufferFormat = NoSRGB(m_backBufferFormat);
// If the swap chain already exists, resize it, otherwise create one.
if (m_swapChain)
{
// If the swap chain already exists, resize it.
HRESULT hr = m_swapChain->ResizeBuffers(
m_backBufferCount,
backBufferWidth,
backBufferHeight,
backBufferFormat,
0
);
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
#ifdef _DEBUG
char buff[64] = {};
sprintf_s(buff, "Device Lost on ResizeBuffers: Reason code 0x%08X\n",
static_cast<unsigned int>((hr == DXGI_ERROR_DEVICE_REMOVED) ? m_d3dDevice->GetDeviceRemovedReason() : hr));
OutputDebugStringA(buff);
#endif
// If the device was removed for any reason, a new device and swap chain will need to be created.
HandleDeviceLost();
// Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method
// and correctly set up the new device.
return;
}
else
{
ThrowIfFailed(hr);
}
}
else
{
// Create a descriptor for the swap chain.
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
swapChainDesc.Width = backBufferWidth;
swapChainDesc.Height = backBufferHeight;
swapChainDesc.Format = backBufferFormat;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = m_backBufferCount;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsSwapChainDesc = {};
fsSwapChainDesc.Windowed = TRUE;
// Create a swap chain for the window.
ComPtr<IDXGISwapChain1> swapChain;
ThrowIfFailed(m_dxgiFactory->CreateSwapChainForHwnd(
m_commandQueue.Get(),
m_window,
&swapChainDesc,
&fsSwapChainDesc,
nullptr,
swapChain.GetAddressOf()
));
ThrowIfFailed(swapChain.As(&m_swapChain));
// This class does not support exclusive full-screen mode and prevents DXGI from responding to the ALT+ENTER shortcut
ThrowIfFailed(m_dxgiFactory->MakeWindowAssociation(m_window, DXGI_MWA_NO_ALT_ENTER));
}
// Obtain the back buffers for this window which will be the final render targets
// and create render target views for each of them.
for (UINT n = 0; n < m_backBufferCount; n++)
{
ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(m_renderTargets[n].GetAddressOf())));
wchar_t name[25] = {};
swprintf_s(name, L"Render target %u", n);
m_renderTargets[n]->SetName(name);
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {};
rtvDesc.Format = m_backBufferFormat;
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvDescriptor(
m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(),
static_cast<INT>(n), m_rtvDescriptorSize);
m_d3dDevice->CreateRenderTargetView(m_renderTargets[n].Get(), &rtvDesc, rtvDescriptor);
}
// Reset the index to the current back buffer.
m_backBufferIndex = m_swapChain->GetCurrentBackBufferIndex();
#endif
if (m_depthBufferFormat != DXGI_FORMAT_UNKNOWN)
{
// Allocate a 2-D surface as the depth/stencil buffer and create a depth/stencil view
// on this surface.
CD3DX12_HEAP_PROPERTIES depthHeapProperties(D3D12_HEAP_TYPE_DEFAULT);
D3D12_RESOURCE_DESC depthStencilDesc = CD3DX12_RESOURCE_DESC::Tex2D(
m_depthBufferFormat,
backBufferWidth,
backBufferHeight,
1, // This depth stencil view has only one texture.
1 // Use a single mipmap level.
);
depthStencilDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
depthOptimizedClearValue.Format = m_depthBufferFormat;
depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
depthOptimizedClearValue.DepthStencil.Stencil = 0;
ThrowIfFailed(m_d3dDevice->CreateCommittedResource(
&depthHeapProperties,
D3D12_HEAP_FLAG_NONE,
&depthStencilDesc,
D3D12_RESOURCE_STATE_DEPTH_WRITE,
&depthOptimizedClearValue,
IID_GRAPHICS_PPV_ARGS(m_depthStencil.ReleaseAndGetAddressOf())
));
m_depthStencil->SetName(L"Depth stencil");
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
dsvDesc.Format = m_depthBufferFormat;
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
m_d3dDevice->CreateDepthStencilView(m_depthStencil.Get(), &dsvDesc, m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
}
// Set the 3D rendering viewport and scissor rectangle to target the entire window.
m_screenViewport.TopLeftX = m_screenViewport.TopLeftY = 0.f;
m_screenViewport.Width = static_cast<float>(backBufferWidth);
m_screenViewport.Height = static_cast<float>(backBufferHeight);
m_screenViewport.MinDepth = D3D12_MIN_DEPTH;
m_screenViewport.MaxDepth = D3D12_MAX_DEPTH;
m_scissorRect.left = m_scissorRect.top = 0;
m_scissorRect.right = static_cast<LONG>(backBufferWidth);
m_scissorRect.bottom = static_cast<LONG>(backBufferHeight);
}
// This method is called when the Win32 window is created (or re-created).
void DeviceResources::SetWindow(HWND window, int width, int height) noexcept
{
m_window = window;
m_outputSize.left = m_outputSize.top = 0;
m_outputSize.right = width;
m_outputSize.bottom = height;
}
// This method is called when the Win32 window changes size.
bool DeviceResources::WindowSizeChanged(int width, int height)
{
RECT newRc;
newRc.left = newRc.top = 0;
newRc.right = width;
newRc.bottom = height;
if (newRc.left == m_outputSize.left
&& newRc.top == m_outputSize.top
&& newRc.right == m_outputSize.right
&& newRc.bottom == m_outputSize.bottom)
{
return false;
}
m_outputSize = newRc;
CreateWindowSizeDependentResources();
return true;
}
// Recreate all device resources and set them back to the current state.
void DeviceResources::HandleDeviceLost()
{
#ifdef _GAMING_DESKTOP
if (m_deviceNotify)
{
m_deviceNotify->OnDeviceLost();
}
for (UINT n = 0; n < m_backBufferCount; n++)
{
m_commandAllocators[n].Reset();
m_renderTargets[n].Reset();
}
m_depthStencil.Reset();
m_commandQueue.Reset();
m_commandList.Reset();
m_fence.Reset();
m_rtvDescriptorHeap.Reset();
m_dsvDescriptorHeap.Reset();
m_swapChain.Reset();
m_d3dDevice.Reset();
m_dxgiFactory.Reset();
#ifdef _DEBUG
{
ComPtr<IDXGIDebug1> dxgiDebug;
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug))))
{
dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL));
}
}
#endif
CreateDeviceResources();
CreateWindowSizeDependentResources();
if (m_deviceNotify)
{
m_deviceNotify->OnDeviceRestored();
}
#endif
}
// Prepare the command list and render target for rendering.
void DeviceResources::Prepare(D3D12_RESOURCE_STATES beforeState, D3D12_RESOURCE_STATES afterState)
{
#ifdef _GAMING_XBOX
// Wait until frame start is signaled
m_framePipelineToken = D3D12XBOX_FRAME_PIPELINE_TOKEN_NULL;
ThrowIfFailed(m_d3dDevice->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE, nullptr, D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE, &m_framePipelineToken));
#endif
// Reset command list and allocator.
ThrowIfFailed(m_commandAllocators[m_backBufferIndex]->Reset());
ThrowIfFailed(m_commandList->Reset(m_commandAllocators[m_backBufferIndex].Get(), nullptr));
if (beforeState != afterState)
{
// Transition the render target into the correct state to allow for drawing into it.
D3D12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_backBufferIndex].Get(),
beforeState, afterState);
m_commandList->ResourceBarrier(1, &barrier);
}
}
// Present the contents of the swap chain to the screen.
void DeviceResources::Present(D3D12_RESOURCE_STATES beforeState)
{
if (beforeState != D3D12_RESOURCE_STATE_PRESENT)
{
// Transition the render target to the state that allows it to be presented to the display.
D3D12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_backBufferIndex].Get(), beforeState, D3D12_RESOURCE_STATE_PRESENT);
m_commandList->ResourceBarrier(1, &barrier);
}
// Send the command list off to the GPU for processing.
ThrowIfFailed(m_commandList->Close());
m_commandQueue->ExecuteCommandLists(1, CommandListCast(m_commandList.GetAddressOf()));
#ifdef _GAMING_XBOX
// Present the backbuffer using the PresentX API.
D3D12XBOX_PRESENT_PLANE_PARAMETERS planeParameters = {};
planeParameters.Token = m_framePipelineToken;
planeParameters.ResourceCount = 1;
planeParameters.ppResources = m_renderTargets[m_backBufferIndex].GetAddressOf();
ThrowIfFailed(
m_commandQueue->PresentX(1, &planeParameters, nullptr)
);
// Xbox One apps do not need to handle DXGI_ERROR_DEVICE_REMOVED or DXGI_ERROR_DEVICE_RESET.
#else
// The first argument instructs DXGI to block until VSync, putting the application
// to sleep until the next VSync. This ensures we don't waste any cycles rendering
// frames that will never be displayed to the screen.
HRESULT hr = m_swapChain->Present(1, 0);
// If the device was reset we must completely reinitialize the renderer.
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
#ifdef _DEBUG
char buff[64] = {};
sprintf_s(buff, "Device Lost on Present: Reason code 0x%08X\n",
static_cast<unsigned int>((hr == DXGI_ERROR_DEVICE_REMOVED) ? m_d3dDevice->GetDeviceRemovedReason() : hr));
OutputDebugStringA(buff);
#endif
HandleDeviceLost();
}
else
{
ThrowIfFailed(hr);
}
#endif
MoveToNextFrame();
}
// Handle GPU suspend/resume
void DeviceResources::Suspend()
{
#ifdef _GAMING_XBOX
m_commandQueue->SuspendX(0);
#endif
}
void DeviceResources::Resume()
{
#ifdef _GAMING_XBOX
m_commandQueue->ResumeX();
RegisterFrameEvents();
#endif
}
// Wait for pending GPU work to complete.
void DeviceResources::WaitForGpu() noexcept
{
if (m_commandQueue && m_fence && m_fenceEvent.IsValid())
{
// Schedule a Signal command in the GPU queue.
UINT64 fenceValue = m_fenceValues[m_backBufferIndex];
if (SUCCEEDED(m_commandQueue->Signal(m_fence.Get(), fenceValue)))
{
// Wait until the Signal has been processed.
if (SUCCEEDED(m_fence->SetEventOnCompletion(fenceValue, m_fenceEvent.Get())))
{
WaitForSingleObjectEx(m_fenceEvent.Get(), INFINITE, FALSE);
// Increment the fence value for the current frame.
m_fenceValues[m_backBufferIndex]++;
}
}
}
}
// Prepare to render the next frame.
void DeviceResources::MoveToNextFrame()
{
// Schedule a Signal command in the queue.
const UINT64 currentFenceValue = m_fenceValues[m_backBufferIndex];
ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), currentFenceValue));
// Update the back buffer index.
#ifdef _GAMING_XBOX
m_backBufferIndex = (m_backBufferIndex + 1) % m_backBufferCount;
#else
m_backBufferIndex = m_swapChain->GetCurrentBackBufferIndex();
#endif
// If the next frame is not ready to be rendered yet, wait until it is ready.
if (m_fence->GetCompletedValue() < m_fenceValues[m_backBufferIndex])
{
ThrowIfFailed(m_fence->SetEventOnCompletion(m_fenceValues[m_backBufferIndex], m_fenceEvent.Get()));
WaitForSingleObjectEx(m_fenceEvent.Get(), INFINITE, FALSE);
}
// Set the fence value for the next frame.
m_fenceValues[m_backBufferIndex] = currentFenceValue + 1;
}
#ifdef _GAMING_XBOX
// Set frame interval and register for frame events
void DeviceResources::RegisterFrameEvents()
{
// First, retrieve the underlying DXGI device from the D3D device.
ComPtr<IDXGIDevice1> dxgiDevice;
ThrowIfFailed(m_d3dDevice.As(&dxgiDevice));
// Identify the physical adapter (GPU or card) this device is running on.
ComPtr<IDXGIAdapter> dxgiAdapter;
ThrowIfFailed(dxgiDevice->GetAdapter(dxgiAdapter.GetAddressOf()));
// Retrieve the outputs for the adapter.
ComPtr<IDXGIOutput> dxgiOutput;
ThrowIfFailed(dxgiAdapter->EnumOutputs(0, dxgiOutput.GetAddressOf()));
// Set frame interval and register for frame events
ThrowIfFailed(m_d3dDevice->SetFrameIntervalX(
dxgiOutput.Get(),
D3D12XBOX_FRAME_INTERVAL_60_HZ,
m_backBufferCount - 1u /* Allow n-1 frames of latency */,
D3D12XBOX_FRAME_INTERVAL_FLAG_NONE));
ThrowIfFailed(m_d3dDevice->ScheduleFrameEventX(
D3D12XBOX_FRAME_EVENT_ORIGIN,
0U,
nullptr,
D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE));
}
#else
// This method acquires the first available hardware adapter that supports Direct3D 12.
// If no such adapter can be found, try WARP. Otherwise throw an exception.
void DeviceResources::GetAdapter(IDXGIAdapter1** ppAdapter)
{
*ppAdapter = nullptr;
ComPtr<IDXGIAdapter1> adapter;
for (UINT adapterIndex = 0;
SUCCEEDED(m_dxgiFactory->EnumAdapterByGpuPreference(
adapterIndex,
DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
IID_PPV_ARGS(adapter.ReleaseAndGetAddressOf())));
adapterIndex++)
{
DXGI_ADAPTER_DESC1 desc;
ThrowIfFailed(adapter->GetDesc1(&desc));
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
{
// Don't select the Basic Render Driver adapter.
continue;
}
// Check to see if the adapter supports Direct3D 12, but don't create the actual device yet.
if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
{
#ifdef _DEBUG
wchar_t buff[256] = {};
swprintf_s(buff, L"Direct3D Adapter (%u): VID:%04X, PID:%04X - %ls\n", adapterIndex, desc.VendorId, desc.DeviceId, desc.Description);
OutputDebugStringW(buff);
#endif
break;
}
}
#if !defined(NDEBUG)
if (!adapter)
{
// Try WARP12 instead
if (FAILED(m_dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(adapter.ReleaseAndGetAddressOf()))))
{
throw std::runtime_error("WARP12 not available. Enable the 'Graphics Tools' optional feature");
}
OutputDebugStringA("Direct3D Adapter - WARP12\n");
}
#endif
if (!adapter)
{
throw std::runtime_error("No Direct3D 12 device found");
}
*ppAdapter = adapter.Detach();
}
#endif

Просмотреть файл

@ -0,0 +1,135 @@
//
// DeviceResources.h - A wrapper for the Direct3D 12/12.X device and swapchain
//
#pragma once
namespace DX
{
// Provides an interface for an application that owns DeviceResources to be notified of the device being lost or created.
interface IDeviceNotify
{
virtual void OnDeviceLost() = 0;
virtual void OnDeviceRestored() = 0;
protected:
~IDeviceNotify() = default;
};
// Controls all the DirectX device resources.
class DeviceResources
{
public:
DeviceResources(DXGI_FORMAT backBufferFormat = DXGI_FORMAT_B8G8R8A8_UNORM,
DXGI_FORMAT depthBufferFormat = DXGI_FORMAT_D32_FLOAT,
UINT backBufferCount = 2) noexcept(false);
~DeviceResources();
DeviceResources(DeviceResources&&) = default;
DeviceResources& operator= (DeviceResources&&) = default;
DeviceResources(DeviceResources const&) = delete;
DeviceResources& operator= (DeviceResources const&) = delete;
void CreateDeviceResources();
void CreateWindowSizeDependentResources();
void SetWindow(HWND window, int width, int height) noexcept;
bool WindowSizeChanged(int width, int height);
void HandleDeviceLost();
void RegisterDeviceNotify(IDeviceNotify* deviceNotify) noexcept { m_deviceNotify = deviceNotify; }
void Prepare(D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_PRESENT,
D3D12_RESOURCE_STATES afterState = D3D12_RESOURCE_STATE_RENDER_TARGET);
void Present(D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_RENDER_TARGET);
void Suspend();
void Resume();
void WaitForGpu() noexcept;
// Device Accessors.
RECT GetOutputSize() const noexcept { return m_outputSize; }
// Direct3D Accessors.
auto GetD3DDevice() const noexcept { return m_d3dDevice.Get(); }
#ifdef _GAMING_DESKTOP
auto GetSwapChain() const noexcept { return m_swapChain.Get(); }
auto GetDXGIFactory() const noexcept { return m_dxgiFactory.Get(); }
#endif
HWND GetWindow() const noexcept { return m_window; }
D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const noexcept { return m_d3dFeatureLevel; }
ID3D12Resource* GetRenderTarget() const noexcept { return m_renderTargets[m_backBufferIndex].Get(); }
ID3D12Resource* GetDepthStencil() const noexcept { return m_depthStencil.Get(); }
ID3D12CommandQueue* GetCommandQueue() const noexcept { return m_commandQueue.Get(); }
ID3D12CommandAllocator* GetCommandAllocator() const noexcept { return m_commandAllocators[m_backBufferIndex].Get(); }
auto GetCommandList() const noexcept { return m_commandList.Get(); }
DXGI_FORMAT GetBackBufferFormat() const noexcept { return m_backBufferFormat; }
DXGI_FORMAT GetDepthBufferFormat() const noexcept { return m_depthBufferFormat; }
D3D12_VIEWPORT GetScreenViewport() const noexcept { return m_screenViewport; }
D3D12_RECT GetScissorRect() const noexcept { return m_scissorRect; }
UINT GetCurrentFrameIndex() const noexcept { return m_backBufferIndex; }
UINT GetBackBufferCount() const noexcept { return m_backBufferCount; }
CD3DX12_CPU_DESCRIPTOR_HANDLE GetRenderTargetView() const noexcept
{
return CD3DX12_CPU_DESCRIPTOR_HANDLE(
m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(),
static_cast<INT>(m_backBufferIndex), m_rtvDescriptorSize);
}
CD3DX12_CPU_DESCRIPTOR_HANDLE GetDepthStencilView() const noexcept
{
return CD3DX12_CPU_DESCRIPTOR_HANDLE(m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
}
private:
void MoveToNextFrame();
#ifdef _GAMING_XBOX
void RegisterFrameEvents();
#else
void GetAdapter(IDXGIAdapter1** ppAdapter);
#endif
static constexpr size_t MAX_BACK_BUFFER_COUNT = 3;
UINT m_backBufferIndex;
// Direct3D objects.
Microsoft::WRL::ComPtr<ID3D12Device> m_d3dDevice;
Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList> m_commandList;
Microsoft::WRL::ComPtr<ID3D12CommandQueue> m_commandQueue;
Microsoft::WRL::ComPtr<ID3D12CommandAllocator> m_commandAllocators[MAX_BACK_BUFFER_COUNT];
// Swap chain objects.
#ifdef _GAMING_DESKTOP
Microsoft::WRL::ComPtr<IDXGIFactory6> m_dxgiFactory;
Microsoft::WRL::ComPtr<IDXGISwapChain3> m_swapChain;
#endif
Microsoft::WRL::ComPtr<ID3D12Resource> m_renderTargets[MAX_BACK_BUFFER_COUNT];
Microsoft::WRL::ComPtr<ID3D12Resource> m_depthStencil;
// Presentation fence objects.
Microsoft::WRL::ComPtr<ID3D12Fence> m_fence;
UINT64 m_fenceValues[MAX_BACK_BUFFER_COUNT];
Microsoft::WRL::Wrappers::Event m_fenceEvent;
#ifdef _GAMING_XBOX
D3D12XBOX_FRAME_PIPELINE_TOKEN m_framePipelineToken;
#endif
// Direct3D rendering objects.
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> m_rtvDescriptorHeap;
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> m_dsvDescriptorHeap;
UINT m_rtvDescriptorSize;
D3D12_VIEWPORT m_screenViewport;
D3D12_RECT m_scissorRect;
// Direct3D properties.
DXGI_FORMAT m_backBufferFormat;
DXGI_FORMAT m_depthBufferFormat;
UINT m_backBufferCount;
// Cached device properties.
HWND m_window;
D3D_FEATURE_LEVEL m_d3dFeatureLevel;
RECT m_outputSize;
// The IDeviceNotify can be held directly as it owns the DeviceResources.
IDeviceNotify* m_deviceNotify;
};
}

Просмотреть файл

@ -0,0 +1,423 @@
//--------------------------------------------------------------------------------------
// Main.cpp
//
// Entry point for Microsoft Game Development Kit (GDK)
//
// Advanced Technology Group (ATG)
// Copyright (C) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "pch.h"
#include "ManualTest.h"
#include <appnotify.h>
#include <XGameRuntimeInit.h>
#include <XGameErr.h>
#ifdef ATG_ENABLE_TELEMETRY
#include "ATGTelemetry.h"
#endif
using namespace DirectX;
#ifdef __clang__
#pragma clang diagnostic ignored "-Wcovered-switch-default"
#pragma clang diagnostic ignored "-Wswitch-enum"
#endif
#pragma warning(disable : 4061)
namespace
{
std::unique_ptr<Sample> g_sample;
#ifdef _GAMING_XBOX
HANDLE g_plmSuspendComplete = nullptr;
HANDLE g_plmSignalResume = nullptr;
#endif
}
LPCWSTR g_szAppName = L"ManualTest";
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void ExitSample() noexcept;
// Entry point
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(lpCmdLine);
if (!XMVerifyCPUSupport())
{
#ifdef _DEBUG
OutputDebugStringA("ERROR: This hardware does not support the required instruction set.\n");
#if defined(_GAMING_XBOX) && defined(__AVX2__)
OutputDebugStringA("This may indicate a Gaming.Xbox.Scarlett.x64 binary is being run on an Xbox One.\n");
#endif
#endif
return 1;
}
// Initialize COM for WIC usage
if (FAILED(CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)))
return 1;
#ifdef _GAMING_DESKTOP
// NOTE: When running the app from the Start Menu (required for
// Store API's to work) the Current Working Directory will be
// returned as C:\Windows\system32 unless you overwrite it.
// The sample relies on the font and image files in the .exe's
// directory and so we do the following to set the working
// directory to what we want.
char dir[_MAX_PATH] = {};
if (GetModuleFileNameA(nullptr, dir, _MAX_PATH) > 0)
{
std::string exe = dir;
exe = exe.substr(0, exe.find_last_of("\\"));
std::ignore = SetCurrentDirectoryA(exe.c_str());
}
#endif
HRESULT hr = XGameRuntimeInitialize();
if (FAILED(hr))
{
if (hr == E_GAMERUNTIME_DLL_NOT_FOUND || hr == E_GAMERUNTIME_VERSION_MISMATCH)
{
#ifdef _GAMING_DESKTOP
std::ignore = MessageBoxW(nullptr, L"Game Runtime is not installed on this system or needs updating.", g_szAppName, MB_ICONERROR | MB_OK);
#endif
}
return 1;
}
#ifdef _GAMING_XBOX
// Default main thread to CPU 0
SetThreadAffinityMask(GetCurrentThread(), 0x1);
#endif
g_sample = std::make_unique<Sample>();
// Register class and create window
#ifdef _GAMING_XBOX
PAPPSTATE_REGISTRATION hPLM = {};
#endif
{
// Register class
WNDCLASSEXW wcex = {};
wcex.cbSize = sizeof(WNDCLASSEXW);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
wcex.lpszClassName = L"ManualTestWindowClass";
if (!RegisterClassExW(&wcex))
return 1;
// Create window
#ifdef _GAMING_XBOX
RECT rc = { 0, 0, 1920, 1080 };
#else
int w, h;
g_sample->GetDefaultSize(w, h);
RECT rc = { 0, 0, static_cast<LONG>(w), static_cast<LONG>(h) };
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
#endif
HWND hwnd = CreateWindowExW(0, L"ManualTestWindowClass", g_szAppName, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance,
nullptr);
if (!hwnd)
return 1;
ShowWindow(hwnd, nCmdShow);
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(g_sample.get()));
// Sample Usage Telemetry
//
// Disable or remove this code block to opt-out of sample usage telemetry
GetClientRect(hwnd, &rc);
g_sample->Initialize(hwnd, rc.right - rc.left, rc.bottom - rc.top);
#ifdef _GAMING_XBOX
g_plmSuspendComplete = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
g_plmSignalResume = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
if (!g_plmSuspendComplete || !g_plmSignalResume)
return 1;
if (RegisterAppStateChangeNotification([](BOOLEAN quiesced, PVOID context)
{
if (quiesced)
{
ResetEvent(g_plmSuspendComplete);
ResetEvent(g_plmSignalResume);
// To ensure we use the main UI thread to process the notification, we self-post a message
PostMessage(reinterpret_cast<HWND>(context), WM_USER, 0, 0);
// To defer suspend, you must wait to exit this callback
std::ignore = WaitForSingleObject(g_plmSuspendComplete, INFINITE);
}
else
{
SetEvent(g_plmSignalResume);
}
}, hwnd, &hPLM))
return 1;
#endif
}
// Main message loop
MSG msg = {};
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
g_sample->Tick();
}
}
g_sample.reset();
#ifdef _GAMING_XBOX
UnregisterAppStateChangeNotification(hPLM);
CloseHandle(g_plmSuspendComplete);
CloseHandle(g_plmSignalResume);
#endif
XGameRuntimeUninitialize();
CoUninitialize();
return static_cast<int>(msg.wParam);
}
// Windows procedure
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
#ifdef _GAMING_DESKTOP
static bool s_in_sizemove = false;
static bool s_in_suspend = false;
static bool s_minimized = false;
static bool s_fullscreen = false;
#endif
auto sample = reinterpret_cast<Sample*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
switch (message)
{
case WM_ACTIVATEAPP:
if (sample)
{
Keyboard::ProcessMessage(message, wParam, lParam);
Mouse::ProcessMessage(message, wParam, lParam);
if (wParam)
{
sample->OnActivated();
}
else
{
sample->OnDeactivated();
}
}
break;
case WM_ACTIVATE:
Keyboard::ProcessMessage(message, wParam, lParam);
Mouse::ProcessMessage(message, wParam, lParam);
break;
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MOUSEWHEEL:
case WM_XBUTTONDOWN:
case WM_XBUTTONUP:
Mouse::ProcessMessage(message, wParam, lParam);
break;
#ifdef _GAMING_XBOX
case WM_USER:
if (sample)
{
sample->OnSuspending();
// Complete deferral
SetEvent(g_plmSuspendComplete);
std::ignore = WaitForSingleObject(g_plmSignalResume, INFINITE);
sample->OnResuming();
}
break;
#else
case WM_PAINT:
if (s_in_sizemove && sample)
{
sample->Tick();
}
else
{
PAINTSTRUCT ps;
std::ignore = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_MOVE:
if (sample)
{
sample->OnWindowMoved();
}
break;
case WM_SIZE:
if (wParam == SIZE_MINIMIZED)
{
if (!s_minimized)
{
s_minimized = true;
if (!s_in_suspend && sample)
sample->OnSuspending();
s_in_suspend = true;
}
}
else if (s_minimized)
{
s_minimized = false;
if (s_in_suspend && sample)
sample->OnResuming();
s_in_suspend = false;
}
else if (!s_in_sizemove && sample)
{
sample->OnWindowSizeChanged(LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_ENTERSIZEMOVE:
s_in_sizemove = true;
break;
case WM_EXITSIZEMOVE:
s_in_sizemove = false;
if (sample)
{
RECT rc;
GetClientRect(hWnd, &rc);
sample->OnWindowSizeChanged(rc.right - rc.left, rc.bottom - rc.top);
}
break;
case WM_GETMINMAXINFO:
if (lParam)
{
auto info = reinterpret_cast<MINMAXINFO*>(lParam);
info->ptMinTrackSize.x = 320;
info->ptMinTrackSize.y = 200;
}
break;
case WM_POWERBROADCAST:
switch (wParam)
{
case PBT_APMQUERYSUSPEND:
if (!s_in_suspend && sample)
sample->OnSuspending();
s_in_suspend = true;
return TRUE;
case PBT_APMRESUMESUSPEND:
if (!s_minimized)
{
if (s_in_suspend && sample)
sample->OnResuming();
s_in_suspend = false;
}
return TRUE;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_INPUT:
case WM_MOUSEHOVER:
Mouse::ProcessMessage(message, wParam, lParam);
break;
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
Keyboard::ProcessMessage(message, wParam, lParam);
break;
case WM_SYSKEYDOWN:
if (wParam == VK_RETURN && (lParam & 0x60000000) == 0x20000000)
{
// Implements the classic ALT+ENTER fullscreen toggle
if (s_fullscreen)
{
SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW);
SetWindowLongPtr(hWnd, GWL_EXSTYLE, 0);
int width = 800;
int height = 600;
if (sample)
sample->GetDefaultSize(width, height);
ShowWindow(hWnd, SW_SHOWNORMAL);
SetWindowPos(hWnd, HWND_TOP, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
else
{
SetWindowLongPtr(hWnd, GWL_STYLE, 0);
SetWindowLongPtr(hWnd, GWL_EXSTYLE, WS_EX_TOPMOST);
SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
ShowWindow(hWnd, SW_SHOWMAXIMIZED);
}
s_fullscreen = !s_fullscreen;
}
Keyboard::ProcessMessage(message, wParam, lParam);
break;
case WM_MOUSEACTIVATE:
// When you click activate the window, we want Mouse to ignore that event.
return MA_ACTIVATEANDEAT;
case WM_MENUCHAR:
// A menu is active and the user presses a key that does not correspond
// to any mnemonic or accelerator key. Ignore so we don't produce an error beep.
return MAKELRESULT(0, MNC_CLOSE);
#endif
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
// Exit helper
void ExitSample() noexcept
{
PostQuitMessage(0);
}

Просмотреть файл

@ -0,0 +1,874 @@
//--------------------------------------------------------------------------------------
// ManualTest.cpp
//
// Advanced Technology Group (ATG)
// Copyright (C) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "pch.h"
#include "ManualTest.h"
#include "ATGColors.h"
#include "FindMedia.h"
#include "StringUtil.h"
#include <XGameRuntimeFeature.h>
#include <XNetworking.h>
#include <XGameRuntimeInit.h>
inline std::string DebugFormat(_In_z_ _Printf_format_string_ const char* format, ...)
{
#ifdef _DEBUG
va_list args;
va_start(args, format);
char buff[1024*10] = {};
vsprintf_s(buff, format, args);
std::string str = buff;
va_end(args);
return buff;
#else
UNREFERENCED_PARAMETER(format);
#endif
}
extern void ExitSample() noexcept;
using namespace DirectX;
using Microsoft::WRL::ComPtr;
Sample* g_sample = nullptr;
namespace
{
const char *ProgressStateText[] = {
u8"Unknown",
u8"Achieved",
u8"Not Started",
u8"In Progress"
};
const char *AchievementTypeText[] = {
u8"Unknown",
u8"All",
u8"Persistent",
u8"Challenge"
};
const int c_sampleUIPanel = 2000;
const int c_getAchievementsBtn = 2101;
const int c_getSingleAchievementBtn = 2102;
const int c_setSingleAchievementBtn = 2103;
const int c_getSingleAchievementBtn2 = 2104;
const int c_setSingleAchievement2Btn25 = 2105;
const int c_setSingleAchievement2Btn50 = 2106;
const int c_setSingleAchievement2Btn100 = 2107;
}
void CALLBACK MyXUserChangeEventCallback(
_In_opt_ void* context,
_In_ XUserLocalId userLocalId,
_In_ XUserChangeEvent event)
{
UNREFERENCED_PARAMETER(context);
std::string eventType = "";
switch (event)
{
case XUserChangeEvent::SignedInAgain: eventType = "SignedInAgain"; break;
case XUserChangeEvent::SigningOut: eventType = "SigningOut"; break;
case XUserChangeEvent::SignedOut: eventType = "SignedOut"; break;
case XUserChangeEvent::Gamertag: eventType = "Gamertag"; break;
case XUserChangeEvent::GamerPicture: eventType = "GamerPicture"; break;
case XUserChangeEvent::Privileges:eventType = "Privileges"; break;
default: break;
}
XUserHandle handle;
uint64_t xuid = {};
HRESULT hr = XUserFindUserByLocalId(
userLocalId,
&handle);
if (SUCCEEDED(hr))
{
XUserGetId(handle, &xuid);
XUserCloseHandle(handle);
}
g_sample->AddLog(DebugFormat("XUserChangeEventCallback: userLocalId: %ull = %s xuid: 0x%0.8x", userLocalId.value, eventType.c_str(), xuid));
}
void __cdecl MyHCCallRoutedHandler(
_In_ HCCallHandle call,
_In_opt_ void* context
)
{
UNREFERENCED_PARAMETER(context);
const char* url = nullptr;
uint32_t status = 0;
HCHttpCallGetRequestUrl(call, &url);
HCHttpCallResponseGetStatusCode(call, &status);
HRESULT hrNet = S_OK;
uint32_t hrPlat = S_OK;
HCHttpCallResponseGetNetworkErrorCode(call, &hrNet, &hrPlat);
g_sample->AddLog(DebugFormat("HCCallRoutedHandler: %d [0x%0.8x] %s", status, hrNet, url));
}
void CALLBACK MyHCTraceCallback(
_In_z_ const char* areaName,
_In_ HCTraceLevel level,
_In_ uint64_t threadId,
_In_ uint64_t timestamp,
_In_z_ const char* message
)
{
UNREFERENCED_PARAMETER(areaName);
UNREFERENCED_PARAMETER(level);
UNREFERENCED_PARAMETER(threadId);
UNREFERENCED_PARAMETER(timestamp);
g_sample->AddLog(DebugFormat("HC: %s", message));
}
void MyNetworkConnectivityChangedCallback(void* context, const XNetworkingConnectivityHint* /*hint*/)
{
UNREFERENCED_PARAMETER(context);
// Always requery the latest network connectivity hint rather than relying on the passed parameter in case this is a stale notification
XNetworkingConnectivityHint hint{};
HRESULT hr = XNetworkingGetConnectivityHint(&hint);
if (SUCCEEDED(hr))
{
g_sample->AddLog(DebugFormat("NetworkConnectivityChangedCallback: networkInitialized: %d connectivityLevel: %d", hint.networkInitialized, hint.connectivityLevel));
}
else
{
g_sample->AddLog(DebugFormat("NetworkConnectivityChangedCallback: 0x%0.8x", hr));
}
}
Sample::Sample() noexcept(false) :
m_frame(0)
{
g_sample = this;
m_deviceResources = std::make_unique<DX::DeviceResources>();
m_deviceResources->RegisterDeviceNotify(this);
m_liveInfoHUD = std::make_unique<ATG::SampleLiveInfoHUD>("Title-managed ManualTest Sample");
DX::ThrowIfFailed(
XTaskQueueCreate(XTaskQueueDispatchMode::ThreadPool, XTaskQueueDispatchMode::Manual, &m_mainAsyncQueue)
);
ATG::UIConfig uiconfig;
m_ui = std::make_unique<ATG::UIManager>(uiconfig);
m_log = std::make_unique<DX::TextConsoleImage>();
m_display = std::make_unique<DX::TextConsoleImage>();
XTaskQueueRegistrationToken token = {};
XUserRegisterForChangeEvent(nullptr, nullptr, MyXUserChangeEventCallback, &token);
HCTraceSetClientCallback(MyHCTraceCallback);
m_liveInfoHUD->AddLog("**************** GAME START ****************");
XTaskQueueRegistrationToken tokenHint;
HRESULT hr = XNetworkingRegisterConnectivityHintChanged(nullptr, nullptr, MyNetworkConnectivityChangedCallback, &tokenHint);
m_liveInfoHUD->AddLog(DebugFormat("XNetworkingRegisterConnectivityHintChanged 0x%0.8x", hr));
}
Sample::~Sample()
{
if (m_deviceResources)
{
m_deviceResources->WaitForGpu();
}
if (m_mainAsyncQueue)
{
XTaskQueueCloseHandle(m_mainAsyncQueue);
m_mainAsyncQueue = nullptr;
}
XGameRuntimeUninitialize();
}
// Initialize the Direct3D resources required to run.
void Sample::Initialize(HWND window, int width, int height)
{
m_gamePad = std::make_unique<GamePad>();
m_keyboard = std::make_unique<Keyboard>();
m_mouse = std::make_unique<Mouse>();
m_mouse->SetWindow(window);
m_deviceResources->SetWindow(window, width, height);
wchar_t result[MAX_PATH];
DX::FindMediaFile(result, MAX_PATH, L".\\Assets\\SampleUI.csv");
m_ui->LoadLayout(result, L".\\Assets\\");
HRESULT hr = XGameRuntimeInitialize();
m_deviceResources->CreateDeviceResources();
CreateDeviceDependentResources();
m_deviceResources->CreateWindowSizeDependentResources();
CreateWindowSizeDependentResources();
m_liveInfoHUD->Initialize();
SetupUI();
}
void Sample::SetupUI()
{
}
#pragma region Frame Update
// Executes basic render loop.
void Sample::Tick()
{
PIXBeginEvent(PIX_COLOR_DEFAULT, L"Frame %llu", m_frame);
m_timer.Tick([&]()
{
Update(m_timer);
});
Render();
PIXEndEvent();
m_frame++;
}
static std::string NewGuid()
{
GUID id = {};
char buf[64] = {};
CoCreateGuid(&id);
sprintf_s(buf, "%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX",
id.Data1, id.Data2, id.Data3,
id.Data4[0], id.Data4[1], id.Data4[2], id.Data4[3],
id.Data4[4], id.Data4[5], id.Data4[6], id.Data4[7]);
return std::string(buf);
}
void Sample::CreateSession()
{
if (m_xblContext == nullptr)
{
g_sample->m_liveInfoHUD->AddLog(DebugFormat("CreateSession no m_xblContext"));
return;
}
if (m_userHandle1 == nullptr)
{
g_sample->m_liveInfoHUD->AddLog(DebugFormat("CreateSession Add user first"));
return;
}
if (m_currentSessionHandle != nullptr)
{
g_sample->m_liveInfoHUD->AddLog(DebugFormat("CreateSession Session exists"));
return;
}
XblMultiplayerSessionInitArgs initArgs;
initArgs.MaxMembersInSession = 8; //This matches our session template
initArgs.Visibility = XblMultiplayerSessionVisibility::Open; //The session is open and can be joined by anyone.
initArgs.InitiatorXuids = nullptr;
initArgs.InitiatorXuidsCount = 0;
initArgs.CustomJson = nullptr;
const char* scid = nullptr;
XblGetScid(&scid);
std::string currentSessionName = NewGuid();
XblMultiplayerSessionReference createdSessionRef = XblMultiplayerSessionReferenceCreate(scid, "GameSession", currentSessionName.c_str());
uint64_t userId = 0;
XUserGetId(m_userHandle1, &userId);
m_currentSessionHandle = XblMultiplayerSessionCreateHandle(userId, &createdSessionRef, &initArgs);
m_liveInfoHUD->AddLog(DebugFormat("m_currentSessionHandle 0x%0.8x", m_currentSessionHandle));
HRESULT hr = XblMultiplayerSessionJoin(m_currentSessionHandle, nullptr, true, true);
m_liveInfoHUD->AddLog(DebugFormat("XblMultiplayerSessionJoin 0x%0.8x", hr));
}
void Sample::WriteSession()
{
if (m_xblContext == nullptr)
{
g_sample->m_liveInfoHUD->AddLog(DebugFormat("no m_xblContext"));
return;
}
if( m_currentSessionHandle == nullptr)
{
g_sample->m_liveInfoHUD->AddLog(DebugFormat("no m_currentSessionHandle"));
return;
}
auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->queue = nullptr;
asyncBlock->context = nullptr;
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
g_sample->m_liveInfoHUD->AddLog("***** XblMultiplayerWriteSessionAsync callback");
std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; //Take over ownership of the XAsyncBlock*
XblMultiplayerSessionHandle createdHandle;
HRESULT hr = XblMultiplayerWriteSessionResult(asyncBlock, &createdHandle);
g_sample->m_liveInfoHUD->AddLog(DebugFormat("XblMultiplayerWriteSessionResult 0x%0.8x", hr));
if (hr == S_OK)
{
XblWriteSessionStatus status = XblMultiplayerSessionWriteStatus(createdHandle);
g_sample->m_liveInfoHUD->AddLog(DebugFormat("XblMultiplayerSessionWriteStatus %d", status));
}
XblMultiplayerSessionCloseHandle(createdHandle);
};
HRESULT hr = XblMultiplayerWriteSessionAsync(m_xblContext, m_currentSessionHandle, XblMultiplayerSessionWriteMode::UpdateOrCreateNew, asyncBlock.get());
m_liveInfoHUD->AddLog(DebugFormat("XblMultiplayerWriteSessionAsync 0x%0.8x", hr));
if (SUCCEEDED(hr))
{
// The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* since the callback will take over ownership.
// If the call fails, the std::unique_ptr will keep ownership and delete the XAsyncBlock*
asyncBlock.release();
}
else
{
XblMultiplayerSessionCloseHandle(m_currentSessionHandle);
}
}
// Updates the world.
void Sample::Update(DX::StepTimer const& timer)
{
PIXBeginEvent(PIX_COLOR_DEFAULT, L"Update");
float elapsedTime = float(timer.GetElapsedSeconds());
auto pad = m_gamePad->GetState(0);
if (pad.IsConnected())
{
m_gamePadButtons.Update(pad);
if (pad.IsViewPressed())
{
ExitSample();
}
if (m_gamePadButtons.menu == GamePad::ButtonStateTracker::PRESSED)
{
}
m_ui->Update(elapsedTime, pad);
}
else
{
m_gamePadButtons.Reset();
}
auto kb = m_keyboard->GetState();
m_keyboardButtons.Update(kb);
if (kb.Escape)
{
ExitSample();
}
bool isControlPressed = kb.LeftControl || kb.RightControl;
if (!isControlPressed)
{
if ((m_keyboardButtons.IsKeyPressed(Keyboard::Keys::D1) && !m_keyboardButtonsLast.IsKeyPressed(Keyboard::Keys::D1)))
{
if (!m_xblInit)
{
m_xblInit = true;
uint32_t titleId = 0;
auto hr = XGameGetXboxTitleId(&titleId);
char scidBuffer[64] = {};
sprintf_s(scidBuffer, "00000000-0000-0000-0000-0000%08X", titleId);
XblInitArgs xblInit = { nullptr, scidBuffer };
hr = XblInitialize(&xblInit);
m_liveInfoHUD->AddLog(DebugFormat("XblInitialize 0x%0.8x", hr));
hr = HCAddCallRoutedHandler(MyHCCallRoutedHandler, nullptr);
m_liveInfoHUD->AddLog(DebugFormat("HCAddCallRoutedHandler 0x%0.8x", hr));
g_sample->AddLog(DebugFormat("XblInitialize 0x%0.8x done", hr));
}
}
if ((m_keyboardButtons.IsKeyPressed(Keyboard::Keys::D2) && !m_keyboardButtonsLast.IsKeyPressed(Keyboard::Keys::D2)))
{
if (m_userHandle1 == nullptr)
{
AddUser(XUserAddOptions::AddDefaultUserSilently);
g_sample->AddLog(DebugFormat("AddUser done"));
}
else
{
g_sample->AddLog(DebugFormat("no user"));
}
}
if ((m_keyboardButtons.IsKeyPressed(Keyboard::Keys::D3) && !m_keyboardButtonsLast.IsKeyPressed(Keyboard::Keys::D3)))
{
if (m_xblInit && !m_xblRTA && m_xblContext)
{
HRESULT hr = XblMultiplayerSetSubscriptionsEnabled(m_xblContext, true);
g_sample->AddLog(DebugFormat("XblMultiplayerSetSubscriptionsEnabled 0x%0.8x", hr));
m_xblRTA = true;
hr = XblRealTimeActivityActivate(m_xblContext);
g_sample->AddLog(DebugFormat("XblRealTimeActivityActivate 0x%0.8x", hr));
g_sample->AddLog(DebugFormat("RTA done"));
}
else
{
if(!m_xblInit)
g_sample->AddLog(DebugFormat("rta - not init"));
if (!m_xblContext)
g_sample->AddLog(DebugFormat("rta - not m_xblContext"));
}
}
if ((m_keyboardButtons.IsKeyPressed(Keyboard::Keys::D4) && !m_keyboardButtonsLast.IsKeyPressed(Keyboard::Keys::D4)))
{
CreateSession();
}
if ((m_keyboardButtons.IsKeyPressed(Keyboard::Keys::D5) && !m_keyboardButtonsLast.IsKeyPressed(Keyboard::Keys::D5)))
{
WriteSession();
}
}
else
{
if ((m_keyboardButtons.IsKeyPressed(Keyboard::Keys::D1) && !m_keyboardButtonsLast.IsKeyPressed(Keyboard::Keys::D1)))
{
if (m_xblInit)
{
m_xblInit = false;
auto async = new XAsyncBlock{};
HRESULT hr = XblCleanupAsync(async);
g_sample->AddLog(DebugFormat("XblCleanupAsync 0x%0.8x", hr));
XAsyncGetStatus(async, true);
g_sample->AddLog(DebugFormat("XblCleanupAsync 0x%0.8x done", hr));
}
else
{
g_sample->AddLog(DebugFormat("cleanup - not init"));
}
}
if ((m_keyboardButtons.IsKeyPressed(Keyboard::Keys::D2) && !m_keyboardButtonsLast.IsKeyPressed(Keyboard::Keys::D2)))
{
if (m_userHandle1 != nullptr)
{
uint64_t xuid = {};
XUserGetId(m_userHandle1, &xuid);
XUserLocalId userLocalId = {};
XUserGetLocalId(m_userHandle1, &userLocalId);
g_sample->AddLog(DebugFormat("Closing XUserHandle 0x%0.8x. userLocalId: %ull, xuid: 0x%0.8x", m_userHandle1, userLocalId, xuid));
SetUserHandle(nullptr);
}
else
{
g_sample->AddLog(DebugFormat("cleanup - no user"));
}
}
if ((m_keyboardButtons.IsKeyPressed(Keyboard::Keys::D3) && !m_keyboardButtonsLast.IsKeyPressed(Keyboard::Keys::D3)))
{
if (m_xblInit && m_xblRTA)
{
m_xblRTA = false;
HRESULT hr = XblRealTimeActivityDeactivate(m_xblContext);
g_sample->AddLog(DebugFormat("XblRealTimeActivityDeactivate 0x%0.8x", hr));
}
else
{
g_sample->AddLog(DebugFormat("cleanup - no session"));
}
}
if ((m_keyboardButtons.IsKeyPressed(Keyboard::Keys::D4) && !m_keyboardButtonsLast.IsKeyPressed(Keyboard::Keys::D4)))
{
if (m_currentSessionHandle != nullptr)
{
XblMultiplayerSessionCloseHandle(m_currentSessionHandle);
g_sample->AddLog(DebugFormat("XblMultiplayerSessionCloseHandle"));
m_currentSessionHandle = nullptr;
}
else
{
g_sample->AddLog(DebugFormat("cleanup - no session"));
}
}
}
m_keyboardButtonsLast = m_keyboardButtons;
m_ui->Update(elapsedTime, *m_mouse, *m_keyboard);
m_liveInfoHUD->Update(m_deviceResources->GetCommandQueue());
// Process any completed tasks
while (XTaskQueueDispatch(m_mainAsyncQueue, XTaskQueuePort::Completion, 0))
{
SwitchToThread();
}
PIXEndEvent();
}
#pragma endregion
#pragma region Frame Render
// Draws the scene.
void Sample::Render()
{
// Don't try to render anything before the first Update.
if (m_timer.GetFrameCount() == 0)
{
return;
}
// Prepare the command list to render a new frame.
m_deviceResources->Prepare();
Clear();
auto commandList = m_deviceResources->GetCommandList();
PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Render");
ID3D12DescriptorHeap* heap = m_resourceDescriptors->Heap();
commandList->SetDescriptorHeaps(1, &heap);
m_liveInfoHUD->Render(commandList);
//m_log->Render(commandList);
//m_display->Render(commandList);
m_ui->Render(commandList);
PIXEndEvent(commandList);
// Show the new frame.
PIXBeginEvent(PIX_COLOR_DEFAULT, L"Present");
m_deviceResources->Present();
m_graphicsMemory->Commit(m_deviceResources->GetCommandQueue());
PIXEndEvent();
}
// Helper method to clear the back buffers.
void Sample::Clear()
{
auto commandList = m_deviceResources->GetCommandList();
PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Clear");
// Clear the views.
auto rtvDescriptor = m_deviceResources->GetRenderTargetView();
auto dsvDescriptor = m_deviceResources->GetDepthStencilView();
commandList->OMSetRenderTargets(1, &rtvDescriptor, FALSE, &dsvDescriptor);
commandList->ClearRenderTargetView(rtvDescriptor, ATG::Colors::Background, 0, nullptr);
commandList->ClearDepthStencilView(dsvDescriptor, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);
// Set the viewport and scissor rect.
auto viewport = m_deviceResources->GetScreenViewport();
auto scissorRect = m_deviceResources->GetScissorRect();
commandList->RSSetViewports(1, &viewport);
commandList->RSSetScissorRects(1, &scissorRect);
PIXEndEvent(commandList);
}
#pragma endregion
#pragma region Message Handlers
// Message handlers
void Sample::OnActivated()
{
}
void Sample::OnDeactivated()
{
}
void Sample::AddLog(const std::string& str)
{
m_liveInfoHUD->AddLog(str);
}
void CALLBACK HandleXblRealTimeActivityConnectionStateChange(
_In_opt_ void* context,
_In_ XblRealTimeActivityConnectionState connectionState
)
{
UNREFERENCED_PARAMETER(context);
if (connectionState == XblRealTimeActivityConnectionState::Connected)
{
g_sample->AddLog(DebugFormat("RTA connected"));
}
if (connectionState == XblRealTimeActivityConnectionState::Connecting)
{
g_sample->AddLog(DebugFormat("RTA connecting"));
}
if (connectionState == XblRealTimeActivityConnectionState::Disconnected)
{
g_sample->AddLog(DebugFormat("RTA disconnected"));
}
}
void Sample::SetUserHandle(XUserHandle user)
{
if (m_userHandle1 != nullptr)
{
XblContextCloseHandle(m_xblContext);
XUserCloseHandle(m_userHandle1);
}
m_userHandle1 = user;
if (m_userHandle1 != nullptr)
{
HRESULT hr = XblContextCreateHandle(m_userHandle1, &m_xblContext);
if (FAILED(hr))
{
g_sample->AddLog(DebugFormat("XblContextCreateHandle 0x%0.8x", hr));
}
else
{
hr = XblRealTimeActivityAddConnectionStateChangeHandler(m_xblContext, HandleXblRealTimeActivityConnectionStateChange, nullptr);
g_sample->AddLog(DebugFormat("XblRealTimeActivityAddConnectionStateChangeHandler 0x%0.8x", hr));
}
}
}
HRESULT Sample::AddUser(XUserAddOptions options)
{
// Attempt to get the default user, i.e. the user who launched the game
auto async = new XAsyncBlock{};
//async->context = (void*)options;
async->callback = [](XAsyncBlock* async)
{
//int x = static_cast<int>(reinterpret_cast<std::uintptr_t>(async->context));
//XUserAddOptions options = (XUserAddOptions)x;
XUserHandle user = nullptr;
HRESULT result = XUserAddResult(async, &user);
if (SUCCEEDED(result))
{
// This failure doesn't come up until you try to actually do something with the user
uint64_t xuid = {};
if (FAILED(result = XUserGetId(user, &xuid)))
{
g_sample->AddLog(DebugFormat("User ResolveUserIssueWithUI 0x%0.8x", result));
//ResolveUserIssueWithUI(user);
}
else
{
XUserLocalId userLocalId = {};
XUserGetLocalId(user, &userLocalId);
g_sample->AddLog(DebugFormat("Got XUserHandle 0x%0.8x. userLocalId: %ull, xuid: 0x%0.8x", user, userLocalId.value, xuid));
g_sample->SetUserHandle(user);
//OnSignInCompleted(ATG::XboxHandle<XUserHandle>{user});
}
}
else if (result == E_GAMEUSER_RESOLVE_USER_ISSUE_REQUIRED
|| result == E_GAMEUSER_NO_DEFAULT_USER
|| result == static_cast<HRESULT>(0x8015DC12))
{
g_sample->AddLog(DebugFormat("User SwitchUser 0x%0.8x", result));
g_sample->AddUser(XUserAddOptions::AllowGuests);
}
else
{
g_sample->AddLog(DebugFormat("User HandleError 0x%0.8x", result));
//HandleError(result);
}
delete async;
};
HRESULT hr = XUserAddAsync(
options,
async
);
g_sample->AddLog(DebugFormat("XUserAddAsync 0x%0.8x", hr));
if (FAILED(hr))
{
g_sample->AddLog("Unable to add user!");
delete async;
return hr;
}
return S_OK;
}
void Sample::OnSuspending()
{
m_liveInfoHUD->AddLog("PLM resuming");
m_deviceResources->Suspend();
}
void Sample::OnResuming()
{
m_liveInfoHUD->AddLog("PLM resuming");
//AddUser(XUserAddOptions::AddDefaultUserSilently);
m_deviceResources->Resume();
m_timer.ResetElapsedTime();
m_gamePadButtons.Reset();
m_keyboardButtons.Reset();
}
void Sample::OnWindowMoved()
{
auto r = m_deviceResources->GetOutputSize();
m_deviceResources->WindowSizeChanged(r.right, r.bottom);
}
void Sample::OnWindowSizeChanged(int width, int height)
{
if (!m_deviceResources->WindowSizeChanged(width, height))
return;
CreateWindowSizeDependentResources();
}
// Properties
void Sample::GetDefaultSize(int& width, int& height) const noexcept
{
width = 1840;
height = 1035;
}
#pragma endregion
#pragma region Direct3D Resources
// These are the resources that depend on the device.
void Sample::CreateDeviceDependentResources()
{
auto device = m_deviceResources->GetD3DDevice();
#ifdef _GAMING_DESKTOP
D3D12_FEATURE_DATA_SHADER_MODEL shaderModel = { D3D_SHADER_MODEL_6_0 };
if (FAILED(device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shaderModel, sizeof(shaderModel)))
|| (shaderModel.HighestShaderModel < D3D_SHADER_MODEL_6_0))
{
#ifdef _DEBUG
OutputDebugStringA("ERROR: Shader Model 6.0 is not supported!\n");
#endif
throw std::runtime_error("Shader Model 6.0 is not supported!");
}
#endif
m_graphicsMemory = std::make_unique<GraphicsMemory>(device);
RenderTargetState rtState(m_deviceResources->GetBackBufferFormat(), m_deviceResources->GetDepthBufferFormat());
m_resourceDescriptors = std::make_unique<DirectX::DescriptorPile>(device,
Descriptors::Count,
Descriptors::Reserve
);
ResourceUploadBatch resourceUpload(device);
resourceUpload.Begin();
m_liveInfoHUD->RestoreDevice(device, rtState, resourceUpload, *m_resourceDescriptors);
wchar_t font[260];
wchar_t background[260];
DX::FindMediaFile(font, 260, L"courier_16.spritefont");
DX::FindMediaFile(background, 260, L"ATGSampleBackground.DDS");
m_log->RestoreDevice(
device,
resourceUpload,
rtState,
font,
background,
m_resourceDescriptors->GetCpuHandle(Descriptors::Font),
m_resourceDescriptors->GetGpuHandle(Descriptors::Font),
m_resourceDescriptors->GetCpuHandle(Descriptors::Background),
m_resourceDescriptors->GetGpuHandle(Descriptors::Background)
);
m_display->RestoreDevice(
device,
resourceUpload,
rtState,
font,
background,
m_resourceDescriptors->GetCpuHandle(Descriptors::ConsoleFont),
m_resourceDescriptors->GetGpuHandle(Descriptors::ConsoleFont),
m_resourceDescriptors->GetCpuHandle(Descriptors::ConsoleBackground),
m_resourceDescriptors->GetGpuHandle(Descriptors::ConsoleBackground)
);
m_ui->RestoreDevice(device, rtState, resourceUpload, *m_resourceDescriptors);
auto uploadResourcesFinished = resourceUpload.End(m_deviceResources->GetCommandQueue());
uploadResourcesFinished.wait();
}
void ScaleRect(const RECT &originalDisplayRect, const RECT &displayRect, const RECT &originalSubRect, RECT &scaledSubRect)
{
const float widthScale = ((float)displayRect.right - (float)displayRect.left) / ((float)originalDisplayRect.right - (float)originalDisplayRect.left);
const float heightScale = ((float)displayRect.bottom - (float)displayRect.top) / ((float)originalDisplayRect.bottom - (float)originalDisplayRect.top);
scaledSubRect.top = (LONG)((float)originalSubRect.top * heightScale);
scaledSubRect.left = (LONG)((float)originalSubRect.left * widthScale);
scaledSubRect.bottom = (LONG)((float)originalSubRect.bottom * heightScale);
scaledSubRect.right = (LONG)((float)originalSubRect.right * widthScale);
}
// Allocate all memory resources that change on a window SizeChanged event.
void Sample::CreateWindowSizeDependentResources()
{
RECT fullscreen = m_deviceResources->GetOutputSize();
auto viewport = m_deviceResources->GetScreenViewport();
m_liveInfoHUD->SetViewport(viewport);
// Scaled for 1920x1080
static const RECT originalScale = { 0, 0, 1920, 1080 };
static const RECT screenDisplay = { 960, 200, 1780, 450 };
RECT scaledDisplay;
ScaleRect(originalScale, fullscreen, screenDisplay, scaledDisplay);
m_log->SetWindow(scaledDisplay, false);
m_log->SetViewport(viewport);
// Scaled for 1920x1080
static const RECT screenDisplay2 = { 960, 500, 1780, 950 };
ScaleRect(originalScale, fullscreen, screenDisplay2, scaledDisplay);
m_display->SetWindow(scaledDisplay, false);
m_display->SetViewport(viewport);
m_ui->SetWindow(fullscreen);
}
void Sample::OnDeviceLost()
{
m_ui->ReleaseDevice();
m_graphicsMemory.reset();
m_liveInfoHUD->ReleaseDevice();
m_resourceDescriptors.reset();
}
void Sample::OnDeviceRestored()
{
CreateDeviceDependentResources();
CreateWindowSizeDependentResources();
}
#pragma endregion

Просмотреть файл

@ -0,0 +1,117 @@
//--------------------------------------------------------------------------------------
// ManualTest.h
//
// Advanced Technology Group (ATG)
// Copyright (C) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#pragma once
#include "DeviceResources.h"
#include "LiveResources.h"
#include "SampleLiveInfoHUD.h"
#include "StepTimer.h"
#include "SampleGUI.h"
#include "TextConsole.h"
// A basic sample implementation that creates a D3D12 device and
// provides a render loop.
class Sample final : public DX::IDeviceNotify
{
public:
Sample() noexcept(false);
~Sample();
Sample(Sample&&) = default;
Sample& operator= (Sample&&) = default;
Sample(Sample const&) = delete;
Sample& operator= (Sample const&) = delete;
// Initialization and management
void Initialize(HWND window, int width, int height);
// Basic render loop
void Tick();
// IDeviceNotify
void OnDeviceLost() override;
void OnDeviceRestored() override;
// Messages
void OnActivated();
void OnDeactivated();
void OnSuspending();
void OnResuming();
void OnWindowMoved();
void OnWindowSizeChanged(int width, int height);
// Properties
void GetDefaultSize(int& width, int& height) const noexcept;
HRESULT AddUser(XUserAddOptions options);
void AddLog(const std::string& str);
void SetUserHandle(XUserHandle user);
void CreateSession();
void WriteSession();
private:
void Update(DX::StepTimer const& timer);
void Render();
void Clear();
void CreateDeviceDependentResources();
void CreateWindowSizeDependentResources();
void SetupUI();
// Device resources.
std::unique_ptr<DX::DeviceResources> m_deviceResources;
// Rendering loop timer.
uint64_t m_frame;
DX::StepTimer m_timer;
// Input devices.
std::unique_ptr<DirectX::GamePad> m_gamePad;
std::unique_ptr<DirectX::Keyboard> m_keyboard;
std::unique_ptr<DirectX::Mouse> m_mouse;
DirectX::GamePad::ButtonStateTracker m_gamePadButtons;
DirectX::Keyboard::KeyboardStateTracker m_keyboardButtons;
DirectX::Keyboard::KeyboardStateTracker m_keyboardButtonsLast;
// DirectXTK objects.
std::unique_ptr<DirectX::GraphicsMemory> m_graphicsMemory;
std::unique_ptr<DirectX::DescriptorPile> m_resourceDescriptors;
std::unique_ptr<ATG::SampleLiveInfoHUD> m_liveInfoHUD;
XTaskQueueHandle m_mainAsyncQueue;
// UI Objects
std::unique_ptr<ATG::UIManager> m_ui;
std::unique_ptr<DX::TextConsoleImage> m_log;
std::unique_ptr<DX::TextConsoleImage> m_display;
XUserHandle m_userHandle1 = nullptr;
XblContextHandle m_xblContext = nullptr;
bool m_xblInit = false;
bool m_xblRTA = false;
XblMultiplayerSessionHandle m_currentSessionHandle = nullptr;
enum Descriptors
{
Font,
ConsoleFont,
Background,
ConsoleBackground,
Reserve,
Count = 32,
};
};

Просмотреть файл

@ -0,0 +1,74 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32802.440
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ManualTest", "ManualTest.vcxproj", "{A501FE41-49C6-4ED4-9711-1C7231784849}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTK12", "..\APIRunner.GDK\Kits\DirectXTK12\DirectXTK12_GDK_2017.vcxproj", "{49F83A6D-D2A5-44C4-B84F-786E9F292499}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Gaming.Desktop.x64 = Debug|Gaming.Desktop.x64
Debug|Gaming.Xbox.Scarlett.x64 = Debug|Gaming.Xbox.Scarlett.x64
Debug|Gaming.Xbox.XboxOne.x64 = Debug|Gaming.Xbox.XboxOne.x64
Profile|Gaming.Desktop.x64 = Profile|Gaming.Desktop.x64
Profile|Gaming.Xbox.Scarlett.x64 = Profile|Gaming.Xbox.Scarlett.x64
Profile|Gaming.Xbox.XboxOne.x64 = Profile|Gaming.Xbox.XboxOne.x64
Release|Gaming.Desktop.x64 = Release|Gaming.Desktop.x64
Release|Gaming.Xbox.Scarlett.x64 = Release|Gaming.Xbox.Scarlett.x64
Release|Gaming.Xbox.XboxOne.x64 = Release|Gaming.Xbox.XboxOne.x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A501FE41-49C6-4ED4-9711-1C7231784849}.Debug|Gaming.Desktop.x64.ActiveCfg = Debug|Gaming.Desktop.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Debug|Gaming.Desktop.x64.Build.0 = Debug|Gaming.Desktop.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Debug|Gaming.Desktop.x64.Deploy.0 = Debug|Gaming.Desktop.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Debug|Gaming.Xbox.Scarlett.x64.ActiveCfg = Debug|Gaming.Xbox.Scarlett.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Debug|Gaming.Xbox.Scarlett.x64.Build.0 = Debug|Gaming.Xbox.Scarlett.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Debug|Gaming.Xbox.Scarlett.x64.Deploy.0 = Debug|Gaming.Xbox.Scarlett.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Debug|Gaming.Xbox.XboxOne.x64.ActiveCfg = Debug|Gaming.Xbox.XboxOne.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Debug|Gaming.Xbox.XboxOne.x64.Build.0 = Debug|Gaming.Xbox.XboxOne.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Debug|Gaming.Xbox.XboxOne.x64.Deploy.0 = Debug|Gaming.Xbox.XboxOne.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Profile|Gaming.Desktop.x64.ActiveCfg = Profile|Gaming.Desktop.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Profile|Gaming.Desktop.x64.Build.0 = Profile|Gaming.Desktop.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Profile|Gaming.Desktop.x64.Deploy.0 = Profile|Gaming.Desktop.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Profile|Gaming.Xbox.Scarlett.x64.ActiveCfg = Profile|Gaming.Xbox.Scarlett.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Profile|Gaming.Xbox.Scarlett.x64.Build.0 = Profile|Gaming.Xbox.Scarlett.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Profile|Gaming.Xbox.Scarlett.x64.Deploy.0 = Profile|Gaming.Xbox.Scarlett.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Profile|Gaming.Xbox.XboxOne.x64.ActiveCfg = Profile|Gaming.Xbox.XboxOne.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Profile|Gaming.Xbox.XboxOne.x64.Build.0 = Profile|Gaming.Xbox.XboxOne.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Profile|Gaming.Xbox.XboxOne.x64.Deploy.0 = Profile|Gaming.Xbox.XboxOne.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Release|Gaming.Desktop.x64.ActiveCfg = Release|Gaming.Desktop.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Release|Gaming.Desktop.x64.Build.0 = Release|Gaming.Desktop.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Release|Gaming.Desktop.x64.Deploy.0 = Release|Gaming.Desktop.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Release|Gaming.Xbox.Scarlett.x64.ActiveCfg = Release|Gaming.Xbox.Scarlett.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Release|Gaming.Xbox.Scarlett.x64.Build.0 = Release|Gaming.Xbox.Scarlett.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Release|Gaming.Xbox.Scarlett.x64.Deploy.0 = Release|Gaming.Xbox.Scarlett.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Release|Gaming.Xbox.XboxOne.x64.ActiveCfg = Release|Gaming.Xbox.XboxOne.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Release|Gaming.Xbox.XboxOne.x64.Build.0 = Release|Gaming.Xbox.XboxOne.x64
{A501FE41-49C6-4ED4-9711-1C7231784849}.Release|Gaming.Xbox.XboxOne.x64.Deploy.0 = Release|Gaming.Xbox.XboxOne.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Debug|Gaming.Desktop.x64.ActiveCfg = Debug|Gaming.Desktop.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Debug|Gaming.Desktop.x64.Build.0 = Debug|Gaming.Desktop.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Debug|Gaming.Xbox.Scarlett.x64.ActiveCfg = Debug|Gaming.Xbox.Scarlett.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Debug|Gaming.Xbox.Scarlett.x64.Build.0 = Debug|Gaming.Xbox.Scarlett.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Debug|Gaming.Xbox.XboxOne.x64.ActiveCfg = Debug|Gaming.Xbox.XboxOne.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Debug|Gaming.Xbox.XboxOne.x64.Build.0 = Debug|Gaming.Xbox.XboxOne.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Profile|Gaming.Desktop.x64.ActiveCfg = Profile|Gaming.Desktop.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Profile|Gaming.Desktop.x64.Build.0 = Profile|Gaming.Desktop.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Profile|Gaming.Xbox.Scarlett.x64.ActiveCfg = Profile|Gaming.Xbox.Scarlett.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Profile|Gaming.Xbox.Scarlett.x64.Build.0 = Profile|Gaming.Xbox.Scarlett.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Profile|Gaming.Xbox.XboxOne.x64.ActiveCfg = Profile|Gaming.Xbox.XboxOne.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Profile|Gaming.Xbox.XboxOne.x64.Build.0 = Profile|Gaming.Xbox.XboxOne.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Release|Gaming.Desktop.x64.ActiveCfg = Release|Gaming.Desktop.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Release|Gaming.Desktop.x64.Build.0 = Release|Gaming.Desktop.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Release|Gaming.Xbox.Scarlett.x64.ActiveCfg = Release|Gaming.Xbox.Scarlett.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Release|Gaming.Xbox.Scarlett.x64.Build.0 = Release|Gaming.Xbox.Scarlett.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Release|Gaming.Xbox.XboxOne.x64.ActiveCfg = Release|Gaming.Xbox.XboxOne.x64
{49F83A6D-D2A5-44C4-B84F-786E9F292499}.Release|Gaming.Xbox.XboxOne.x64.Build.0 = Release|Gaming.Xbox.XboxOne.x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {613F8626-6BFE-415A-A22D-4BA72EC62705}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,592 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Gaming.Xbox.Scarlett.x64">
<Configuration>Debug</Configuration>
<Platform>Gaming.Xbox.Scarlett.x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Profile|Gaming.Xbox.Scarlett.x64">
<Configuration>Profile</Configuration>
<Platform>Gaming.Xbox.Scarlett.x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Gaming.Xbox.Scarlett.x64">
<Configuration>Release</Configuration>
<Platform>Gaming.Xbox.Scarlett.x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Gaming.Xbox.XboxOne.x64">
<Configuration>Release</Configuration>
<Platform>Gaming.Xbox.XboxOne.x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Profile|Gaming.Xbox.XboxOne.x64">
<Configuration>Profile</Configuration>
<Platform>Gaming.Xbox.XboxOne.x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Gaming.Xbox.XboxOne.x64">
<Configuration>Debug</Configuration>
<Platform>Gaming.Xbox.XboxOne.x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Gaming.Desktop.x64">
<Configuration>Release</Configuration>
<Platform>Gaming.Desktop.x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Profile|Gaming.Desktop.x64">
<Configuration>Profile</Configuration>
<Platform>Gaming.Desktop.x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Gaming.Desktop.x64">
<Configuration>Debug</Configuration>
<Platform>Gaming.Desktop.x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>ManualTest</RootNamespace>
<ProjectGuid>{a501fe41-49c6-4ed4-9711-1c7231784849}</ProjectGuid>
<DefaultLanguage>en-US</DefaultLanguage>
<Keyword>Win32Proj</Keyword>
<!-- - - - -->
<MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
<TargetRuntime>Native</TargetRuntime>
<GDKExtLibNames>Xbox.Services.API.C</GDKExtLibNames>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<Import Condition="Exists($(ATGBuildProps))" Project="$(ATGBuildProps)" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<EmbedManifest>false</EmbedManifest>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.Scarlett.x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<EmbedManifest>false</EmbedManifest>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Xbox.XboxOne.x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<EmbedManifest>false</EmbedManifest>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Xbox.Scarlett.x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<EmbedManifest>false</EmbedManifest>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.XboxOne.x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<EmbedManifest>false</EmbedManifest>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.Scarlett.x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<EmbedManifest>false</EmbedManifest>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Desktop.x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Desktop.x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Desktop.x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.Scarlett.x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Xbox.XboxOne.x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Xbox.Scarlett.x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.XboxOne.x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.Scarlett.x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Desktop.x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Desktop.x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Desktop.x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'">
<ReferencePath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</ReferencePath>
<LibraryPath>$(Console_SdkLibPath)</LibraryPath>
<LibraryWPath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</LibraryWPath>
<IncludePath>$(Console_SdkIncludeRoot)</IncludePath>
<ExecutablePath>$(Console_SdkRoot)bin;$(Console_SdkToolPath);$(ExecutablePath)</ExecutablePath>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.Scarlett.x64'">
<ReferencePath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</ReferencePath>
<LibraryPath>$(Console_SdkLibPath)</LibraryPath>
<LibraryWPath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</LibraryWPath>
<IncludePath>$(Console_SdkIncludeRoot)</IncludePath>
<ExecutablePath>$(Console_SdkRoot)bin;$(Console_SdkToolPath);$(ExecutablePath)</ExecutablePath>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Xbox.XboxOne.x64'">
<ReferencePath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</ReferencePath>
<LibraryPath>$(Console_SdkLibPath)</LibraryPath>
<LibraryWPath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</LibraryWPath>
<IncludePath>$(Console_SdkIncludeRoot)</IncludePath>
<ExecutablePath>$(Console_SdkRoot)bin;$(Console_SdkToolPath);$(ExecutablePath)</ExecutablePath>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Xbox.Scarlett.x64'">
<ReferencePath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</ReferencePath>
<LibraryPath>$(Console_SdkLibPath)</LibraryPath>
<LibraryWPath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</LibraryWPath>
<IncludePath>$(Console_SdkIncludeRoot)</IncludePath>
<ExecutablePath>$(Console_SdkRoot)bin;$(Console_SdkToolPath);$(ExecutablePath)</ExecutablePath>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.XboxOne.x64'">
<ReferencePath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</ReferencePath>
<LibraryPath>$(Console_SdkLibPath)</LibraryPath>
<LibraryWPath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</LibraryWPath>
<IncludePath>$(Console_SdkIncludeRoot)</IncludePath>
<ExecutablePath>$(Console_SdkRoot)bin;$(Console_SdkToolPath);$(ExecutablePath)</ExecutablePath>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.Scarlett.x64'">
<ReferencePath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</ReferencePath>
<LibraryPath>$(Console_SdkLibPath)</LibraryPath>
<LibraryWPath>$(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath)</LibraryWPath>
<IncludePath>$(Console_SdkIncludeRoot)</IncludePath>
<ExecutablePath>$(Console_SdkRoot)bin;$(Console_SdkToolPath);$(ExecutablePath)</ExecutablePath>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Desktop.x64'">
<LibraryPath>$(Console_SdkLibPath);$(LibraryPath)</LibraryPath>
<IncludePath>$(Console_SdkIncludeRoot);$(IncludePath)</IncludePath>
<ExecutablePath>$(Console_SdkRoot)bin;$(Console_SdkToolPath);$(ExecutablePath)</ExecutablePath>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Desktop.x64'">
<LibraryPath>$(Console_SdkLibPath);$(LibraryPath)</LibraryPath>
<IncludePath>$(Console_SdkIncludeRoot);$(IncludePath)</IncludePath>
<ExecutablePath>$(Console_SdkRoot)bin;$(Console_SdkToolPath);$(ExecutablePath)</ExecutablePath>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Desktop.x64'">
<LibraryPath>$(Console_SdkLibPath);$(LibraryPath)</LibraryPath>
<IncludePath>$(Console_SdkIncludeRoot);$(IncludePath)</IncludePath>
<ExecutablePath>$(Console_SdkRoot)bin;$(Console_SdkToolPath);$(ExecutablePath)</ExecutablePath>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'">
<Link>
<AdditionalDependencies>uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(ProjectDir);..\APIRunner.GDK\Kits\LiveTK;..\APIRunner.GDK\Kits\DirectXTK12\Inc;..\APIRunner.GDK\Kits\ATGTK;..\APIRunner.GDK\Kits\ATGTelemetry\GDK;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories />
<ForcedUsingFiles />
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>ATG_ENABLE_TELEMETRY;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<ConformanceMode>true</ConformanceMode>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>5204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.Scarlett.x64'">
<Link>
<AdditionalDependencies>uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(ProjectDir);..\APIRunner.GDK\Kits\LiveTK;..\APIRunner.GDK\Kits\DirectXTK12\Inc;..\APIRunner.GDK\Kits\ATGTK;..\APIRunner.GDK\Kits\ATGTelemetry\GDK;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
<ForcedUsingFiles>
</ForcedUsingFiles>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>ATG_ENABLE_TELEMETRY;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<ConformanceMode>true</ConformanceMode>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>5204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Xbox.XboxOne.x64'">
<Link>
<AdditionalDependencies>uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(ProjectDir);..\APIRunner.GDK\Kits\LiveTK;..\APIRunner.GDK\Kits\DirectXTK12\Inc;..\APIRunner.GDK\Kits\ATGTK;..\APIRunner.GDK\Kits\ATGTelemetry\GDK;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories />
<ForcedUsingFiles />
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>ATG_ENABLE_TELEMETRY;NDEBUG;PROFILE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<ConformanceMode>true</ConformanceMode>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>5204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Xbox.Scarlett.x64'">
<Link>
<AdditionalDependencies>uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(ProjectDir);..\APIRunner.GDK\Kits\LiveTK;..\APIRunner.GDK\Kits\DirectXTK12\Inc;..\APIRunner.GDK\Kits\ATGTK;..\APIRunner.GDK\Kits\ATGTelemetry\GDK;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
<ForcedUsingFiles>
</ForcedUsingFiles>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>ATG_ENABLE_TELEMETRY;NDEBUG;PROFILE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<ConformanceMode>true</ConformanceMode>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>5204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.XboxOne.x64'">
<Link>
<AdditionalDependencies>uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<ClCompile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeader>Use</PrecompiledHeader>
<MinimalRebuild>false</MinimalRebuild>
<AdditionalIncludeDirectories>$(ProjectDir);..\APIRunner.GDK\Kits\LiveTK;..\APIRunner.GDK\Kits\DirectXTK12\Inc;..\APIRunner.GDK\Kits\ATGTK;..\APIRunner.GDK\Kits\ATGTelemetry\GDK;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories />
<ForcedUsingFiles />
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>ATG_ENABLE_TELEMETRY;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>5204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.Scarlett.x64'">
<Link>
<AdditionalDependencies>uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<ClCompile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeader>Use</PrecompiledHeader>
<MinimalRebuild>false</MinimalRebuild>
<AdditionalIncludeDirectories>$(ProjectDir);..\APIRunner.GDK\Kits\LiveTK;..\APIRunner.GDK\Kits\DirectXTK12\Inc;..\APIRunner.GDK\Kits\ATGTK;..\APIRunner.GDK\Kits\ATGTelemetry\GDK;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
<ForcedUsingFiles>
</ForcedUsingFiles>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>ATG_ENABLE_TELEMETRY;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>5204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Desktop.x64'">
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>uuid.lib;$(Console_Libs);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(ProjectDir);..\APIRunner.GDK\Kits\LiveTK;..\APIRunner.GDK\Kits\DirectXTK12\Inc;..\APIRunner.GDK\Kits\ATGTK;..\APIRunner.GDK\Kits\ATGTelemetry\GDK;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>ATG_ENABLE_TELEMETRY;NDEBUG;__WRL_NO_DEFAULT_LIB__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<ConformanceMode>true</ConformanceMode>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>5204</DisableSpecificWarnings>
</ClCompile>
<FXCompile>
<ShaderModel>6.0</ShaderModel>
<EnableDebuggingInformation>true</EnableDebuggingInformation>
<AdditionalOptions>/Fd "$(OutDir)%(Filename).pdb" %(AdditionalOptions)</AdditionalOptions>
</FXCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Desktop.x64'">
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>uuid.lib;$(Console_Libs);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(ProjectDir);..\APIRunner.GDK\Kits\LiveTK;..\APIRunner.GDK\Kits\DirectXTK12\Inc;..\APIRunner.GDK\Kits\ATGTK;..\APIRunner.GDK\Kits\ATGTelemetry\GDK;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>ATG_ENABLE_TELEMETRY;NDEBUG;__WRL_NO_DEFAULT_LIB__;PROFILE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<ConformanceMode>true</ConformanceMode>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>5204</DisableSpecificWarnings>
</ClCompile>
<FXCompile>
<ShaderModel>6.0</ShaderModel>
<EnableDebuggingInformation>true</EnableDebuggingInformation>
<AdditionalOptions>/Fd "$(OutDir)%(Filename).pdb" %(AdditionalOptions)</AdditionalOptions>
</FXCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Desktop.x64'">
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>uuid.lib;$(Console_Libs);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
<ClCompile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeader>Use</PrecompiledHeader>
<MinimalRebuild>false</MinimalRebuild>
<AdditionalIncludeDirectories>$(ProjectDir);..\APIRunner.GDK\Kits\LiveTK;..\APIRunner.GDK\Kits\DirectXTK12\Inc;..\APIRunner.GDK\Kits\ATGTK;..\APIRunner.GDK\Kits\ATGTelemetry\GDK;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>ATG_ENABLE_TELEMETRY;_DEBUG;__WRL_NO_DEFAULT_LIB__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>5204</DisableSpecificWarnings>
</ClCompile>
<FXCompile>
<ShaderModel>6.0</ShaderModel>
<EnableDebuggingInformation>true</EnableDebuggingInformation>
<AdditionalOptions>/Fd "$(OutDir)%(Filename).pdb" %(AdditionalOptions)</AdditionalOptions>
</FXCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<CopyFileToFolders>
<DestinationFolders>$(OutDir)Assets</DestinationFolders>
</CopyFileToFolders>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\ControllerFont.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\CSVReader.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\SampleGUI.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\TextConsole.h" />
<ClInclude Include="ManualTest.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="SampleLiveInfoHUD.h" />
<ClInclude Include="StepTimer.h" />
<ClInclude Include="DeviceResources.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\StringUtil.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\Json.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\json\json.hpp" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\ATGColors.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\d3dx12.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\FindMedia.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\APIRunner.GDK\Kits\ATGTK\SampleGUI.cpp" />
<ClCompile Include="..\APIRunner.GDK\Kits\ATGTK\TextConsole.cpp" />
<ClCompile Include="ManualTest.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="DeviceResources.cpp" />
<ClCompile Include="..\APIRunner.GDK\Kits\ATGTK\StringUtil.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.Scarlett.x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Xbox.XboxOne.x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Xbox.Scarlett.x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.XboxOne.x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.Scarlett.x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Desktop.x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Desktop.x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Desktop.x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="SampleLiveInfoHUD.cpp" />
</ItemGroup>
<ItemGroup>
<MGCCompile Include="MicrosoftGameConfig.mgc" />
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="Media\Textures\GamerPic.png">
<DeploymentContent>true</DeploymentContent>
</CopyFileToFolders>
</ItemGroup>
<ItemGroup>
<None Include="Media\Fonts\Courier_16.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\Courier_36.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\SegoeUI_18.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\SegoeUI_18_Bold.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\SegoeUI_18_Italic.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\SegoeUI_22.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\SegoeUI_22_Bold.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\SegoeUI_22_Italic.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\SegoeUI_36.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\SegoeUI_36_Bold.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\SegoeUI_36_Italic.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\XboxOneController.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\XboxOneControllerLegend.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\XboxOneControllerLegendSmall.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Media\Fonts\XboxOneControllerSmall.spritefont">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Assets\SampleUI.csv">
<DeploymentContent>true</DeploymentContent>
</None>
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="Assets\Logo.png">
<DeploymentContent>true</DeploymentContent>
</CopyFileToFolders>
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="Assets\LargeLogo.png">
<DeploymentContent>true</DeploymentContent>
</CopyFileToFolders>
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="Assets\SmallLogo.png">
<DeploymentContent>true</DeploymentContent>
</CopyFileToFolders>
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="Assets\SplashScreen.png">
<DeploymentContent>true</DeploymentContent>
</CopyFileToFolders>
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="Assets\StoreLogo.png">
<DeploymentContent>true</DeploymentContent>
</CopyFileToFolders>
</ItemGroup>
<ItemGroup>
<Image Include="Media\Textures\ATGSampleBackground.DDS">
<DeploymentContent>true</DeploymentContent>
</Image>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\APIRunner.GDK\Kits\DirectXTK12\DirectXTK12_GDK_2017.vcxproj">
<Project>{49f83a6d-d2a5-44c4-b84f-786e9f292499}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

Просмотреть файл

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Common">
<UniqueIdentifier>d0a754c7-880c-4d67-8324-08611b7402c1</UniqueIdentifier>
</Filter>
<Filter Include="Assets">
<UniqueIdentifier>d99f4f2b-95af-447b-9a87-a5636e45af50</UniqueIdentifier>
<Extensions>ico;cur;bmp;dds;dlg;fbx;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="ATG Tool Kit">
<UniqueIdentifier>655550be-56fc-4265-8a51-5c51c987dea5</UniqueIdentifier>
</Filter>
<Filter Include="Xbox Live Tool Kit">
<UniqueIdentifier>003f9d58-a022-48a0-bad6-143a8dfa78c2</UniqueIdentifier>
</Filter>
<Filter Include="External">
<UniqueIdentifier>396f274a-6b80-4569-a46f-bc59173d9d04</UniqueIdentifier>
</Filter>
<Filter Include="ReadMe">
<UniqueIdentifier>{b6361f05-2e9f-4f2f-b537-15bf9ca05024}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="ManualTest.h" />
<ClInclude Include="StepTimer.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="DeviceResources.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="SampleLiveInfoHUD.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\ControllerFont.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\CSVReader.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\SampleGUI.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\TextConsole.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\StringUtil.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\Json.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\json\json.hpp" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\ATGColors.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\d3dx12.h" />
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\FindMedia.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="ManualTest.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="DeviceResources.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="SampleLiveInfoHUD.cpp" />
<ClCompile Include="..\APIRunner.GDK\Kits\ATGTK\SampleGUI.cpp" />
<ClCompile Include="..\APIRunner.GDK\Kits\ATGTK\TextConsole.cpp" />
<ClCompile Include="..\APIRunner.GDK\Kits\ATGTK\StringUtil.cpp" />
</ItemGroup>
<ItemGroup>
<MGCCompile Include="MicrosoftGameConfig.mgc" />
</ItemGroup>
<ItemGroup>
<None Include="Assets\SampleUI.csv">
<Filter>Assets</Filter>
</None>
<None Include="Media\Fonts\Courier_16.spritefont" />
<None Include="Media\Fonts\XboxOneController.spritefont" />
<None Include="Media\Fonts\XboxOneControllerLegend.spritefont" />
<None Include="Media\Fonts\XboxOneControllerLegendSmall.spritefont" />
<None Include="Media\Fonts\XboxOneControllerSmall.spritefont" />
<None Include="Media\Fonts\Courier_36.spritefont" />
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="Assets\Logo.png">
<Filter>Assets</Filter>
</CopyFileToFolders>
<CopyFileToFolders Include="Assets\LargeLogo.png">
<Filter>Assets</Filter>
</CopyFileToFolders>
<CopyFileToFolders Include="Assets\SmallLogo.png">
<Filter>Assets</Filter>
</CopyFileToFolders>
<CopyFileToFolders Include="Assets\SplashScreen.png">
<Filter>Assets</Filter>
</CopyFileToFolders>
<CopyFileToFolders Include="Assets\StoreLogo.png">
<Filter>Assets</Filter>
</CopyFileToFolders>
<CopyFileToFolders Include="Media\Textures\GamerPic.png">
<Filter>Assets</Filter>
</CopyFileToFolders>
</ItemGroup>
<ItemGroup>
<Image Include="Media\Textures\ATGSampleBackground.DDS">
<Filter>Assets</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Font Include="Media\Fonts\SegoeUI_36_Italic.spritefont">
<Filter>Assets</Filter>
</Font>
<Font Include="Media\Fonts\SegoeUI_18.spritefont">
<Filter>Assets</Filter>
</Font>
<Font Include="Media\Fonts\SegoeUI_18_Bold.spritefont">
<Filter>Assets</Filter>
</Font>
<Font Include="Media\Fonts\SegoeUI_18_Italic.spritefont">
<Filter>Assets</Filter>
</Font>
<Font Include="Media\Fonts\SegoeUI_22.spritefont">
<Filter>Assets</Filter>
</Font>
<Font Include="Media\Fonts\SegoeUI_22_Bold.spritefont">
<Filter>Assets</Filter>
</Font>
<Font Include="Media\Fonts\SegoeUI_22_Italic.spritefont">
<Filter>Assets</Filter>
</Font>
<Font Include="Media\Fonts\SegoeUI_36.spritefont">
<Filter>Assets</Filter>
</Font>
<Font Include="Media\Fonts\SegoeUI_36_Bold.spritefont">
<Filter>Assets</Filter>
</Font>
</ItemGroup>
</Project>

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/Courier_16.spritefont Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/Courier_36.spritefont Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/SegoeUI_18.spritefont Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/SegoeUI_18_Bold.spritefont Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/SegoeUI_18_Italic.spritefont Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/SegoeUI_22.spritefont Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/SegoeUI_22_Bold.spritefont Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/SegoeUI_22_Italic.spritefont Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/SegoeUI_36.spritefont Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/SegoeUI_36_Bold.spritefont Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/SegoeUI_36_Italic.spritefont Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Fonts/XboxOneController.spritefont Normal file

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Textures/ATGSampleBackground.DDS Normal file

Двоичный файл не отображается.

Двоичные данные
Tests/GDK/ManualTest.GDK/Media/Textures/GamerPic.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 766 B

Просмотреть файл

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Game configVersion="1">
<!-- Version "1" is supported by March 2022 GDK or later -->
<Identity Name="41336MicrosoftATG.NetRumble2" Publisher="CN=A4954634-DF4B-47C7-AB70-D3215D246AF1" Version="1.0.1.0"/>
<ExecutableList>
<Executable Name="ManualTest.exe"
Id="Game"/>
</ExecutableList>
<TitleId>76b1590E</TitleId>
<MSAAppId>0000000044264AE3</MSAAppId>
<ShellVisuals DefaultDisplayName="ATG ManualTest Sample"
PublisherDisplayName="Xbox ATG"
StoreLogo="Assets\StoreLogo.png"
Square480x480Logo="Assets\LargeLogo.png"
Square150x150Logo="Assets\Logo.png"
Square44x44Logo="Assets\SmallLogo.png"
Description="ManualTest"
ForegroundText="dark"
BackgroundColor="#000000"
SplashScreenImage="Assets\SplashScreen.png"/>
</Game>

Просмотреть файл

@ -0,0 +1,341 @@
//--------------------------------------------------------------------------------------
// File: LiveInfoHUD.cpp
//
// A Heads Up Display (HUD) for Xbox Live samples
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-------------------------------------------------------------------------------------
#include "pch.h"
#include "SampleLiveInfoHUD.h"
#include <XGame.h>
#include <XSystem.h>
#include "DescriptorHeap.h"
#include "DirectXHelpers.h"
#include "ResourceUploadBatch.h"
#include "WICTextureLoader.h"
#include "ATGColors.h"
#include "FindMedia.h"
using namespace ATG;
using namespace DirectX;
namespace
{
const size_t c_GamerPicBuffer = 1024 * 16;
constexpr float c_StatusBarCoordinate = 1010.0f;
constexpr float c_HeaderBarCoordinate = 10.0f;
constexpr long c_GamerPicCoordinate = long(c_HeaderBarCoordinate) + 11;
}
_Use_decl_annotations_
SampleLiveInfoHUD::SampleLiveInfoHUD(char const* sampleTitle) noexcept(false) :
m_sampleTitle(sampleTitle),
m_gamerTag("No User Signed in"),
m_scaleWidth(1.f),
m_scaleHeight(1.f),
m_gamerPicCPU{},
m_gamerPicGPU{},
m_gamerPicDataSize(0),
m_gamerPicReady(false)
{
}
void SampleLiveInfoHUD::Initialize(int windowWidth, int windowHeight)
{
UNREFERENCED_PARAMETER(windowWidth);
UNREFERENCED_PARAMETER(windowHeight);
uint32_t titleId = {};
HRESULT hr = XGameGetXboxTitleId(&titleId);
if (SUCCEEDED(hr))
{
char hexTitleId[16] = {};
sprintf_s(hexTitleId, "0x%08X", titleId);
m_titleId.assign(hexTitleId);
char scidBuffer[64] = {};
sprintf_s(scidBuffer, "00000000-0000-0000-0000-0000%08x", titleId);
m_serviceConfigId = scidBuffer;
}
else
{
m_titleId = "Not Set";
m_serviceConfigId = "Not Set";
}
char sandboxId[XSystemXboxLiveSandboxIdMaxBytes] = {};
XSystemGetXboxLiveSandboxId(XSystemXboxLiveSandboxIdMaxBytes, sandboxId, nullptr);
m_sandboxId = sandboxId;
}
void SampleLiveInfoHUD::Update(_In_ ID3D12CommandQueue* commandQueue)
{
if (!m_gamerPicReady || !m_device)
return;
CreateShaderResourceView(m_device.Get(), m_gamerDefaultPic.Get(), m_gamerPicCPU);
if (m_gamerPicDataSize && m_gamerPicData)
{
ResourceUploadBatch upload(m_device.Get());
upload.Begin();
if (SUCCEEDED(CreateWICTextureFromMemory(m_device.Get(), upload, m_gamerPicData.get(), m_gamerPicDataSize, m_gamerPic.ReleaseAndGetAddressOf())))
{
CreateShaderResourceView(m_device.Get(), m_gamerPic.Get(), m_gamerPicCPU);
}
auto result = upload.End(commandQueue);
result.wait();
}
m_gamerPicReady = false;
}
void SampleLiveInfoHUD::ReleaseDevice()
{
m_gamerPic.Reset();
m_gamerDefaultPic.Reset();
m_device.Reset();
m_batch.reset();
m_smallFont.reset();
m_boldFont.reset();
m_titleFont.reset();
m_gamerPicCPU = {};
m_gamerPicGPU = {};
}
_Use_decl_annotations_
void SampleLiveInfoHUD::RestoreDevice(
ID3D12Device* device,
const RenderTargetState& renderTarget,
ResourceUploadBatch& resourceUpload,
DescriptorPile& pile)
{
m_device = device;
SpriteBatchPipelineStateDescription pd(renderTarget);
m_batch = std::make_unique<SpriteBatch>(device, resourceUpload, pd);
wchar_t buff[MAX_PATH] = {};
DX::FindMediaFile(buff, MAX_PATH, L"SegoeUI_18.spritefont");
size_t index = pile.Allocate();
m_smallFont = std::make_unique<SpriteFont>(device, resourceUpload, buff, pile.GetCpuHandle(index), pile.GetGpuHandle(index));
DX::FindMediaFile(buff, MAX_PATH, L"SegoeUI_18_Bold.spritefont");
index = pile.Allocate();
m_boldFont = std::make_unique<SpriteFont>(device, resourceUpload, buff, pile.GetCpuHandle(index), pile.GetGpuHandle(index));
DX::FindMediaFile(buff, MAX_PATH, L"SegoeUI_36.spritefont");
index = pile.Allocate();
m_titleFont = std::make_unique<SpriteFont>(device, resourceUpload, buff, pile.GetCpuHandle(index), pile.GetGpuHandle(index));
DX::FindMediaFile(buff, MAX_PATH, L"GamerPic.png");
DX::ThrowIfFailed(
CreateWICTextureFromFile(device, resourceUpload, buff, m_gamerDefaultPic.ReleaseAndGetAddressOf())
);
index = pile.Allocate();
m_gamerPicCPU = pile.GetCpuHandle(index);
m_gamerPicGPU = pile.GetGpuHandle(index);
if (m_gamerPicDataSize > 0 && m_gamerPicData)
{
m_gamerPicReady = true;
}
CreateShaderResourceView(device, m_gamerDefaultPic.Get(), m_gamerPicCPU);
}
_Use_decl_annotations_
void SampleLiveInfoHUD::SetUser(XUserHandle user, XTaskQueueHandle queue)
{
if (!user)
{
m_gamerTag = "No User Signed in";
m_gamerPicDataSize = 0;
m_gamerPicData.reset();
CreateShaderResourceView(m_device.Get(), m_gamerDefaultPic.Get(), m_gamerPicCPU);
}
else
{
m_gamerTag.resize(XUserGamertagComponentClassicMaxBytes);
if (FAILED(XUserGetGamertag(user, XUserGamertagComponent::Classic, XUserGamertagComponentClassicMaxBytes, &m_gamerTag[0], nullptr)))
{
m_gamerTag = "***ERROR***";
}
auto async = new XAsyncBlock{};
async->context = this;
async->queue = queue;
async->callback = [](XAsyncBlock *async)
{
auto pThis = reinterpret_cast<SampleLiveInfoHUD*>(async->context);
pThis->m_gamerPicData.reset(new uint8_t[c_GamerPicBuffer]);
size_t bufferFilled = 0;
HRESULT hr = XUserGetGamerPictureResult(async, c_GamerPicBuffer, pThis->m_gamerPicData.get(), &bufferFilled);
if (SUCCEEDED(hr))
{
pThis->m_gamerPicDataSize = bufferFilled;
pThis->m_gamerPicReady = true;
}
else
{
pThis->m_gamerPicDataSize = 0;
pThis->m_gamerPicData.reset();
}
delete async;
};
DX::ThrowIfFailed(XUserGetGamerPictureAsync(user, XUserGamerPictureSize::Small, async));
}
}
void SampleLiveInfoHUD::ClearLog()
{
std::lock_guard<std::mutex> lock(m_logLinesMutex);
m_logLines.clear();
}
void WriteLogToFile(const std::string& strIn)
{
HANDLE hFile;
std::string str = strIn;
str += "\r\n";
DWORD dwBytesToWrite = (DWORD) str.length();
DWORD dwBytesWritten = 0;
BOOL bErrorFlag = FALSE;
hFile = CreateFile(L"D:\\EventsLog.txt", FILE_APPEND_DATA, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return;
}
bErrorFlag = WriteFile(
hFile, // open file handle
str.data(), // start of data to write
dwBytesToWrite, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL); // no overlapped structure
if (FALSE == bErrorFlag)
{
}
else
{
if (dwBytesWritten != dwBytesToWrite)
{
//printf("Error: dwBytesWritten != dwBytesToWrite\n");
}
else
{
//printf("Wrote %d bytes to EventsLog.txt successfully.\n", dwBytesWritten);
}
}
CloseHandle(hFile);
}
void SampleLiveInfoHUD::AddLog(const std::string& strIn)
{
std::lock_guard<std::mutex> lock(m_logLinesMutex);
SYSTEMTIME st;
GetLocalTime(&st);
char sz[255];
sprintf_s(sz, 255, "[%0.2d/%0.2d %0.2d:%0.2d:%0.2d:%0.4d] ",
st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
std::string strTime = sz;
std::string str = strTime + strIn;
for (size_t i = 0; i < str.length(); i++)
{
if (static_cast<unsigned char>(str[i]) > 0x80) // ignore invalid chars since font can't render
{
str[i] = ' ';
}
}
OutputDebugStringA(str.c_str());
OutputDebugStringA("\n");
if (m_logLines.size() > 27)
{
m_logLines.erase(m_logLines.begin());
}
m_logLines.push_back(str);
WriteLogToFile(str);
}
_Use_decl_annotations_
void SampleLiveInfoHUD::Render(ID3D12GraphicsCommandList* commandList)
{
m_batch->Begin(
commandList,
SpriteSortMode_Deferred,
DirectX::XMMatrixAffineTransformation2D(XMVectorSet(m_scaleWidth, m_scaleHeight, 0, 0), XMVectorZero(), 0.f, XMVectorZero())
);
if(m_logLines.size() > 0)
{
std::lock_guard<std::mutex> lock(m_logLinesMutex);
float y = 100.0f;
for (auto& s : m_logLines)
{
m_smallFont->DrawString(m_batch.get(), s.c_str(), XMFLOAT2(60.f, y), ATG::Colors::White, 0.0f);
y += 30.0f;
}
}
float y = 800.0f;
float x = 1210.0f;
m_smallFont->DrawString(m_batch.get(), "Press 1 for XblInit. Ctrl+1 for XblCleanup", XMFLOAT2(x, y += 30.0f), ATG::Colors::OffWhite, 0.0f);
m_smallFont->DrawString(m_batch.get(), "Press 2 for XUserAdd. Ctrl+2 for UserClose", XMFLOAT2(x, y += 30.0f), ATG::Colors::OffWhite, 0.0f);
m_smallFont->DrawString(m_batch.get(), "Press 3 for RTA on. Ctrl+3 for RTA off", XMFLOAT2(x, y += 30.0f), ATG::Colors::OffWhite, 0.0f);
m_smallFont->DrawString(m_batch.get(), "Press 4 for CreateSession. Ctrl+4 for session close", XMFLOAT2(x, y += 30.0f), ATG::Colors::OffWhite, 0.0f);
m_smallFont->DrawString(m_batch.get(), "Press 5 for WriteSession", XMFLOAT2(x, y += 30.0f), ATG::Colors::OffWhite, 0.0f);
m_boldFont->DrawString(m_batch.get(), "Sandbox Id:", XMFLOAT2(270.f, c_StatusBarCoordinate), ATG::Colors::OffWhite, 0.0f);
m_smallFont->DrawString(m_batch.get(), m_sandboxId.c_str(), XMFLOAT2(410.f, c_StatusBarCoordinate), ATG::Colors::OffWhite, 0.0f);
m_boldFont->DrawString(m_batch.get(), "Title Id:", XMFLOAT2(590.f, c_StatusBarCoordinate), ATG::Colors::OffWhite, 0.0f);
m_smallFont->DrawString(m_batch.get(), m_titleId.c_str(), XMFLOAT2(680.f, c_StatusBarCoordinate), ATG::Colors::OffWhite, 0.0f);
m_boldFont->DrawString(m_batch.get(), "Service Config Id:", XMFLOAT2(950.f, c_StatusBarCoordinate), ATG::Colors::OffWhite, 0.0f);
m_smallFont->DrawString(m_batch.get(), m_serviceConfigId.c_str(), XMFLOAT2(1155.f, c_StatusBarCoordinate), ATG::Colors::OffWhite, 0.0f);
m_batch->End();
}
void SampleLiveInfoHUD::SetViewport(const D3D12_VIEWPORT &viewport)
{
if (m_batch)
{
m_batch->SetViewport(viewport);
SetWindowSize(viewport.Width, viewport.Height);
}
}

Просмотреть файл

@ -0,0 +1,90 @@
//--------------------------------------------------------------------------------------
// File: LiveInfoHUD.h
//
// A Heads Up Display (HUD) for Xbox Live samples
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-------------------------------------------------------------------------------------
#pragma once
#include <atomic>
#include <memory>
#include <string>
#include <XUser.h>
#include "SpriteBatch.h"
#include "SpriteFont.h"
namespace ATG
{
class SampleLiveInfoHUD
{
public:
explicit SampleLiveInfoHUD(_In_ char const* sampleTitle) noexcept(false);
void Initialize(int windowWidth = 0, int windowHeight = 0);
void Update(_In_ ID3D12CommandQueue* commandQueue);
void ReleaseDevice();
void RestoreDevice(_In_ ID3D12Device* context,
const DirectX::RenderTargetState& renderTarget,
DirectX::ResourceUploadBatch& resourceUpload,
DirectX::DescriptorPile& pile);
void SetUser(_In_opt_ XUserHandle user, _In_ XTaskQueueHandle queue);
void AddLog(const std::string& str);
void ClearLog();
void Render(_In_ ID3D12GraphicsCommandList *commandList);
void SetViewport(const D3D12_VIEWPORT &viewport);
void SetWindowSize(float width, float height) { m_scaleWidth = width / LAYOUT_PIXEL_WIDTH, m_scaleHeight = height / LAYOUT_PIXEL_HEIGHT; }
private:
SampleLiveInfoHUD(SampleLiveInfoHUD&&) = delete;
SampleLiveInfoHUD& operator= (SampleLiveInfoHUD&&) = delete;
SampleLiveInfoHUD(SampleLiveInfoHUD const&) = delete;
SampleLiveInfoHUD& operator= (SampleLiveInfoHUD const&) = delete;
private:
const float LAYOUT_PIXEL_WIDTH = 1920.f;
const float LAYOUT_PIXEL_HEIGHT = 1080.f;
std::string m_sampleTitle;
std::string m_serviceConfigId;
std::string m_titleId;
std::string m_sandboxId;
std::string m_gamerTag;
Microsoft::WRL::ComPtr<ID3D12Resource> m_gamerPic;
Microsoft::WRL::ComPtr<ID3D12Resource> m_gamerDefaultPic;
Microsoft::WRL::ComPtr<ID3D12Device> m_device;
// Direct3D resources
std::unique_ptr<DirectX::SpriteBatch> m_batch;
std::unique_ptr<DirectX::SpriteFont> m_smallFont;
std::unique_ptr<DirectX::SpriteFont> m_boldFont;
std::unique_ptr<DirectX::SpriteFont> m_titleFont;
float m_scaleWidth;
float m_scaleHeight;
D3D12_CPU_DESCRIPTOR_HANDLE m_gamerPicCPU;
D3D12_GPU_DESCRIPTOR_HANDLE m_gamerPicGPU;
std::unique_ptr<uint8_t> m_gamerPicData;
size_t m_gamerPicDataSize;
std::atomic<bool> m_gamerPicReady;
std::mutex m_logLinesMutex;
std::vector<std::string> m_logLines;
};
}

Просмотреть файл

@ -0,0 +1,190 @@
//
// StepTimer.h - A simple timer that provides elapsed time information
//
#pragma once
#include <cmath>
#include <cstdint>
#include <exception>
namespace DX
{
// Helper class for animation and simulation timing.
class StepTimer
{
public:
StepTimer() noexcept(false) :
m_elapsedTicks(0),
m_totalTicks(0),
m_leftOverTicks(0),
m_frameCount(0),
m_framesPerSecond(0),
m_framesThisSecond(0),
m_qpcSecondCounter(0),
m_isFixedTimeStep(false),
m_targetElapsedTicks(TicksPerSecond / 60)
{
if (!QueryPerformanceFrequency(&m_qpcFrequency))
{
throw std::exception();
}
if (!QueryPerformanceCounter(&m_qpcLastTime))
{
throw std::exception();
}
// Initialize max delta to 1/10 of a second.
m_qpcMaxDelta = static_cast<uint64_t>(m_qpcFrequency.QuadPart / 10);
}
// Get elapsed time since the previous Update call.
uint64_t GetElapsedTicks() const noexcept { return m_elapsedTicks; }
double GetElapsedSeconds() const noexcept { return TicksToSeconds(m_elapsedTicks); }
// Get total time since the start of the program.
uint64_t GetTotalTicks() const noexcept { return m_totalTicks; }
double GetTotalSeconds() const noexcept { return TicksToSeconds(m_totalTicks); }
// Get total number of updates since start of the program.
uint32_t GetFrameCount() const noexcept { return m_frameCount; }
// Get the current framerate.
uint32_t GetFramesPerSecond() const noexcept { return m_framesPerSecond; }
// Set whether to use fixed or variable timestep mode.
void SetFixedTimeStep(bool isFixedTimestep) noexcept { m_isFixedTimeStep = isFixedTimestep; }
// Set how often to call Update when in fixed timestep mode.
void SetTargetElapsedTicks(uint64_t targetElapsed) noexcept { m_targetElapsedTicks = targetElapsed; }
void SetTargetElapsedSeconds(double targetElapsed) noexcept { m_targetElapsedTicks = SecondsToTicks(targetElapsed); }
// Integer format represents time using 10,000,000 ticks per second.
static constexpr uint64_t TicksPerSecond = 10000000;
static constexpr double TicksToSeconds(uint64_t ticks) noexcept { return static_cast<double>(ticks) / TicksPerSecond; }
static constexpr uint64_t SecondsToTicks(double seconds) noexcept { return static_cast<uint64_t>(seconds * TicksPerSecond); }
// After an intentional timing discontinuity (for instance a blocking IO operation)
// call this to avoid having the fixed timestep logic attempt a set of catch-up
// Update calls.
void ResetElapsedTime()
{
if (!QueryPerformanceCounter(&m_qpcLastTime))
{
throw std::exception();
}
m_leftOverTicks = 0;
m_framesPerSecond = 0;
m_framesThisSecond = 0;
m_qpcSecondCounter = 0;
}
// Update timer state, calling the specified Update function the appropriate number of times.
template<typename TUpdate>
void Tick(const TUpdate& update)
{
// Query the current time.
LARGE_INTEGER currentTime;
if (!QueryPerformanceCounter(&currentTime))
{
throw std::exception();
}
uint64_t timeDelta = static_cast<uint64_t>(currentTime.QuadPart - m_qpcLastTime.QuadPart);
m_qpcLastTime = currentTime;
m_qpcSecondCounter += timeDelta;
// Clamp excessively large time deltas (e.g. after paused in the debugger).
if (timeDelta > m_qpcMaxDelta)
{
timeDelta = m_qpcMaxDelta;
}
// Convert QPC units into a canonical tick format. This cannot overflow due to the previous clamp.
timeDelta *= TicksPerSecond;
timeDelta /= static_cast<uint64_t>(m_qpcFrequency.QuadPart);
uint32_t lastFrameCount = m_frameCount;
if (m_isFixedTimeStep)
{
// Fixed timestep update logic
// If the app is running very close to the target elapsed time (within 1/4 of a millisecond) just clamp
// the clock to exactly match the target value. This prevents tiny and irrelevant errors
// from accumulating over time. Without this clamping, a game that requested a 60 fps
// fixed update, running with vsync enabled on a 59.94 NTSC display, would eventually
// accumulate enough tiny errors that it would drop a frame. It is better to just round
// small deviations down to zero to leave things running smoothly.
if (static_cast<uint64_t>(std::abs(static_cast<int64_t>(timeDelta - m_targetElapsedTicks))) < TicksPerSecond / 4000)
{
timeDelta = m_targetElapsedTicks;
}
m_leftOverTicks += timeDelta;
while (m_leftOverTicks >= m_targetElapsedTicks)
{
m_elapsedTicks = m_targetElapsedTicks;
m_totalTicks += m_targetElapsedTicks;
m_leftOverTicks -= m_targetElapsedTicks;
m_frameCount++;
update();
}
}
else
{
// Variable timestep update logic.
m_elapsedTicks = timeDelta;
m_totalTicks += timeDelta;
m_leftOverTicks = 0;
m_frameCount++;
update();
}
// Track the current framerate.
if (m_frameCount != lastFrameCount)
{
m_framesThisSecond++;
}
if (m_qpcSecondCounter >= static_cast<uint64_t>(m_qpcFrequency.QuadPart))
{
m_framesPerSecond = m_framesThisSecond;
m_framesThisSecond = 0;
m_qpcSecondCounter %= static_cast<uint64_t>(m_qpcFrequency.QuadPart);
}
}
private:
// Source timing data uses QPC units.
LARGE_INTEGER m_qpcFrequency;
LARGE_INTEGER m_qpcLastTime;
uint64_t m_qpcMaxDelta;
// Derived timing data uses a canonical tick format.
uint64_t m_elapsedTicks;
uint64_t m_totalTicks;
uint64_t m_leftOverTicks;
// Members for tracking the framerate.
uint32_t m_frameCount;
uint32_t m_framesPerSecond;
uint32_t m_framesThisSecond;
uint64_t m_qpcSecondCounter;
// Members for configuring fixed timestep mode.
bool m_isFixedTimeStep;
uint64_t m_targetElapsedTicks;
};
}

Просмотреть файл

@ -0,0 +1,10 @@
//--------------------------------------------------------------------------------------
// pch.cpp
//
// Include the standard header and generate the precompiled header.
//
// Advanced Technology Group (ATG)
// Copyright (C) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "pch.h"

Просмотреть файл

@ -0,0 +1,153 @@
//--------------------------------------------------------------------------------------
// pch.h
//
// Header for standard system include files.
//
// Advanced Technology Group (ATG)
// Copyright (C) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#pragma once
#include <winsdkver.h>
#define _WIN32_WINNT 0x0A00
#include <sdkddkver.h>
// Use the C++ standard templated min/max
#define NOMINMAX
// DirectX apps don't need GDI
#define NODRAWTEXT
#define NOGDI
#define NOBITMAP
// Include <mcx.h> if you need this
#define NOMCX
// Include <winsvc.h> if you need this
#define NOSERVICE
// WinHelp is deprecated
#define NOHELP
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#include <wrl/client.h>
#include <wrl/event.h>
#include <grdk.h>
#if _GRDK_VER < 0x55F00C58 /* GDK Edition 220300 */
#error This sample requires the March 2022 GDK or later
#endif
#ifdef _GAMING_XBOX_SCARLETT
#include <d3d12_xs.h>
#include <d3dx12_xs.h>
#elif defined(_GAMING_XBOX)
#include <d3d12_x.h>
#include <d3dx12_x.h>
#else
#include <d3d12.h>
#include <dxgi1_6.h>
#ifdef _DEBUG
#include <dxgidebug.h>
#endif
#include "d3dx12.h"
#endif
#define _XM_NO_XMVECTOR_OVERLOADS_
#include <DirectXMath.h>
#include <DirectXColors.h>
#include <algorithm>
#include <atomic>
#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <cwchar>
#include <exception>
#include <iterator>
#include <memory>
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <tuple>
#ifdef _GAMING_XBOX
#include <pix3.h>
#else
// To use graphics markup events with the latest version of PIX, change this to include <pix3.h>
// then add the NuGet package WinPixEventRuntime to the project.
#include <pix.h>
#endif
#include "xal\xal.h"
#include "xsapi-c\services_c.h"
#include <XUser.h>
#include <XTaskQueue.h>
#include <XGame.h>
#include <XSystem.h>
#include "DescriptorHeap.h"
#include "ResourceUploadBatch.h"
#include "SpriteBatch.h"
#include "SpriteFont.h"
#include "DirectXHelpers.h"
#include "GamePad.h"
#include "GraphicsMemory.h"
#include "Keyboard.h"
#include "Mouse.h"
#include "RenderTargetState.h"
namespace DX
{
// Helper class for COM exceptions
class com_exception : public std::exception
{
public:
com_exception(HRESULT hr) noexcept : result(hr) {}
const char* what() const override
{
static char s_str[64] = {};
sprintf_s(s_str, "Failure with HRESULT of %08X", static_cast<unsigned int>(result));
return s_str;
}
private:
HRESULT result;
};
// Helper utility converts D3D API failures into exceptions.
inline void ThrowIfFailed(HRESULT hr)
{
if (FAILED(hr))
{
#ifdef _DEBUG
char str[64] = {};
sprintf_s(str, "**ERROR** Fatal Error with HRESULT of %08X\n", static_cast<unsigned int>(hr));
OutputDebugStringA(str);
__debugbreak();
#endif
throw com_exception(hr);
}
}
}
// Enable off by default warnings to improve code conformance
#pragma warning(default : 4061 4062 4191 4242 4263 4264 4265 4266 4289 4365 4746 4826 4841 4986 4987 5029 5038 5042)

Просмотреть файл

@ -55,6 +55,7 @@ HttpMock & HttpMock::operator=(HttpMock&& other)
HttpMock::~HttpMock()
{
HCMockRemoveMock(m_handle);
HCMockCallCloseHandle(m_handle);
}
void HttpMock::SetResponseHttpStatus(uint32_t httpStatus) const noexcept