1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     demo2.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: 47228 $
14  *---------------------------------------------------------------------------*/
15 
16 #include <nn.h>
17 #include <nn/math.h>
18 #include <nn/applet.h>
19 #include "graphics.h"
20 #include "mic.h"
21 #include "snd.h"
22 #include "applet.h"
23 
24 // Heap used by the application
25 nn::fnd::ExpHeap s_AppHeap;
26 
StartDemo()27 void StartDemo()
28 {
29     // Description of Operations
30     NN_LOG("BUTTON_UP,DOWN,LEFT,RIGHT,L,R : Change camera position\n");
31     NN_LOG("AnalogStick, TouchPanel, BUTTON_A,B,X,Y : Change camera focus\n");
32     NN_LOG("Accelerometer : Incline plane\n");
33     NN_LOG("Mic : Blow ball\n");
34     NN_LOG("BUTTON_START : Reset camera position and focus\n");
35 
36     nn::Result result;
37 
38     // Initialize the heap
39     s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize() );
40 
41     // fs initialization
42     nn::fs::Initialize();
43 
44     const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
45     static char buffer[ROMFS_BUFFER_SIZE];
46     NN_UTIL_PANIC_IF_FAILED(
47         nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
48 
49     // Initialize hid
50     result = nn::hid::Initialize();
51     NN_UTIL_PANIC_IF_FAILED(result);
52 
53     // Initialize sound
54     InitializeSnd();
55 
56     // Prepare pad
57     nn::hid::PadReader padReader;
58     nn::hid::PadStatus padStatus;
59     // Prepare touch panel
60     nn::hid::TouchPanelReader tpReader;
61     nn::hid::TouchPanelStatus tpStatus;
62     // Prepare accelerometer
63     nn::hid::AccelerometerReader accReader;
64     nn::hid::AccelerometerStatus accStatus;
65     accReader.SetSensitivity(0, nn::hid::MAX_OF_ACCELEROMETER_SENSITIVITY / 4);  // Set tracking
66 
67     // Initialize mic and start sampling
68     StartMic();
69 
70     // Initialize graphics
71     InitializeGraphics();
72 
73     // Parameters for rendering
74     f32 SPEED = 0.05f;
75     f32 FOCUS_DISTANCE = 10.0f + SPEED / 2;    // Shift a little so that the camera position and focus do not match
76     // Camera position
77     f32 cam_x = 0;
78     f32 cam_y = 7.f;
79     f32 cam_z = FOCUS_DISTANCE;
80     // Camera viewpoint
81     f32 focus_x = 0;
82     f32 focus_y = 0;
83     f32 focus_z = 0;
84     // Accelerometer
85     f32 gx = 0;
86     f32 gz = 0;
87 
88     // Wait for HID input to stabilize
89     nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromSeconds(1));
90 
91     // After this, the application itself handles sleep
92     TransitionHandler::EnableSleep();
93 
94     while(true)
95     {
96         // Get input
97         padReader.ReadLatest(&padStatus);
98         tpReader.ReadLatest(&tpStatus);
99         accReader.ReadLatest(&accStatus);
100 
101         nn::hid::AccelerationFloat acceleration;
102         accReader.ConvertToAcceleration(&acceleration, 1, &accStatus);
103         if(acceleration.y > 0)
104         {
105             NN_LOG("Upside-down!\n");
106         }
107         else
108         {
109             gx = acceleration.x;
110             gz = acceleration.z;
111         }
112 
113         // Calculate parameters for rendering
114         if(tpStatus.touch == 1)
115         {
116             focus_x += ((static_cast<f32>(tpStatus.x) / 160) - 1) * SPEED;
117             focus_y -= ((static_cast<f32>(tpStatus.y) / 120) - 1) * SPEED;
118         }
119         else
120         {
121             focus_x += padReader.NormalizeStick(padStatus.stick.x) * SPEED;
122             focus_y += padReader.NormalizeStick(padStatus.stick.y) * SPEED;
123         }
124 
125         if(padStatus.hold & nn::hid::BUTTON_X)
126         {
127             focus_y += SPEED;
128         }
129 
130         if(padStatus.hold & nn::hid::BUTTON_B)
131         {
132             focus_y -= SPEED;
133         }
134 
135         if(padStatus.hold & nn::hid::BUTTON_A)
136         {
137             focus_x += SPEED;
138         }
139 
140         if(padStatus.hold & nn::hid::BUTTON_Y)
141         {
142             focus_x -= SPEED;
143         }
144 
145         if(padStatus.hold & nn::hid::BUTTON_UP)
146         {
147             cam_z -= SPEED;
148         }
149 
150         if(padStatus.hold & nn::hid::BUTTON_DOWN)
151         {
152             cam_z += SPEED;
153         }
154 
155         if(padStatus.hold & nn::hid::BUTTON_LEFT)
156         {
157             cam_x -= SPEED;
158         }
159 
160         if(padStatus.hold & nn::hid::BUTTON_RIGHT)
161         {
162             cam_x += SPEED;
163         }
164 
165         if(padStatus.hold & nn::hid::BUTTON_L)
166         {
167             cam_y += SPEED;
168         }
169 
170         if(padStatus.hold & nn::hid::BUTTON_R)
171         {
172             cam_y -= SPEED;
173         }
174 
175         if(padStatus.trigger & nn::hid::BUTTON_START)
176         {
177             cam_x = 0;
178             cam_y = 7.f;
179             cam_z = FOCUS_DISTANCE;
180             focus_x = 0;
181             focus_y = 0;
182             focus_z = 0;
183         }
184 
185         // Microphone
186         u8 loudness = GetLoudness();
187 
188         // Render
189         nn::math::VEC3 cam(cam_x, cam_y, cam_z);
190         nn::math::VEC3 focus(focus_x, focus_y, focus_z);
191         nn::math::VEC2 g(-gx, -gz);
192         DrawFrame(cam, focus, g, loudness);
193 
194         // Run sleep, HOME Menu, and POWER Menu transitions.
195         TransitionHandler::Process();
196         // Determine whether there has been an exit notification.
197         if (TransitionHandler::IsExitRequired())
198         {
199             break;
200         }
201     }
202 
203     // Graphics termination processing
204     FinalizeGraphics();
205 
206     // Mic termination processing
207     EndMic();
208 
209     // Sound termination processing
210     FinalizeSnd();
211 
212     // Destroy heap
213     s_AppHeap.Finalize();
214 }
215 
nnMain()216 void nnMain()
217 {
218     NN_LOG("Demo Start\n");
219 
220     // Initialize via the applet.
221     // Sleep Mode is rejected automatically until TransitionHandler::EnableSleep is called.
222     TransitionHandler::Initialize();
223     // Here we need to check for exit notifications.
224     if (!TransitionHandler::IsExitRequired())
225     {
226         StartDemo();
227     }
228     // Finalize via the applet.
229     TransitionHandler::Finalize();
230 
231     NN_LOG("Demo2 End\n");
232 
233     // Finalize the application. The call to nn::applet::CloseApplication does not return.
234     nn::applet::CloseApplication();
235 }
236 
237 /*---------------------------------------------------------------------------*
238   End of file
239  *---------------------------------------------------------------------------*/
240