1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     phtsel_demo.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:$
14  *---------------------------------------------------------------------------*/
15 
16 #include <nn.h>
17 
18 #include "demo.h"
19 #include "PadEx.h"
20 #include "Menu.h"
21 #include "PhtselMenu.h"
22 
23 #include <nn/phtsel.h>
24 
25 #include <string.h>
26 #include <wchar.h>
27 
28 
29 //----------------------------------------------------------------
30 
31 namespace
32 {
33     nn::phtsel::Parameter psel_param; // Photo selection settings structure
34 
35     //==============================
36 
37     Menu  menu;
38 
39     // data for menu
40     namespace
41     {
42         using namespace nn::phtsel;
43 
44         //==============================
45         // items
46         //==============================
47 
48         // parameter names
49         const char* const  cFalseTrueName[] =
50         {
51             "FALSE",
52             "TRUE",
53         };
54 
55         const char* const  cOnOffAllName[] =
56         {
57             "ON",
58             "OFF",
59             "ALL",
60         };
61 
62         const char* const  cImageKindName[] =
63         {
64             "JPEG",
65             "MP",
66             "Picture",
67         };
68         const char* const  cMessageName[] =
69         {
70             "\"\"",
71             "\"TEST MESSAGE\"",
72         };
73 
74         // value table
75         const bool  cFalseTrueTable[] =
76         {
77             false,
78             true,
79         };
80         const PhtselInput::ImageKindBit  cImageKindTable[] =
81         {
82             PhtselInput::IMAGE_KIND_BIT_JPEG    ,
83             PhtselInput::IMAGE_KIND_BIT_MP      ,
84             PhtselInput::IMAGE_KIND_BIT_PICTURE ,
85         };
86         const PhtselInput::ScreenShotType  cScreenShotTypeTable[] =
87         {
88             PhtselInput::SCREEN_SHOT_TYPE_FLAG_ON ,
89             PhtselInput::SCREEN_SHOT_TYPE_FLAG_OFF,
90             PhtselInput::SCREEN_SHOT_TYPE_ALL    ,
91         };
92         const PhtselInput::FaceType  cFaceTypeTable[] =
93         {
94             PhtselInput::FACE_TYPE_FLAG_ON ,
95             PhtselInput::FACE_TYPE_FLAG_OFF,
96             PhtselInput::FACE_TYPE_ALL    ,
97         };
98         const PhtselInput::DistributeType  cDistributeTypeTable[] =
99         {
100             PhtselInput::DISTRIBUTE_TYPE_FLAG_ON ,
101             PhtselInput::DISTRIBUTE_TYPE_FLAG_OFF,
102             PhtselInput::DISTRIBUTE_TYPE_ALL    ,
103         };
104         const wchar_t* const  cMessageTable[] =
105         {
106             L"",
107             L"TEST MESSAGE",
108         };
109 
110         //==============================
111         // Variables
112         //==============================
113 
114         // items
115         ArrayItem<bool>  itemEnableSoftReset ( "ENABLE SOFT RESET",  cFalseTrueTable, cFalseTrueName );
116         ArrayItem<bool>  itemEnableHomeButton( "ENABLE HOME BUTTON", cFalseTrueTable, cFalseTrueName );
117 
118         DateTimeItem  itemSecStart( "SEC START" );
119         DateTimeItem  itemSecEnd  ( "SEC END" );
120 
121         ArrayItem<PhtselInput::ImageKindBit  >  itemImageKind     ( "IMAGE KIND BIT",   cImageKindTable     , cImageKindName );
122         ArrayItem<PhtselInput::ScreenShotType>  itemScreenShotType( "SCREEN SHOT TYPE", cScreenShotTypeTable, cOnOffAllName  );
123         ArrayItem<PhtselInput::FaceType      >  itemFaceType      ( "FACE TYPE",        cFaceTypeTable      , cOnOffAllName  );
124 
125         RangeItem<0, PhtselInput::MAX_FACE_INFO_NUM>  itemMinFaceNum( "MIN FACE NUM" );
126         RangeItem<0, PhtselInput::MAX_FACE_INFO_NUM>  itemMaxFaceNum( "MAX FACE NUM" );
127 
128         TitleIdItem  itemTitleId( "TITLE UNIQUE ID" );
129 
130         ArrayItem<PhtselInput::DistributeType>  itemDistributeType( "DISTRIBUTE TYPE", cDistributeTypeTable, cOnOffAllName );
131         ArrayItem<bool                       >  itemSoundEnable   ( "SOUND ENABLE",    cFalseTrueTable     , cFalseTrueName);
132         ArrayItem<const wchar_t* const       >  itemMessage       ( "MESSAGE",         cMessageTable       , cMessageName  );
133     }
134 
135     //==============================
136     // Functions
137     //==============================
138 
139     // read default parameter
ReadDefaultParameter()140     void  ReadDefaultParameter()
141     {
142         nn::phtsel::Parameter  param;
143         nn::phtsel::InitializeParameter( param );
144 
145         nn::phtsel::Config&       rConfig = param.config;
146         nn::phtsel::PhtselInput&  rInput  = param.input;
147 
148         itemEnableSoftReset .SetSelectValue( rConfig.enableSoftReset  );
149         itemEnableHomeButton.SetSelectValue( rConfig.enableHomeButton );
150 
151         itemSecStart      .SetSelectValue( rInput.GetSecStart()       );
152         itemSecEnd        .SetSelectValue( rInput.GetSecEnd()         );
153         itemImageKind     .SetSelectValue( rInput.GetImgKindBit()     );
154         itemScreenShotType.SetSelectValue( rInput.GetScreenShotType() );
155         itemFaceType      .SetSelectValue( rInput.GetFaceType()       );
156         itemMinFaceNum    .SetSelectValue( rInput.GetMinFaceNum()     );
157         itemMaxFaceNum    .SetSelectValue( rInput.GetMaxFaceNum()     );
158         itemTitleId       .ResetValueAll();
159         itemDistributeType.SetSelectValue( rInput.GetDistributeType() );
160         itemSoundEnable   .SetSelectValue( rInput.GetSoundEnable()    );
161         itemMessage       .SetSelectIndex( 0 );
162     }
163 
164     // reflect parameter
ReflectParameter()165     void  ReflectParameter()
166     {
167         nn::phtsel::Config&       rConfig = psel_param.config;
168         nn::phtsel::PhtselInput&  rInput  = psel_param.input;
169 
170         rInput.InitAll();
171 
172         rConfig.enableSoftReset  = itemEnableSoftReset.GetSelectValue();
173         rConfig.enableHomeButton = itemEnableHomeButton.GetSelectValue();
174 
175         rInput.SetSecStart      ( itemSecStart      .GetSelectValue() );
176         rInput.SetSecEnd        ( itemSecEnd        .GetSelectValue() );
177 
178         rInput.SetImgKindBit    ( itemImageKind     .GetSelectValue() );
179         rInput.SetScreenShotType( itemScreenShotType.GetSelectValue() );
180         rInput.SetFaceType      ( itemFaceType      .GetSelectValue() );
181         rInput.SetMinFaceNum    ( itemMinFaceNum    .GetSelectValue() );
182         rInput.SetMaxFaceNum    ( itemMaxFaceNum    .GetSelectValue() );
183         for( s32 i=0; i<TitleIdItem::cIdMaxNum; ++i )
184         {
185             const u32  value = itemTitleId.GetValue(i);
186             if( value ){
187                 rInput.AddTitleUniqueId( value );
188             }
189         }
190         rInput.SetDistributeType( itemDistributeType.GetSelectValue() );
191         rInput.SetSoundEnable   ( itemSoundEnable   .GetSelectValue() );
192         rInput.SetMessage       ( itemMessage       .GetSelectValue() );
193     }
194 
195     // initialize menu
InitMenu()196     void  InitMenu()
197     {
198         menu.Append( &itemEnableSoftReset );
199         menu.Append( &itemEnableHomeButton );
200 
201         menu.Append( &itemSecStart );
202         menu.Append( &itemSecEnd );
203         menu.Append( &itemImageKind );
204         menu.Append( &itemScreenShotType );
205         menu.Append( &itemFaceType );
206         menu.Append( &itemMinFaceNum );
207         menu.Append( &itemMaxFaceNum );
208         menu.Append( &itemTitleId );
209         menu.Append( &itemDistributeType );
210         menu.Append( &itemSoundEnable );
211         menu.Append( &itemMessage );
212 
213         // read default parameter
214         ReadDefaultParameter();
215     }
216 }
217 
218 //----------------------------------------------------------------
219 
220 namespace
221 {
222     demo::RenderSystemDrawing df;
223 
224     s32 loopCnt = 0;
225 
SetupRenderSystem()226     void SetupRenderSystem()
227     {
228         demo::RenderBufferDescription colorBufferDesc;
229         {
230             colorBufferDesc.m_Format     = GL_RGBA8_OES;
231             colorBufferDesc.m_Width      = nn::gx::DISPLAY0_WIDTH;
232             colorBufferDesc.m_Height     = nn::gx::DISPLAY0_HEIGHT;
233             colorBufferDesc.m_Area       = NN_GX_MEM_VRAMA;
234             colorBufferDesc.m_Attachment = GL_COLOR_ATTACHMENT0;
235         }
236         demo::RenderBufferDescription depthStencilBufferDesc;
237         {
238             depthStencilBufferDesc.m_Format     = GL_DEPTH24_STENCIL8_EXT;
239             depthStencilBufferDesc.m_Width      = nn::gx::DISPLAY0_WIDTH;
240             depthStencilBufferDesc.m_Height     = nn::gx::DISPLAY0_HEIGHT;
241             depthStencilBufferDesc.m_Area       = NN_GX_MEM_VRAMB;
242             depthStencilBufferDesc.m_Attachment = GL_DEPTH_STENCIL_ATTACHMENT;
243         }
244 
245         demo::FrameBufferDescription frameBufferDesc;
246         {
247             frameBufferDesc.m_RenderBufferDescriptionArray[demo::DEMO_COLOR_BUFFER_INDEX] = colorBufferDesc;
248             frameBufferDesc.m_RenderBufferDescriptionArray[demo::DEMO_DEPTH_STENCIL_BUFFER_INDEX] = depthStencilBufferDesc;
249         }
250 
251         demo::DisplayBuffersDescription display0BuffersDesc;
252         {
253             display0BuffersDesc.m_TargetDisplay    = NN_GX_DISPLAY0;
254             display0BuffersDesc.m_DisplayBufferNum = demo::DEMO_DISPLAY_BUFFER_NUM;
255             display0BuffersDesc.m_Format           = GL_RGB8_OES;
256             display0BuffersDesc.m_Width            = nn::gx::DISPLAY0_WIDTH;
257             display0BuffersDesc.m_Height           = nn::gx::DISPLAY0_HEIGHT;
258             display0BuffersDesc.m_Area             = NN_GX_MEM_FCRAM;
259 //            display0BuffersDesc.m_Area             = NN_GX_MEM_VRAMA;
260         }
261 
262         demo::DisplayBuffersDescription display1BuffersDesc;
263         {
264             display1BuffersDesc.m_TargetDisplay    = NN_GX_DISPLAY1;
265             display1BuffersDesc.m_DisplayBufferNum = demo::DEMO_DISPLAY_BUFFER_NUM;
266             display1BuffersDesc.m_Format           = GL_RGB8_OES;
267             display1BuffersDesc.m_Width            = nn::gx::DISPLAY1_WIDTH;
268             display1BuffersDesc.m_Height           = nn::gx::DISPLAY1_HEIGHT;
269             display1BuffersDesc.m_Area             = NN_GX_MEM_FCRAM;
270 //            display1BuffersDesc.m_Area             = NN_GX_MEM_VRAMB;
271         }
272 
273         df.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize(),
274                                   0x40000, 128, true,
275                                   display0BuffersDesc, display1BuffersDesc,
276                                   frameBufferDesc
277                                   );
278     }
279 
ReleaseRenderSystem()280     void ReleaseRenderSystem()
281     {
282         df.Finalize();
283     }
284 
DrawText()285     void DrawText()
286     {
287         // display 0
288         df.SetRenderTarget(NN_GX_DISPLAY0);
289         df.Clear();
290         {
291             df.SetColor(0.0f, 0.0f, 0.5f);
292             df.FillRectangle( 0, 0, 399, 255 );
293             df.SetColor(0.5f, 0.4f, 0.0f);
294             df.FillRectangle( 0, 0, 399, 40 );
295             df.SetColor(0.5f, 0.0f, 0.4f);
296             df.FillRectangle( 0, 180, 399, 40 );
297             df.SetColor(1.0f, 1.0f, 1.0f);
298             df.DrawText( 100, 50, "** DEMO APPLICATION **" );
299 
300             df.SetColor(1.0f, 1.0f, 1.0f);
301             df.DrawText( 30,  80, "[X]     Launch library applet." );
302             df.DrawText( 30, 100, "[START] Reset parameter." );
303 
304             df.DrawText( 0, 0, "phtsel" );
305 
306             // Count
307             df.DrawText( 340, 50, "%d", loopCnt );
308             df.DrawText( 340, 82, "%d", nngxCheckVSync(NN_GX_DISPLAY0) );
309         }
310         df.SwapBuffers();
311 
312         // display 1
313         df.SetRenderTarget(NN_GX_DISPLAY1);
314         df.Clear();
315         {
316             df.SetColor(0.0f, 0.5f, 0.0f);
317             df.FillRectangle( 0, 0, 399, 255 );
318             df.SetColor(1.0f, 1.0f, 1.0f);
319             df.DrawText( 80,   0, "** DEMO APPLICATION **" );
320 
321             df.DrawText( 0, 0, "phtsel" );
322 
323             // Render item
324             for( s32 i=0; i<menu.GetItemNum(); ++i )
325             {
326                 const s32 y = 20+14*i;
327                 df.SetColor(1.0f, 1.0f, 1.0f);
328                 menu.GetItemPtr(i)->Draw( df, 4, y, menu.GetSelectItemIndex()==i );
329             }
330         }
331         df.SwapBuffers();
332     }
DrawDisplay()333     void DrawDisplay()
334     {
335         DrawText();
336     }
RestoreGraphics()337     void RestoreGraphics()
338     {
339         // Recover the GPU register settings
340         nngxUpdateState(NN_GX_STATE_ALL);
341         nngxValidateState(NN_GX_STATE_ALL,GL_TRUE);
342     }
343 }
344 
345 //----------------------------------------------------------------
myReceiveSleepQueryNotification(uptr arg)346 AppletQueryReply myReceiveSleepQueryNotification( uptr arg )
347 {
348     NN_UNUSED_VAR( arg );
349     NN_LOG("*** Application-1 sleepQuery \n");
350     return /*applet::IsActive()? applet::REPLY_LATER:*/ nn::applet::REPLY_ACCEPT;
351 }
352 
353 //----------------------------------------------------------------
myReceiveAwakeNotification(uptr arg)354 void myReceiveAwakeNotification( uptr arg )
355 {
356     NN_UNUSED_VAR( arg );
357     NN_LOG("*** Application-1 awake \n");
358     if ( nn::applet::IsActive() )
359     {
360         nngxStartLcdDisplay();
361     }
362 }
363 
364 //----------------------------------------------------------------
nnMain()365 extern "C" void nnMain()
366 {
367     NN_TLOG_("----Application start\n");
368     nn::Result result;
369 
370     // applet declarations
371     nn::applet::SetSleepQueryCallback( myReceiveSleepQueryNotification, 0 );
372     nn::applet::SetAwakeCallback( myReceiveAwakeNotification, 0 );
373     nn::applet::Enable();
374     if(nn::applet::IsExpectedToCloseApplication())
375     {
376         // Quickly end the application
377         nn::applet::PrepareToCloseApplication();
378         nn::applet::CloseApplication();
379 
380         // Never reached
381         return;
382     }
383     // hid
384     result = nn::hid::Initialize();
385     NN_UTIL_PANIC_IF_FAILED(result);
386 
387     // Render class initialization
388     SetupRenderSystem();
389 
390     nn::hid::PadReader padReader;
391     nn::hid::PadStatus ps;
392     PadEx padEx(ps);
393 
394     // Initialize photo selection settings structure
395     nn::phtsel::InitializeParameter( psel_param );
396     InitMenu();
397 
398     while(1)
399     {
400         loopCnt++;
401 
402         padReader.ReadLatest(&ps);
403         padEx.Tick();
404 
405         // Render
406         DrawDisplay();
407 
408         bool  bDetailEdit = menu.GetSelectItemPtr()->IsDetailEditMode();
409 
410         // Start library applet
411         if ( ps.trigger & nn::hid::BUTTON_X )
412         {
413             ReflectParameter();
414             // Get memory address of work buffer
415             void* pWorkBuffer = std::malloc(nn::phtsel::GetWorkBufferSize());
416             NN_NULL_ASSERT(pWorkBuffer);
417             nn::phtsel::StartPhtsel( &psel_param, pWorkBuffer );
418             std::free(pWorkBuffer);
419             if(nn::applet::IsExpectedToCloseApplication())
420             {
421                 break;
422             }
423 
424             // Recover the GPU register settings
425             RestoreGraphics();
426 
427             NN_LOG("return code = %d\n",psel_param.output.GetReturnCode());
428 
429             // Show information for selected file path
430             NN_LOG("file path = [%ls]\n",psel_param.output.GetValue());
431             NN_LOG("file path length = %2d\n--\n",psel_param.output.GetValueLen());
432 
433             padEx.Reset();
434         }
435 
436         // Initialize settings
437         if ( (ps.trigger & (nn::hid::BUTTON_START)) && !bDetailEdit )
438         {
439             ReadDefaultParameter();
440         }
441 
442         // Switch to detailed edit mode
443         if( menu.GetSelectItemPtr()->IsEnableDetailEditMode() )
444         {
445             if ( ( !bDetailEdit && (ps.trigger & (nn::hid::BUTTON_A)) ) || ( bDetailEdit && (ps.trigger & (nn::hid::BUTTON_B)) ) )
446             {
447                 bDetailEdit = !bDetailEdit;
448                 menu.GetSelectItemPtr()->SetDetailEditMode(bDetailEdit);
449             }
450         }
451 
452         // Item selection
453         if( !bDetailEdit )
454         {
455             if ( (padEx.GetRepeat() & (nn::hid::BUTTON_UP)) )
456             {
457                 menu.AddSelectItemIndex( -1 );
458             }
459             else if ( (padEx.GetRepeat() & (nn::hid::BUTTON_DOWN)) )
460             {
461                 menu.AddSelectItemIndex( 1 );
462             }
463         }
464 
465         // Item setting
466         menu.GetSelectItemPtr()->Proc( padEx );
467 
468         // Process HOME Button
469         if ( nn::applet::IsExpectedToProcessHomeButton() )
470         {
471             NN_LOG("HomeBtn.\n");
472             nn::applet::ProcessHomeButtonAndWait();
473 
474             if(nn::applet::IsExpectedToCloseApplication())
475             {
476                 break;
477             }
478 
479 
480             RestoreGraphics();
481 
482         }
483 
484         // POWER button process
485         if ( nn::applet::IsExpectedToProcessPowerButton() )
486         {
487             NN_LOG("PowerBtn.\n");
488             nn::applet::ProcessPowerButtonAndWait();
489 
490             if(nn::applet::IsExpectedToCloseApplication())
491             {
492                 break;
493             }
494 
495             RestoreGraphics();
496         }
497     }
498 
499     NN_TLOG_("----Application is to be end\n");
500 
501     // Free the render class
502     ReleaseRenderSystem();
503 
504     // Finalize hid
505     nn::hid::Finalize();
506 
507     // Exit application
508     nn::applet::PrepareToCloseApplication();
509     nn::applet::CloseApplication();
510 
511     // No need to call Finalize on applet
512     // Execution will probably not reach here.
513     NN_TLOG_("----Application end\n");
514 }
515