1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: demolib.cpp
4
5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain proprietary
8 information of Nintendo and/or its licensed developers and are protected by
9 national and international copyright laws. They may not be disclosed to third
10 parties or copied or duplicated in any form, in whole or in part, without the
11 prior written consent of Nintendo.
12
13 The content herein is highly confidential and should be handled accordingly.
14
15 $Revision: $
16 *---------------------------------------------------------------------------*/
17
18 #include "precompiled.h"
19
20 #include "demolib.h"
21 #include <nn/pl.h>
22
23 #ifdef NW_PLATFORM_CTRWIN
24 #include <windows.h> // WAVE_MAPPER
25 #endif
26
27 namespace nw {
28 namespace snd {
29 namespace demolib {
30
31 namespace {
32
33 #ifdef NW_PLATFORM_CTRWIN
34 const char FONT_PATH[] = NW_SND_DEMO_PATH_PREFIX "sampleFont.bcfnt";
35 #endif
36 const size_t ROMFS_MAX_FILE = 128;
37 const size_t ROMFS_MAX_DIRECTORY = 128;
38 const s32 DRAW_STRING_BUFFER_UPPER_LCD = 512;
39 const s32 DRAW_STRING_BUFFER_LOWER_LCD = 512;
40
41 const f32 FONT_SIZE_HIGHT = 14.0f;
42
43 const nw::ut::FloatColor CLEAR_BUFFER_COLOR( 0.3f, 0.3f, 0.3f, 1.0f );
44 const f32 CLEAR_BUFFER_DEPTH = 0.0f;
45
46 } // anonymous namespace
47
AppBase()48 AppBase::AppBase()
49 : m_pMemoryForRomFileSystem( NULL ),
50 m_IsDraw( true )
51 {
52 }
53
LoadDspComponent()54 void AppBase::LoadDspComponent()
55 {
56 #ifdef NW_PLATFORM_CTR
57 nn::Result result;
58 result = nn::dsp::LoadDefaultComponent();
59 NN_UTIL_PANIC_IF_FAILED(result);
60 #endif
61 }
62
InitializeSDK()63 void AppBase::InitializeSDK()
64 {
65 // サウンド SDK の初期化
66 // (サウンド以外に初期化は demo_GraphicsSysteCTR.cppi の InitializeGraphicsSystem() で行われます。)
67 #ifdef NW_PLATFORM_CTRWIN
68 {
69 AI_Init( WAVE_MAPPER );
70 AX_Init();
71 }
72 #else
73 {
74 nn::Result result;
75 result = nn::dsp::Initialize();
76 NN_UTIL_PANIC_IF_FAILED(result);
77 LoadDspComponent();
78 result = nn::snd::Initialize();
79 NN_UTIL_PANIC_IF_FAILED(result);
80 }
81 #endif
82 }
83
InitializeDraw(int width,int height)84 void AppBase::InitializeDraw( int width, int height )
85 {
86 // カラーバッファ情報
87 // LCDの向きに合わせて、幅と高さを入れ替えています。
88 const nw::font::ColorBufferInfo colBufInfo = { height, width, PICA_DATA_DEPTH24_STENCIL8_EXT };
89
90 const u32 screenSettingCommands[] =
91 {
92 // ビューポートの設定
93 NW_FONT_CMD_SET_VIEWPORT( 0, 0, colBufInfo.width, colBufInfo.height ),
94
95 // シザー処理を無効
96 NW_FONT_CMD_SET_DISABLE_SCISSOR( colBufInfo ),
97
98 // wバッファの無効化
99 // デプスレンジの設定
100 // ポリゴンオフセットの無効化
101 NW_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET(
102 0.0f, // wScale : 0.0 でWバッファが無効
103 0.0f, // depth range near
104 1.0f, // depth range far
105 0, // polygon offset units : 0.0 で ポリゴンオフセットが無効
106 colBufInfo),
107 };
108
109 nngxAdd3DCommand(screenSettingCommands, sizeof(screenSettingCommands), true);
110
111 static const u32 s_InitCommands[] =
112 {
113 // カリングを無効
114 NW_FONT_CMD_SET_CULL_FACE( NW_FONT_CMD_CULL_FACE_DISABLE ),
115
116 // ステンシルテストを無効
117 NW_FONT_CMD_SET_DISABLE_STENCIL_TEST(),
118
119 // デプステストを無効
120 // カラーバッファの全ての成分を書き込み可
121 NW_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK(
122 false, // isDepthTestEnabled
123 0, // depthFunc
124 true, // depthMask
125 true, // red
126 true, // green
127 true, // blue
128 true), // alpha
129
130 // アーリーデプステストを無効
131 NW_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST( false ),
132
133 // フレームバッファアクセス制御
134 NW_FONT_CMD_SET_FBACCESS(
135 true, // colorRead
136 true, // colorWrite
137 false, // depthRead
138 false, // depthWrite
139 false, // stencilRead
140 false), // stencilWrite
141 };
142
143 nngxAdd3DCommand(s_InitCommands, sizeof(s_InitCommands), true);
144 }
145
InitializeFont()146 bool AppBase::InitializeFont()
147 {
148 void* buffer = NULL;
149
150 #ifdef NW_PLATFORM_CTRWIN
151 {
152 nn::fs::FileReader fontReader( FONT_PATH );
153
154 s32 fileSize = (s32)fontReader.GetSize();
155 if ( fileSize <= 0 ) { return false; }
156
157 buffer = MemAlloc( fileSize, nw::font::GlyphDataAlignment );
158 if ( buffer == NULL ) { return false; }
159
160 s32 readSize = fontReader.Read( buffer, fileSize );
161 if ( readSize != fileSize )
162 {
163 MemFree( buffer );
164 return false;
165 }
166 }
167 #else
168 {
169 NN_UTIL_PANIC_IF_FAILED(nn::pl::InitializeSharedFont());
170
171 // 共有フォントのロードが完了するまで待機
172 while (nn::pl::GetSharedFontLoadState() != nn::pl::SHARED_FONT_LOAD_STATE_LOADED)
173 {
174 // 共有フォントのロードに失敗していないか確認
175 if (nn::pl::GetSharedFontLoadState() == nn::pl::SHARED_FONT_LOAD_STATE_FAILED)
176 {
177 NN_TPANIC_("failed to load shared font!\n");
178 }
179 nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(10));
180 NN_LOG("loading SharedFont ...\n");
181 }
182 buffer = nn::pl::GetSharedFontAddress();
183 }
184 #endif
185
186 // フォントリソースをセットします
187 bool bSuccess = m_Font.SetResource( buffer );
188 NW_ASSERT( bSuccess );
189
190 if ( !bSuccess )
191 {
192 MemFree( buffer );
193 }
194
195 // 描画用バッファの設定。 (処理速度高速化のため。)
196 const size_t drawBufferSize = nw::font::ResFont::GetDrawBufferSize( buffer );
197 void* drawBuffer = MemAlloc( drawBufferSize, 4 );
198 NW_NULL_ASSERT(drawBuffer);
199 m_Font.SetDrawBuffer( drawBuffer );
200
201 return bSuccess;
202 }
203
FinalizeFont()204 void AppBase::FinalizeFont()
205 {
206 void *const drawBuffer = m_Font.SetDrawBuffer( NULL );
207 if ( drawBuffer != NULL )
208 {
209 MemFree( drawBuffer );
210 }
211
212 void *const resource = m_Font.RemoveResource();
213 if ( resource != NULL )
214 {
215 MemFree( resource );
216 }
217 }
218
InitializeShaders()219 void AppBase::InitializeShaders()
220 {
221 // NOTE: demo/font/ResFont の InitShaders を参考にした。
222 const wchar_t* shaders = NW_DEMO_FILE_PATH( NW_FONT_RECTDRAWER_SHADERBINARY );
223 nn::fs::FileReader shaderReader( shaders );
224
225 const u32 fileSize = (u32)shaderReader.GetSize();
226 void* shaderBinary = MemAlloc( fileSize );
227 NW_NULL_ASSERT( shaderBinary );
228
229 s32 read = shaderReader.Read( shaderBinary, fileSize );
230 NW_ASSERT( read == fileSize );
231
232 const u32 vtxBufCmdBufSize =
233 nw::font::RectDrawer::GetVertexBufferCommandBufferSize( shaderBinary, fileSize );
234 void *const vtxBufCmdBuf = MemAlloc( vtxBufCmdBufSize );
235 NW_NULL_ASSERT( vtxBufCmdBuf );
236 m_Drawer.Initialize( vtxBufCmdBuf, shaderBinary, fileSize );
237
238 MemFree( shaderBinary );
239 m_pMemoryForDrawBuffer = vtxBufCmdBuf;
240 }
241
FinalizeShaders()242 void AppBase::FinalizeShaders()
243 {
244 m_Drawer.Finalize();
245 MemFree( m_pMemoryForDrawBuffer );
246 }
247
InitializeDrawStringBuffer()248 void AppBase::InitializeDrawStringBuffer()
249 {
250 m_pDrawStringBufferUpperLcd = AllocDispStringBuffer( DRAW_STRING_BUFFER_UPPER_LCD );
251 m_pDrawStringBufferLowerLcd = AllocDispStringBuffer( DRAW_STRING_BUFFER_LOWER_LCD );
252 }
FinalizeDrawStringBuffer()253 void AppBase::FinalizeDrawStringBuffer()
254 {
255 MemFree( m_pDrawStringBufferUpperLcd );
256 MemFree( m_pDrawStringBufferLowerLcd );
257 }
258
259 nw::font::DispStringBuffer*
AllocDispStringBuffer(int charMax)260 AppBase::AllocDispStringBuffer(int charMax)
261 {
262 const u32 DrawBufferSize = nw::font::CharWriter::GetDispStringBufferSize(charMax);
263 void *const bufMem = MemAlloc(DrawBufferSize);
264 NN_NULL_ASSERT(bufMem);
265
266 return nw::font::CharWriter::InitDispStringBuffer(bufMem, charMax);
267 }
268
269
FinalizeSDK()270 void AppBase::FinalizeSDK()
271 {
272 #ifdef NW_PLATFORM_CTRWIN
273 #else
274 {
275 nn::Result result;
276 result = nn::snd::Finalize();
277 NN_UTIL_PANIC_IF_FAILED( result );
278
279 result = nn::dsp::UnloadComponent();
280 NN_UTIL_PANIC_IF_FAILED( result );
281
282 nn::dsp::Finalize();
283
284 MemFree( m_pMemoryForRomFileSystem ); // fs::Finalize が無いので、解放するとまずい?
285 }
286
287 // nn::fs::Finalize は無い
288 // nn::os::Finalize は無い
289 #endif
290 }
291
SetupTextCamera(nw::font::RectDrawer * pDrawer,int width,int height)292 void AppBase::SetupTextCamera(
293 nw::font::RectDrawer* pDrawer,
294 int width,
295 int height )
296 {
297 // 射影行列を正射影に設定
298 {
299 // 左上原点とし、Y軸とZ軸の向きが逆になるように設定します。
300 nn::math::MTX44 proj;
301 f32 znear = 0.0f;
302 f32 zfar = -1.0f;
303 f32 t = 0;
304 f32 b = static_cast<f32>(height);
305 f32 l = 0;
306 f32 r = static_cast<f32>(width);
307 nn::math::MTX44OrthoPivot(&proj, l, r, b, t, znear, zfar, nn::math::PIVOT_UPSIDE_TO_TOP);
308 pDrawer->SetProjectionMtx(proj);
309 }
310
311 // モデルビュー行列を単位行列に設定
312 {
313 nn::math::MTX34 mv;
314 nn::math::MTX34Identity(&mv);
315 pDrawer->SetViewMtxForText(mv);
316 }
317 }
318
Initialize()319 void AppBase::Initialize()
320 {
321 // 規定の初期化
322 nw::demo::SimpleApp::GetInstance().Initialize();
323 InitializeSDK();
324
325 // フォントの構築
326 InitializeFont();
327
328 // 描画リソースの構築
329 InitializeShaders();
330 InitializeDrawStringBuffer();
331
332 // ユーザーの初期化処理
333 OnInitialize();
334 }
335
Finalize()336 void AppBase::Finalize()
337 {
338 // ユーザーの終了処理
339 OnFinalize();
340
341 // 規定の終了処理
342 FinalizeDrawStringBuffer();
343 FinalizeShaders();
344
345 FinalizeFont();
346 FinalizeSDK();
347
348 // demoPadの終了処理
349 nw::demo::PadFactory::Finalize();
350 }
351
Run()352 void AppBase::Run()
353 {
354 while ( true )
355 {
356 // パッドなどの更新処理
357 Update();
358
359 // 描画 (Vブランク待ちを含む)
360 Draw();
361 }
362 }
363
DrawStringPreProcess(nw::font::TextWriter & writer,const nw::gfx::FrameBufferObject & frameBufferObject,int width,int height)364 void AppBase::DrawStringPreProcess(
365 nw::font::TextWriter& writer,
366 const nw::gfx::FrameBufferObject& frameBufferObject,
367 int width,
368 int height )
369 {
370 frameBufferObject.ClearBuffer( CLEAR_BUFFER_COLOR, CLEAR_BUFFER_DEPTH );
371
372 InitializeDraw( width, height );
373
374 writer.SetDispStringBuffer( m_pDrawStringBufferUpperLcd );
375 writer.SetCursor( 0, 0 );
376
377 writer.StartPrint();
378 }
DrawStringPostProcess(nw::font::TextWriter & writer,int width,int height)379 void AppBase::DrawStringPostProcess( nw::font::TextWriter& writer, int width, int height )
380 {
381 writer.EndPrint();
382 m_Drawer.BuildTextCommand( &writer );
383
384 m_Drawer.DrawBegin();
385 {
386 SetupTextCamera( &m_Drawer, width, height );
387 writer.UseCommandBuffer();
388 }
389 m_Drawer.DrawEnd();
390 }
Draw()391 void AppBase::Draw()
392 {
393 nw::demo::SimpleApp& app = nw::demo::SimpleApp::GetInstance();
394
395 if ( m_IsDraw == true )
396 {
397 nw::font::TextWriter writer;
398 writer.SetFont( &m_Font );
399 writer.SetCharSpace( 1.0f );
400 writer.EnableFixedWidth( true );
401 writer.SetFontSize( FONT_SIZE_HIGHT );
402 writer.SetFixedWidth( writer.GetLineHeight() / 2.f );
403
404 app.SetRenderingTarget( app.DISPLAY0 );
405 {
406 DrawStringPreProcess(
407 writer,
408 app.GetFrameBufferObject(),
409 app.DISPLAY0_WIDTH,
410 app.DISPLAY0_HEIGHT );
411 OnDrawUpLCD( writer );
412 DrawStringPostProcess( writer, app.DISPLAY0_WIDTH, app.DISPLAY0_HEIGHT );
413 }
414
415 app.SetRenderingTarget( app.DISPLAY1 );
416 {
417 DrawStringPreProcess(
418 writer,
419 app.GetFrameBufferObject(),
420 app.DISPLAY1_WIDTH,
421 app.DISPLAY1_HEIGHT );
422 OnDrawDownLCD( writer );
423 DrawStringPostProcess( writer, app.DISPLAY1_WIDTH, app.DISPLAY1_HEIGHT );
424 }
425 }
426
427 app.SwapBuffer(app.DISPLAY_BOTH);
428 }
429
430
Update()431 void AppBase::Update()
432 {
433 // パッド更新。
434 UpdatePad();
435
436 // ユーザー関数。
437 OnUpdate();
438 }
439
UpdatePad()440 void AppBase::UpdatePad()
441 {
442 nw::demo::Pad* pad = nw::demo::PadFactory::GetPad();
443 pad->Update();
444 OnUpdatePad( (*pad) );
445 }
446
MemAlloc(size_t size,u8 alignment)447 void* AppBase::MemAlloc( size_t size, u8 alignment )
448 {
449 #ifdef NW_PLATFORM_CTRWIN
450 void* ret = nw::demo::Alloc( size, alignment );
451 #else
452 void* ret = nw::demo::SimpleApp::AllocateDeviceMemory( size, alignment );
453 #endif
454
455 // メモリをランダムに初期化しても動作するか確認する。
456 if ( ret != NULL )
457 {
458 std::memset( ret, 0xcd, size );
459 }
460 return ret;
461 }
462
MemFree(void * memory)463 void AppBase::MemFree( void* memory )
464 {
465 #ifdef NW_PLATFORM_CTRWIN
466 nw::demo::Free( memory );
467 #else
468 nw::demo::SimpleApp::Free( memory );
469 #endif
470 }
471
472 } // namespace nw::snd::demolib
473 } // namespace nw::snd
474 } // namespace nw
475