1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     coppacs_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 #include <nn/cfg.h>
18 
19 #include "demo.h"
20 
21 //----------------------------------------------------------------
22 
23 namespace
24 {
25     demo::RenderSystemDrawing df;
26 
27     s32 loopCnt = 0;
28 
29 
30     // State related to COPPACS
31     bool isCoppacsSupported;
32     nn::cfg::CfgCoppacsRestriction  coppacsRestriction;
33 
34     // Whether we've returned from System Settings
35     bool isFromMset;
36     // Which System Settings scene we've returned from
37     nn::applet::AppletMsetScene msetScene;
38 
39 
40 
41     const char* COPPACS_RESTRICTION_STRING[] = {
42         "RESTRICTION_NONE",
43         "RESTRICTION_NEED_PARENTAL_PIN_CODE",
44         "RESTRICTION_NEED_PARENTAL_AUTHENTICATION"
45     };
46 
47 
SetupRenderSystem()48     void SetupRenderSystem()
49     {
50         demo::RenderBufferDescription colorBufferDesc;
51         {
52             colorBufferDesc.m_Format     = GL_RGBA8_OES;
53             colorBufferDesc.m_Width      = nn::gx::DISPLAY0_WIDTH;
54             colorBufferDesc.m_Height     = nn::gx::DISPLAY0_HEIGHT;
55             colorBufferDesc.m_Area       = NN_GX_MEM_VRAMA;
56             colorBufferDesc.m_Attachment = GL_COLOR_ATTACHMENT0;
57         }
58         demo::RenderBufferDescription depthStencilBufferDesc;
59         {
60             depthStencilBufferDesc.m_Format     = GL_DEPTH24_STENCIL8_EXT;
61             depthStencilBufferDesc.m_Width      = nn::gx::DISPLAY0_WIDTH;
62             depthStencilBufferDesc.m_Height     = nn::gx::DISPLAY0_HEIGHT;
63             depthStencilBufferDesc.m_Area       = NN_GX_MEM_VRAMB;
64             depthStencilBufferDesc.m_Attachment = GL_DEPTH_STENCIL_ATTACHMENT;
65         }
66 
67         demo::FrameBufferDescription frameBufferDesc;
68         {
69             frameBufferDesc.m_RenderBufferDescriptionArray[demo::DEMO_COLOR_BUFFER_INDEX] = colorBufferDesc;
70             frameBufferDesc.m_RenderBufferDescriptionArray[demo::DEMO_DEPTH_STENCIL_BUFFER_INDEX] = depthStencilBufferDesc;
71         }
72 
73         demo::DisplayBuffersDescription display0BuffersDesc;
74         {
75             display0BuffersDesc.m_TargetDisplay    = NN_GX_DISPLAY0;
76             display0BuffersDesc.m_DisplayBufferNum = demo::DEMO_DISPLAY_BUFFER_NUM;
77             display0BuffersDesc.m_Format           = GL_RGB8_OES;
78             display0BuffersDesc.m_Width            = nn::gx::DISPLAY0_WIDTH;
79             display0BuffersDesc.m_Height           = nn::gx::DISPLAY0_HEIGHT;
80             display0BuffersDesc.m_Area             = NN_GX_MEM_FCRAM;
81 //            display0BuffersDesc.m_Area             = NN_GX_MEM_VRAMA;
82         }
83 
84         demo::DisplayBuffersDescription display1BuffersDesc;
85         {
86             display1BuffersDesc.m_TargetDisplay    = NN_GX_DISPLAY1;
87             display1BuffersDesc.m_DisplayBufferNum = demo::DEMO_DISPLAY_BUFFER_NUM;
88             display1BuffersDesc.m_Format           = GL_RGB8_OES;
89             display1BuffersDesc.m_Width            = nn::gx::DISPLAY1_WIDTH;
90             display1BuffersDesc.m_Height           = nn::gx::DISPLAY1_HEIGHT;
91             display1BuffersDesc.m_Area             = NN_GX_MEM_FCRAM;
92 //            display1BuffersDesc.m_Area             = NN_GX_MEM_VRAMB;
93         }
94 
95         df.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize(),
96                                   0x40000, 128, true,
97                                   display0BuffersDesc, display1BuffersDesc,
98                                   frameBufferDesc
99                                   );
100     }
101 
ReleaseRenderSystem()102     void ReleaseRenderSystem()
103     {
104         df.Finalize();
105     }
106 
DrawText()107     void DrawText()
108     {
109         // display 0
110         df.SetRenderTarget(NN_GX_DISPLAY0);
111         df.Clear();
112         {
113             df.SetColor(0.0f, 0.0f, 0.5f);
114             df.FillRectangle( 0, 0, 399, 255 );
115             df.SetColor(0.5f, 0.4f, 0.0f);
116             df.FillRectangle( 0, 0, 399, 40 );
117             df.SetColor(0.5f, 0.0f, 0.4f);
118             df.FillRectangle( 0, 180, 399, 40 );
119             df.SetColor(1.0f, 1.0f, 1.0f);
120             df.DrawText( 100, 50, "** DEMO APPLICATION **" );
121 
122             df.SetColor(1.0f, 1.0f, 0.0f);
123             if(coppacsRestriction == nn::cfg::CFG_COPPACS_RESTRICTION_NEED_PARENTAL_AUTHENTICATION)
124             {
125                 df.DrawText( 40, 90, "push [START] to run COPPACS Setting Menu");
126             }
127 
128             df.SetColor(1.0f, 1.0f, 1.0f);
129             // Count
130             df.DrawText( 340, 50, "%d", loopCnt );
131 
132             // COPPACS state
133             df.DrawText( 30,  130, "IsCoppacsSupported   :%s" ,isCoppacsSupported?"true":"false");
134             df.DrawText( 30,  140, "GetCoppacsRestriction:");
135             df.DrawText( 60,  150, "%s" ,COPPACS_RESTRICTION_STRING[coppacsRestriction]);
136 
137             // Whether we've returned from Mset
138             if(isFromMset)
139             {
140                 df.DrawText( 30,  160, "IsFromMset           :true(%d)",msetScene);
141             }
142             else
143             {
144                 df.DrawText( 30,  160, "IsFromMset           :false");
145             }
146 
147         }
148         df.SwapBuffers();
149 
150         // display 1
151         df.SetRenderTarget(NN_GX_DISPLAY1);
152         df.Clear();
153         {
154             df.SetColor(0.0f, 0.5f, 0.0f);
155             df.FillRectangle( 0, 0, 399, 255 );
156             df.SetColor(1.0f, 1.0f, 1.0f);
157             df.DrawText( 80, 50, "** DEMO APPLICATION **" );
158         }
159         df.SwapBuffers();
160     }
DrawDisplay()161     void DrawDisplay()
162     {
163         DrawText();
164     }
RestoreGraphics()165     void RestoreGraphics()
166     {
167         // Recover the GPU register settings
168         nngxUpdateState(NN_GX_STATE_ALL);
169         nngxValidateState(NN_GX_STATE_ALL,GL_TRUE);
170     }
171 }
172 
173 //----------------------------------------------------------------
myReceiveSleepQueryNotification(uptr arg)174 AppletQueryReply myReceiveSleepQueryNotification( uptr arg )
175 {
176     NN_UNUSED_VAR( arg );
177     NN_LOG("*** Application sleepQuery \n");
178     return /*applet::IsActive()? applet::REPLY_LATER:*/ nn::applet::REPLY_ACCEPT;
179 }
180 
181 //----------------------------------------------------------------
myReceiveAwakeNotification(uptr arg)182 void myReceiveAwakeNotification( uptr arg )
183 {
184     NN_UNUSED_VAR( arg );
185     NN_LOG("*** Application awake \n");
186     if ( nn::applet::IsActive() )
187     {
188         nngxStartLcdDisplay();
189     }
190 }
191 
192 //----------------------------------------------------------------
nnMain()193 extern "C" void nnMain()
194 {
195     NN_TLOG_("----Application start\n");
196 
197     nn::Result result;
198 
199     // applet declarations
200     nn::applet::SetSleepQueryCallback( myReceiveSleepQueryNotification, 0 );
201     nn::applet::SetAwakeCallback( myReceiveAwakeNotification, 0 );
202     nn::applet::Enable();
203     if(nn::applet::IsExpectedToCloseApplication())
204     {
205         // Quickly end the application
206         nn::applet::PrepareToCloseApplication();
207         nn::applet::CloseApplication();
208 
209         // Never reached
210         return;
211     }
212 
213     // hid
214     result = nn::hid::Initialize();
215     NN_UTIL_PANIC_IF_FAILED(result);
216 
217     // fs
218     nn::fs::Initialize();
219 
220     // Memory allocation
221     SetupRenderSystem();
222 
223     nn::hid::PadReader padReader;
224     nn::hid::PadStatus ps;
225 
226     nn::cfg::Initialize();
227 
228     // Get COPPACS-related information
229     {
230         isCoppacsSupported = nn::cfg::IsCoppacsSupported();
231 
232         /*
233          * The GetCoppacsRestriction return value could be any of the following.
234          *
235          * CFG_COPPACS_RESTRICTION_NONE:
236          *  No COPPACS restrictions
237          *
238          * CFG_COPPACS_RESTRICTION_NEED_PARENTAL_PIN_CODE:
239          *  COPPACS restrictions can be removed by entering a PIN code.
240          *  Use the nn::cfg::CheckParentalControlPinCode function as needed to verify the PIN code.
241          *
242          * CFG_COPPACS_RESTRICTION_NEED_PARENTAL_AUTHENTICATION:
243          *  Need to jump to System Settings and get COPPACS authentication. (Start this in this demo by pressing the START Button.)
244          */
245         coppacsRestriction = nn::cfg::GetCoppacsRestriction();
246 
247     }
248 
249     // Check whether we've returned from Mset, and if so, from which scene
250     isFromMset = nn::applet::IsFromMset(&msetScene);
251 
252     while(1)
253     {
254         loopCnt++;
255 
256         padReader.ReadLatest( &ps );
257 
258         // Render
259         DrawDisplay();
260 
261         if(coppacsRestriction == nn::cfg::CFG_COPPACS_RESTRICTION_NEED_PARENTAL_AUTHENTICATION)
262         {
263             if(ps.trigger == nn::hid::BUTTON_START)
264             {
265                 nn::applet::JumpToParentalControls(nn::applet::PARENTAL_CONTROLS_COPPACS);
266             }
267         }
268 
269         // Process HOME Button
270         if ( nn::applet::IsExpectedToProcessHomeButton() )
271         {
272             NN_LOG("HomeBtn.\n");
273             nn::applet::ProcessHomeButtonAndWait();
274 
275             if(nn::applet::IsExpectedToCloseApplication())
276             {
277                 break;
278             }
279 
280             RestoreGraphics();
281 
282         }
283 
284         // POWER button process
285         if ( nn::applet::IsExpectedToProcessPowerButton() )
286         {
287             NN_LOG("PowerBtn.\n");
288             nn::applet::ProcessPowerButtonAndWait();
289 
290             if(nn::applet::IsExpectedToCloseApplication())
291             {
292                 break;
293             }
294 
295             RestoreGraphics();
296         }
297 
298     }
299 
300 
301     NN_TLOG_("----Application is to be end\n");
302 
303     // Memory deallocation
304     ReleaseRenderSystem();
305 
306     nn::cfg::Finalize();
307 
308     // Finalize hid
309     nn::hid::Finalize();
310 
311     // Exit application
312     nn::applet::PrepareToCloseApplication();
313     nn::applet::CloseApplication();
314 
315     // No need to call Finalize on applet
316     // Execution will probably not reach here.
317     NN_TLOG_("----Application end\n");
318 }
319