1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: TextWriter.cpp
4
5 Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Rev: 47859 $
14 *---------------------------------------------------------------------------*/
15
16 #include "TextWriter.h"
17
18 //////////////////////////////////////////////////////////////////////////////////////////
19 // Constant definitions
20 //////////////////////////////////////////////////////////////////////////////////////////
21
22 // Number of displays
23 #define DISPLAY_NUM 2
24
25 // Display number
26 #define DISPLAY_0 0
27 #define DISPLAY_1 1
28
29 extern bit8 NNFONT_RECTDRAWERSHADER_BEGIN[];
30 extern bit8 NNFONT_RECTDRAWERSHADER_END[];
31
32 namespace
33 {
34 // Initialization flag
35 bool s_isInitialized = false;
36 // unit matrix
37 nn::math::MTX34 s_mtxIdentify;
38 // Projection matrix
39 nn::math::MTX44 s_mtxProjection[DISPLAY_NUM];
40
41 // Color buffer information
42 const nn::font::ColorBufferInfo s_colBufferInfos[DISPLAY_NUM] =
43 {
44 {NN_GX_DISPLAY0_WIDTH, NN_GX_DISPLAY0_HEIGHT, PICA_DATA_DEPTH24_STENCIL8_EXT},
45 {NN_GX_DISPLAY1_WIDTH, NN_GX_DISPLAY1_HEIGHT, PICA_DATA_DEPTH24_STENCIL8_EXT}
46 };
47
48 // Render setting command
49 const u32 s_screenSettingCommands0[] =
50 {
51 // Viewport settings
52 NN_FONT_CMD_SET_VIEWPORT(0, 0, s_colBufferInfos[DISPLAY_0].width, s_colBufferInfos[DISPLAY_0].height),
53 // Disable scissoring
54 NN_FONT_CMD_SET_DISABLE_SCISSOR(s_colBufferInfos[DISPLAY_0]),
55 // Disable w Buffer / Set depth range / Disable polygon offset
56 NN_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET(0, 0, 1, 0, s_colBufferInfos[DISPLAY_0])
57 };
58
59 // Render setting command
60 const u32 s_screenSettingCommands1[] =
61 {
62 // Viewport settings
63 NN_FONT_CMD_SET_VIEWPORT(0, 0, s_colBufferInfos[DISPLAY_1].width, s_colBufferInfos[DISPLAY_1].height),
64 // Disable scissoring
65 NN_FONT_CMD_SET_DISABLE_SCISSOR(s_colBufferInfos[DISPLAY_1]),
66 // Disable w Buffer / Set depth range / Disable polygon offset
67 NN_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET(0, 0, 1, 0, s_colBufferInfos[DISPLAY_1])
68 };
69
70 // Initialization command
71 const u32 s_initCommands[] =
72 {
73 // Disable culling
74 NN_FONT_CMD_SET_CULL_FACE(NN_FONT_CMD_CULL_FACE_DISABLE),
75 // Disable stencil test
76 NN_FONT_CMD_SET_DISABLE_STENCIL_TEST(),
77 // Disable depth test / Make all elements of the color buffer writable
78 NN_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK(false, 0, true, true, true, true, true),
79 // Disable early depth test
80 NN_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST(false),
81 // Framebuffer access control
82 NN_FONT_CMD_SET_FBACCESS(true, true, false, false, false, false)
83 };
84 }
85
86 //////////////////////////////////////////////////////////////////////////////////////////
87 namespace scene
88 {
89
90 // Constructor.
TextWriter()91 TextWriter::TextWriter()
92 {
93 m_pExpHeap = NULL;
94 m_pStringBuffer = NULL;
95 m_textColor = nn::util::Color8(255, 255, 255, 255);
96 m_pShaderBuffer = NULL;
97 m_targetDisplay = DISPLAY_0;
98 }
99
100 // Destructor.
~TextWriter()101 TextWriter::~TextWriter()
102 {
103 Finalize();
104 }
105
106 // Performs initialization.
Initialize(nn::fnd::ExpHeap * pExpHeap)107 void TextWriter::Initialize(nn::fnd::ExpHeap* pExpHeap)
108 {
109 // Perform shared font initialization
110 if (nn::pl::InitializeSharedFont().IsSuccess())
111 {
112 // Standby until shared font has completed loading
113 while (nn::pl::GetSharedFontLoadState() != nn::pl::SHARED_FONT_LOAD_STATE_LOADED)
114 {
115 nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(1));
116 }
117
118 // Confirm that shared font loading has not failed
119 if (nn::pl::GetSharedFontLoadState() == nn::pl::SHARED_FONT_LOAD_STATE_FAILED)
120 {
121 NN_PANIC("nn::pl::InitializeSharedFont() failed!\n");
122 }
123 }
124
125 m_pExpHeap = pExpHeap;
126
127 // Perform font initialization
128 if (!InitializeFont())
129 {
130 NN_PANIC("InitializeFont() failed!\n");
131 }
132
133 // Perform shader initialization
134 if (!InitializeShader())
135 {
136 NN_PANIC("InitializeShader() failed!\n");
137 }
138
139 // Allocate the string buffer
140 m_pStringBuffer = AllocateStringBuffer(512);
141
142 if (!m_pStringBuffer)
143 {
144 NN_PANIC("Allocate string buffer failed!\n");
145 }
146
147 // Initialization process that is fine to perform once during startup
148 if (!s_isInitialized)
149 {
150 // Create projection matrix
151 nn::math::MTX44OrthoPivot(&s_mtxProjection[DISPLAY_0], 0, NN_GX_DISPLAY0_HEIGHT, NN_GX_DISPLAY0_WIDTH, 0, 0, -1, nn::math::PIVOT_UPSIDE_TO_TOP);
152 nn::math::MTX44OrthoPivot(&s_mtxProjection[DISPLAY_1], 0, NN_GX_DISPLAY1_HEIGHT, NN_GX_DISPLAY1_WIDTH, 0, 0, -1, nn::math::PIVOT_UPSIDE_TO_TOP);
153
154 // Create the unit matrix
155 nn::math::MTX34Identity(&s_mtxIdentify);
156
157 s_isInitialized = true;
158 }
159
160 // Set font object
161 m_writer.SetFont(&m_font);
162 // Since the initial font size is too big, make it smaller
163 m_writer.SetScale(0.6f);
164 }
165
166 // Performs shutdown.
Finalize()167 void TextWriter::Finalize()
168 {
169 if (m_pExpHeap)
170 {
171 // Disable buffer for rendering
172 void* pDrawBuffer = m_font.SetDrawBuffer(NULL);
173
174 if (pDrawBuffer)
175 {
176 m_pExpHeap->Free(pDrawBuffer);
177 }
178
179 if (m_pShaderBuffer)
180 {
181 m_pExpHeap->Free(m_pShaderBuffer);
182 }
183 if (m_pStringBuffer)
184 {
185 m_pExpHeap->Free(m_pStringBuffer);
186 }
187
188 // Initialize variables
189 m_pExpHeap = NULL;
190 m_pStringBuffer = NULL;
191 m_pShaderBuffer = NULL;
192 }
193 }
194
195 // Start rendering.
BeginRender(GLenum targetDisplay)196 void TextWriter::BeginRender(GLenum targetDisplay)
197 {
198 if (targetDisplay == NN_GX_DISPLAY0)
199 {
200 nngxAdd3DCommand(s_screenSettingCommands0, sizeof (s_screenSettingCommands0), true);
201 m_targetDisplay = DISPLAY_0;
202 }
203 else
204 {
205 nngxAdd3DCommand(s_screenSettingCommands1, sizeof (s_screenSettingCommands1), true);
206 m_targetDisplay = DISPLAY_1;
207 }
208
209 nngxAdd3DCommand(s_initCommands, sizeof (s_initCommands), true);
210
211 m_writer.SetDispStringBuffer(m_pStringBuffer);
212 m_writer.StartPrint();
213 }
214
215 // End rendering.
EndRender()216 void TextWriter::EndRender()
217 {
218 m_writer.EndPrint();
219
220 m_drawer.BuildTextCommand(&m_writer);
221 m_drawer.DrawBegin();
222 {
223 // Set projection matrix
224 m_drawer.SetProjectionMtx(s_mtxProjection[m_targetDisplay]);
225 // Initialize view matrix
226 m_drawer.SetViewMtxForText(s_mtxIdentify);
227
228 m_writer.UseCommandBuffer();
229 }
230 m_drawer.DrawEnd();
231 nngxUpdateState(NN_GX_STATE_ALL);
232 }
233
234 // Renders a character string.
Printf(f32 x,f32 y,const wchar_t * pFormat,...)235 void TextWriter::Printf(f32 x, f32 y, const wchar_t* pFormat, ...)
236 {
237 va_list pArgs;
238
239 va_start(pArgs, pFormat);
240 {
241 m_writer.SetCursor(x, y);
242 m_writer.SetTextColor(m_textColor);
243 m_writer.VPrintf(pFormat, pArgs);
244 }
245 va_end(pArgs);
246 }
247
248 // Renders a character string.
PutString(f32 x,f32 y,const wchar_t * pString)249 void TextWriter::PutString(f32 x, f32 y, const wchar_t* pString)
250 {
251 m_writer.SetCursor(x, y);
252 m_writer.SetTextColor(m_textColor);
253 m_writer.Print(pString);
254 }
255
256 // Set the font color.
SetTextColor(u8 red,u8 green,u8 blue,u8 alpha)257 void TextWriter::SetTextColor(u8 red, u8 green, u8 blue, u8 alpha)
258 {
259 // Font color
260 m_textColor = nn::util::Color8(red, green, blue, alpha);
261 }
262
263 // Get the font size.
GetFontSize()264 f32 TextWriter::GetFontSize()
265 {
266 return m_writer.GetFontHeight();
267 }
268
269 // Sets the font size.
SetFontSize(f32 size)270 void TextWriter::SetFontSize(f32 size)
271 {
272 m_writer.SetFontSize(size);
273 }
274
275 // Get the font scale.
276
GetFontScale()277 f32 TextWriter::GetFontScale()
278 {
279 return m_writer.GetScaleH();
280 }
281
282 // Set the font scale.
SetFontScale(f32 scale)283 void TextWriter::SetFontScale(f32 scale)
284 {
285 m_writer.SetScale(scale);
286 }
287
288 // Get the character spacing.
GetCharSpace()289 f32 TextWriter::GetCharSpace()
290 {
291 return m_writer.GetCharSpace();
292 }
293
294 // Set the character spacing.
SetCharSpace(f32 charSpace)295 void TextWriter::SetCharSpace(f32 charSpace)
296 {
297 m_writer.SetCharSpace(charSpace);
298 }
299
300 // Calculates the width of a character string.
CalculateStringWidth(const wchar_t * pString)301 f32 TextWriter::CalculateStringWidth(const wchar_t* pString)
302 {
303 return m_writer.CalcStringWidth(pString);
304 }
305
306 // Calculates the height of a character string.
CalculateStringHeight(const wchar_t * pString)307 f32 TextWriter::CalculateStringHeight(const wchar_t* pString)
308 {
309 return m_writer.CalcStringHeight(pString);
310 }
311
312 // Perform font initialization.
InitializeFont()313 bool TextWriter::InitializeFont()
314 {
315 // Font buffer
316 void* pBuffer = nn::pl::GetSharedFontAddress();
317 // Set font resource
318 bool isSuccess = m_font.SetResource(pBuffer);
319
320 // Size of the buffer for rendering
321 u32 drawBufferSize = nn::font::ResFont::GetDrawBufferSize(pBuffer);
322 // Buffer for rendering
323 void* pDrawBuffer = m_pExpHeap->Allocate(drawBufferSize, 4);
324
325 NN_NULL_ASSERT(pDrawBuffer);
326
327 // Set the render buffer
328 m_font.SetDrawBuffer(pDrawBuffer);
329
330 return isSuccess;
331 }
332
333 // Perform shader initialization.
InitializeShader()334 bool TextWriter::InitializeShader()
335 {
336 const size_t SHADER_SIZE = NNFONT_RECTDRAWERSHADER_END - NNFONT_RECTDRAWERSHADER_BEGIN;
337 void* pShaderBinary = m_pExpHeap->Allocate(SHADER_SIZE);
338
339 NN_NULL_ASSERT(pShaderBinary);
340
341 // Size of the buffer for vertices and command buffer
342 u32 vtxBufferCmdBufferSize = nn::font::RectDrawer::GetVertexBufferCommandBufferSize(NNFONT_RECTDRAWERSHADER_BEGIN, SHADER_SIZE);
343 // Buffer for vertices and command buffer
344 m_pShaderBuffer = m_pExpHeap->Allocate(vtxBufferCmdBufferSize);
345
346 NN_NULL_ASSERT(m_pShaderBuffer);
347
348 // Perform render object initialization
349 m_drawer.Initialize(m_pShaderBuffer, NNFONT_RECTDRAWERSHADER_BEGIN, SHADER_SIZE);
350
351 m_pExpHeap->Free(pShaderBinary);
352
353 return true;
354 }
355
356 // Allocate the string buffer.
AllocateStringBuffer(s32 charMax)357 nn::font::DispStringBuffer* TextWriter::AllocateStringBuffer(s32 charMax)
358 {
359 // Buffer size
360 const u32 bufferSize = nn::font::CharWriter::GetDispStringBufferSize(charMax);
361 // Buffer
362 void* pBuffer = m_pExpHeap->Allocate(bufferSize);
363
364 NN_NULL_ASSERT(pBuffer);
365
366 return nn::font::CharWriter::InitDispStringBuffer(pBuffer, charMax);
367 }
368
369 } // namespace scene
370