1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: main.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: 31311 $
16 *---------------------------------------------------------------------------*/
17
18 //------------------------------------------------------------------
19 // デモ: bounding
20 //
21 // 概要
22 // boudingペインによるヒットチェックを行うデモです。
23 //
24 // 操作
25 // 十字ボタンの操作でクロスラインが移動します。
26 // クロスラインのクロスしている部分をペインに移動させると、
27 // そのペインのみ異なるアニメーションをします。
28 //
29 //------------------------------------------------------------------
30
31 #include <nw/lyt.h>
32 #include <nw/demo.h>
33
34 namespace
35 {
36
37 typedef nw::ut::MoveArray<u8> File;
38
39 /*---------------------------------------------------------------------------*
40 @brief 描画の初期設定を行います。
41
42 @param width 画面の幅。
43 @param height 画面の高さ。
44 *---------------------------------------------------------------------------*/
45 void
InitDraw(int width,int height)46 InitDraw(int width, int height)
47 {
48 // カラーバッファ情報
49 // LCDの向きに合わせて、幅と高さを入れ替えています。
50 const nw::font::ColorBufferInfo colBufInfo =
51 {
52 height, width, PICA_DATA_DEPTH24_STENCIL8_EXT
53 };
54
55 const u32 commands[] =
56 {
57 // ビューポートの設定
58 NW_FONT_CMD_SET_VIEWPORT(0, 0, colBufInfo.width, colBufInfo.height),
59
60 // シザー処理を無効
61 NW_FONT_CMD_SET_DISABLE_SCISSOR(colBufInfo),
62
63 // wバッファの無効化
64 // デプスレンジの設定
65 // ポリゴンオフセットの無効化
66 NW_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET(
67 0.0f, // wScale : 0.0 でWバッファが無効
68 0.0f, // depth range near
69 1.0f, // depth range far
70 0, // polygon offset units : 0.0 で ポリゴンオフセットが無効
71 colBufInfo),
72 };
73
74 nngxAdd3DCommand(commands, sizeof(commands), true);
75
76 static const u32 constCommands[] =
77 {
78 // カリングを無効
79 NW_FONT_CMD_SET_CULL_FACE(NW_FONT_CMD_CULL_FACE_DISABLE),
80
81 // ステンシルテストを無効
82 NW_FONT_CMD_SET_DISABLE_STENCIL_TEST(),
83
84 // デプステストを無効
85 // カラーバッファの全ての成分を書き込み可
86 NW_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK(
87 false, // isDepthTestEnabled
88 0, // depthFunc
89 true, // depthMask
90 true, // red
91 true, // green
92 true, // blue
93 true), // alpha
94
95 // アーリーデプステストを無効
96 NW_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST(false),
97
98 // フレームバッファアクセス制御
99 NW_FONT_CMD_SET_FBACCESS(
100 true, // colorRead
101 true, // colorWrite
102 false, // depthRead
103 false, // depthWrite
104 false, // stencilRead
105 false), // stencilWrite
106 };
107
108 nngxAdd3DCommand(constCommands, sizeof(constCommands), true);
109 }
110
111 /*---------------------------------------------------------------------------*
112 @brief モデルビュー行列と射影行列を設定します。
113
114 @param pDrawInfo 描画情報です。
115 @param layout レイアウトです。
116 *---------------------------------------------------------------------------*/
117 void
SetupCamera(nw::lyt::DrawInfo & drawInfo,const nw::lyt::Layout & layout)118 SetupCamera(nw::lyt::DrawInfo& drawInfo, const nw::lyt::Layout& layout)
119 {
120 nw::ut::Rect layoutRect = layout.GetLayoutRect();
121
122 f32 znear = 0.f;
123 f32 zfar = 500.f;
124
125 // 射影行列を正射影に設定
126 // (Layoutデータは横向きなので向きを変換する)
127 nw::math::MTX44 projMtx;
128 nw::math::MTX44Ortho(
129 &projMtx,
130 layoutRect.bottom, // left
131 layoutRect.top, // right
132 -layoutRect.right, // bottom
133 -layoutRect.left, // top
134 znear,
135 zfar);
136 drawInfo.SetProjectionMtx(projMtx);
137
138 // モデルビュー行列を設定
139 // (Layoutデータは横向きなので画面の上方向はレイアウトの-X方向)
140 nw::math::VEC3 pos(0, 0, 1);
141 nw::math::VEC3 up(-1, 0, 0);
142 nw::math::VEC3 target(0, 0, 0);
143
144 nw::math::MTX34 viewMtx;
145 nw::math::MTX34LookAt(&viewMtx, &pos, &up, &target);
146 drawInfo.SetViewMtx(viewMtx);
147 }
148
149 /*---------------------------------------------------------------------------*
150 @brief カーソルの位置をレイアウトの座標系で取得します。
151
152 @param pLayout レイアウトです。
153
154 @return カーソル位置を返します。
155 *---------------------------------------------------------------------------*/
156 const nw::math::VEC2
GetCursorPosition(nw::lyt::Layout * pLayout)157 GetCursorPosition(nw::lyt::Layout* pLayout)
158 {
159 const nw::ut::Rect& layoutRect = pLayout->GetLayoutRect();
160 const nw::math::VEC2 center(
161 (layoutRect.left + layoutRect.right ) / 2,
162 (layoutRect.top + layoutRect.bottom) / 2
163 );
164
165 nw::math::VEC2 curPos;
166
167 // カーソルの座標系をレイアウトの座標系に変換します。
168 const nw::ut::Rect cursorRect(-0.5, 0.5, 0.5, -0.5); // LTRB
169 nw::demo::Pad& pad = *nw::demo::PadFactory::GetPad();
170 const nw::math::VEC2 stick = pad.GetAnalogStick();
171 curPos.x = center.x + stick.x / (cursorRect.right - cursorRect.left ) * (layoutRect.right - layoutRect.left );
172 curPos.y = center.y + stick.y / (cursorRect.top - cursorRect.bottom) * (layoutRect.top - layoutRect.bottom);
173 // NW_LOG("curPos %f, %f\n", curPos.x, curPos.y);
174 return curPos;
175 }
176
177 /*---------------------------------------------------------------------------*
178 @brief カーソルの位置をレイアウトに反映します。
179
180 @param pLayout レイアウトです。
181 @param curPos レイアウトの座標系におけるカーソルの位置です。
182 *---------------------------------------------------------------------------*/
183 void
ApplyCursorPosition(nw::lyt::Layout * pLayout,const nw::math::VEC2 & curPos)184 ApplyCursorPosition(nw::lyt::Layout* pLayout, const nw::math::VEC2& curPos)
185 {
186 nw::lyt::Pane* pCrossBar = pLayout->GetRootPane()->FindPaneByName("CrossBar", true);
187 if (pCrossBar)
188 {
189 pCrossBar->SetTranslate(curPos);
190 }
191 }
192
193 } // namespace
194
195 /*---------------------------------------------------------------------------*
196 @brief サンプルのメイン関数です。
197 *---------------------------------------------------------------------------*/
198 void
nnMain()199 nnMain()
200 {
201 nw::demo::SimpleApp& demoApp = nw::demo::SimpleApp::GetInstance();
202 demoApp.Initialize();
203
204 nw::lyt::Initialize(&demoApp.GetAllocator(), &demoApp.GetDeviceAllocator());
205
206 nw::lyt::Layout* pLayout = new nw::lyt::Layout();
207
208 // レイアウトのバイナリリソース(アーカイブ)を読み込み。
209 File fileLayout = nw::demo::Utility::LoadFile(
210 &demoApp.GetDeviceAllocator(), NW_DEMO_FILE_PATH(L"layout.arc"), 128);
211
212 if (fileLayout.empty())
213 {
214 NW_FATAL_ERROR("can not open layout archive.\n");
215 }
216
217 // バイナリリソースのルートディレクトリを指定してリソースアクセサを生成。
218 nw::lyt::ArcResourceAccessor* pResAccessor = new nw::lyt::ArcResourceAccessor;
219 if (!pResAccessor->Attach(fileLayout.begin(), "."))
220 {
221 NW_FATAL_ERROR("can not attach layout archive.\n");
222 }
223
224 // レイアウトリソースの読み込み
225 {
226 const void* lytRes = pResAccessor->GetResource(0, "bounding.bclyt");
227 NW_NULL_ASSERT(lytRes);
228 pLayout->Build(lytRes, pResAccessor);
229 }
230
231 const int BoundPaneNum = 6;
232
233 static const char *const paneNames[] = { "picture_0", "picture_1", "picture_2", "picture_3", "picture_4", "picture_5" };
234
235 enum
236 {
237 ANIMTYPE_UNSELECT,
238 ANIMTYPE_SELECT,
239
240 ANIMTYPE_MAX
241 };
242
243 nw::lyt::AnimTransform* pAnimTrans[ANIMTYPE_MAX];
244
245 const void* rlanRes = pResAccessor->GetResource(0, "bounding_unselect.bclan");
246 NW_NULL_ASSERT(rlanRes);
247 pAnimTrans[ANIMTYPE_UNSELECT] = pLayout->CreateAnimTransform(rlanRes, pResAccessor);
248 rlanRes = pResAccessor->GetResource(0, "bounding_select.bclan");
249 NW_NULL_ASSERT(rlanRes);
250 pAnimTrans[ANIMTYPE_SELECT] = pLayout->CreateAnimTransform(rlanRes, pResAccessor);
251
252 for (int i = 0; i < BoundPaneNum; ++i)
253 {
254 // 特定のペイン(とその子供)に対してアニメーションを設定する
255 if (nw::lyt::Pane* pPane = pLayout->GetRootPane()->FindPaneByName(paneNames[i]))
256 {
257 pPane->BindAnimation(pAnimTrans[ANIMTYPE_UNSELECT]);
258 pPane->BindAnimation(pAnimTrans[ANIMTYPE_SELECT]);
259 }
260 }
261
262 f32 animFrame[ANIMTYPE_MAX];
263 for (int i = 0; i < ANIMTYPE_MAX; ++i)
264 {
265 animFrame[i] = 0.f;
266 }
267
268 nw::lyt::GraphicsResource graphicsResource;
269 // グローバルなリソースファイルを読み込みます。
270 {
271 graphicsResource.StartSetup();
272 const wchar_t* resourcePath = 0;
273 for (int i = 0;
274 (resourcePath = graphicsResource.GetResourcePath(i)) != NULL;
275 ++i)
276 {
277 File file = nw::demo::Utility::LoadFile(&demoApp.GetAllocator(), resourcePath);
278
279 if (file.empty())
280 {
281 NW_FATAL_ERROR("can not read lyt resource file.");
282 }
283
284 graphicsResource.SetResource(i, file.begin(), file.size(), false);
285 }
286
287 graphicsResource.FinishSetup();
288 }
289
290 nw::lyt::DrawInfo drawInfo;
291 drawInfo.SetGraphicsResource(&graphicsResource);
292 #if ! defined(NW_RELEASE)
293 drawInfo.SetDebugDrawMode(true);
294 #endif
295
296 nw::lyt::Drawer drawer;
297 drawer.Initialize(graphicsResource);
298
299 nw::lyt::Pane* pHitPane = 0;
300 nw::math::VEC2 curPos(0.f, 0.f);
301
302 const nw::ut::FloatColor clearColor(0.3f, 0.3f, 0.3f, 1.0f);
303 const f32 clearDepth = 0.0f;
304
305 bool loop = true;
306 while (loop)
307 {
308 nw::demo::PadFactory::GetPad()->Update();
309
310 demoApp.SetRenderingTarget(demoApp.DISPLAY0);
311 {
312 demoApp.GetFrameBufferObject().ClearBuffer(clearColor, clearDepth);
313
314 InitDraw(demoApp.DISPLAY0_WIDTH, demoApp.DISPLAY0_HEIGHT);
315
316 SetupCamera(drawInfo, *pLayout);
317
318 // 子供のアニメーション
319 for (nw::lyt::PaneList::Iterator it = pLayout->GetRootPane()->GetChildList().GetBeginIter(); it != pLayout->GetRootPane()->GetChildList().GetEndIter(); ++it)
320 {
321 // ヒットしているペインの親ペイン(ピクチャペイン)は選択アニメを有効にする。
322 // それ以外の親ペインのアニメは非選択アニメを有効にする。
323 const bool bSelected = pHitPane && &(*it) == pHitPane->GetParent();
324 it->SetAnimationEnable(pAnimTrans[ANIMTYPE_UNSELECT], ! bSelected);
325 it->SetAnimationEnable(pAnimTrans[ANIMTYPE_SELECT] , bSelected);
326 }
327
328 // フレームの更新
329 for (int i = 0; i < ANIMTYPE_MAX; ++i)
330 {
331 animFrame[i] += 1.0f;
332 while (animFrame[i] >= pAnimTrans[i]->GetFrameSize())
333 {
334 animFrame[i] -= pAnimTrans[i]->GetFrameSize();
335 }
336 pAnimTrans[i]->SetFrame(animFrame[i]);
337 }
338
339 pLayout->Animate();
340 pLayout->CalculateMtx(drawInfo);
341
342 curPos = GetCursorPosition(pLayout);
343
344 ApplyCursorPosition(pLayout, curPos);
345
346 // カーソル位置をレイアウト座標系からビュー座標系に変換。
347 {
348 nw::math::VEC3 tmp(curPos.x, curPos.y, 0.0f);
349 nw::math::VEC3Transform(&tmp, &drawInfo.GetViewMtx(), &tmp);
350 curPos = nw::math::VEC2(tmp.x, tmp.y);
351 }
352
353 // 行列を利用するため、CalculateMtx()の後に行う
354 pHitPane = nw::lyt::FindHitPane(pLayout, curPos);
355
356 drawer.DrawBegin(drawInfo);
357 drawer.Draw(pLayout, drawInfo);
358 drawer.DrawEnd(drawInfo);
359 }
360
361 demoApp.SetRenderingTarget(demoApp.DISPLAY1);
362 {
363 demoApp.GetFrameBufferObject().ClearBuffer(clearColor, clearDepth);
364 }
365
366 demoApp.SwapBuffer(demoApp.DISPLAY_BOTH);
367 }
368
369 delete pLayout;
370
371 delete pResAccessor;
372 }
373
374