xbox-kernel/private/ntos/dd/usb/enumtest/main.cpp
2020-09-30 17:17:25 +02:00

181 lines
6.1 KiB
C++

#include <xtl.h>
#include "draw.h"
// Hack! DbgPrint is much nicer than OutputDebugString so JonT exported it from xapi.lib
// (as DebugPrint) but the prototype isn't in the public headers...
extern "C"
{
ULONG
DebugPrint(
PCHAR Format,
...
);
}
//
// Colors
//
#define BACKDROP_BLUE 0x000080
#define LABEL_WHITE 0xffffff
#define DISCONNECTED_BLUE 0x000040
#define CONNECTED_YELLOW 0xffff00
//
// Useful Macro
//
#define DECLARE_DO_TWICE int doTwice;
#define DO_TWICE doTwice=2; while(doTwice--)
//
// Forward Declations
//
void InitDisplay(Draw *pDraw);
void InitDevices(PXPP_DEVICE_TYPE DeviceType, DWORD& dwState, BOOL fHasBottomSlots, Draw *pDraw, ULONG yPos);
void UpdateDevices(PXPP_DEVICE_TYPE DeviceType, DWORD& dwState, BOOL fHasBottomSlots, Draw *pDraw, ULONG yPos);
LPWSTR DeviceTypeToString(PXPP_DEVICE_TYPE DeviceType);
void DrawPortTopSlotsBitmap(Draw *pDraw, DWORD dwState, ULONG yPos);
void DrawPortBottomSlotsBitmap(Draw *pDraw, DWORD dwState, ULONG yPos);
//------------------------------------------------------------------------------
// TestMain
void __cdecl main()
{
DebugPrint("ENUMTEST APPLICATION.\nBuilt on %s at %s\n", __DATE__, __TIME__);
//Initialize core peripheral port support
XDEVICE_PREALLOC_TYPE deviceTypes[] =
{
{XDEVICE_TYPE_GAMEPAD,4},
{XDEVICE_TYPE_MEMORY_UNIT,8},
{XDEVICE_TYPE_VOICE_MICROPHONE,4},
{XDEVICE_TYPE_VOICE_HEADPHONE,4}
};
XInitDevices(sizeof(deviceTypes)/sizeof(XDEVICE_PREALLOC_TYPE),deviceTypes);
Draw draw;
DWORD dwStateGamePads;
DWORD dwStateMemoryUnits;
DWORD dwStateChatButtons;
DWORD dwStateChatMicrophone;
DWORD dwStateChatHeadphone;
InitDisplay(&draw);
InitDevices(XDEVICE_TYPE_GAMEPAD, dwStateGamePads, FALSE, &draw, 80);
InitDevices(XDEVICE_TYPE_MEMORY_UNIT, dwStateMemoryUnits, TRUE, &draw, 100);
InitDevices(XDEVICE_TYPE_VOICE_MICROPHONE, dwStateChatMicrophone, FALSE, &draw, 130);
InitDevices(XDEVICE_TYPE_VOICE_HEADPHONE, dwStateChatHeadphone, FALSE, &draw, 150);
while(1)
{
UpdateDevices(XDEVICE_TYPE_GAMEPAD, dwStateGamePads, FALSE, &draw, 80);
UpdateDevices(XDEVICE_TYPE_MEMORY_UNIT, dwStateMemoryUnits, TRUE, &draw, 100);
UpdateDevices(XDEVICE_TYPE_VOICE_MICROPHONE, dwStateChatMicrophone, FALSE, &draw, 130);
UpdateDevices(XDEVICE_TYPE_VOICE_HEADPHONE, dwStateChatHeadphone, FALSE, &draw, 150);
}
}
void InitDisplay(Draw *pDraw)
{
DECLARE_DO_TWICE;
DO_TWICE{
//Draw the title screen
pDraw->FillRect(0, 0, 640, 480, BACKDROP_BLUE);
pDraw->DrawText(L"USB Enumeration Test Application", 50, 50, LABEL_WHITE);
pDraw->Present();
}
}
void InitDevices(PXPP_DEVICE_TYPE DeviceType, DWORD& dwState, BOOL fHasBottomSlots, Draw *pDraw, ULONG yPos)
{
WCHAR FormatBuffer[80];
DECLARE_DO_TWICE;
if(fHasBottomSlots)
{
DO_TWICE{
wsprintf(FormatBuffer, L"%ws's(Top):", DeviceTypeToString(DeviceType));
pDraw->DrawText(FormatBuffer, 55, yPos, LABEL_WHITE);
wsprintf(FormatBuffer, L"%ws's(Bottom):", DeviceTypeToString(DeviceType));
pDraw->DrawText(FormatBuffer, 55, yPos+10, LABEL_WHITE);
pDraw->Present();
}
} else
{
DO_TWICE
{
wsprintf(FormatBuffer, L"%ws's:", DeviceTypeToString(DeviceType));
pDraw->DrawText(FormatBuffer, 55, yPos, LABEL_WHITE);
pDraw->Present();
}
}
dwState = XGetDevices(DeviceType);
DebugPrint("%ws Initial State = 0x%0.8x\n", DeviceTypeToString(DeviceType), dwState);
DrawPortTopSlotsBitmap(pDraw, dwState, yPos);
if(fHasBottomSlots) DrawPortBottomSlotsBitmap(pDraw, dwState, yPos+10);
}
void UpdateDevices(PXPP_DEVICE_TYPE DeviceType, DWORD& dwState, BOOL fHasBottomSlots, Draw *pDraw, ULONG yPos)
{
DWORD dwInsertions, dwRemovals;
//
// Only update the text, if something changed.
// This is why you want to ask for insertions and removals (last parameter is false)
// rather than state, which returns TRUE if anything is attached.
//
if(XGetDeviceChanges(DeviceType, &dwInsertions, &dwRemovals))
{
dwState &= ~dwRemovals; //Always process removals first
dwState |= dwInsertions;
DebugPrint("%ws Changed, Insert=0x%0.8x, Remove=0x%0.8x, State=0x%0.8x\n", DeviceTypeToString(DeviceType), dwInsertions, dwRemovals, dwState);
DrawPortTopSlotsBitmap(pDraw, dwState, yPos);
if(fHasBottomSlots) DrawPortBottomSlotsBitmap(pDraw, dwState, yPos+10);
}
}
LPWSTR DeviceTypeToString(PXPP_DEVICE_TYPE DeviceType)
{
if(XDEVICE_TYPE_GAMEPAD == DeviceType) return L"XDEVICE_TYPE_GAMEPAD";
if(XDEVICE_TYPE_MEMORY_UNIT == DeviceType) return L"XDEVICE_TYPE_MEMORY_UNIT";
if(XDEVICE_TYPE_VOICE_MICROPHONE == DeviceType) return L"XDEVICE_TYPE_VOICE_MICROPHONE";
if(XDEVICE_TYPE_VOICE_HEADPHONE == DeviceType) return L"XDEVICE_TYPE_VOICE_HEADPHONE";
return L"XDEVICE_TYPE_????";
}
void DrawPortTopSlotsBitmap(Draw *pDraw, DWORD dwState, ULONG yPos)
/*++
Draws the state of the top slots of players one to four.
--*/
{
DECLARE_DO_TWICE;
DO_TWICE
{
ULONG xPos = 250;
WCHAR PortString[2]=L"0";
for(int index = 0; index < XGetPortCount(); index++)
{
(*PortString)++;
pDraw->DrawText(PortString, xPos, yPos, (dwState&(1<<index)) ? CONNECTED_YELLOW : DISCONNECTED_BLUE);
xPos += 20;
}
pDraw->Present();
}
}
void DrawPortBottomSlotsBitmap(Draw *pDraw, DWORD dwState, ULONG yPos)
/*++
Draws the state of the bottom slots of players one to four
--*/
{
DECLARE_DO_TWICE;
DO_TWICE
{
ULONG xPos = 250;
WCHAR PortString[2]=L"0";
for(int index = 0; index < XGetPortCount(); index++)
{
(*PortString)++;
pDraw->DrawText(PortString, xPos, yPos, (dwState&(1<<(index+16))) ? CONNECTED_YELLOW : DISCONNECTED_BLUE);
xPos += 20;
}
pDraw->Present();
}
}