1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: swkbd_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: 47394 $
14 *---------------------------------------------------------------------------*/
15
16 #include <nn.h>
17
18 #include "demo.h"
19
20 #include <nn/swkbd.h>
21
22 #include <string.h>
23 #include <wchar.h>
24
25
26 //----------------------------------------------------------------
27
28 namespace
29 {
30 demo::RenderSystemDrawing df;
31
32 s32 loopCnt = 0;
33
SetupRenderSystem()34 void SetupRenderSystem()
35 {
36 demo::RenderBufferDescription colorBufferDesc;
37 {
38 colorBufferDesc.m_Format = GL_RGBA8_OES;
39 colorBufferDesc.m_Width = nn::gx::DISPLAY0_WIDTH;
40 colorBufferDesc.m_Height = nn::gx::DISPLAY0_HEIGHT;
41 colorBufferDesc.m_Area = NN_GX_MEM_VRAMA;
42 colorBufferDesc.m_Attachment = GL_COLOR_ATTACHMENT0;
43 }
44 demo::RenderBufferDescription depthStencilBufferDesc;
45 {
46 depthStencilBufferDesc.m_Format = GL_DEPTH24_STENCIL8_EXT;
47 depthStencilBufferDesc.m_Width = nn::gx::DISPLAY0_WIDTH;
48 depthStencilBufferDesc.m_Height = nn::gx::DISPLAY0_HEIGHT;
49 depthStencilBufferDesc.m_Area = NN_GX_MEM_VRAMB;
50 depthStencilBufferDesc.m_Attachment = GL_DEPTH_STENCIL_ATTACHMENT;
51 }
52
53 demo::FrameBufferDescription frameBufferDesc;
54 {
55 frameBufferDesc.m_RenderBufferDescriptionArray[demo::DEMO_COLOR_BUFFER_INDEX] = colorBufferDesc;
56 frameBufferDesc.m_RenderBufferDescriptionArray[demo::DEMO_DEPTH_STENCIL_BUFFER_INDEX] = depthStencilBufferDesc;
57 }
58
59 demo::DisplayBuffersDescription display0BuffersDesc;
60 {
61 display0BuffersDesc.m_TargetDisplay = NN_GX_DISPLAY0;
62 display0BuffersDesc.m_DisplayBufferNum = demo::DEMO_DISPLAY_BUFFER_NUM;
63 display0BuffersDesc.m_Format = GL_RGB8_OES;
64 display0BuffersDesc.m_Width = nn::gx::DISPLAY0_WIDTH;
65 display0BuffersDesc.m_Height = nn::gx::DISPLAY0_HEIGHT;
66 display0BuffersDesc.m_Area = NN_GX_MEM_FCRAM;
67 // display0BuffersDesc.m_Area = NN_GX_MEM_VRAMA;
68 }
69
70 demo::DisplayBuffersDescription display1BuffersDesc;
71 {
72 display1BuffersDesc.m_TargetDisplay = NN_GX_DISPLAY1;
73 display1BuffersDesc.m_DisplayBufferNum = demo::DEMO_DISPLAY_BUFFER_NUM;
74 display1BuffersDesc.m_Format = GL_RGB8_OES;
75 display1BuffersDesc.m_Width = nn::gx::DISPLAY1_WIDTH;
76 display1BuffersDesc.m_Height = nn::gx::DISPLAY1_HEIGHT;
77 display1BuffersDesc.m_Area = NN_GX_MEM_FCRAM;
78 // display1BuffersDesc.m_Area = NN_GX_MEM_VRAMB;
79 }
80
81 df.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize(),
82 0x40000, 128, true,
83 display0BuffersDesc, display1BuffersDesc,
84 frameBufferDesc
85 );
86 }
87
ReleaseRenderSystem()88 void ReleaseRenderSystem()
89 {
90 df.Finalize();
91 }
92
DrawText()93 void DrawText()
94 {
95 // display 0
96 df.SetRenderTarget(NN_GX_DISPLAY0);
97 df.Clear();
98 {
99 df.SetColor(0.0f, 0.0f, 0.5f);
100 df.FillRectangle( 0, 0, 399, 255 );
101 df.SetColor(0.5f, 0.4f, 0.0f);
102 df.FillRectangle( 0, 0, 399, 40 );
103 df.SetColor(0.5f, 0.0f, 0.4f);
104 df.FillRectangle( 0, 180, 399, 40 );
105 df.SetColor(1.0f, 1.0f, 1.0f);
106 df.DrawText( 100, 50, "** DEMO APPLICATION **" );
107
108 df.SetColor(1.0f, 1.0f, 1.0f);
109 df.DrawText( 30, 80, "[A] Launch library applet." );
110
111 // Count
112 df.DrawText( 340, 50, "%d", loopCnt );
113 df.DrawText( 340, 82, "%d", nngxCheckVSync(NN_GX_DISPLAY0) );
114 }
115 df.SwapBuffers();
116
117 // display 1
118 df.SetRenderTarget(NN_GX_DISPLAY1);
119 df.Clear();
120 {
121 df.SetColor(0.0f, 0.5f, 0.0f);
122 df.FillRectangle( 0, 0, 399, 255 );
123 df.SetColor(1.0f, 1.0f, 1.0f);
124 df.DrawText( 80, 50, "** DEMO APPLICATION **" );
125 }
126 df.SwapBuffers();
127 }
128
DrawDisplay()129 void DrawDisplay()
130 {
131 DrawText();
132 }
133
RestoreGraphics()134 void RestoreGraphics()
135 {
136 // Recover the GPU register settings
137 nngxUpdateState(NN_GX_STATE_ALL);
138 nngxValidateState(NN_GX_STATE_ALL,GL_TRUE);
139 }
140 }
141
142 //----------------------------------------------------------------
myReceiveSleepQueryNotification(uptr arg)143 AppletQueryReply myReceiveSleepQueryNotification( uptr arg )
144 {
145 NN_UNUSED_VAR( arg );
146 NN_LOG("*** Application-1 sleepQuery \n");
147 return /*applet::IsActive()? applet::REPLY_LATER:*/ nn::applet::REPLY_ACCEPT;
148 }
149
150 //----------------------------------------------------------------
myReceiveAwakeNotification(uptr arg)151 void myReceiveAwakeNotification( uptr arg )
152 {
153 NN_UNUSED_VAR( arg );
154 NN_LOG("*** Application-1 awake \n");
155 if ( nn::applet::IsActive() )
156 {
157 nngxStartLcdDisplay();
158 }
159 }
160
161 //----------------------------------------------------------------
nnMain()162 extern "C" void nnMain()
163 {
164 NN_TLOG_("----Application start\n");
165
166 nn::Result result;
167
168 // applet declarations
169 nn::applet::SetSleepQueryCallback( myReceiveSleepQueryNotification, 0 );
170 nn::applet::SetAwakeCallback( myReceiveAwakeNotification, 0 );
171 nn::applet::Enable();
172 if(nn::applet::IsExpectedToCloseApplication())
173 {
174 // Quickly end the application
175 nn::applet::PrepareToCloseApplication();
176 nn::applet::CloseApplication();
177
178 // Never reached
179 return;
180 }
181
182 // hid
183 result = nn::hid::Initialize();
184 NN_UTIL_PANIC_IF_FAILED(result);
185
186 // Render class initialization
187 SetupRenderSystem();
188
189 nn::hid::PadReader padReader;
190 nn::hid::PadStatus ps;
191
192 while(1)
193 {
194 loopCnt++;
195
196 padReader.ReadLatest(&ps);
197
198 // Render
199 DrawDisplay();
200
201
202 // Start library applet with A Button
203 if ( ps.trigger & nn::hid::BUTTON_A )
204 {
205 nn::applet::WakeupState wstate;
206 nn::swkbd::Parameter kbd_param; // structure for keyboard configuration and structure containing screen capture information
207
208 // Initialize structure for keyboard configuration
209 nn::swkbd::InitializeConfig( &kbd_param.config );
210 kbd_param.config.keyboardType = nn::swkbd::KEYBOARD_TYPE_QWERTY;
211 kbd_param.config.upperScreenFlag = nn::swkbd::UPPER_SCREEN_DARK;
212 kbd_param.config.bottomButtonType = nn::swkbd::BOTTOM_BUTTON_TYPE_2BUTTON;
213 kbd_param.config.textLengthMax = 10;
214 kbd_param.config.prediction = false;
215 kbd_param.config.lineFeed = false;
216 kbd_param.config.bottomButtonToFinish[nn::swkbd::BOTTOM_BUTTON_2BUTTON_RIGHT] = true;
217 wcsncpy( kbd_param.config.guideText, L"Please input text.", 19 );
218
219 /*
220 The code below modifies the text of the OK and Cancel buttons shown on the bottom of the screen.
221 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.
222
223 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.
224
225 Localization of text used for button on the screen is therefore unnecessary at the application level as long as you use default settings.
226
227 */
228 //wcsncpy( kbd_param.config.bottomButtonText[nn::swkbd::BOTTOM_BUTTON_2BUTTON_LEFT], L"Cancel", 7 );
229 //wcsncpy( kbd_param.config.bottomButtonText[nn::swkbd::BOTTOM_BUTTON_2BUTTON_RIGHT], L"OK", 3 );
230
231 // Calculate size of shared memory region
232 s32 memSize = nn::swkbd::GetSharedMemorySize( &kbd_param.config, NULL, NULL );
233 // Allocate shared memory
234 const u32 ALIGN = 4096;
235 void* share_buf = std::malloc(memSize + (ALIGN - 1));
236 NN_NULL_ASSERT( share_buf );
237
238 if( share_buf )
239 {
240 void* aligned_share_buf = reinterpret_cast<void*>((reinterpret_cast<u32>(share_buf) + (ALIGN - 1)) & ~(ALIGN-1));
241
242 // Call keyboard
243 nn::swkbd::StartKeyboardApplet(
244 &wstate,
245 &kbd_param,
246 aligned_share_buf, // Must be 4096-byte aligned.ipp Device memory cannot be specified.
247 memSize ); // Must be a multiple of 4096
248 // Recover the GPU register settings
249 if(nn::applet::IsExpectedToCloseApplication())
250 {
251 std::free(share_buf);
252 break;
253 }
254 RestoreGraphics();
255
256
257 // Get the input string
258 u8* buf = static_cast<u8*>(aligned_share_buf);
259 wchar_t text_buf[11];
260 memset( text_buf, 0, sizeof( text_buf ) );
261
262 memcpy( text_buf, &buf[kbd_param.config.inputText], kbd_param.config.inputTextLength * sizeof( wchar_t ) );
263
264 for( s32 i = 0; i < 10; ++i )
265 {
266 NN_LOG("%d\n", text_buf[i]);
267 }
268 std::free(share_buf);
269 }
270 }
271
272
273 // Handle HOME Button on keyboard
274 if ( nn::applet::IsExpectedToProcessHomeButton() )
275 {
276 NN_LOG("swkbd HomeBtn.\n");
277 nn::applet::ProcessHomeButtonAndWait();
278
279 if(nn::applet::IsExpectedToCloseApplication())
280 {
281 break;
282 }
283
284 RestoreGraphics();
285
286 }
287
288 // Handle POWER Button on keyboard
289 if ( nn::applet::IsExpectedToProcessPowerButton() )
290 {
291 NN_LOG("swkbd PowerBtn.\n");
292 nn::applet::ProcessPowerButtonAndWait();
293
294 if(nn::applet::IsExpectedToCloseApplication())
295 {
296 break;
297 }
298
299 RestoreGraphics();
300
301 }
302 }
303
304 NN_TLOG_("----Application is to be end\n");
305
306 // Free the render class
307 ReleaseRenderSystem();
308
309 // Finalize hid
310 nn::hid::Finalize();
311
312 // Exit application
313 nn::applet::PrepareToCloseApplication();
314 nn::applet::CloseApplication();
315
316 // No need to call Finalize on applet
317 // Execution will probably not reach here.
318 NN_TLOG_("----Application end\n");
319 }
320