/*---------------------------------------------------------------------------* Project: Horizon File: coppacs_demo.cpp Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev:$ *---------------------------------------------------------------------------*/ #include #include #include "demo.h" //---------------------------------------------------------------- namespace { demo::RenderSystemDrawing df; s32 loopCnt = 0; // State related to COPPACS bool isCoppacsSupported; nn::cfg::CfgCoppacsRestriction coppacsRestriction; // Whether we've returned from System Settings bool isFromMset; // Which System Settings scene we've returned from nn::applet::AppletMsetScene msetScene; const char* COPPACS_RESTRICTION_STRING[] = { "RESTRICTION_NONE", "RESTRICTION_NEED_PARENTAL_PIN_CODE", "RESTRICTION_NEED_PARENTAL_AUTHENTICATION" }; void SetupRenderSystem() { demo::RenderBufferDescription colorBufferDesc; { colorBufferDesc.m_Format = GL_RGBA8_OES; colorBufferDesc.m_Width = nn::gx::DISPLAY0_WIDTH; colorBufferDesc.m_Height = nn::gx::DISPLAY0_HEIGHT; colorBufferDesc.m_Area = NN_GX_MEM_VRAMA; colorBufferDesc.m_Attachment = GL_COLOR_ATTACHMENT0; } demo::RenderBufferDescription depthStencilBufferDesc; { depthStencilBufferDesc.m_Format = GL_DEPTH24_STENCIL8_EXT; depthStencilBufferDesc.m_Width = nn::gx::DISPLAY0_WIDTH; depthStencilBufferDesc.m_Height = nn::gx::DISPLAY0_HEIGHT; depthStencilBufferDesc.m_Area = NN_GX_MEM_VRAMB; depthStencilBufferDesc.m_Attachment = GL_DEPTH_STENCIL_ATTACHMENT; } demo::FrameBufferDescription frameBufferDesc; { frameBufferDesc.m_RenderBufferDescriptionArray[demo::DEMO_COLOR_BUFFER_INDEX] = colorBufferDesc; frameBufferDesc.m_RenderBufferDescriptionArray[demo::DEMO_DEPTH_STENCIL_BUFFER_INDEX] = depthStencilBufferDesc; } demo::DisplayBuffersDescription display0BuffersDesc; { display0BuffersDesc.m_TargetDisplay = NN_GX_DISPLAY0; display0BuffersDesc.m_DisplayBufferNum = demo::DEMO_DISPLAY_BUFFER_NUM; display0BuffersDesc.m_Format = GL_RGB8_OES; display0BuffersDesc.m_Width = nn::gx::DISPLAY0_WIDTH; display0BuffersDesc.m_Height = nn::gx::DISPLAY0_HEIGHT; display0BuffersDesc.m_Area = NN_GX_MEM_FCRAM; // display0BuffersDesc.m_Area = NN_GX_MEM_VRAMA; } demo::DisplayBuffersDescription display1BuffersDesc; { display1BuffersDesc.m_TargetDisplay = NN_GX_DISPLAY1; display1BuffersDesc.m_DisplayBufferNum = demo::DEMO_DISPLAY_BUFFER_NUM; display1BuffersDesc.m_Format = GL_RGB8_OES; display1BuffersDesc.m_Width = nn::gx::DISPLAY1_WIDTH; display1BuffersDesc.m_Height = nn::gx::DISPLAY1_HEIGHT; display1BuffersDesc.m_Area = NN_GX_MEM_FCRAM; // display1BuffersDesc.m_Area = NN_GX_MEM_VRAMB; } df.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize(), 0x40000, 128, true, display0BuffersDesc, display1BuffersDesc, frameBufferDesc ); } void ReleaseRenderSystem() { df.Finalize(); } void DrawText() { // display 0 df.SetRenderTarget(NN_GX_DISPLAY0); df.Clear(); { df.SetColor(0.0f, 0.0f, 0.5f); df.FillRectangle( 0, 0, 399, 255 ); df.SetColor(0.5f, 0.4f, 0.0f); df.FillRectangle( 0, 0, 399, 40 ); df.SetColor(0.5f, 0.0f, 0.4f); df.FillRectangle( 0, 180, 399, 40 ); df.SetColor(1.0f, 1.0f, 1.0f); df.DrawText( 100, 50, "** DEMO APPLICATION **" ); df.SetColor(1.0f, 1.0f, 0.0f); if(coppacsRestriction == nn::cfg::CFG_COPPACS_RESTRICTION_NEED_PARENTAL_AUTHENTICATION) { df.DrawText( 40, 90, "push [START] to run COPPACS Setting Menu"); } df.SetColor(1.0f, 1.0f, 1.0f); // Count df.DrawText( 340, 50, "%d", loopCnt ); // COPPACS state df.DrawText( 30, 130, "IsCoppacsSupported :%s" ,isCoppacsSupported?"true":"false"); df.DrawText( 30, 140, "GetCoppacsRestriction:"); df.DrawText( 60, 150, "%s" ,COPPACS_RESTRICTION_STRING[coppacsRestriction]); // Whether we've returned from Mset if(isFromMset) { df.DrawText( 30, 160, "IsFromMset :true(%d)",msetScene); } else { df.DrawText( 30, 160, "IsFromMset :false"); } } df.SwapBuffers(); // display 1 df.SetRenderTarget(NN_GX_DISPLAY1); df.Clear(); { df.SetColor(0.0f, 0.5f, 0.0f); df.FillRectangle( 0, 0, 399, 255 ); df.SetColor(1.0f, 1.0f, 1.0f); df.DrawText( 80, 50, "** DEMO APPLICATION **" ); } df.SwapBuffers(); } void DrawDisplay() { DrawText(); } void RestoreGraphics() { // Recover the GPU register settings nngxUpdateState(NN_GX_STATE_ALL); nngxValidateState(NN_GX_STATE_ALL,GL_TRUE); } } //---------------------------------------------------------------- AppletQueryReply myReceiveSleepQueryNotification( uptr arg ) { NN_UNUSED_VAR( arg ); NN_LOG("*** Application sleepQuery \n"); return /*applet::IsActive()? applet::REPLY_LATER:*/ nn::applet::REPLY_ACCEPT; } //---------------------------------------------------------------- void myReceiveAwakeNotification( uptr arg ) { NN_UNUSED_VAR( arg ); NN_LOG("*** Application awake \n"); if ( nn::applet::IsActive() ) { nngxStartLcdDisplay(); } } //---------------------------------------------------------------- extern "C" void nnMain() { NN_TLOG_("----Application start\n"); nn::Result result; // applet declarations nn::applet::SetSleepQueryCallback( myReceiveSleepQueryNotification, 0 ); nn::applet::SetAwakeCallback( myReceiveAwakeNotification, 0 ); nn::applet::Enable(); if(nn::applet::IsExpectedToCloseApplication()) { // Quickly end the application nn::applet::PrepareToCloseApplication(); nn::applet::CloseApplication(); // Never reached return; } // hid result = nn::hid::Initialize(); NN_UTIL_PANIC_IF_FAILED(result); // fs nn::fs::Initialize(); // Memory allocation SetupRenderSystem(); nn::hid::PadReader padReader; nn::hid::PadStatus ps; nn::cfg::Initialize(); // Get COPPACS-related information { isCoppacsSupported = nn::cfg::IsCoppacsSupported(); /* * The GetCoppacsRestriction return value could be any of the following. * * CFG_COPPACS_RESTRICTION_NONE: * No COPPACS restrictions * * CFG_COPPACS_RESTRICTION_NEED_PARENTAL_PIN_CODE: * COPPACS restrictions can be removed by entering a PIN code. * Use the nn::cfg::CheckParentalControlPinCode function as needed to verify the PIN code. * * CFG_COPPACS_RESTRICTION_NEED_PARENTAL_AUTHENTICATION: * Need to jump to System Settings and get COPPACS authentication. (Start this in this demo by pressing the START Button.) */ coppacsRestriction = nn::cfg::GetCoppacsRestriction(); } // Check whether we've returned from Mset, and if so, from which scene isFromMset = nn::applet::IsFromMset(&msetScene); while(1) { loopCnt++; padReader.ReadLatest( &ps ); // Render DrawDisplay(); if(coppacsRestriction == nn::cfg::CFG_COPPACS_RESTRICTION_NEED_PARENTAL_AUTHENTICATION) { if(ps.trigger == nn::hid::BUTTON_START) { nn::applet::JumpToParentalControls(nn::applet::PARENTAL_CONTROLS_COPPACS); } } // Process HOME Button if ( nn::applet::IsExpectedToProcessHomeButton() ) { NN_LOG("HomeBtn.\n"); nn::applet::ProcessHomeButtonAndWait(); if(nn::applet::IsExpectedToCloseApplication()) { break; } RestoreGraphics(); } // POWER button process if ( nn::applet::IsExpectedToProcessPowerButton() ) { NN_LOG("PowerBtn.\n"); nn::applet::ProcessPowerButtonAndWait(); if(nn::applet::IsExpectedToCloseApplication()) { break; } RestoreGraphics(); } } NN_TLOG_("----Application is to be end\n"); // Memory deallocation ReleaseRenderSystem(); nn::cfg::Finalize(); // Finalize hid nn::hid::Finalize(); // Exit application nn::applet::PrepareToCloseApplication(); nn::applet::CloseApplication(); // No need to call Finalize on applet // Execution will probably not reach here. NN_TLOG_("----Application end\n"); }