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