> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Guía de migración al Microsoft Game Development Kit para XBOX One

> Información general sobre la migración de un título de juego o motor existente de XBOX One al GDK.

# Guía de migración al Microsoft Game Development Kit para XBOX One

Este tema proporciona información general sobre las técnicas para migrar una base de código existente a la plataforma del Microsoft Game Development Kit (GDK) para XBOX. Para los desarrolladores que ya realizan desarrollo para XBOX One, la mayoría de los subsistemas les resultarán familiares, aunque con un diseño de API diferente. Algunas áreas, como los gráficos Direct3D, permanecen prácticamente sin cambios. Este tema proporciona una visión general de alto nivel de todo el proceso de migración, vínculos a áreas específicas y algunos trucos y sugerencias para evitar errores comunes.

¿Tienes comentarios sobre esta guía? Háznoslo saber en el [foro de desarrolladores del Microsoft Game Development Kit (GDK)](https://aka.ms/gdkforum).

Si estás desarrollando un título nuevo con la plataforma del Microsoft Game Development Kit (GDK) en lugar de migrar un título existente, consulta Desarrollo de un título nuevo con el GDK.

## Acerca del Microsoft Game Development Kit (GDK)

Ustedes, nuestros asociados de desarrollo de juegos, han proporcionado al equipo de Gaming de Microsoft valiosos comentarios sobre lo que hacemos bien y lo que necesitamos mejorar. Nuestro objetivo principal con el Microsoft Game Development Kit (GDK) es abordar directamente sus comentarios y garantizar que puedan:

* Seguir desarrollando juegos exactamente como lo hacen hoy
* Compartir fácilmente la mayor cantidad de código posible entre todas las iniciativas y programas de Microsoft Gaming: nuestras consolas y PC de hoy, y nuestras consolas y XBOX Game Streaming del mañana
* Confiar en que nuestras herramientas y plataformas de desarrollo proporcionan un entorno rápido, confiable y centrado en el desarrollador
* Aprovechar los nuevos servicios y experiencias multiplataforma de la forma más rápida y sencilla posible

Queremos ayudarte a desarrollar tu juego en la plataforma en la que quieras desarrollarlo, usando los paradigmas de programación que ya utilizas. Queremos ayudarte a llevar tus juegos a todas nuestras plataformas de juego que existen hoy, a todas las plataformas en las que estamos trabajando y que deleitarán a los jugadores del mañana.

Para obtener información más detallada sobre el Microsoft Game Development Kit (GDK), consulta ¿Qué es el Microsoft Game Development Kit? e Introducción al Microsoft Game Development Kit (GDK).

## Contenido

* [Planificación del proyecto de migración](#portfrom)
* [Entorno de desarrollo](#devenv)
* [Inicio de la aplicación](#appstartup)
* [Inicialización de aplicaciones](#appinit)
* [Bucle de mensajes de Windows](#winmsgloop)
* [Creación de dispositivos Direct3D](#d3ddevicecreate)
* [Presentación](#presentation)
* [Administración de la duración de procesos (PLM)](#plm)
* [Administración de memoria](#memmgmt)
* [Modelo de programación](#appmodel)
* [Sombreadores HLSL](#hlsl)
* [Administración de usuarios](#user)
* [Redes e integración de los servicios XBOX](#live)
* [Pasos siguientes](#nextsteps)
* [Trucos y sugerencias](#tips)
* [Compatibilidad binaria y reutilización de componentes](#bincompat)
* [Estilo de codificación y procedimientos recomendados](#codingstyle)
* [Consulte también](#seealso)

<Note>
  A efectos de esta guía de migración, supondremos que el destino son las plataformas Gaming.Xbox.XboxOne.x64 o Gaming.Xbox.Scarlett.x64. El Microsoft Game Development Kit (GDK) también incluye la plataforma Gaming.Desktop.x64. Es una variante de la plataforma x64 Win32 estándar, que no se trata en esta guía de migración.

  El valor principal de Gaming.Desktop.x64 es proporcionar una experiencia similar a Gaming.Xbox.\*.x64 en cuanto a configuración de compilación, integración con Visual Studio, comportamiento del diseño suelto (loose layout), etc., cuando el destino es un PC. Como alternativa, puedes usar la plataforma x64 "estándar" e implementar toda la configuración y el empaquetado directamente para PC.
</Note>

<a id="portfrom" />

## Planificación del proyecto de migración

Cuando migras una base de código existente al Microsoft Game Development Kit (GDK), normalmente partes de un proyecto existente del XBOX One Software Development Kit o de una aplicación clásica de escritorio Win32. Muchos desarrolladores con un título existente de XBOX One encontrarán que su base de código `Durango` es un mejor punto de partida, siempre que el uso de las API de Windows Runtime esté relativamente aislado. Las bases de código clásicas de escritorio Win32 están mucho más cerca del modelo de programación del Microsoft Game Development Kit (GDK), pero a menudo asumen esquemas de interfaz de usuario y control centrados en el escritorio que deben modificarse para la consola. Las bases de código clásicas de escritorio Win32 también tienden a tener mucha integración centrada en el escritorio, especialmente cuando se usan como parte del conjunto de herramientas de edición del juego, que utiliza conjuntos de API no compatibles con el Microsoft Game Development Kit (GDK) en XBOX. Empezar por cada una tiene ventajas y desventajas. En algunos casos, puede resultarte más fácil tomar elementos de ambos tipos para distintas partes de tu base de código.

### Migración desde el XBOX One Software Development Kit

Si tu base de código ya es compatible con XBOX One a través del XBOX One Software Development Kit (también conocido como la plataforma `Durango`), ya has hecho la mayor parte del trabajo de modernizar el uso de API de tu aplicación. El código también debería estar bien optimizado para las restricciones específicas de la consola y, probablemente, hace un uso significativo de las extensiones específicas de XBOX One, como se indica a continuación.

* Se requiere DirectX 12.X. Si ya usas DirectX 12.X para tu título de XBOX One, no deberían ser necesarios cambios más allá de la API de presentación para tu uso de Direct3D.

> Si actualmente usas DirectX 11.X, actualiza primero a DirectX 12.X. Esto puede ser más fácil de hacer con tu compilación existente del XBOX One Software Development Kit antes de pasar al Microsoft Game Development Kit (GDK). Para más detalles, consulta estos temas: [Migración de Direct3D 11 a Direct3D 12](https://learn.microsoft.com/windows/desktop/direct3d12/porting-from-direct3d-11-to-direct3d-12), la charla de Xfest Introduction to Direct3D 12 on XBOX One [(XBOX Developer Downloads->Conference Material->Xfest 2015 GPU Track Videos)](https://aka.ms/gdkdl) y la charla de Xfest Porting from Direct3D 11 to Direct3D 12 [(XBOX Developer Downloads->Conference Material->Xfest 2015 GPU Track Videos)](https://aka.ms/gdkdl).

* En lugar de usar una cadena de intercambio DXGI, tu lógica de presentación debe usar la API PresentX.
* Se han realizado algunos cambios significativos en el subsistema de memoria del Game OS del GDK para el Microsoft Game Development Kit (GDK). Revisa la implementación de tu administrador de memoria.
* Para la entrada de mando, usa la nueva API GameInput en lugar de `Windows.Xbox.Input`.
* Dado que las API de Windows Runtime ya no se usan en la mayoría de los escenarios, reemplaza tu código C++/CX o C++/WinRT existente por las nuevas API COM de estilo Win32 o de estilo DirectX.
  | Área | Microsoft Game Development Kit (GDK) |
  | - | - |
  | Almacenamiento conectado | Nueva API C plana |
  | Redes | [WinSock2](https://learn.microsoft.com/windows/desktop/WinSock/) <br /> [WinHTTP](https://learn.microsoft.com/windows/desktop/WinHttp/about-winhttp) |
  | Empaquetado e instalación por streaming | Nueva API C plana |
  | Interfaz de usuario estándar (interfaz de usuario invocable desde el título (TCUI)) | Nueva API C plana |
  | Store | Nueva API C plana |
  | Administración de usuarios | Nueva API C plana |
  | API de los servicios XBOX (XSAPI) | Nueva API C plana; consulta Introducción a las API C de los servicios XBOX y la referencia de XSAPI. |
* La funcionalidad de Core Audio no ha cambiado. Sin embargo, es posible que se requieran algunos cambios de API, como se describe en la comparación de API de audio. Se admiten XAudio2 con extensiones XMA, WASAPI e `ISpatialAudioClient`.
* Al compilar en Visual Studio, agrega las configuraciones de plataforma `Gaming.Xbox.XboxOne.x64` o `Gaming.Xbox.Scarlett.x64` en lugar de tus configuraciones de plataforma `Durango`, y actualiza a Visual Studio 2019 o Visual Studio 2022.

<Note>
  Para ayudar a agregar nuevas configuraciones de plataforma hemos creado un ejemplo llamado [*SolutionUpdater*](https://aka.ms/xgdsamples). Esta herramienta de ejemplo toma un archivo de solución de Visual Studio existente y crea automáticamente las nuevas configuraciones de plataforma para todos los archivos de proyecto asociados a los que hace referencia la solución, lo que acelera enormemente el proceso y reduce la posibilidad de errores manuales. Para más información, revisa el documento incluido con el ejemplo.
</Note>

> Si tu base de código admite el modelo de aplicación de la Plataforma universal de Windows (UWP), tienes una ruta de migración similar a la del XBOX One Software Development Kit.

### Migración desde el escritorio Win32 clásico

Si tu base de código solo admite el escritorio Win32 clásico, el proceso de migración podría ser bastante extenso, según lo reciente que sea la base de código con respecto a las API en desuso y otras características. Ten en cuenta que las bases de código clásicas de escritorio Win32 pueden abarcar un rango muy amplio de API que se remontan hasta la era de Windows 9x/ME. Esta lista no es exhaustiva de todos los posibles problemas que podrías encontrar. Cuando el destino es XBOX, también tendrás las consideraciones habituales de migrar de PC a consola: interfaz de usuario, modelos de entrada, pantalla de resolución fija, memoria limitada, etc.

* Se requiere x64 nativo. Para más información, consulta [Programación de 64 bits para desarrolladores de juegos](https://learn.microsoft.com/windows/desktop/DxTechArts/sixty-four-bit-programming-for-game-developers).
* Se requiere DirectX 12.X. No se pueden usar DirectX 11, Direct3D 10, Direct3D 9 ni versiones anteriores. Además, OpenGL y Vulkan no se admiten. Para más detalles, consulta las guías de migración de [DirectX11](https://learn.microsoft.com/windows/desktop/direct3d11/d3d11-programming-guide-migrating) y [DirectX12](https://learn.microsoft.com/windows/desktop/direct3d12/porting-from-direct3d-11-to-direct3d-12).
* No se pueden usar los componentes heredados del SDK de DirectX D3DX9, D3DX10, D3DX11 y XACT. Para más información, consulta [Microsoft Docs](https://learn.microsoft.com/windows/desktop/directx-sdk--august-2009-), [Where is the DirectX SDK (2021 Edition)?](https://aka.ms/dxsdk), [Living without D3DX](https://aka.ms/Kfsdiu) y [The Zombie DirectX SDK](https://aka.ms/AA4gfea).
* `WINAPI_FAMILY_GAMES` es un subconjunto de la familia completa de API Win32. Limítate a esas API.
* Se requiere el empaquetado AppX. Actualiza tu proceso de empaquetado e implementación.
* Para la entrada de mando, usa la nueva API GameInput en lugar de `Windows.Gaming.Input` o DirectInput.
* Para el audio, usa XAudio2, WASAPI, ISpatialAudioClient o middleware de audio compatible.
* Elimina los usos del Registro.
* El manejo de los mensajes de `WndProc` debe reducirse. Muchos de los mensajes, en particular los que tratan del posicionamiento, el tamaño de las ventanas y la integración con el shell, no se aplican al Microsoft Game Development Kit (GDK) en XBOX.
* Si compilas con Visual Studio, actualiza tu código para que funcione con Visual Studio 2019 o Visual Studio 2022. En caso contrario, asegúrate de que tu compilación use las nuevas definiciones del preprocesador y se vincule con las bibliotecas de `GXDK\gameKit\lib\amd64`, como la biblioteca paraguas `xgameplatform.lib`.
* Para los componentes COM, solo se admite el modelo de subprocesamiento de apartamento multiproceso (MTA). Ten en cuenta que `COINITBASE_MULTITHREADED` es lo habitual para una aplicación Direct3D.
* Solo se admite una única instancia de ventana. No se admiten varias instancias de ventana simultáneas ni cuadros de diálogo.

<a id="devenv" />

## Entorno de desarrollo

Visual Studio 2019 (actualización 16.11) o Visual Studio 2022 es el entorno de desarrollo compatible con el Microsoft Game Development Kit (GDK).

Instala lo siguiente:

* Carga de trabajo: Desarrollo de juegos con C++ para el conjunto de herramientas principal
* Carga de trabajo: Desarrollo de UWP para las herramientas de empaquetado.
* Carga de trabajo (opcional): Desarrollo de escritorio con C++ para las herramientas y ejemplos del lado del PC.

> El desarrollo con el XBOX One Software Development Kit con Visual Studio 2017 también requería el componente opcional *Windows 8.1 SDK and UCRT SDK*. Este componente no es necesario para el Microsoft Game Development Kit (GDK).

Si todavía usas Visual Studio 2015 o una versión anterior, el primer paso de tu esfuerzo de migración es actualizar a Visual Studio 2019 o posterior.

### Plataforma de Visual Studio

El Microsoft Game Development Kit (GDK) se integra con Visual Studio para proporcionar las plataformas `Gaming.Xbox.XboxOne.x64` y `Gaming.Xbox.Scarlett.x64` cuyo destino es el Game OS del GDK de Microsoft en XBOX. Esto reemplaza a la plataforma `Durango` del XBOX One Software Development Kit.

### Soluciones de compilación personalizadas

Para compilar código fuera de Visual Studio, se han cambiado las variables auxiliares de entorno para las ubicaciones.

XBOX One Software Development Kit:

```text theme={null}
DurangoXDK=C:\Program Files (x86)\Microsoft Durango XDK\
XboxOneXDKLatest=C:\Program Files (x86)\Microsoft Durango XDK\170614\
XboxOneExtensionSDKLatest=C:\Program Files (x86)\Microsoft SDKs\Durango.170614\v8.0\
```

Microsoft Game Development Kit (GDK):

```text theme={null}
GameDK=C:\Program Files (x86)\Microsoft GDK\
GameDKLatest=C:\Program Files (x86)\Microsoft GDK\build_number\
```

<Note>
  En la ruta de ejemplo anterior, *build\_number* representa la compilación instalada en tu sistema (por ejemplo, 190700).
</Note>

Hay varias ubicaciones en el Microsoft Game Development Kit (GDK) a las que deberán hacer referencia los sistemas de compilación personalizados. `%GameDKLatest%\GXDK\gameKit` contiene todos los encabezados y bibliotecas para las extensiones específicas de la consola, y la biblioteca paraguas principal de la plataforma para vincular un binario del Microsoft Game Development Kit (GDK). De forma similar, `%GameDKLatest%\GRDK\gameKit` contiene los encabezados y bibliotecas de toda la funcionalidad que no es específica del desarrollo para consola. El Microsoft Game Development Kit (GDK) requiere que esté instalado el Windows 10 SDK (10.0.19041.0) o posterior como dependencia. Algunos encabezados y bibliotecas adicionales están disponibles en `%GameDKLatest%\GXDK\toolKit` para las herramientas de consola del lado del PC.

> A partir de la versión de octubre de 2023, el Windows 11 SDK (10.0.22000.0) es la versión mínima admitida.

También hay una serie de opciones y definiciones que deberías usar. Consulta las recomendaciones de modificadores del compilador y enlazador de Visual C++ para conocer todos los detalles, así como el ejemplo [*CMakeExample*](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/Tools/CMakeExample).

#### Compilador (cl.exe)

* `/D_GAMING_XBOX` reemplaza tanto a `/D_XBOX_ONE /D_TITLE` como a `/D_DURANGO`.
* `/D_GAMING_XBOX_XBOXONE` se define solo para la plataforma `Gaming.Xbox.XboxOne.x64`.
* `/D_GAMING_XBOX_SCARLETT` se define solo para la plataforma `Gaming.Xbox.Scarlett.x64`.
* `/DWINAPI_FAMILY=WINAPI_FAMILY_GAMES` controla la partición de API en lugar de la familia de API `WINAPI_FAMILY_TV_TITLE`.
* Debes definir `/DWIN32_LEAN_AND_MEAN`, `/D_ATL_NO_DEFAULT_LIBS` y `/D__WRL_NO_DEFAULT_LIB__`
* Para el Microsoft Game Development Kit (GDK), ya no se usa ningún modificador de Windows Runtime como `/AI`, `/FU` o `/ZW`.
* Sigue usando `/favor:AMD64`, `/EHsc` y `/fp:fast`.
* Para la plataforma `Gaming.Xbox.XboxOne.x64`, sigue usando `/arch:AVX`
* Para la plataforma `Gaming.Xbox.Scarlett.x64`, usa `/arch:AVX2`

> Con VS 2019 Update 3 o posterior y la plataforma `Gaming.Xbox.Scarlett.x64`, usa también `/d2vzeroupper`. Si usas la optimización de todo el programa (WPO) / generación de código en tiempo de vínculo (LTCG), debe ser `/d2:-vzeroupper`.

> Con VS 2022 y la plataforma `Gaming.Xbox.XboxOne.x64`, usa también `/d2vzeroupper-`. Si usas la optimización de todo el programa (WPO) / generación de código en tiempo de vínculo (LTCG), debe ser `/d2:-vzeroupper-`.

#### Enlazador (link.exe)

* Vincula con `xgameplatform.lib`, `xgameruntime.lib`, `d3d12_x.lib` o `d3d12_xs.lib`, `xmem.lib` y `pixevt.lib`. No uses `kernel32.lib`, `kernelx.lib`, `onecore.lib` ni `WindowsApp.lib`.
* Para la biblioteca XGraphics, usa `xg_x.lib` o `xg_xs.lib`.
* No necesitas usar `/WINMD` ni `/WINMDFILE`, que eran para las API de Windows Runtime.
* El Microsoft Game Development Kit (GDK) en XBOX no usa manifiestos incrustados, así que usa `/MANIFEST:NO`.
* Sigue usando `/DYNAMICBASE`, `/NXCOMPAT`.

> Deberías considerar usar `/NODEFAULTLIB` para asegurarte de no vincular con ninguna biblioteca Win32 no compatible, incluidas `advapi32.lib comctl32.lib comsupp.lib dbghelp.lib gdi32.lib gdiplus.lib guardcfw.lib kernel32.lib mmc.lib msimg32.lib msvcole.lib msvcoled.lib mswsock.lib ntstrsafe.lib ole2.lib ole2autd.lib ole2auto.lib ole2d.lib ole2ui.lib ole2uid.lib ole32.lib oleacc.lib oleaut32.lib oledlg.lib oledlgd.lib oldnames.lib runtimeobject.lib shell32.lib shlwapi.lib strsafe.lib urlmon.lib user32.lib userenv.lib wlmole.lib wlmoled.lib onecore.lib`.

### Optimización del uso de encabezados de Windows

El Microsoft Game Development Kit (GDK) usa el encabezado estándar `<Windows.h>`. Es útil definir las distintas definiciones de preprocesador "lean and mean", además de `WIN32_LEAN_AND_MEAN`, como se mencionó anteriormente, para mantener bajo control el número total de encabezados de sistema Win32 que incorporas.

```cpp theme={null}
// 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

#include <Windows.h>
```

### Runtime de Visual C++

Con el XBOX One Software Development Kit, los encabezados y bibliotecas del runtime de Visual C++ formaban parte del XBOX One Software Development Kit, y las DLL del runtime se colocaban dentro del Game OS. Esto requería actualizar a una versión más reciente del XBOX One Software Development Kit o a un nivel de QFE que coincidiera con la versión de actualización menor de Visual Studio que se usaba para compilar el código.

Con el Microsoft Game Development Kit (GDK), las DLL del runtime de Visual C++ se incluyen como parte del paquete de tu juego y coinciden con la versión de Visual Studio que esté instalada localmente en la máquina de compilación.

* `VCRuntime*.dll` y `msvcp*.dll` son las DLL del runtime del compilador de Visual C++ y de la biblioteca estándar de C++. Hay una `ucrtbase.dll` incluida en el Game OS que también se usa.
* Para las compilaciones de depuración, tu paquete contendrá `VCRuntime*d.dll`, `msvcp*d.dll` y `ucrbased.dll`

> Si haces uso de la *ERA Migration Library*, también necesitas `vccorlib*.dll`, que el compilador usa al compilar con `/ZW`.

<Note>
  AMP no se admite para XBOX y se ha declarado en desuso en la versión más reciente de Visual C++.
</Note>

<a id="appstartup" />

## Inicio de la aplicación

Los proyectos del Microsoft Game Development Kit (GDK) usan una versión simplificada del inicio de aplicación y el bucle de mensajes de estilo escritorio de Win32, no los eventos de CoreWindow de estilo Windows Runtime. Tu base de código existente debería tener uno de los siguientes puntos de entrada.

### Desarrollo de escritorio Win32

```cpp theme={null}
int WINAPI wWinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR lpCmdLine,
    _In_ int nCmdShow)
{
...
```

### Aplicación del XBOX One Software Development Kit o UWP con C++/CX

```cpp theme={null}
int __cdecl main(Platform::Array<Platform::String^>^ /*argv*/)
{
    auto viewProviderFactory = ref new ViewProviderFactory();
    CoreApplication::Run(viewProviderFactory);
    return 0;
}
```

### Aplicación del XBOX One Software Development Kit o UWP con C++/WinRT

```cpp theme={null}
int WINAPIV WinMain()
{
    winrt::init_apartment();

    ViewProviderFactory viewProviderFactory;
    CoreApplication::Run(viewProviderFactory);

    winrt::uninit_apartment();
    return 0;
}
```

### Microsoft Game Development Kit (GDK) en XBOX

Para los títulos del GDK, el punto de entrada es el mismo que en el escritorio clásico Win32.

```cpp theme={null}
int WINAPI wWinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR lpCmdLine,
    _In_ int nCmdShow)
{
...
}
```

<a id="appinit" />

## Inicialización de aplicaciones

Una función de punto de entrada Win32 típica y muy básica tiene este aspecto.

```cpp theme={null}
int WINAPI wWinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR lpCmdLine,
    _In_ int nCmdShow)
{
    HRESULT hr = CoInitializeEx(nullptr, COINITBASE_MULTITHREADED);
    if (FAILED(hr))
        return 1;

    // Register a class and create a window.
    {
        // Register class
        WNDCLASSEXW wcex = {};
        wcex.cbSize = sizeof(WNDCLASSEXW);
        wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = WndProc;
        wcex.hInstance = hInstance;
        wcex.hIcon = LoadIconW(hInstance, L"IDI_ICON");
        wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
        wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
        wcex.lpszClassName = L"MyGameWindowClass";
        wcex.hIconSm = LoadIconW(wcex.hInstance, L"IDI_ICON");
        if (!RegisterClassExW(&wcex))
            return 1;

        // Create a window.
        RECT rc = { 0, 0, static_cast<LONG>(1280), static_cast<LONG>(720) };

        AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);

        HWND hwnd = CreateWindowExW(0, L"MyGameWindowClass", L"My Game",
            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, /* some object */ );

        GetClientRect(hwnd, &rc);

        // Initialize a device and more by using rc as the "real" size of the swap chain.
    }

    // Main message loop.
    MSG msg = {};
    while (WM_QUIT != msg.message)
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            // Update and Render
        }
    }

    CoUninitialize();

    return static_cast<int>(msg.wParam);
}
```

Este patrón es prácticamente el mismo para los títulos del Microsoft Game Development Kit (GDK) en XBOX, pero podemos simplificarlo un poco:

* Uso mínimo de clases y estilos de ventana
* Cadenas UTF-8 en lugar de UTF-16LE
* Inicialización del subsistema Game Runtime

```cpp theme={null}
int WINAPI wWinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR lpCmdLine,
    _In_ int nCmdShow)
{
    // Initialize the Game Runtime APIs.
    if (FAILED(InitializeGameRuntime())) // Function in GameRuntimeInit.h
        return 1;

    // Register a class and create a window.
    {
        // Register class
        WNDCLASSEXA wcex = {};
        wcex.cbSize = sizeof(WNDCLASSEXA);
        wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = WndProc;
        wcex.hInstance = hInstance;
        wcex.lpszClassName = "MyGameWindowClass";
        wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
        if (!RegisterClassExA(&wcex))
            return 1;

        // Create a window.

        HWND hwnd = CreateWindowExA(0, u8"MyGameWindowClass", u8"My Game",
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT,
            1920, 1080, nullptr, nullptr, hInstance,
            nullptr);
        if (!hwnd)
            return 1;

        ShowWindow(hwnd, nCmdShow);

        SetWindowLongPtr(hwnd, GWLP_USERDATA, /* some object of type SomeClass */ );

        // Initialize a device and more.
        // Assume a swap chain of 1080p, 1440p, or 4K.
    }

    // Main message loop.
    MSG msg = {};
    while (WM_QUIT != msg.message)
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            // Update and Render
        }
    }

    UninitializeGameRuntime();

    return static_cast<int>(msg.wParam);
}
```

> Para los títulos del Microsoft Game Development Kit (GDK) en XBOX, solo puedes tener una ventana Win32.

<a id="winmsgloop" />

## Bucle de mensajes de Windows

Dado que muchos mensajes no se aplican, las aplicaciones del Microsoft Game Development Kit (GDK) en XBOX pueden usar un bucle de mensajes Win32 muy básico.

```cpp theme={null}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    auto appPtr = reinterpret_cast<SomeClass*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));

    switch (message)
    {
    case WM_CREATE:
        break;

    case WM_ACTIVATEAPP:
        break;

    // WM_USER messages the application posts to itself.

    return DefWindowProc(hWnd, message, wParam, lParam);
}
```

El uso de un bucle de mensajes Win32 es opcional, pero es un punto de partida útil si vienes de una base de código Win32 existente.

La siguiente tabla muestra una lista de mensajes Win32 comunes que se encuentran en los juegos clásicos de escritorio Win32 y la aplicación (o la falta de ella) de estos mensajes a los títulos del Microsoft Game Development Kit (GDK) en XBOX.

| Mensaje | Descripción |
| - | - |
| WM\_CREATE | Este mensaje se envía cuando se crea la ventana. |
| WM\_DESTROY <br /> WM\_CLOSE | Estos mensajes no se aplican a los títulos del Microsoft Game Development Kit (GDK) en XBOX, que usan un modelo de suspensión/finalización de administración de la duración de procesos (PLM). |
| WM\_CHAR <br /> WM\_KEYDOWN <br /> WM\_KEYUP | Estos mensajes se envían para la entrada de teclado y las teclas virtuales del GamePad. |
| WM\_SYSKEYDOWN <br /> WM\_SYSKEYUP <br /> WM\_CHAR | Estos mensajes se envían para la entrada de teclado. |
| WM\_USER | Las aplicaciones pueden enviar sus propios mensajes al bucle de mensajes. Las aplicaciones pueden aprovechar esto porque se procesan en el contexto del subproceso del bucle principal. |
| WM\_SIZE | Este mensaje se relaciona con los estados minimizado, maximizado y restaurado. Sin embargo, los títulos del Microsoft Game Development Kit (GDK) en XBOX no se encuentran con estos escenarios. |
| WM\_ENTERSIZEMOVE <br /> WM\_EXITSIZEMOVE <br /> WM\_GETMINMAXINFO | Estos mensajes se relacionan con el redimensionamiento arrastrando el borde en el escritorio. Sin embargo, un título del Microsoft Game Development Kit (GDK) en XBOX no se encuentra con este escenario. |
| WM\_PAINT | Para las aplicaciones de escritorio Win32, este mensaje suele implementarse para volver a dibujar la ventana en escenarios de pausa o de redimensionamiento, que no se aplican. |
| WM\_POWERBROADCAST | Los títulos del Microsoft Game Development Kit (GDK) en XBOX usan las notificaciones PLM para suspender/reanudar, no el modelo de escritorio de modos de energía de suspensión. |
| WM\_SETFOCUS <br /> WM\_KILLFOCUS <br /> WM\_ACTIVATE <br /> WM\_ACTIVATEAPP <br /> WM\_SHOWWINDOW | Para los títulos del Microsoft Game Development Kit (GDK) en XBOX, estos mensajes se envían cuando el usuario interactúa con la guía o regresa de otra interfaz de usuario invocable desde el título (TCUI). |
| WM\_TIMER | Este mensaje se admite para los títulos del Microsoft Game Development Kit (GDK) en XBOX si usas `SetTimer` / `KillTimer`. |

<a id="d3ddevicecreate" />

## Creación de dispositivos Direct3D

Los juegos compilados con el Microsoft Game Development Kit (GDK) en XBOX usan la API Direct3D 12.X, que se implementa como el runtime monolítico, tal como se implementa con el XBOX One Software Development Kit.

| Direct3D 12 estándar | Extensiones de DirectX 12.X |
| - | - |
| `#include <d3d12.h>` <br /> `#include <dxgi1_4.h>` | `#include <d3d12_x.h>` o `#include <d3d12_xs.h>` |
| `#include <d3dx12.h>` | `#include <d3dx12_x.h>` o `#include <d3dx12_xs.h>` |
| D3D12CreateDevice | D3D12XboxCreateDevice |
| Macro IDD\_PPV\_ARGS | Macro IDD\_GRAPHICS\_PPV\_ARGS |

Direct3D 12 estándar y Direct3D 11 no se admiten para los juegos compilados con el Microsoft Game Development Kit (GDK) en XBOX. Cuando crees un dispositivo Direct3D 12 para DirectX 12.X, usa el método `D3D12XboxCreateDevice`.

```cpp theme={null}
ComPtr<ID3D12Device> device;

...

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);

ThrowIfFailed(D3D12XboxCreateDevice(
    nullptr,
    &params,
    IID_GRAPHICS_PPV_ARGS(device.GetAddressOf())
    ));
```

A partir de aquí, la cola de comandos, la lista de comandos y otros elementos se seguirán creando como se haría con Direct3D 12 estándar.

Para admitir la representación en 4K, simplemente usa un ancho y alto mayores en la cadena de intercambio, pero deberías seguir admitiendo 1080p para las consolas de gama más baja. Una forma recomendada de determinar cuándo usar 4K frente a 1440p frente a 1080p es la siguiente:

```cpp theme={null}
RECT outputSize = { 0, 0, 1920, 1080 };
switch (XSystemGetDeviceType())
{
case XSystemDeviceType::XboxOne:
case XSystemDeviceType::XboxOneS:
    break;

case XSystemDeviceType::XboxScarlettLockhart /* Xbox Series S */:
    outputSize = { 0, 0, 2560, 1440 };
    break;

case XSystemDeviceType::XboxScarlettAnaconda /* Xbox Series X */:
case XSystemDeviceType::XboxOneXDevkit:
case XSystemDeviceType::XboxScarlettDevkit:
default:
   outputSize = { 0, 0, 3840, 2160 };
   break;
}
```

Para más detalles, consulta el ejemplo [*SimpleDeviceAndSwapChain*](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/IntroGraphics/SimpleDeviceAndSwapChain).

### API XMem\*

Cualquier llamada a las API `XMem*` que use `XMEM_GRAPHICS` requiere que el dispositivo Direct3D se haya creado antes de usarlas. Como alternativa, puedes llamar a D3DConfigureVirtualMemory si necesitas usar esas llamadas antes de que exista el dispositivo Direct3D.

```cpp theme={null}
D3D11X_VIRTUAL_MEMORY_CONFIGURATION vmConfig = {};
vmConfig.PageTableMemory4MBPageCount = 5;
ThrowIfFailed(
      D3DConfigureVirtualMemory(&VMConfig)
    );
```

### Reserva de CPU/GPU

Todos los títulos del Microsoft Game Development Kit (GDK) obtienen los recursos completos (es decir, sin reserva de GPU para Kinect) y el séptimo núcleo de CPU. De forma predeterminada, obtienes el equivalente de la siguiente configuración de manifiesto del XBOX One Software Development Kit.

```xml theme={null}
<mx:Extension Category="xbox.system.resources">
  <mx:XboxSystemResources resourceConfiguration="extended">
    <mx:GpuAvailability>variable</mx:GpuAvailability>
  </mx:XboxSystemResources>
</mx:Extension>
```

### Diferencias de Direct3D entre XBOX One y XBOX Series X|S

La implementación del runtime monolítico de Direct3D 12.x para la plataforma `Gaming.Xbox.XboxOne.x64` es casi idéntica a la implementación de Direct3D 12.x del XBOX One Software Development Kit. Para tu migración inicial al Microsoft Game Development Kit (GDK) en XBOX, esta plataforma es probablemente el punto de partida más fácil.

* `Gaming.Xbox.Scarlett.x64` admite hasta las interfaces ID3D12Device8 e ID3D12GraphicsCommandList5 o versiones posteriores.
* `Gaming.Xbox.XboxOne.x64` admite hasta ID3D12Device, ID3D12Device1, ID3D12Device2 e ID3D12GraphicsCommandList.

Al pasar a la plataforma `Gaming.Xbox.Scarlett.x64`, hay algunas capacidades adicionales, así como algunas diferencias en la implementación de Direct3D 12.x.

* Necesitas usar una versión diferente de los encabezados y bibliotecas de Direct3D (es decir, `d3d12_xs.h`, `d3dx12_xs.h`, `xg_xs.h`, `d3d12_xs.lib`, etc.). No puedes mezclar las dos versiones de Direct3D 12.x en el mismo binario.
* Cuando se implementó por primera vez el runtime monolítico de Direct3D 12.x, se construyó sobre el runtime monolítico de Direct3D 11.x, por lo que hay varios tipos de Direct3D 11 definidos al compilar con las plataformas `Durango` o `Gaming.Xbox.XboxOne.x64`. Estos se han eliminado de la implementación de XBOX Series X|S, por lo que podrías encontrarte con problemas de compilación con cualquier referencia residual al encabezado `d3d11_x.h`, las definiciones `D3D11_*`, las clases `CD3D11_*` o las interfaces `ID3D11*`. Se pueden eliminar y aun así compilar para ambas plataformas.
* ESRAM no es una característica de XBOX Series X|S, por lo que las extensiones relacionadas con ESRAM no están definidas para esta plataforma. Esto también significa que `xgmemory.h` (una utilidad auxiliar para usar ESRAM) solo se admite para la plataforma `Gaming.Xbox.XboxOne.x64`.

<Note>
  Sigue siendo importante utilizar ESRAM en los dispositivos XBOX One / XBOX One S para un rendimiento de representación óptimo. Consulta los ejemplos SimpleESRAM y [*AdvancedESRAM*](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/Graphics/AdvancedESRAM).
</Note>

* Hay varias diferencias en los diseños de memoria de la GPU, en particular en las técnicas de H-tile y C-Mask. Para más detalles, consulta los ejemplos *CMaskDecode*, *HiZDecode*, *HiStencil* y *PrimeHTile*.

<a id="presentation" />

## Presentación

El Microsoft Game Development Kit (GDK) en XBOX no admite las cadenas de intercambio DXGI heredadas para la presentación, sino que usa la API PresentX. Las nuevas API PresentX están diseñadas para abordar los problemas de latencia de las cadenas de intercambio DXGI y proporcionan al desarrollador un control más directo de los búferes de presentación. Esta API también está diseñada para escalar para futuras aplicaciones de streaming.

El primer paso para usar PresentX es registrarse para los eventos de fotograma después de crear el dispositivo Direct3D.

```cpp theme={null}
// First, retrieve the underlying DXGI device from the D3D device.
ComPtr<IDXGIDevice1> dxgiDevice;
ThrowIfFailed(device.As(&dxgiDevice));

// Identify the physical adapter (GPU or card) that 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 the frame interval, and register for frame events.
ThrowIfFailed(device->SetFrameIntervalX(
    dxgiOutput.Get(),
    D3D12XBOX_FRAME_INTERVAL_60_HZ,
    2 /* Allow 2 frames of latency */,
    D3D12XBOX_FRAME_INTERVAL_FLAG_NONE));

ThrowIfFailed(device->ScheduleFrameEventX(
    D3D12XBOX_FRAME_EVENT_ORIGIN,
    0U,
    nullptr,
    D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE));
```

En lugar de crear una cadena de intercambio DXGI y solicitar los recursos del búfer trasero, créalos directamente con la marca `D3D12_HEAP_FLAG_ALLOW_DISPLAY`.

```cpp theme={null}
ComPtr<ID3D12Resource> renderTargets[MAX_BACK_BUFFER_COUNT];

...

CD3DX12_HEAP_PROPERTIES swapChainHeapProperties(D3D12_HEAP_TYPE_DEFAULT);

D3D12_RESOURCE_DESC swapChainBufferDesc = CD3DX12_RESOURCE_DESC::Tex2D(
    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 = 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(renderTargets[n].GetAddressOf())));

    D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {};
    rtvDesc.Format = m_backBufferFormat;
    rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;

    CD3DX12_CPU_DESCRIPTOR_HANDLE rtvDescriptor(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), n,
         rtvDescriptorSize);
    device->CreateRenderTargetView(renderTargets[n].Get(), &rtvDesc, rtvDescriptor);
}
```

Al comienzo de cada fotograma de representación, establece primero un token de canalización mediante `WaitFrameEventX`.

```cpp theme={null}
D3D12XBOX_FRAME_PIPELINE_TOKEN framePipelineToken = {};

...

framePipelineToken = D3D12XBOX_FRAME_PIPELINE_TOKEN_NULL;
ThrowIfFailed(device->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE, nullptr,
      D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE, &framePipelineToken));
```

Al final del fotograma, usa el mismo token para llamar a PresentX.

```cpp theme={null}
D3D12XBOX_PRESENT_PLANE_PARAMETERS planeParameters = {};
planeParameters.Token = framePipelineToken;
planeParameters.ResourceCount = 1;
planeParameters.ppResources = renderTargets[backBufferIndex].GetAddressOf();

ThrowIfFailed(commandQueue->PresentX(1, &planeParameters, nullptr));
```

Al igual que ocurre con los títulos del XBOX One Software Development Kit, los juegos del Microsoft Game Development Kit (GDK) en XBOX no se encuentran con los errores `DXGI_ERROR_DEVICE_REMOVED` y `DXGI_ERROR_DEVICE_RESET`, que deben manejarse en los juegos para PC.

Se ha eliminado otra funcionalidad relacionada de DXGI, y la función `ScheduleFrameEventX` mencionada anteriormente sustituye a `DXGIXSetFrameNotification` del XBOX One Software Development Kit.

Este es el código del XBOX One Software Development Kit para la notificación de cambio de fotograma (flip).

```cpp theme={null}
FlipEvent = CreateEvent(nullptr, false, false, "DXGIXFrameFlipEvent");
VERIFYD3D12RESULT(DXGIXSetFrameNotification(FRAME_NOTIFICATION_FLIPPED, FlipEvent));
```

Código equivalente para los títulos del Microsoft Game Development Kit (GDK) en XBOX.

```cpp theme={null}
FlipEvent = CreateEventA(nullptr, false, false, u8"ScheduleFrameEventX");
D3D12XBOX_SCHEDULE_FRAME_OBJECT_LIST objList = { 1, &FlipEvent };
VERIFYD3D12RESULT(GetD3D12Device()->ScheduleFrameEventX(D3D12XBOX_FRAME_EVENT_DISPLAY_FLIP, 0, &objList, D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE));
```

Para más detalles, consulta Programación de fotogramas y presentación en XBOX One, y los ejemplos [*SimpleDeviceAndSwapChain*](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/IntroGraphics/SimpleDeviceAndSwapChain), [*HDR10*](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/Graphics/HDR10) y [*SimpleHDR*](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/Graphics/SimpleHDR).

<a id="plm" />

## Administración de la duración de procesos (PLM)

Los juegos compilados con el Microsoft Game Development Kit (GDK) en XBOX usan el mismo modelo básico de administración de la duración de procesos (PLM) que utilizan las aplicaciones del XBOX One XDK y las aplicaciones UWP. Las aplicaciones se ejecutan sin restricciones, con restricciones, suspendidas o finalizadas; es decir, no se ejecuta ningún código para la finalización y el proceso simplemente se destruye.

Las aplicaciones del XBOX One Software Development Kit y las aplicaciones UWP reciben notificaciones a través de su CoreWindow de Windows Runtime. Los juegos del Microsoft Game Development Kit (GDK) en XBOX reciben notificaciones a través de devoluciones de llamada registradas. Ten en cuenta que solo hay un evento de suspensión y otro de reanudación, y ya no hay una fase de activación explícita.

Un enfoque de implementación sencillo es manejar esto publicando un mensaje `WM_USER`.

```cpp theme={null}
#include <appnotify.h>

...

PAPPSTATE_REGISTRATION hPLM = {};
HANDLE plmSuspendComplete = nullptr;
HANDLE plmSignalResume = nullptr;

...

// Create a window.

plmSuspendComplete = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
plmSignalResume = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
if (!plmSuspendComplete || !plmSignalResume)
    return 1;

if (RegisterAppStateChangeNotification([](BOOLEAN quiesced, PVOID context)
{
    if (quiesced)
    {
        ResetEvent(plmSuspendComplete);
        ResetEvent(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 suspension, we must wait to exit this callback.
        (void)WaitForSingleObject(plmSuspendComplete, INFINITE);
    }
    else
    {
        SetEvent(plmSignalResume);
    }
}, hwnd, &hPLM))
    return 1;

// Message loop.

UnregisterAppStateChangeNotification(hPLM);

CloseHandle(plmSuspendComplete);
CloseHandle(plmSignalResume);
```

Posteriormente, el bucle de mensajes manejaría el mensaje `WM_USER` para garantizar que el bucle se pause hasta la reanudación, y que el comportamiento adecuado de suspensión/reanudación de la GPU tenga lugar en un momento seguro del bucle de representación.

```cpp theme={null}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
...
    switch (message)
    {
    case WM_USER:
        // Call SuspendX(0) on your command queue, and cease all GPU submissions.

        // Complete deferral.
        SetEvent(plmSuspendComplete);

        (void)WaitForSingleObject(plmSignalResume, INFINITE);

        // Before picking up rendering again, call ResumeX on your command queue.

        // You'll also need to register again for frame events
        // via SetFrameIntervalX and ScheduleFrameEventX.
        break;
    }
...
}
```

Para más detalles, consulta el ejemplo [*SimplePLM*](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/System/SimplePLM).

### Restringido frente a completo

La notificación de recursos restringidos frente a completos se maneja mediante una API similar.

```cpp theme={null}
#include <appnotify.h>

PAPPCONSTRAIN_REGISTRATION hPLM2 = {};

// Create a window.

if (RegisterAppConstrainedChangeNotification([](BOOLEAN constrained, PVOID context)
{
    SendMessage(reinterpret_cast<HWND>(context), WM_USER+1, (constrained) ? 1 : 0, 0);
}, hwnd, &hPLM2))
    return 1;

// Message loop

UnregisterAppConstrainedChangeNotification(hPLM2);
```

Aquí usamos un mensaje por las mismas razones que antes en el caso de suspensión/reanudación.

```cpp theme={null}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_USER+1:
        if (wParam)
        {
          // Constrained resources mode
        }
        else
        {
          // Full resource mode
        }
        break;
    }
}
```

Para más detalles, consulta el ejemplo [*SimplePLM*](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/System/SimplePLM).

### Finalización de procesos

Para los títulos comerciales, la finalización de procesos se maneja igual que en la plataforma anterior del XBOX One Software Development Kit. El proceso se suspende y después se finaliza. No se procesa ninguno de los destructores de C++ ni la limpieza. Esto también era cierto si llamabas a `Windows::ApplicationModel::Core::CoreApplication::Exit`.

Con el Microsoft Game Development Kit (GDK), puedes lograr una salida limpia como en las aplicaciones clásicas de escritorio Win32 mediante `PostQuitMessage`. Esto hace que tu bucle de mensajes finalice y que se realicen la limpieza normal del código y el desmontaje del proceso. Esto es útil durante el desarrollo para ayudar a detectar fugas y otros problemas de limpieza que, de otro modo, pueden ser difíciles de encontrar. Sin embargo, es probable que este comportamiento invoque rutas de código que nunca se ejecutan en la plataforma anterior del XBOX One Software Development Kit.

<a id="memmgmt" />

## Administración de memoria

Para más información sobre la administración de memoria, consulta Información general sobre la memoria.

### Cambios en el modelo de memoria

La plataforma del Microsoft Game Development Kit (GDK) incluye muchos cambios realizados en el modelo de memoria con respecto al Game OS original de XBOX One. La mayor parte de este esfuerzo se ha dedicado a mejorar el aislamiento de la memoria usada por el título respecto de la memoria usada por el sistema. Mejorar el aislamiento haría que el uso de memoria fuera más predecible entre el título y el sistema, y evitaría un uso inesperado por parte de las llamadas del sistema.

Como parte de este trabajo, estamos pasando a la versión más reciente del subsistema de administración de memoria de Windows. Aunque muchos juegos no requerirán cambios importantes, deberías examinar cuidadosamente tu uso de estas API de memoria. Los significados y el comportamiento de las marcas han cambiado.

Si asignas y mapeas páginas físicas manualmente, ten en cuenta que algunas restricciones de los mapeos han cambiado y que debe seguirse un patrón diferente para las API.

* Cuando las páginas físicas se mapean en el espacio de direcciones virtuales más de una vez, todas las asignaciones deben compartir la misma configuración de coherencia de caché. Por ejemplo, no puedes mezclar la configuración de páginas Write Combined y la de lectura/escritura normal de CPU en la misma memoria física.
* La configuración de páginas y los valores de coherencia de caché ahora residen en la región de direcciones virtuales en la que se mapean las páginas. Esta región debe reservarse con antelación llamando a XMemVirtualAlloc y usando el patrón `MEM_RESERVE`. Este paso no era necesario en la versión anterior del sistema operativo.

Para todas las asignaciones que se mapean para acceso por parte de la GPU, ahora se requieren marcas explícitas de acceso de GPU. Ya no hay un valor predeterminado basado en la configuración de protección de la CPU.

Ten cuidado de identificar, en cualquier parte de tu base de código, dónde has usado la constante `MEM_LARGE_PAGES`. Sus valores y significados han cambiado para coincidir con los significados usados en todo Windows.

| Nombre | Significado en la API del XBOX One Software Development Kit | Significado en el Microsoft Game Development Kit (GDK) en XBOX | Significado en Windows de escritorio |
| :- | -: | -: | -: |
| MEM\_LARGE\_PAGES | Página de 64 KB | Página de 2 MB (ambiguo, puede eliminarse) | Página de 2 MB |
| MEM\_4MB\_PAGES | Página de 4 MB | No definido | No definido |
| MEM\_64K\_PAGES | No definido | Página de 64 KB | No definido |
| MEM\_2MB\_PAGES | No definido | Página de 2 MB | No definido |

Con el cambio de las páginas grandes de 4 MB en el Game OS de XBOX One a 2 MB en el sistema operativo del Microsoft Game Development Kit (GDK) en XBOX, los especificadores de tamaño de XMemAlloc también han cambiado para las páginas grandes de `XALLOC_PAGESIZE_4MB` a `XALLOC_PAGESIZE_2MB`.

Nuestro mapa de memoria también ha cambiado y ya no está segmentado en las regiones Legacy, Title, Graphics y Physical. Ahora cubren todo el espacio de direcciones de 8 TB.

### Cambios en las API

Las API de memoria del Microsoft Game Development Kit (GDK) comienzan con el prefijo **XMem** y, en su mayor parte, reflejan las API ya existentes en el sistema operativo del XBOX One XDK, aunque su comportamiento ha cambiado.

| API del XBOX One Software Development Kit | Microsoft Game Development Kit (GDK) en XBOX |
| :- | :- |
| VirtualAlloc | XMemVirtualAlloc |
| VirtualFree | [VirtualFree](https://learn.microsoft.com/windows/desktop/api/memoryapi/nf-memoryapi-virtualfree) |
| AllocateTitlePhysicalPages | XMemAllocatePhysicalPages |
| MapTitlePhysicalPages | XMemMapPhysicalPages |
| FreeTitlePhysicalPages | XMemFreePhysicalPages |
| TitleMemoryStatus | XMemGetWorkingSetStatistics |

Las nuevas API se muestran en la siguiente tabla.

| Nombre | Descripción |
| :- | :- |
| XMemVirtualQuery | Consulta el espacio de direcciones virtuales y devuelve información sobre cómo están mapeadas sus páginas. Es similar a VirtualQuery en Win32, pero se usa principalmente para depuración y diagnóstico. |

### Uso de XMemVirtualAlloc en lugar de VirtualAlloc

En el Microsoft Game Development Kit (GDK), la nueva API `XMemVirtualAlloc` reemplaza todos los usos de `VirtualAlloc` para asignar memoria gráfica de XBOX. Ten en cuenta los requisitos anteriores para especificar los requisitos de página de GPU y coherencia de caché en las reservas que posteriormente se respaldan con mapeos físicos.

Una comparación de una reserva de este tipo en el XBOX One Software Development Kit:

```cpp theme={null}
void * memPool = VirtualAlloc(nullptr,
    size,
    MEM_LARGE_PAGES | MEM_GRAPHICS | MEM_RESERVE,
    PAGE_READONLY);
```

y en el Microsoft Game Development Kit (GDK):

```cpp theme={null}
void * memPool = XMemVirtualAlloc(nullptr,
    size,
    MEM_64K_PAGES | MEM_RESERVE,
    XMEM_GRAPHICS | XMEM_MAPPABLE,
    PAGE_READONLY | PAGE_GRAPHICS_COHERENT | PAGE_GRAPHICS_READWRITE);
```

O para una asignación no respaldada por páginas físicas mapeadas y confirmada en el momento de la reserva:

```cpp theme={null}
void* memory = VirtualAlloc(nullptr,
    size,
    MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES | MEM_GRAPHICS,
    PAGE_READWRITE | PAGE_WRITECOMBINE);
```

Cambia a:

```cpp theme={null}
void* memory = XMemVirtualAlloc(nullptr,
    size,
    MEM_RESERVE | MEM_COMMIT | MEM_64K_PAGES,
    TITLE_MEM_GRAPHICS,
    PAGE_READWRITE | PAGE_WRITECOMBINE | PAGE_GRAPHICS_READWRITE);
```

### Uso de VirtualFree

La memoria asignada por `VirtualAlloc` o XMemVirtualAlloc se sigue liberando con `VirtualFree`. No hay una API `XMemVirtualFree`.

### Uso de XMemAlloc

La macro Attributes ahora tiene un parámetro adicional. Por ejemplo:

```cpp theme={null}
const uint64_t c_XMemAllocAttributes = MAKE_XALLOC_ATTRIBUTES(
    eXALLOCAllocatorId_MiddlewareReservedMin,
    0,
    XALLOC_MEMTYPE_GRAPHICS_WRITECOMBINE_GPU_READONLY,
    XALLOC_PAGESIZE_64KB,
    XALLOC_ALIGNMENT_64K);
```

Cambia a:

```cpp theme={null}
const uint64_t c_XMemAllocAttributes = MAKE_XALLOC_ATTRIBUTES(
    eXALLOCAllocatorId_MiddlewareReservedMin,
    0,
    XALLOC_MEMTYPE_GRAPHICS_WRITECOMBINE_GPU_READONLY,
    XALLOC_PAGESIZE_64KB,
    XALLOC_ALIGNMENT_64K,
    0);
```

### XMemAllocatePhysicalPages y XMemMapPhysicalPages

Con el cambio de mover las marcas de página y la coherencia de caché al momento de la reserva, las llamadas para asignar y mapear memoria física se simplifican, pero por lo demás son similares a las del XBOX One Software Development Kit. `XMemAllocatePhysicalPages` reemplaza a `AllocateTitlePhysicalPages`. XMemMapPhysicalPages reemplaza a `MapTitlePhysicalPages`.

Este código del XBOX One Software Development Kit:

```cpp theme={null}
void * memPool = VirtualAlloc(nullptr, size, MEM_LARGE_PAGES | MEM_GRAPHICS | MEM_RESERVE, PAGE_READONLY);
AllocateTitlePhysicalPages(GetCurrentProcess(), MEM_LARGE_PAGES, &NumPages64, PageArray);
MapTitlePhysicalPages(memPool, NumPages64, MEM_GRAPHICS | MEM_LARGE_PAGES, PAGE_READONLY, PageArray);
```

Cambia a esto para los títulos del Microsoft Game Development Kit (GDK):

```cpp theme={null}
void * memPool = XMemVirtualAlloc(nullptr, size, MEM_64K_PAGES | MEM_RESERVE, XMEM_GRAPHICS | XMEM_MAPPABLE, PAGE_READONLY | PAGE_GRAPHICS_COHERENT | PAGE_GRAPHICS_READWRITE);
XMemAllocatePhysicalPages(MEM_64K_PAGES, &NumPages64, PageArray);
XMemMapPhysicalPages(memPool, NumPages64, PageArray);
```

<a id="appmodel" />

## Modelo de programación

Para más información sobre el modelo de programación, consulta el tema Modelo de programación asincrónica.

### Código sincrónico (con bloqueo) con GameRuntime

Para las API en las que el bloqueo es una opción razonable, se han proporcionado las versiones con bloqueo (sincrónicas) de toda la funcionalidad de la biblioteca, incluso si las llamadas fueran de larga duración. El desarrollador puede generar subprocesos y llamar a las funciones con bloqueo desde esos subprocesos usando el programador para administrar la simultaneidad, lo que a menudo es más sencillo de implementar que los futures y promises de estilo C++11. Hay algunos casos (como las llamadas de red) en los que se sabe que el tiempo de ejecución de las funciones no es determinista, por lo que solo se proporcionan versiones asincrónicas.

### Código asincrónico con GameRuntime

La plataforma del Microsoft Game Development Kit (GDK) incluye un nuevo modelo para realizar tareas asincrónicas y notificar sus resultados mediante devoluciones de llamada. Este modelo reemplaza a Windows Runtime. Usa las API de GameRuntime para especificar cómo y dónde se producen el trabajo asincrónico y las devoluciones de llamada.

El siguiente código de ejemplo incluye ejemplos básicos y sencillos de cómo se configura una cola de tareas del Game Runtime para procesar tus llamadas del sistema. Esta cola puede usarse para procesar tareas del sistema *y* como la ubicación donde se ejecutan las devoluciones de llamada. Conceptualmente, una devolución de llamada es una tarea que ejecuta *tu* código en respuesta a acciones del sistema. Si es necesario, puedes crear varias colas de tareas para administrar el trabajo en distintos núcleos, o para especificar la cola que ejecuta las devoluciones de llamada llamada por llamada.

El despacho de los elementos de trabajo en cola puede bombearse manualmente desde tu código (esto es similar a una cola de mensajes de Windows) o bombearse automáticamente. Los siguientes son ejemplos sencillos de cómo se crea y luego se bombea una cola bombeada manualmente.

```cpp theme={null}
XTaskQueueHandle queue;

// This one allows async work to use the default thread pool, but completion is explicit.
ThrowIfFailed(
    XTaskQueueCreate(XTaskQueueDispatchMode::ThreadPool, XTaskQueueDispatchMode::Manual, &queue)
);

...

// This pumps the completion work, which takes place on the calling thread.
while (XTaskQueueDispatch(m_queue, XTaskQueuePort::Completion, 0))
{
    // ... do other work ...
}
```

Para más información, consulta el ejemplo [*SimplePLM*](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/System/SimplePLM), que activa la configuración así como la interfaz de usuario invocable desde el título (TCUI) para iniciar sesión usando una cola asincrónica XTask.

Para más detalles sobre el modelo de programación asincrónica, consulta los temas Modelo de programación asincrónica y Diseño de la cola de tareas asincrónicas. Consulta también el ejemplo [*AsynchronousProgramming*](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/System/AsynchronousProgramming).

### Patrón general de nomenclatura para las llamadas API asincrónicas

La siguiente tabla muestra el patrón general usado por el Microsoft Game Development Kit (GDK) y el Game Runtime para nombrar las llamadas asincrónicas.

| Esquema de función | Significado |
| :- | :- |
| QueryUpdateStatus | Llamada sincrónica de larga duración |
| QueryUpdateStatusAsync | Llamada asincrónica de larga duración, probablemente no determinista |
| QueryUpdateStatusAsyncResultSize | Se llama antes de obtener los resultados de la operación, si varían de tamaño |
| QueryUpdateStatusAsyncResult | Obtiene el resultado de la operación asincrónica |

### XAsyncBlock reemplaza a IAsyncOperation e IAsyncAction

Al llamar a una función asincrónica, crea una estructura `XAsyncBlock`, que debe mantenerse viva durante toda la llamada hasta que se haya completado, cancelado o haya fallado.

El tipo `XAsyncBlock` contiene tres parámetros de relevancia inmediata.

| Tipo | Campo | Uso |
| -: | :- | :- |
| XTaskQueueHandle | queue | La cola que has designado como aquella en la que se realizará el trabajo asincrónico. <br /> Un valor nulo implica ejecutar en el grupo de subprocesos del sistema. |
| void\* | context | Un campo que puedes usar para identificar qué llamada realizaste que provocó la operación asincrónica. <br /> Normalmente, es un puntero *this* de un objeto o un identificador único. |
| XAsyncCompletionRoutine\* | callback | El puntero de función de la rutina que se llamará cuando se ejecute la devolución de llamada. |

Ejemplo de uso:

```cpp theme={null}
auto b = new XAsyncBlock{};
b->context = this;
b->queue = queue;
b->callback = [](XAsyncBlock* async)
{
    UpdateStatus status;
    if(SUCCEEDED(QueryUpdateStatusAsyncResult(async, &status)))
    {
       printf("Update Status: %d\r\n", status);
    }
    delete async;
};
QueryUpdateStatusAsync("Foo", b);
```

> Ten en cuenta que es fundamental que "rellenes con ceros" la estructura XAsyncBlock cuando la crees, de ahí el uso de `{}` en lugar de `()`.

### Operaciones sensibles al tiempo

Las bibliotecas del Microsoft Game Development Kit (GDK) te permiten especificar si el subproceso desde el que llamas es sensible al tiempo. Se pueden notificar advertencias en tiempo de ejecución si llamas a funciones que *no* son sensibles al tiempo desde un subproceso sensible al tiempo.

```cpp theme={null}
HRESULT SetTimeSensitiveThread(bool isTimeSensitive);
HRESULT VerifyNotTimeSensitiveThread();
```

Para marcar un subproceso como sensible al tiempo, llama a `SetTimeSensitiveThread(true)` en el subproceso. También puedes llamar a `VerifyNotTimeSensitiveThread()` desde dentro de las funciones de larga duración de tu propio código para notificar un uso indebido desde subprocesos de tiempo crítico.

<a id="hlsl" />

## Sombreadores HLSL

La plataforma del XBOX One Software Development Kit usaba una versión personalizada del compilador HLSL `FXC.EXE` que admitía la precompilación de sombreadores programables del Shader Model 5.1 a microcódigo ATI. Además, se admitía en versión preliminar el compilador DXIL `DXC.EXE` para el Shader Model 6.

Para el Microsoft Game Development Kit (GDK) en XBOX, se recomienda el uso del compilador DXIL y el Shader Model 6 mediante `DXC.EXE`. El compilador `FXC.EXE` del Shader Model 5.1 se considera ahora heredado. El nuevo compilador admite la mayoría de las marcas de línea de comandos admitidas por el compilador antiguo, aunque algunas de las `defines` de extensión específicas de XBOX no son aplicables o no se admiten. Para más detalles sobre el Shader Model 6 y DXIL, consulta el proyecto de [GitHub](https://github.com/Microsoft/DirectXShaderCompiler).

<Note>
  Para el uso del Shader Model 6 en PC: Windows 10 Creators Update y versiones posteriores admiten los sombreadores DXIL del Shader Model 6.x, al igual que muchos controladores comerciales. En lugar de depender de los controladores WHQL de Windows Update para esta característica, necesitas instalar el controlador más reciente directamente desde su proveedor. El compilador `DXC.EXE` para Windows se incluye en el SDK de Windows 10 April 2018 Update y versiones posteriores. En tiempo de ejecución, puedes determinar si tu PC admite el Shader Model 6.x mediante `CheckFeatureSupport` usando `D3D12_FEATURE_SHADER_MODEL`, pero ¡asegúrate de inicializar `shaderModel.HighestShaderModel` antes de llamar a la función!
</Note>

La versión de XBOX One del compilador DXIL se encuentra aquí: `%GameDKLatest%\GXDK\bin\XboxOne\DXC.exe`.

La versión de XBOX Series X|S del compilador DXIL se encuentra aquí: `%GameDKLatest%\GXDK\bin\Scarlett\DXC.exe`.

### API D3DCompile

Para el Shader Model 6, deberías usar la biblioteca `dxcompiler_x.lib` o `dxcompiler_xs.lib` en lugar de `d3dcompiler_x.lib`.

<a id="user" />

## Administración de usuarios

El modelo de usuarios ha cambiado en el Microsoft Game Development Kit (GDK) con respecto a lo que podrías estar acostumbrado en el XBOX One Software Development Kit. Esto se debe, en parte, a la necesidad de administrar mejor las expectativas de privacidad de los usuarios y a aliviar la carga de tener que estar siempre al tanto de lo que el sistema hace en segundo plano con usuarios que al título no deberían importarle. En lugar de que los títulos supervisen una colección de todo el sistema con los usuarios e invitados que han iniciado sesión en la consola, el sistema solo expone los usuarios a petición.

Para adquirir un usuario para tu título (por ejemplo, cuando el usuario presiona el botón A de un mando para iniciar una sesión de juego y el mando aún no se ha asociado a un usuario), realiza una llamada a XUserAddAsync. Esta llamada realizará dos acciones importantes: inicia la sesión de los usuarios en el título y actualiza el emparejamiento de dispositivos de entrada de los usuarios.

Los usuarios pueden tener cualquier cantidad de dispositivos de entrada emparejados a la vez. Sin embargo, el título solo recibe información sobre las asociaciones de los usuarios que han iniciado sesión con XUserAddAsync. Si se usa la Guía del sistema para iniciar la sesión de un usuario o cambiar asociaciones fuera del título a un usuario que el título desconoce, entonces al título solo se le indica que el dispositivo de entrada se ha desemparejado. El sistema fuera del título, sin embargo, sigue conociendo el emparejamiento para uso del sistema.

Los títulos pueden supervisar los cambios en el estado de un usuario o en la *información* asociada a un usuario (como su gamertag, imagen de jugador o privilegios) suscribiéndose a `XUserChangeEvent` (aunque parte de esta información, como el estado de inicio de sesión del usuario, podría supervisarse mediante sondeo). Esto se hace llamando a XUserRegisterForChangeEvent.

La mayoría de los títulos deberían prever la necesidad de crear su propia colección de usuarios, hacer el seguimiento de cuándo los usuarios inician sesión en el título, hacer el seguimiento de las asociaciones de dispositivos de entrada y manejar el cierre de sesión de los usuarios.

Para una discusión en profundidad de estos cambios, consulta Usuarios y dispositivos de entrada. Consulta también el ejemplo *UserManagement*.

<a id="live" />

## Redes e integración de los servicios XBOX

### Transporte de red

El Microsoft Game Development Kit (GDK) en XBOX admite tanto WinSock2 como BCrypt mediante CNG. Si usas UDP, en lugar de codificar de forma rígida un puerto como el 3074 para el enlace del socket multijugador, para el Microsoft Game Development Kit (GDK) deberías hacer uso de esta nueva API C plana:

```cpp theme={null}
uint16_t port;
hr = XNetworkingQueryPreferredLocalUdpMultiplayerPort(&port);
if (FAILED(hr))
    // NAT traversal failure
```

Para detectar la conectividad de red con el Microsoft Game Development Kit (GDK), haz uso de [IPHelper](https://learn.microsoft.com/windows/desktop/IpHlp/ip-helper-start-page) en lugar del espacio de nombres `Windows.Networking.Connectivity`. Para código de ejemplo, consulta Inicialización de red y conectividad.

<Note>
  Los sockets seguros (espacio de nombres `Windows.Xbox.Networking`) se han eliminado para el Microsoft Game Development Kit (GDK).
</Note>

Para más detalles, consulta Introducción a las redes con WinSock.

### Solicitudes web mediante HTTP

El Microsoft Game Development Kit (GDK) ya no admite `IXMLHTTPRequest2` ni `MessageWebSocket` / `StreamWebSocket` (espacio de nombres `Windows.Networking.Sockets`). En su lugar, deberías hacer uso de [WinHTTP](https://learn.microsoft.com/windows/desktop/WinHttp/about-winhttp).

Para más detalles, consulta Solicitudes web.

### API de los servicios XBOX

Los desarrolladores que actualmente usan las versiones de Windows Runtime o C++ de XSAPI deberán pasar a usar la versión C plana para las características de integración de los servicios XBOX:

* Logros
* Presencia
* Perfil
* Social
* Social Manager

Consulta Introducción a las API C de los servicios XBOX y la referencia de XSAPI.

Si haces uso de Game Chat 2, ten en cuenta que se cambió el nombre de algunas clases, como se muestra en la siguiente tabla.

| Nombre en el XBOX One Software Development Kit | Nombre en el Microsoft Game Development Kit (GDK) en XBOX |
| :- | :- |
| game\_chat\_audio\_encoding\_type\_and\_bitrate | game\_chat\_audio\_encoding\_bitrate |
| set\_audio\_encoding\_type\_and\_bitrate | set\_audio\_encoding\_bitrate |
| audio\_encoding\_type\_and\_bitrate | audio\_encoding\_bitrate |

<a id="nextsteps" />

## Pasos siguientes

Después de completar tu migración inicial desde ERA, estarás en una excelente posición para habilitar una serie de características del Microsoft Game Development Kit (GDK) en XBOX. Si tu título funciona bien en hardware XBOX One S / XBOX One X, estas son formas fáciles de mejorar la experiencia en las consolas XBOX Series X|S.

**Ten en cuenta que muchas de estas características se habilitan automáticamente para los títulos ERA heredados, pero son de participación voluntaria (opt-in) para los títulos del Microsoft Game Development Kit (GDK) en XBOX. Ahora que tu título es nativo del Microsoft Game Development Kit (GDK) en XBOX, ¡asegúrate de habilitarlas!**

* **AutoHDR**: esta característica convierte automáticamente un título SDR a HDR a nivel de sistema, mejorando la calidad visual del juego cuando se reproduce en una pantalla compatible con HDR10. Usa hardware específico de XBOX Series X|S, por lo que no hay costo adicional de CPU, GPU, memoria, ancho de banda ni latencia. La mejora visual no cambia la intención artística original y expande el brillo hasta 1000 nits y los colores al espacio de color P3-D65. Una implementación HDR nativa siempre será mejor, ya que permite un control artístico total, pero si no tienes los recursos o el tiempo para implementar HDR nativo, AutoHDR es una forma fácil y eficaz de lograr una experiencia mejorada.

```cpp theme={null}
// Try to switch the display into HDR mode
auto result = XDisplayTryEnableHdrMode(XDisplayHdrModePreference::PreferHdr, nullptr);

if (result == XDisplayHdrModeResult::Enabled)
{
   // Specify the Auto HDR flag during D3D device creation
   params.CreateDeviceFlags = D3D12XBOX_CREATE_DEVICE_FLAG_ENABLE_AUTO_HDR;
}

// Create the D3D device
HRESULT hr = D3D12XboxCreateDevice(...);
```

Consulta Salida de alto rango dinámico (HDR) y el ejemplo *AutoHDR* para más detalles.

* **Aniso Boost**: se obtiene una mejora de la calidad de imagen en las consolas XBOX Series X|S promoviendo el filtrado lineal de texturas a filtrado anisotrópico completo. Esta es una forma rápida y fácil de aplicar potencia adicional de GPU a un título de juego existente. Como título del Microsoft Game Development Kit (GDK) en XBOX, esto se logra usando la configuración `D3D12_FILTER_ANISOTROPIC` para tus estados de muestreador en lugar de `D3D12_FILTER_MIN_MAG_MIP_LINEAR` cuando se ejecuta en XBOX Series X|S:

```cpp theme={null}
D3D12_SAMPLER_DESC desc = { D3D12_FILTER_ANISOTROPIC,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    0, D3D12_MAX_MAXANISOTROPY, D3D12_COMPARISON_FUNC_NEVER,
    { 0, 0, 0, 0 }, 0, D3D12_FLOAT32_MAX };

D3D12_SAMPLER_DESC desc = { D3D12_FILTER_ANISOTROPIC,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    0, D3D12_MAX_MAXANISOTROPY, D3D12_COMPARISON_FUNC_NEVER,
    { 0, 0, 0, 0 }, 0, D3D12_FLOAT32_MAX };
```

* **FPS Boost**: otra mejora sencilla es aumentar la velocidad de fotogramas de representación en las consolas XBOX Series X|S. Si tu título se ejecuta a 30 fps en XBOX One S / XBOX One X (`D3D12XBOX_FRAME_INTERVAL_30_HZ`), normalmente puede ejecutarse a 60 fps en XBOX Series X|S (`D3D12XBOX_FRAME_INTERVAL_60_HZ`). Si se ejecuta a 60 fps en XBOX One S/X, es probable que pueda ejecutarse a 120 fps en XBOX Series X|S. Consulta Compatibilidad con 120 Hz y el ejemplo Simple120Hz para más información.

> Además del aumento de la velocidad de fotogramas, es probable que también puedas representar a 4K en XBOX One X y XBOX Series X con el mismo rendimiento que a 1080p en XBOX One S / XBOX Series S.

* **Quick Resume**: esta característica es automática en su mayor parte, siempre que tu título implemente correctamente la administración del ciclo de vida de procesos (PLM). Consulta [Ciclo de vida del juego de XBOX](/es/build/console-features/console-workflows/xbox-game-life-cycle) para más detalles.

<a id="tips" />

## Trucos y sugerencias

### Archivo de empaquetado Microsoft Game Config

El Microsoft Game Development Kit (GDK) ya no usa un archivo `Package.appxmanifest` durante la cadena de herramientas de compilación de Visual Studio para generar `AppxManifest.xml`. En su lugar, se usa un archivo MicrosoftGameConfig para alojar toda la configuración del paquete de la aplicación en tiempo de desarrollo.

```xml theme={null}
<?xml version="1.0" encoding="utf-8"?>
<Game configVersion="1">

  <Identity Name="<project identifier or name>"
            Publisher="CN=<Publisher>"
            Version="1.0.0.0"/>

  <ExecutableList>
    <Executable Name="<name of title>.exe"
                Id="Game"/>
  </ExecutableList>

</Game>
```

El elemento `Executable Name` debe coincidir con el nombre del EXE en el diseño del paquete.

> Ten en cuenta que puedes crear un proyecto nuevo usando Visual Studio. Selecciona **File**, **New Project** y, a continuación, selecciona la plantilla Direct3D 12 XBOX Game del Microsoft Game Development Kit (GDK). Después puedes agregar a tu proyecto el archivo `MicrosoftGame.config` creado por la plantilla.

Como opción, puedes agregar los distintos recursos de interfaz de usuario y relacionados con la Store, que deben estar presentes en el paquete, agregando una sección `<ShellVisuals>`.

```xml theme={null}
  <ShellVisuals DefaultDisplayName="<name of title>"
                PublisherDisplayName="<publisher name>"
                StoreLogo="StoreLogo.png"
                Square150x150Logo="Logo.png"
                Square44x44Logo="SmallLogo.png"
                Square480x480Logo="LargeLogo.png"
                Description="<desc of title>"
                ForegroundText="light"
                BackgroundColor="#464646"
                SplashScreenImage="SplashScreen.png"/>
```

> Ten en cuenta que el XBOX One Software Development Kit tenía un elemento `WideLogo`; ahora se hace referencia a él como el atributo Square480x480Logo.

Para la integración de los servicios XBOX, también necesitas proporcionar un Title ID.

```xml theme={null}
    <TitleId>hex-number</TitleId>
```

Como se indicó anteriormente, ya no necesitas usar elementos de manifiesto para obtener el séptimo núcleo y la disponibilidad de recursos extendidos de GPU, pero puedes usar el manifiesto para controlar la memoria del título.

```xml theme={null}
    <mx:Extension Category="xbox.system.resources">
        <mx:XboxSystemResources resourceConfiguration="extended">
          <mx:GpuAvailability>variable</mx:GpuAvailability>
          <mx:TitleMemory ConsoleType="Xbox_One_X" Size="9"/>
        </mx:XboxSystemResources>
    </mx:Extension>
```

El elemento appxmanifest anterior se ha reemplazado por un elemento cuyo valor predeterminado es "Standard" para el control de memoria del título.

```xml theme={null}
    <VirtualMachine>
      <XboxOneXTitleMemory>Advanced</XboxOneXTitleMemory>
    </VirtualMachine>
```

Algunas extensiones de manifiesto del XBOX One Software Development Kit también pueden transferirse al archivo `.config`. Para una definición completa de las opciones permitidas, consulta Archivo MicrosoftGameConfig.

### Obtención del tipo de dispositivo

El método **GetConsoleType** del XBOX One Software Development Kit no está disponible para el Microsoft Game Development Kit (GDK). Usa en su lugar la API de GameRuntime **XSystemGetDeviceType**.

```cpp theme={null}
#include <XSystem.h>

XSystemDeviceType deviceType = XSystemGetDeviceType();

switch (deviceType)
{
case XSystemDeviceType::Pc:                     ... break;
case XSystemDeviceType::XboxOne:                ... break;
case XSystemDeviceType::XboxOneS:               ... break;
case XSystemDeviceType::XboxOneX:               ... break;
case XSystemDeviceType::XboxOneXDevkit:         ... break;
case XSystemDeviceType::XboxScarlettLockhart: /* Xbox Series S */ ... break;
case XSystemDeviceType::XboxScarlettAnaconda: /* Xbox Series X */ ... break;
case XSystemDeviceType::XboxScarlettDevkit:     ... break;
case XSystemDeviceType::Unknown:                ... break;
}
```

### Reemplazo en el GDK de xdk.h y `_XDK_VER`

En el XBOX One Software Development Kit, el encabezado `xdk.h` proporcionaba una serie de símbolos de compilación relacionados con el número de compilación del XDK, el nivel de QFE, etc.

Para las plataformas `Gaming.*.x64`, puedes hacer uso de `grdk.h`:

* `_GRDK_VER` es la codificación de versión del GDK de Gaming usado para compilar el binario (HIWORD.LOWORD). Por ejemplo, `0x4A610479` es el número de compilación 19041.1145.
* `_GRDK_VER_STRING` para esa compilación es "April 2020 GRDK".
* `_GRDK_VER_STRING_W` es el equivalente en cadena ancha UTF16-LE de `_GRDK_VER_STRING`.
* `_GRDK_VER_STRING_COMPACT_W` para esa compilación es una cadena ancha UTF16-LE que contiene "April 2020".

Para las plataformas `Gaming.Xbox.*.x64`, también puedes hacer uso de `gxdk.h`:

* `_GXDK_VER` es la codificación de versión del GDK de Gaming usado para compilar el binario (HIWORD.LOWORD). Por ejemplo, `0x4A610479` es el número de compilación 19041.1145.
* `_GXDK_VER_STRING` para esa compilación es "April 2020 GXDK".
* `_GXDK_VER_STRING_W` es el equivalente en cadena ancha UTF16-LE de `_GXDK_VER_STRING`.
* `_GXDK_VER_STRING_COMPACT_W` para esa compilación es una cadena ancha UTF16-LE que contiene "April 2020".

### Obtención del identificador del punto de conexión de representación de audio predeterminado

Las API de Windows Runtime Windows.Media.Devices y Windows.Devices.Enumeration no se usan para el Microsoft Game Development Kit (GDK) en XBOX. Para obtener el representador predeterminado, usa el código siguiente.

```cpp theme={null}
#include <mmdeviceapi.h>

ComPtr<IMMDeviceEnumerator> devEnum;
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(devEnum.GetAddressOf()));
// Check hr for errors

ComPtr<IMMDeviceCollection> devices;
hr = devEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &devices);
// Check hr for errors

ComPtr<IMMDevice> endpoint;
hr = devices->Item(0, endpoint.GetAddressOf();
// Check hr for errors

LPWSTR id = nullptr;
hr = endpoint->GetId(&id);
// Check hr for errors

// The id variable contains the device identifier used by XAudio2

CoTaskMemFree(id);
```

### MapVirtualKey

Los métodos `MapVirtualKey` y `MapVirtualKeyEx` no se admiten para el Microsoft Game Development Kit (GDK) en XBOX. Lo más común es que se usen para detectar las teclas `VK_SHIFT` izquierda y derecha en el código que maneja el teclado.

```cpp theme={null}
int vk = static_cast<int>(wParam);
switch (vk)
{
    case VK_SHIFT:
    #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_GAMES)
        vk = (((lParam & 0x00ff0000) >> 16) == 0x36) ? VK_RSHIFT : VK_LSHIFT;
    #else
        vk = MapVirtualKey((lParam & 0x00ff0000) >> 16, MAPVK_VSC_TO_VK_EX);
    #endif
        break;

    case VK_CONTROL:
        vk = (lParam & 0x01000000) ? VK_RCONTROL : VK_LCONTROL;
        break;

    case VK_MENU:
        vk = (lParam & 0x01000000) ? VK_RMENU : VK_LMENU;
        break;
}
```

### MultiByteToWideChar y WideCharToMultiByte

Al convertir entre cadenas de caracteres anchos (UTF-16 LE) y cadenas de caracteres estrechos, los desarrolladores de Win32 suelen usar [MultiByteToWideChar](https://learn.microsoft.com/windows/desktop/api/stringapiset/nf-stringapiset-multibytetowidechar) y [WideCharToMultiByte](https://learn.microsoft.com/windows/desktop/api/stringapiset/nf-stringapiset-widechartomultibyte). Para las bases de código modernas, recomendamos usar `CP_UTF8` en lugar de una página de códigos específica o `CP_ACP`.

El código siguiente funciona en Windows 7 Service Pack 1 y posteriores.

```cpp theme={null}
// Name is a char array as input.
wchar_t wname[MAX_PATH] = {};
int result = MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, MAX_PATH);
if (result <= 0) // Error
```

A veces se usan directamente 437 y 1252. 437 no se admite ni para el XBOX One Software Development Kit ni para el Microsoft Game Development Kit (GDK) en XBOX. 1252 funcionaba en el XBOX One XDK, pero no se admite para el Microsoft Game Development Kit (GDK) en XBOX. Para el Microsoft Game Development Kit (GDK) en XBOX, `CP_ACP` se trata como un alias de `CP_UTF8`. En Windows 10 moderno y con el Microsoft Game Development Kit (GDK), normalmente puedes reemplazar todas las instancias de `CP_ACP` por `CP_UTF8` usando buscar y reemplazar. Para simplificar este tipo de migración, se eliminó la validación de otros parámetros relacionados con `CP_UTF8`.

C++11 agregó el encabezado `<codecvt>` como una solución más portable al problema de convertir cadenas, pero ya se ha declarado en desuso en C++17. La recomendación es seguir con las funciones de cadena de la plataforma.

### API de localización y globalización

En ERA, faltaba la mayor parte de la compatibilidad integrada de Windows para la localización, más allá de la simple selección de página de códigos, la traducción de puntos de código (la conversión de multibyte a widechar) y el informe de la configuración regional del sistema/usuario. Para el Microsoft Game Development Kit (GDK), esta funcionalidad de localización es totalmente compatible, al igual que `GetCurrencyFormatEx`, `GetNumberFormatEx`, la enumeración de formatos de fecha y hora, y otras características.

### Notas sobre el audio XMA2

Si te falta la definición de `SHAPE_XMA_INPUT_BUFFER_ALIGNMENT`, tendrás que agregar explícitamente una referencia al encabezado shapexmacontext.h.

```cpp theme={null}
#include <shapexmacontext.h>
```

Con el XBOX One Software Development Kit, este encabezado se incluía implícitamente desde algunos otros encabezados de audio.

### Compatibilidad con cuadros de mensaje de interfaz de usuario

Para ayudar a mejorar la depuración de bloqueos y errores de inicialización tempranos dentro de un título, se ha agregado `XGameUiShowMessageDialogAsync` a la colección de API de interfaz de usuario invocable desde el título (TCUI). Esta API puede usarse en cualquier momento después de que se haya llamado a XGameRuntimeInitialize, incluso antes de la inicialización de D3D. La API se representa dentro de la partición del sistema y se compone sobre la salida del juego. Sigue funcionando incluso si el bucle del juego está detenido o aún no está representando. Esto puede ser muy útil para notificar información de errores de bloqueo, o incluso para solicitar la conexión del depurador mientras se bloquea en el lugar del error. Está pensada principalmente como una herramienta de diagnóstico en tiempo de desarrollo.

Este ejemplo muestra un cuadro de diálogo de error de estilo bloqueante, que solicita al desarrollador que se conecte para investigar.

```cpp theme={null}
XTaskQueueHandle queue;
ThrowIfFailed(
    XTaskQueueCreate(XTaskQueueDispatchMode::ThreadPool, XTaskQueueDispatchMode::Immediate, &queue)
);

XAsyncBlock* ab = new XAsyncBlock;
ZeroMemory(ab, sizeof(XAsyncBlock));
ab->queue = queue;

// Show dialog, wait for completion, get result.

XGameUiMessageDialogButton button;
if (SUCCEEDED(XGameUiShowMessageDialogAsync(ab, u8"This is a title", u8"This is content text", u8"Option #1", u8"Option #2", u8"Option #3", XGameUiMessageDialogButton::First, XGameUiMessageDialogButton::Third)) &&
    SUCCEEDED(XAsyncGetStatus(ab, true)) &&
    SUCCEEDED(XGameUiShowMessageDialogResult(ab, &button)))
{
    DoSomethingWithResponse(button);
}
```

### Bibliotecas de extensión

En el XBOX One Software Development Kit, con el uso de las API de Windows Runtime, agregar bibliotecas de extensión como XSAPI o Game Chat requería usar el cuadro de diálogo 'References...' de Visual Studio. Para el Microsoft Game Development Kit (GDK), este mecanismo ya no se usa. En su lugar, pueden agregarse mediante las propiedades del proyecto de Visual Studio. Esto edita un elemento de propiedad en la sección Globals del `vcxproj`:

```text theme={null}
<PropertyGroup Label="Globals">
    <GDKExtLibNames>Xbox.Game.Chat.2.Cpp.API;Xbox.Services.API.C</GDKExtLibNames>
</PropertyGroup>
```

Si este elemento no está presente, el valor predeterminado es incluir solo XSAPI.

<a id="bincompat" />

## Compatibilidad binaria y reutilización de componentes

Uno de los principios rectores del Microsoft Game Development Kit (GDK) es maximizar la capacidad de los desarrolladores de reutilizar su trabajo entre Windows de escritorio y los títulos de consola XBOX. Un aspecto de esto que no se ha tratado anteriormente es que se ha trabajado para mejorar la compatibilidad binaria entre Windows de escritorio y el sistema operativo del Microsoft Game Development Kit (GDK) en XBOX.

A diferencia de los títulos del XBOX One Software Development Kit, el Microsoft Game Development Kit (GDK) en XBOX puede reutilizar una variedad de componentes que se compilaron originalmente para Windows de escritorio x64. Esto puede ser una valiosa característica de ahorro de tiempo para la creación de prototipos, herramientas u otros escenarios que no sean críticos para el rendimiento.

No hay herramientas en el Microsoft Game Development Kit (GDK) para determinar si un componente de Windows de escritorio puede reutilizarse, sino que esto viene determinado por las API del sistema operativo que consume el componente en cuestión.

Las API compatibles del sistema operativo del Microsoft Game Development Kit (GDK) en XBOX pueden obtenerse ejecutando `dumpbin.exe /exports` en las bibliotecas que se incluyen con el Microsoft Game Development Kit (GDK). Aunque algunas API específicas de un área residen en sus propias bibliotecas (como D3D12XboxCreateDevice dentro de `d3d12_x.lib` o `d3d12_xs.lib`), la mayoría de las API Win32 heredadas se agregan en una única biblioteca llamada `xgameplatform.lib`. El siguiente comando, cuando se ejecuta desde un símbolo del sistema para desarrolladores de Visual Studio, muestra el conjunto principal de API Win32 compatibles (aparte de las que residen en otra biblioteca de importación).

`dumpbin.exe /exports "c:\Program Files (x86)\Microsoft GDK\build_number\GXDK\gameKit\lib\amd64\xgameplatform.lib"`

<Note>
  En la ruta de ejemplo anterior, *build\_number* representa la compilación instalada en tu sistema (por ejemplo, 190700).
</Note>

Las bibliotecas estáticas compiladas originalmente para Windows de escritorio, que solo hacen uso de las API de la lista aprobada, generalmente pueden vincularse directamente en un binario del Microsoft Game Development Kit (GDK) destinado a XBOX. Sin embargo, esto no es universalmente cierto, ya que las diferencias de comportamiento (como la limitación de una única ventana) pueden causar errores en tiempo de ejecución del componente si no se ha diseñado para manejar tales diferencias.

Las bibliotecas de vínculos dinámicos (DLL) que tienen una lista de importación que se encuentra completamente dentro de las API compatibles también, por lo general, se cargarán y funcionarán tal cual. El sistema operativo del Microsoft Game Development Kit (GDK) en XBOX contiene lógica de reenvío para redirigir correctamente este conjunto de API a sus ubicaciones de implementación si difieren de las de Windows de escritorio.

Aunque poder reutilizar componentes de Windows de escritorio en la consola puede ahorrar tiempo en muchos escenarios, no se recomienda para las rutas críticas para el rendimiento dentro de un título que se va a publicar. La mayoría de los componentes compilados pensando en Windows de escritorio no se habrán compilado con las marcas más óptimas para la ejecución con el Microsoft Game Development Kit (GDK). En particular, dado que los componentes de escritorio se dirigen a una gama más amplia de CPU, esos componentes pueden haberse compilado sin optimizaciones AVX. Reutilizar DLL de escritorio también puede llevar a un tamaño de código general mayor, en comparación con recompilar para el Microsoft Game Development Kit (GDK).

<a id="codingstyle" />

## Estilo de codificación y procedimientos recomendados

La guía de Code Generation for XBOX One - Best Practices [(XBOX Developer Downloads->XBOX One->All XBOX One XDK CHMs)](https://aka.ms/gdkdl) se aplica al Microsoft Game Development Kit (GDK). La principal diferencia en la configuración del compilador es que estos proyectos no requieren el uso de C++/CX (`/ZW`) ni C++/WinRT, porque la mayoría de las API de juego tienen el estilo de COM de tipo Win32 o DirectX. Aquí tienes algunas recomendaciones generales:

* Aprovecha la conformidad del lenguaje C++14 y, opcionalmente, C++17. Ten en cuenta que el diseño de las API del Microsoft Game Development Kit (GDK) asume un compilador C++11 o mejor.
* El proceso de generación de código de punto flotante nativo x64 siempre usa SSE/SSE2. XBOX One admite `/arch:AVX`, así como F16C.
* El manejo de excepciones de C++ (`/EHsc`) tiene poca o ninguna sobrecarga en el código nativo x64. Sin embargo, el lanzamiento de excepciones en tiempo de ejecución no es un escenario de rendimiento, por lo que no debería usarse para controlar el flujo.
* El uso de técnicas de codificación seguras frente a excepciones, como las descritas en [Objects Own Resources (RAII)](https://learn.microsoft.com/cpp/cpp/objects-own-resources-raii) y [Resource Acquisition Is Initialization](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization), es un procedimiento recomendado muy aconsejable usando `std::unique_ptr`, `Microsoft::WRL::ComPtr` y otras clases de punteros inteligentes.
* Da preferencia al uso de tipos portables estándar como `size_t`, `ptrdiff_t`, `int8_t`, `uint8_t`, `int16_t`, `uint16_t`, `int32_t`, `uint32_t`, `int64_t`, `uint64_t`, `intptr_t` y `uintptr_t`.
* Para minimizar el relleno interno, agrupa los punteros en estructuras y clases.
* En lugar de la conversión heredada de estilo C, da preferencia a las conversiones de C++ como `const_cast<>`, `static_cast<>`, `reinterpret_cast<>` y `dynamic_cast<>`.
* Usa intrínsecos siempre que sea posible. El código nativo x64 no admite ensamblado en línea.

### Modificadores del compilador y del enlazador

Usa los siguientes modificadores:

* `/O1 /Oi` para optimización general y `/O2` para los módulos críticos
* `/fp:fast`
* `/arch:AVX` para la familia de dispositivos XBOX One; `/arch:AVX2` para XBOX Series X|S.
* `/favor:AMD`
* Optimización de todo el programa y optimización guiada por perfiles
* Modificadores del enlazador `/OPT:REF,ICF`

Por razones históricas, `/Ox` es casi lo mismo que `/O2`, pero le faltan tanto `/GF` (Eliminar cadenas duplicadas) como `/Gy` (Habilitar vinculación en el nivel de función). Da preferencia a `/O2` sobre `/Ox`. Si usas `/Ox`, asegúrate de habilitar explícitamente al menos `/Gy`, que es importante para habilitar la optimización del enlazador.

También se han agregado varios modificadores nuevos del compilador a Visual C++ desde el lanzamiento del XBOX One Software Development Kit, así que asegúrate de informarte sobre ellos: `/Zc:inline`, [/Zc:throwingNew](https://blogs.msdn.com/b/vcblog/archive/2015/08/06/new-in-vs-2015-zc-throwingnew.aspx), [/Zc:\_\_cplusplus](https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/), `/volatile:iso`, [/permissive-](https://blogs.msdn.microsoft.com/vcblog/2016/11/16/permissive-switch/), [/Zc:twoPhase-](https://blogs.msdn.microsoft.com/vcblog/2017/09/11/two-phase-name-lookup-support-comes-to-msvc/) y [/Debug:FASTLINK](https://blogs.msdn.microsoft.com/vcblog/2015/10/16/debugfastlink-for-vs2015-update-1/).

### Código condicional

Para el código condicional en el que las rutas divergen, ten en cuenta las siguientes convenciones.

| Plataforma | Compilación condicional |
| - | - |
| Desarrollo de escritorio Win32 | `#if !defined(WINAPI_FAMILY) \|\| (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)` |
| XBOX One Software Development Kit | `#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_TV_TITLE)` <br /> -o bien- <br /> `#if defined(_XBOX_ONE) && defined(_TITLE)` |
| Microsoft Game Development Kit (GDK) en XBOX One o XBOX Series X\|S | `#ifdef _GAMING_XBOX` |
| Microsoft Game Development Kit (GDK) solo en XBOX One | `#ifdef _GAMING_XBOX_XBOXONE` |
| Microsoft Game Development Kit (GDK) solo en XBOX Series X\|S | `#ifdef _GAMING_XBOX_SCARLETT` |

Si tu base de código ya admite el XBOX One Software Development Kit, un buen punto de partida es hacer lo siguiente:

1. Buscar todas las instancias de `_XBOX_ONE` en tu base de código
2. Cambiar las instancias como `#if defined(_XBOX_ONE) && defined(_TITLE)`, donde el código usa las extensiones de DirectX 12.X, convirtiéndolas en estos casos: <br /> `#if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)`

### UTF-8 en todas partes

En la larga historia de la plataforma Windows, las funciones ANSI originales llevan mucho tiempo en desuso en favor de la solución Unicode de caracteres anchos, es decir, CreateFileW en lugar de CreateFileA. Esto resolvió el problema de tratar con una gran cantidad de páginas de códigos diferentes y simplificó todas las cadenas localizables a `wchar_t*` (UTF-16 LE, little endian). El [manifiesto UTF-8 Everywhere](https://utf8everywhere.org/) defiende que la codificación multibyte UTF-8 con `char*` es una mejor solución en términos de huella de memoria y portabilidad.

Para la plataforma del Microsoft Game Development Kit (GDK) en XBOX, la página de códigos predeterminada está establecida en `CP_UTF8`, por lo que cualquier versión ANSI de las API de la plataforma Win32 usa UTF-8. Puedes seguir usando las API de caracteres anchos con UTF-16 LE, pero también tienes la opción de usar UTF-8.

<Note>
  La compatibilidad completa con UTF-8 en Windows es una incorporación muy reciente, por lo que aún no está muy extendida. También es algo en lo que el usuario tiene que participar de forma voluntaria por el momento, así que podrías encontrar que mantener tu uso de bajo nivel de las API Win32 en las API de caracteres anchos es la mejor opción por portabilidad.
</Note>

Recomendamos lo siguiente:

* Da preferencia al uso de UTF-8 en tus API y convierte a UTF-16 LE solo al llamar a las API Win32 de caracteres anchos. En lugar de usar `std::wstring` y `wchar_t*`, usa `std::string` y `char*` como UTF-8.
* Para los literales de cadena estrechos, garantiza la adherencia a UTF-8 usando el prefijo `u8` de C++ en lugar de ningún prefijo o `L`.
* Mantén las definiciones de preprocesador de compilación `UNICODE` y `_UNICODE` que ya estén en su lugar (en Visual Studio, esto es la propiedad `<CharSet>`) como medida de seguridad, pero en lugar de depender de las macros, llama siempre explícitamente a la versión `W()` o `A()`.
* Evita `TCHAR`, `TEXT()`, `LPTSTR` y otros tipos y macros de texto heredados. Para más información, consulta Compatibilidad con UTF-8 en el Microsoft Game Development Kit (GDK).

### Convención de nomenclatura: indicaciones de rendimiento y comportamiento

Las API de la plataforma del Microsoft Game Development Kit (GDK) en XBOX se han diseñado con el propósito de que los nombres de las funciones hagan afirmaciones implícitas sobre el rendimiento de las funciones que se llaman.

Se espera que una función que incluye la palabra `Get` o `Set` en su nombre tenga una sobrecarga baja y sea predecible. También se espera que tenga aproximadamente el mismo nivel de rendimiento que si se llamara en lugar de una función contenedora de propiedad de C++ con cualquier operación `memcpy` para copiar el resultado. Si una función usara `Query` en lugar de `Get`, esto implicaría que es una operación de larga duración que podría bloquearse hasta completarse.

Para las funciones que realizan cálculos en lugar de consultas simples, normalmente asumimos que el rendimiento es aproximadamente el que esperarías después de inspeccionar sus parámetros de entrada y los tipos de operaciones que realizan, a menos que la documentación indique lo contrario.

Una función cuyo nombre termina en `Async` es una operación asincrónica y podría tardar mucho tiempo o un tiempo indeterminado en completarse. En la mayoría de los casos, proporcionamos versiones con bloqueo y asincrónicas de las funciones que pueden tardar mucho en ejecutarse. Te dejamos decidir qué variante funciona mejor para tu base de código. En algunos casos (como con las API de red), podríamos omitir por completo la versión con bloqueo, porque proporcionarla no tendría sentido.

Si el nombre de una función comienza con `Show` y termina con `Async`, la función muestra elementos de interfaz de usuario y, para regresar, normalmente requiere la interacción del usuario. En algunos casos, el sistema puede cancelar las operaciones de interfaz de usuario.

<a id="seealso" />

## Consulte también

* ¿Qué es el Microsoft Game Development Kit?
* Introducción al Microsoft Game Development Kit (GDK)


## Related topics

- [Características de consola para el XBOX Game Development Kit](/es/build/console-features/index.md)
- [Usuarios y dispositivos de entrada](/es/build/core-features/common/user/users-input-devices.md)
- [Guías de migración del Kit de desarrollo de software de XBOX One](/es/build/console-features/networking/xdk-migration/xdk-migration-toc.md)
- [Migración de las redes del XDK al GDK de XBOX](/es/build/console-features/networking/xdk-migration/index.md)
- [Redes](/es/build/console-features/networking/gc-networking-toc.md)
