/*---------------------------------------------------------------------------* Project: Horizon File: swkbd_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: 47394 $ *---------------------------------------------------------------------------*/ #include #include "demo.h" #include #include #include //---------------------------------------------------------------- namespace { demo::RenderSystemDrawing df; s32 loopCnt = 0; 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, 1.0f); df.DrawText( 30, 80, "[A] Launch library applet." ); // Count df.DrawText( 340, 50, "%d", loopCnt ); df.DrawText( 340, 82, "%d", nngxCheckVSync(NN_GX_DISPLAY0) ); } 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-1 sleepQuery \n"); return /*applet::IsActive()? applet::REPLY_LATER:*/ nn::applet::REPLY_ACCEPT; } //---------------------------------------------------------------- void myReceiveAwakeNotification( uptr arg ) { NN_UNUSED_VAR( arg ); NN_LOG("*** Application-1 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); // Render class initialization SetupRenderSystem(); nn::hid::PadReader padReader; nn::hid::PadStatus ps; while(1) { loopCnt++; padReader.ReadLatest(&ps); // Render DrawDisplay(); // Start library applet with A Button if ( ps.trigger & nn::hid::BUTTON_A ) { nn::applet::WakeupState wstate; nn::swkbd::Parameter kbd_param; // structure for keyboard configuration and structure containing screen capture information // Initialize structure for keyboard configuration nn::swkbd::InitializeConfig( &kbd_param.config ); kbd_param.config.keyboardType = nn::swkbd::KEYBOARD_TYPE_QWERTY; kbd_param.config.upperScreenFlag = nn::swkbd::UPPER_SCREEN_DARK; kbd_param.config.bottomButtonType = nn::swkbd::BOTTOM_BUTTON_TYPE_2BUTTON; kbd_param.config.textLengthMax = 10; kbd_param.config.prediction = false; kbd_param.config.lineFeed = false; kbd_param.config.bottomButtonToFinish[nn::swkbd::BOTTOM_BUTTON_2BUTTON_RIGHT] = true; wcsncpy( kbd_param.config.guideText, L"Please input text.", 19 ); /* The code below modifies the text of the OK and Cancel buttons shown on the bottom of the screen. Although text appears on the button as specified if modified, the default text for a given system region and language will appear as long as default settings are used. For example, "Cancel" and "OK" are displayed on buttons if English is selected as the language, but "Annuler" and "OK" appear if French is selected. Localization of text used for button on the screen is therefore unnecessary at the application level as long as you use default settings. */ //wcsncpy( kbd_param.config.bottomButtonText[nn::swkbd::BOTTOM_BUTTON_2BUTTON_LEFT], L"Cancel", 7 ); //wcsncpy( kbd_param.config.bottomButtonText[nn::swkbd::BOTTOM_BUTTON_2BUTTON_RIGHT], L"OK", 3 ); // Calculate size of shared memory region s32 memSize = nn::swkbd::GetSharedMemorySize( &kbd_param.config, NULL, NULL ); // Allocate shared memory const u32 ALIGN = 4096; void* share_buf = std::malloc(memSize + (ALIGN - 1)); NN_NULL_ASSERT( share_buf ); if( share_buf ) { void* aligned_share_buf = reinterpret_cast((reinterpret_cast(share_buf) + (ALIGN - 1)) & ~(ALIGN-1)); // Call keyboard nn::swkbd::StartKeyboardApplet( &wstate, &kbd_param, aligned_share_buf, // Must be 4096-byte aligned.ipp Device memory cannot be specified. memSize ); // Must be a multiple of 4096 // Recover the GPU register settings if(nn::applet::IsExpectedToCloseApplication()) { std::free(share_buf); break; } RestoreGraphics(); // Get the input string u8* buf = static_cast(aligned_share_buf); wchar_t text_buf[11]; memset( text_buf, 0, sizeof( text_buf ) ); memcpy( text_buf, &buf[kbd_param.config.inputText], kbd_param.config.inputTextLength * sizeof( wchar_t ) ); for( s32 i = 0; i < 10; ++i ) { NN_LOG("%d\n", text_buf[i]); } std::free(share_buf); } } // Handle HOME Button on keyboard if ( nn::applet::IsExpectedToProcessHomeButton() ) { NN_LOG("swkbd HomeBtn.\n"); nn::applet::ProcessHomeButtonAndWait(); if(nn::applet::IsExpectedToCloseApplication()) { break; } RestoreGraphics(); } // Handle POWER Button on keyboard if ( nn::applet::IsExpectedToProcessPowerButton() ) { NN_LOG("swkbd PowerBtn.\n"); nn::applet::ProcessPowerButtonAndWait(); if(nn::applet::IsExpectedToCloseApplication()) { break; } RestoreGraphics(); } } NN_TLOG_("----Application is to be end\n"); // Free the render class ReleaseRenderSystem(); // 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"); }