1+ // --------------------------------------------------------------------------------------
2+ // File: ControllerFont.h
3+ //
4+ // Class for compositing text with Xbox controller font button sprites
5+ //
6+ // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
7+ // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
8+ // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
9+ // PARTICULAR PURPOSE.
10+ //
11+ // Copyright (c) Microsoft Corporation. All rights reserved.
12+ // -------------------------------------------------------------------------------------
13+
14+ #pragma once
15+
16+ #include " SpriteBatch.h"
17+ #include " SpriteFont.h"
18+
19+
20+ namespace DX
21+ {
22+ enum class ControllerFont : wchar_t
23+ {
24+ LeftThumb = L' ' ,
25+ DPad = L' !' ,
26+ RightThumb = L' \" ' ,
27+ View = L' #' ,
28+ Guide = L' $' ,
29+ Menu = L' %' ,
30+ XButton = L' &' ,
31+ YButton = L' \' ' ,
32+ BButton = L' (' ,
33+ AButton = L' )' ,
34+ RightShoulder = L' *' ,
35+ RightTrigger = L' +' ,
36+ LeftTrigger = L' ,' ,
37+ LeftShoulder = L' -' ,
38+ };
39+
40+ inline void XM_CALLCONV DrawControllerString (_In_ DirectX::SpriteBatch* spriteBatch, _In_ DirectX::SpriteFont* textFont, _In_ DirectX::SpriteFont* butnFont,
41+ _In_z_ wchar_t const * text, DirectX::XMFLOAT2 const & position, DirectX::FXMVECTOR color = DirectX::Colors::White, float scale = 1 )
42+ {
43+ using namespace DirectX ;
44+
45+ size_t textLen = wcslen (text);
46+ if (textLen >= 4096 )
47+ {
48+ throw std::out_of_range (" String is too long" );
49+ }
50+
51+ float buttonHeight = butnFont->GetLineSpacing ();
52+ float buttonScale = (textFont->GetLineSpacing () * scale) / buttonHeight;
53+ float offsetY = buttonScale / 2 .f ;
54+
55+ size_t j = 0 ;
56+ wchar_t strBuffer[4096 ] = {0 };
57+
58+ bool buttonText = false ;
59+
60+ XMFLOAT2 outPos = position;
61+
62+ for (size_t ch = 0 ; ch < textLen; ++ch)
63+ {
64+ if (buttonText)
65+ {
66+ strBuffer[j++] = text[ch];
67+
68+ if (text[ch] == L' ]' )
69+ {
70+ wchar_t button[2 ] = { 0 };
71+
72+ if (_wcsicmp (strBuffer, L" [A]" ) == 0 )
73+ {
74+ *button = static_cast <wchar_t >(ControllerFont::AButton);
75+ }
76+ else if (_wcsicmp (strBuffer, L" [B]" ) == 0 )
77+ {
78+ *button = static_cast <wchar_t >(ControllerFont::BButton);
79+ }
80+ else if (_wcsicmp (strBuffer, L" [X]" ) == 0 )
81+ {
82+ *button = static_cast <wchar_t >(ControllerFont::XButton);
83+ }
84+ else if (_wcsicmp (strBuffer, L" [Y]" ) == 0 )
85+ {
86+ *button = static_cast <wchar_t >(ControllerFont::YButton);
87+ }
88+ else if (_wcsicmp (strBuffer, L" [DPad]" ) == 0 )
89+ {
90+ *button = static_cast <wchar_t >(ControllerFont::DPad);
91+ }
92+ else if (_wcsicmp (strBuffer, L" [View]" ) == 0 )
93+ {
94+ *button = static_cast <wchar_t >(ControllerFont::View);
95+ }
96+ else if (_wcsicmp (strBuffer, L" [Menu]" ) == 0 )
97+ {
98+ *button = static_cast <wchar_t >(ControllerFont::Menu);
99+ }
100+ else if (_wcsicmp (strBuffer, L" [Guide]" ) == 0 )
101+ {
102+ *button = static_cast <wchar_t >(ControllerFont::Guide);
103+ }
104+ else if (_wcsicmp (strBuffer, L" [RThumb]" ) == 0 )
105+ {
106+ *button = static_cast <wchar_t >(ControllerFont::RightThumb);
107+ }
108+ else if (_wcsicmp (strBuffer, L" [LThumb]" ) == 0 )
109+ {
110+ *button = static_cast <wchar_t >(ControllerFont::LeftThumb);
111+ }
112+ else if (_wcsicmp (strBuffer, L" [RB]" ) == 0 )
113+ {
114+ *button = static_cast <wchar_t >(ControllerFont::RightShoulder);
115+ }
116+ else if (_wcsicmp (strBuffer, L" [LB]" ) == 0 )
117+ {
118+ *button = static_cast <wchar_t >(ControllerFont::LeftShoulder);
119+ }
120+ else if (_wcsicmp (strBuffer, L" [RT]" ) == 0 )
121+ {
122+ *button = static_cast <wchar_t >(ControllerFont::RightTrigger);
123+ }
124+ else if (_wcsicmp (strBuffer, L" [LT]" ) == 0 )
125+ {
126+ *button = static_cast <wchar_t >(ControllerFont::LeftTrigger);
127+ }
128+
129+ if ( *button )
130+ {
131+ float bsize = XMVectorGetX (butnFont->MeasureString (button));
132+ float offsetX = (bsize * buttonScale / 2 .f );
133+
134+ outPos.x += offsetX;
135+ outPos.y -= offsetY;
136+ butnFont->DrawString (spriteBatch, button, outPos, Colors::White, 0 .f , XMFLOAT2 (0 .f , 0 .f ), XMFLOAT2 (buttonScale, buttonScale));
137+ outPos.x += bsize * buttonScale;
138+ outPos.y += offsetY;
139+ }
140+
141+ memset (strBuffer, 0 , sizeof (strBuffer));
142+ j = 0 ;
143+
144+ buttonText = false ;
145+ }
146+ }
147+ else
148+ {
149+ switch (text[ch])
150+ {
151+ case ' \r ' :
152+ break ;
153+
154+ case ' [' :
155+ if (*strBuffer)
156+ {
157+ textFont->DrawString (spriteBatch, strBuffer, outPos, color, 0 .f , XMFLOAT2 (0 .f , 0 .f ), XMFLOAT2 (scale,scale));
158+ outPos.x += XMVectorGetX (textFont->MeasureString (strBuffer)) * scale;
159+ memset (strBuffer, 0 , sizeof (strBuffer));
160+ j = 0 ;
161+ }
162+ buttonText = true ;
163+ *strBuffer = L' [' ;
164+ ++j;
165+ break ;
166+
167+ case ' \n ' :
168+ if (*strBuffer)
169+ {
170+ textFont->DrawString (spriteBatch, strBuffer, outPos, color, 0 .f , XMFLOAT2 (0 .f , 0 .f ), XMFLOAT2 (scale, scale));
171+ memset (strBuffer, 0 , sizeof (strBuffer));
172+ j = 0 ;
173+ }
174+ outPos.x = position.x ;
175+ outPos.y += textFont->GetLineSpacing () * scale;
176+ break ;
177+
178+ default :
179+ strBuffer[j++] = text[ch];
180+ break ;
181+ }
182+ }
183+ }
184+
185+ if (*strBuffer)
186+ {
187+ textFont->DrawString (spriteBatch, strBuffer, outPos, color, 0 .f , XMFLOAT2 (0 .f , 0 .f ), XMFLOAT2 (scale, scale));
188+ }
189+ }
190+ }
0 commit comments