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