1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: FsSampleSecureSaveFrame.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: 47440 $
14 *---------------------------------------------------------------------------*/
15
16 #include <nn.h>
17 #include "demo.h"
18
19 #include "../Common/FsSampleCommon.h"
20 #include "FsSampleSecureSave.h"
21
22 using namespace nn;
23
24 namespace sample { namespace fs { namespace securesave {
25
26 namespace
27 {
28 enum ENUM_TASK
29 {
30 TASK_NONE,
31 TASK_SAVE,
32 TASK_LOAD,
33 TASK_RENEW,
34
35 ENUM_TASK_NUM
36 } s_Task;
37
38 enum ENUM_STATE
39 {
40 STATE_NONE,
41 STATE_DATA_FORMATTED,
42 STATE_SAVE,
43 STATE_SAVE_DONE,
44 STATE_LOAD,
45 STATE_LOAD_SUCCEEDED,
46 STATE_LOAD_FAILED,
47 STATE_RENEW_SUCCEEDED,
48
49 ENUM_STATE_NUM
50 } s_State;
51
52 enum ENUM_OPERATION
53 {
54 OPERATION_FILEINDEX,
55 OPERATION_DATA,
56
57 ENUM_OPERATION_NUM
58 } s_Operation;
59
60 struct DisplayParameter
61 {
62 bit64 versionValueOnMemory;
63 } s_DisplayParam;
64
65 SaveData s_SaveData;
66 u32 s_FileIndex;
67
68 bool s_IsWorkerThreadAlive;
69 nn::os::Event s_WorkerEvent;
70 nn::os::Thread s_WorkerThread;
71 } // namespace
72
ProceedDisplay(demo::RenderSystemDrawing & renderSystem)73 void ProceedDisplay(demo::RenderSystemDrawing &renderSystem)
74 {
75 renderSystem.SetRenderTarget(NN_GX_DISPLAY0);
76 renderSystem.Clear();
77 renderSystem.SetColor(1.0f, 1.0f, 1.0f);
78
79 switch (s_State)
80 {
81 case STATE_DATA_FORMATTED:
82 renderSystem.DrawText(0, LINE_HEIGHT * 0, "SaveData was formatted");
83 break;
84 case STATE_SAVE:
85 renderSystem.DrawText(0, LINE_HEIGHT * 0, "Saving file index %d...", s_FileIndex);
86 break;
87 case STATE_SAVE_DONE:
88 renderSystem.DrawText(0, LINE_HEIGHT * 0, "Saving Succeeded");
89 break;
90 case STATE_LOAD:
91 renderSystem.DrawText(0, LINE_HEIGHT * 0, "Loading file index %d...", s_FileIndex);
92 break;
93 case STATE_LOAD_SUCCEEDED:
94 renderSystem.DrawText(0, LINE_HEIGHT * 0, "Loading Succeeded");
95 break;
96 case STATE_LOAD_FAILED:
97 renderSystem.DrawText(0, LINE_HEIGHT * 0, "Loading Failed");
98 break;
99 case STATE_RENEW_SUCCEEDED:
100 renderSystem.DrawText(0, LINE_HEIGHT * 0, "Renewal Succeeded");
101 break;
102 default:
103 break;
104 }
105
106 renderSystem.DrawText(0, LINE_HEIGHT * 3 * (1 + s_Operation), ">");
107 renderSystem.DrawText(FONT_SIZE * 1, LINE_HEIGHT * 3, "File index %c %d %c"
108 , (s_Operation == 0) ? '<' : ' '
109 , s_FileIndex
110 , (s_Operation == 0) ? '>' : ' '
111 );
112 renderSystem.DrawText(FONT_SIZE * 1, LINE_HEIGHT * 6, "Data on memory %c %c %c"
113 , (s_Operation == 1) ? '<' : ' '
114 , 'A' + ((s_SaveData.userData.data1 % 26) + 26) % 26
115 , (s_Operation == 1) ? '>' : ' '
116 );
117 renderSystem.DrawText(FONT_SIZE * 1, LINE_HEIGHT * 9, "VersionValue on memory %llu", s_DisplayParam.versionValueOnMemory);
118
119 renderSystem.SwapBuffers();
120
121
122 renderSystem.SetRenderTarget(NN_GX_DISPLAY1);
123 renderSystem.Clear();
124 renderSystem.SetColor(1.0f, 1.0f, 1.0f);
125
126 renderSystem.DrawText(8, LINE_HEIGHT * 1, "PlusPad: Change Data");
127 renderSystem.DrawText(8, LINE_HEIGHT * 4, "A: Save");
128 renderSystem.DrawText(8, LINE_HEIGHT * 5, "Y: Load & Check Version");
129 renderSystem.DrawText(8, LINE_HEIGHT * 6, "X: Renew");
130
131 renderSystem.SwapBuffers();
132 }
133
WorkerThread()134 void WorkerThread()
135 {
136 while (s_IsWorkerThreadAlive)
137 {
138 s_WorkerEvent.Wait();
139 switch (s_Task)
140 {
141 case TASK_SAVE:
142 s_State = STATE_SAVE;
143 Save(s_SaveData, s_FileIndex);
144 s_State = STATE_SAVE_DONE;
145 break;
146 case TASK_LOAD:
147 s_State = STATE_LOAD;
148 s_State = (Load(s_SaveData, s_FileIndex)) ? STATE_LOAD_SUCCEEDED : STATE_LOAD_FAILED;
149 break;
150 case TASK_RENEW:
151 s_State = STATE_RENEW_SUCCEEDED;
152 s_SaveData.Reset();
153 break;
154 default:
155 s_State = STATE_NONE;
156 break;
157 }
158
159 s_DisplayParam.versionValueOnMemory = s_SaveData.version;
160 s_Task = TASK_NONE;
161 }
162 }
163
ProceedHid()164 void ProceedHid()
165 {
166 static nn::hid::PadReader padReader;
167 static nn::hid::PadStatus padStatus;
168
169 if (!padReader.ReadLatest(&padStatus))
170 {
171 nn::dbg::detail::TPrintf("Getting pad status failed.\n");
172 }
173
174 if ((padStatus.trigger & nn::hid::BUTTON_A) && s_Task == TASK_NONE)
175 {
176 s_Task = TASK_SAVE;
177 s_WorkerEvent.Signal();
178 }
179 else if ((padStatus.trigger & nn::hid::BUTTON_Y) && s_Task == TASK_NONE)
180 {
181 s_Task = TASK_LOAD;
182 s_WorkerEvent.Signal();
183 }
184 else if ((padStatus.trigger & nn::hid::BUTTON_X) && s_Task == TASK_NONE)
185 {
186 s_Task = TASK_RENEW;
187 s_WorkerEvent.Signal();
188 }
189 else if (padStatus.trigger & nn::hid::BUTTON_UP)
190 {
191 s_Operation = static_cast<ENUM_OPERATION>((s_Operation - 1 + ENUM_OPERATION_NUM) % ENUM_OPERATION_NUM);
192 }
193 else if (padStatus.trigger & nn::hid::BUTTON_DOWN)
194 {
195 s_Operation = static_cast<ENUM_OPERATION>((s_Operation + 1) % ENUM_OPERATION_NUM);
196 }
197 else if (padStatus.trigger & nn::hid::BUTTON_LEFT)
198 {
199 switch (s_Operation)
200 {
201 case OPERATION_FILEINDEX:
202 s_FileIndex = (s_FileIndex - 1 + DATA_FILE_NUM) % DATA_FILE_NUM;
203 break;
204 case OPERATION_DATA:
205 s_SaveData.userData.data1--;
206 break;
207 }
208 }
209 else if (padStatus.trigger & nn::hid::BUTTON_RIGHT)
210 {
211 switch (s_Operation)
212 {
213 case OPERATION_FILEINDEX:
214 s_FileIndex = (s_FileIndex + 1) % DATA_FILE_NUM;
215 break;
216 case OPERATION_DATA:
217 s_SaveData.userData.data1++;
218 break;
219 }
220 }
221 }
222
223 } // namespace securesave
224
225 using namespace securesave;
226
MainLoop(demo::RenderSystemDrawing & renderSystem)227 void MainLoop(demo::RenderSystemDrawing &renderSystem)
228 {
229 ProceedHid();
230 ProceedDisplay(renderSystem);
231
232 nngxWaitVSync(NN_GX_DISPLAY_BOTH);
233 }
234
Initialize(demo::RenderSystemDrawing &)235 void Initialize(demo::RenderSystemDrawing&)
236 {
237 nn::fs::Initialize();
238 if (InitializeSaveData())
239 {
240 s_State = STATE_DATA_FORMATTED;
241 }
242 else
243 {
244 s_State = STATE_NONE;
245 }
246
247 s_SaveData.Reset();
248 s_FileIndex = 0;
249 s_DisplayParam.versionValueOnMemory = s_SaveData.version;
250
251 s_WorkerEvent.Initialize(false);
252 s_IsWorkerThreadAlive = true;
253 NN_ERR_THROW_FATAL_ALL(s_WorkerThread.TryStartUsingAutoStack(&WorkerThread, 4 * 1024, nn::os::Thread::GetCurrentPriority() + 1));
254 }
255
Finalize()256 void Finalize()
257 {
258 s_IsWorkerThreadAlive = false;
259 s_WorkerEvent.Signal();
260 s_WorkerThread.Join();
261 }
262
263 }} // namespace sample::fs
264