1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - MB - demos - multiboot-wfs - parent
3 File: parent.c
4
5 Copyright 2005-2008 Nintendo. 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 $Date:: 2008-12-08#$
14 $Rev: 9555 $
15 $Author: kitase_hirotake $
16 *---------------------------------------------------------------------------*/
17
18
19 #ifdef SDK_TWL
20 #include <twl.h>
21 #else
22 #include <nitro.h>
23 #endif
24 #include <nitro/wm.h>
25 #include <nitro/wbt.h>
26 #include <nitro/fs.h>
27
28 #include "wfs.h"
29 #include "wh.h"
30
31 #include "util.h"
32 #include "common.h"
33
34
35 /*---------------------------------------------------------------------------*
36 Internal Variable Definitions
37 *---------------------------------------------------------------------------*/
38
39 /* Transfer configuration adjustment */
40 static BOOL is_parent_sync = FALSE;
41 static int parent_packet_size = parent_packet_max;
42
43
44 /*---------------------------------------------------------------------------*
45 Function Definitions
46 *---------------------------------------------------------------------------*/
47
48
49 /*---------------------------------------------------------------------------*
50 Name: ModeSelect
51
52 Description: Process in parent/child selection screen.
53
54 Arguments: None.
55
56 Returns: None.
57 *---------------------------------------------------------------------------*/
ModeSelect(void)58 void ModeSelect(void)
59 {
60 KeyInfo key[1];
61 int i;
62 int file_mode = 0;
63
64 enum
65 {
66 mode_default, mode_shared, mode_max
67 };
68 static const char *(mode_name[]) =
69 {
70 "use child's own FS", "share parent's FS",};
71
72 InitFrameLoop(key);
73 while (WH_GetSystemState() == WH_SYSSTATE_IDLE)
74 {
75 WaitForNextFrame(key);
76
77 PrintString(3, 10, COLOR_WHITE, "Press A to connect as PARENT");
78 PrintString(2, 3, COLOR_GREEN, "<UP & DOWN key>");
79 PrintString(2, 4, COLOR_WHITE, "child's FS mode:");
80 for (i = 0; i < mode_max; ++i)
81 {
82 const BOOL focused = (i == file_mode);
83 PrintString(5, 5 + i, focused ? COLOR_YELLOW : COLOR_WHITE,
84 "%c%s", focused ? '>' : ' ', mode_name[i]);
85 }
86 PrintString(5, 5 + mode_max, COLOR_GRAY, " (overlay is always own.)");
87
88 /*
89 * Press Up and Down on the +Control Pad to select one of the following file system modes.
90 * - File system of the child program for DS Download Play
91 * - File system of the parent program
92 * The former is considered to be the normal mode, but the latter can be used to efficiently reduce ROM usage for applications that share most data resources between the parent and children.
93 *
94 *
95 *
96 * Note: In either case, however, the overlay information is always provided by the child program.
97 *
98 * Applications that share overlays must be configured to clone boot.
99 *
100 */
101 if ((key->trg & PAD_KEY_DOWN) && (++file_mode >= mode_max))
102 {
103 file_mode -= mode_max;
104 }
105 if ((key->trg & PAD_KEY_UP) && (--file_mode < 0))
106 {
107 file_mode += mode_max;
108 }
109
110 /*
111 * Use the A button to start wireless processing as a parent.
112 * In order for the WFS library to run using WM_SetPortCallback, call WFS_Init after WM_Initialize.
113 *
114 */
115 if (key->trg & PAD_BUTTON_A)
116 {
117 /*
118 * Loading a table is only effective for a parent.
119 * For children, the parent's file system table information is held by dynamically-allocated memory in the WFS library, so there is no reason to load this table again.
120 *
121 *
122 */
123 static BOOL table_loaded = FALSE;
124 if (!table_loaded)
125 {
126 u32 need_size = FS_GetTableSize();
127 void *p_table = OS_Alloc(need_size);
128 SDK_ASSERT(p_table != NULL);
129 table_loaded = FS_LoadTable(p_table, need_size);
130 if (!table_loaded && p_table)
131 {
132 OS_Free(p_table);
133 }
134 }
135
136 (void)WH_ParentConnect(WH_CONNECTMODE_MP_PARENT, 0x0000, 1);
137 /*
138 * The parent starts the WFS library and becomes the file server.
139 * The files and overlays requested by children during DS Download Play are all provided automatically by the parent through the WFS library.
140 *
141 */
142 {
143 FSFile file[1];
144 FS_InitFile(file);
145 if (!FS_OpenFileEx(file, "data/main.srl", FS_FILEMODE_R))
146 {
147 OS_TPanic("failed to open DS-downloaded program file!");
148 }
149 WFS_InitParent(port_wbt, StateCallbackForWFS, AllocatorForWFS,
150 NULL, parent_packet_max, file, (file_mode == mode_shared));
151 WFS_EnableSync(0);
152 (void)FS_CloseFile(file);
153 }
154 }
155 }
156 }
157
158 /*---------------------------------------------------------------------------*
159 Name: ModeParent
160
161 Description: Processing in parent communications screen.
162
163 Arguments: None.
164
165 Returns: None.
166 *---------------------------------------------------------------------------*/
ModeParent(void)167 void ModeParent(void)
168 {
169 KeyInfo key[1];
170
171 InitFrameLoop(key);
172 while (WH_GetSystemState() == WH_SYSSTATE_CONNECTED && WH_GetConnectMode() == WH_CONNECTMODE_MP_PARENT)
173 {
174
175 int parent_packet_size = WFS_GetPacketSize();
176 BOOL is_parent_sync = ((WFS_GetSyncBitmap() & ~1) == (WFS_GetCurrentBitmap() & ~1));
177
178 WaitForNextFrame(key);
179
180 PrintString(8, 1, COLOR_WHITE, "Parent mode");
181 PrintString(2, 20, COLOR_WHITE, "Press START to disconnect.");
182
183
184 {
185 /*
186 * Switch the packet size by pressing Up and Down.
187 *
188 * This simply affects the transfer speed.
189 * Note: When a change is made, it will not be applied to any processes in the middle of accessing data.
190 */
191 int new_packet_size = parent_packet_size;
192
193 if (key->trg & PAD_KEY_UP)
194 {
195 new_packet_size += 2;
196 if (new_packet_size > parent_packet_max)
197 new_packet_size = WBT_PACKET_SIZE_MIN + 2;
198 }
199 if (key->trg & PAD_KEY_DOWN)
200 {
201 new_packet_size -= 2;
202 if (new_packet_size < WBT_PACKET_SIZE_MIN + 2)
203 new_packet_size = (parent_packet_max & ~1);
204 }
205 if (parent_packet_size != new_packet_size)
206 {
207 parent_packet_size = new_packet_size;
208 WFS_SetPacketSize(parent_packet_size);
209 }
210 }
211
212 /*
213 * Press the A button to switch to synchronous mode.
214 *
215 * This will cause access to be blocked for the first child if even one of the children specified to be synchronous does not receive the request.
216 *
217 * This setting can make communications more efficient if it is clear that the same combination of files will be requested in the same order.
218 *
219 *
220 * This setting will be reset automatically and a warning message will be sent to debug output when a group of children has conflicting access requests.
221 *
222 */
223 if (key->trg & PAD_BUTTON_A)
224 {
225 is_parent_sync = !is_parent_sync;
226 WFS_EnableSync(is_parent_sync ? WFS_GetCurrentBitmap() : 0);
227 }
228
229 if (key->trg & PAD_BUTTON_START)
230 {
231 WH_Finalize();
232 while (WH_GetSystemState() != WH_SYSSTATE_IDLE) {}
233 }
234
235 /* Display the current configuration and connection state */
236 PrintString(3, 4, COLOR_GREEN, "<UP & DOWN key>");
237 PrintString(3, 5, COLOR_WHITE, "parent packet ... %d BYTE", parent_packet_size);
238
239 PrintString(3, 7, COLOR_GREEN, "<toggle A button>");
240 PrintString(3, 8, COLOR_WHITE, "sync mode ... %s",
241 is_parent_sync ? "ENABLE" : "DISABLE");
242
243 PrintString(3, 10, COLOR_GREEN, "bitmap status");
244 PrintString(5, 11, COLOR_GREEN, "- not connected");
245 PrintString(5, 12, COLOR_GREEN, "+ idle");
246 PrintString(5, 13, COLOR_GREEN, "* busy");
247 PrintString(5, 14, COLOR_GREEN, "! sync-blocking");
248
249 PrintString(12, 15, COLOR_BLUE, "0123456789ABCDEF");
250 {
251 int i;
252 const int cur_bitmap = WFS_GetCurrentBitmap();
253 const int busy_bitmap = WFS_GetBusyBitmap();
254 const int sync_bitmap = WFS_GetSyncBitmap();
255 for (i = 0; i < sizeof(u16) * 8; ++i)
256 {
257 char c;
258 const int bit = (1 << i);
259 if ((bit & busy_bitmap) != 0)
260 c = '*';
261 else if ((bit & cur_bitmap) != 0)
262 c = '+';
263 else
264 c = '-';
265 PrintString(12 + i, 16, COLOR_WHITE, "%c", c);
266 if ((bit & sync_bitmap) != 0)
267 PrintString(12 + i, 17, COLOR_WHITE, "!");
268 }
269 }
270 }
271 }
272
273
274 /*---------------------------------------------------------------------------*
275 End of file
276 *---------------------------------------------------------------------------*/
277