1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - WM - demos - wireless-all
3 File: common.c
4
5 Copyright 2006-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-09-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 #ifdef SDK_TWL
19 #include <twl.h>
20 #else
21 #include <nitro.h>
22 #endif
23
24 #include "common.h"
25
26
27 /*****************************************************************************/
28 /* Constants */
29
30 #define BGSTR_MAX_LENGTH 32
31
32 /* Text rendering data */
33 extern const u16 _binary_bg_plt_dat[16][16];
34 extern const u32 _binary_bg_chr_dat[8 * 0x100];
35
36
37 /*****************************************************************************/
38 /* Variables */
39
40 /* Channel */
41 static u16 current_channel = 0;
42
43 /* Key input */
44 static int own_aid;
45 static GShareData current_input[WH_PLAYER_MAX] ATTRIBUTE_ALIGN(32);
46 static BOOL valid_input[WH_PLAYER_MAX];
47 static GShareData next_input;
48 static u16 padPress;
49 static u16 padTrig;
50
51 /* Rendering variables */
52 static u16 vscr[32 * 32];
53 static GXOamAttr oamBak[128];
54
55
56 /*****************************************************************************/
57 /* Functions */
58
59 /*---------------------------------------------------------------------------*
60 Name: IS_PAD_PRESS
61
62 Description: Determines own key status.
63
64 Arguments: The key flag for determination
65
66 Returns: TRUE if the specified key is being pressed; FALSE otherwise.
67
68 *---------------------------------------------------------------------------*/
IS_PAD_PRESS(u16 flag)69 BOOL IS_PAD_PRESS(u16 flag)
70 {
71 return (padPress & flag) == flag;
72 }
73
74 /*---------------------------------------------------------------------------*
75 Name: IS_PAD_TRIGGER
76
77 Description: Determines own key trigger status.
78
79 Arguments: The key flag for determination
80
81 Returns: If the specified key trigger is enabled, TRUE.
82 If disabled, FALSE
83 *---------------------------------------------------------------------------*/
IS_PAD_TRIGGER(u16 flag)84 BOOL IS_PAD_TRIGGER(u16 flag)
85 {
86 return (padTrig & flag) == flag;
87 }
88
89 /*---------------------------------------------------------------------------*
90 Name: UpdateInput
91
92 Description: Updates key input.
93 Attempts data sharing when a wireless connection is established; otherwise, updates only its own key input.
94
95
96 Arguments: None.
97
98 Returns: Returns TRUE if key input updates are successful.
99 *---------------------------------------------------------------------------*/
UpdateInput(void)100 static BOOL UpdateInput(void)
101 {
102 BOOL retval = FALSE;
103
104 {
105 OSIntrMode bak_cpsr = OS_DisableInterrupts();
106 next_input.key = PAD_Read();
107 next_input.count = next_input.count + 1;
108 /* Sets own key input for cases other than data sharing */
109 if (WH_GetSystemState() != WH_SYSSTATE_DATASHARING)
110 {
111 own_aid = 0;
112 current_input[0] = next_input;
113 valid_input[0] = TRUE;
114 retval = TRUE;
115 }
116 /* For other cases, attempts data sharing */
117 else if (WH_StepDS(&next_input))
118 {
119 /* If successful, reflects everyone's input data */
120 u16 i;
121 for (i = 0; i < WH_PLAYER_MAX; ++i)
122 {
123 void *adr = WH_GetSharedDataAdr(i);
124 if (adr)
125 {
126 MI_CpuCopy8(adr, ¤t_input[i], sizeof(current_input[i]));
127 valid_input[i] = TRUE;
128 }
129 else
130 {
131 valid_input[i] = FALSE;
132 }
133 }
134 retval = TRUE;
135 own_aid = WH_GetCurrentAid();
136 }
137 (void)OS_RestoreInterrupts(bak_cpsr);
138 }
139
140 /* When input is updated, the key trigger is also updated */
141 if (retval && valid_input[own_aid])
142 {
143 padTrig = (u16)(~padPress & current_input[own_aid].key);
144 padPress = current_input[own_aid].key;
145 }
146
147 return retval;
148 }
149
150 /*---------------------------------------------------------------------------*
151 Name: GetCurrentInput
152
153 Description: Gets current key input of the specified player.
154
155 Arguments: aid: The player getting the key input
156
157 Returns: Returns a valid address if the latest data sharing succeeds; otherwise, returns NULL.
158
159 *---------------------------------------------------------------------------*/
GetCurrentInput(int aid)160 GShareData *GetCurrentInput(int aid)
161 {
162 return valid_input[aid] ? ¤t_input[aid] : NULL;
163 }
164
165 /*---------------------------------------------------------------------------*
166 Name: VBlankIntr
167
168 Description: Gets key trigger.
169
170 Arguments: None.
171
172 Returns: None.
173 *---------------------------------------------------------------------------*/
VBlankIntr(void)174 static void VBlankIntr(void)
175 {
176 /* OAM update */
177 DC_FlushRange(oamBak, sizeof(oamBak));
178 MI_DmaCopy32(3, oamBak, (void *)HW_OAM, sizeof(oamBak));
179 /* BG update */
180 DC_FlushRange(vscr, sizeof(vscr));
181 GX_LoadBG0Scr(vscr, 0, sizeof(vscr));
182
183 /* Interrupt check flag */
184 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
185 }
186
187 /*---------------------------------------------------------------------------*
188 Name: InitCommon
189
190 Description: Common initialization functions.
191
192 Arguments: None.
193
194 Returns: None.
195 *---------------------------------------------------------------------------*/
InitCommon(void)196 void InitCommon(void)
197 {
198 /* OS initialization */
199 OS_Init();
200 OS_InitTick();
201 OS_InitAlarm();
202 FX_Init();
203 {
204 void *tempLo;
205 OSHeapHandle hh;
206 tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
207 OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
208 hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
209 if (hh < 0)
210 {
211 OS_TPanic("ARM9: Fail to create heap...\n");
212 }
213 hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
214 }
215
216 /* Initializes key input */
217 MI_CpuClear8(&next_input, sizeof(next_input));
218 MI_CpuClear8(¤t_input, sizeof(current_input));
219 own_aid = 0;
220 (void)UpdateInput();
221
222 /* GX initialization */
223 GX_Init();
224 GX_DispOff();
225 GXS_DispOff();
226 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
227 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
228 (void)GX_DisableBankForLCDC();
229 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
230 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
231 MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
232 MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
233 /* OBJ (VRAM-B) */
234 GX_SetBankForOBJ(GX_VRAM_OBJ_128_B);
235 GX_SetOBJVRamModeChar(GX_OBJVRAMMODE_CHAR_1D_32K);
236 MI_DmaFill32(3, oamBak, 0xC0, sizeof(oamBak));
237 GX_LoadOBJ(_binary_bg_chr_dat, 0, sizeof(_binary_bg_chr_dat));
238 GX_LoadOBJPltt(_binary_bg_plt_dat, 0, sizeof(_binary_bg_plt_dat));
239 /* BG (VRAM-C) */
240 GX_SetBankForBG(GX_VRAM_BG_128_C);
241 G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0xf800, /* SCR base block 31 */
242 GX_BG_CHARBASE_0x00000, /* CHR base block 0 */
243 GX_BG_EXTPLTT_01);
244 G2_SetBG0Priority(0);
245 G2_BG0Mosaic(FALSE);
246 GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
247 G2_SetBG0Offset(0, 0);
248 GX_LoadBG0Char(_binary_bg_chr_dat, 0, sizeof(_binary_bg_chr_dat));
249 GX_LoadBGPltt(_binary_bg_plt_dat, 0, sizeof(_binary_bg_plt_dat));
250 MI_CpuFillFast((void *)vscr, 0, sizeof(vscr));
251 DC_FlushRange(vscr, sizeof(vscr));
252 DC_WaitWriteBufferEmpty();
253 GX_LoadBG0Scr(vscr, 0, sizeof(vscr));
254 GX_SetVisiblePlane(GX_PLANEMASK_BG0 | GX_PLANEMASK_OBJ);
255 GX_DispOn();
256 GXS_DispOn();
257
258 /* V-Blank interrupt configuration */
259 (void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
260 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
261 (void)GX_VBlankIntr(TRUE);
262 (void)OS_EnableIrq();
263 (void)OS_EnableInterrupts();
264
265 /* FS initialization */
266 if (!MB_IsMultiBootChild())
267 {
268 static u8 fs_tablework[0x100] ATTRIBUTE_ALIGN(32);
269 FS_Init(FS_DMA_NOT_USE);
270 (void)FS_LoadTable(fs_tablework, sizeof(fs_tablework));
271 }
272 }
273
274 /*---------------------------------------------------------------------------*
275 Name: GetCurrentChannel
276
277 Description: Gets the currently selected wireless channel.
278
279 Arguments: None.
280
281 Returns: Returns the currently selected wireless channel.
282 *---------------------------------------------------------------------------*/
GetCurrentChannel(void)283 u16 GetCurrentChannel(void)
284 {
285 return current_channel;
286 }
287
288 /*---------------------------------------------------------------------------*
289 Name: SetCurrentChannel
290
291 Description: Sets the current wireless channel.
292
293 Arguments: channel: Channel to be set
294
295 Returns: None.
296 *---------------------------------------------------------------------------*/
SetCurrentChannel(u16 channel)297 void SetCurrentChannel(u16 channel)
298 {
299 current_channel = channel;
300 }
301
302 /*---------------------------------------------------------------------------*
303 Name: LoadLinkIcon
304
305 Description: Loads the link icon into VRAM.
306
307 Arguments: id: The load target's character ID
308 palette: The load target's palette
309 level: The link strength
310
311 Returns: None.
312 *---------------------------------------------------------------------------*/
LoadLinkIcon(int id,int palette,int level)313 void LoadLinkIcon(int id, int palette, int level)
314 {
315 /* *INDENT-OFF* */
316 typedef struct Icon16Format
317 {
318 GXRgb palette[16];
319 u8 image[16 * 16 / 2];
320 }
321 IconFormat;
322 extern const IconFormat _binary_linkimg0_dat[];
323 extern const IconFormat _binary_linkimg1_dat[];
324 extern const IconFormat _binary_linkimg2_dat[];
325 extern const IconFormat _binary_linkimg3_dat[];
326 static const IconFormat * const table[4] =
327 { _binary_linkimg0_dat, _binary_linkimg1_dat, _binary_linkimg2_dat, _binary_linkimg3_dat, };
328 /* *INDENT-ON* */
329 GX_LoadOBJ(table[level]->image, (u32)(32 * id), 16 * 16 / 2);
330 GX_LoadOBJPltt(table[level]->palette, sizeof(GXRgb) * 16 * palette,
331 sizeof(table[level]->palette));
332 }
333
334 /*---------------------------------------------------------------------------*
335 Name: PrintString
336
337 Description: Draws BG text.
338
339 Arguments: x: The rendering x grid position
340 y: The rendering y grid position
341 palette: The palette index
342 format: The format string
343
344 Returns: None.
345 *---------------------------------------------------------------------------*/
PrintString(int x,int y,int palette,const char * format,...)346 void PrintString(int x, int y, int palette, const char *format, ...)
347 {
348 int i;
349 char tmp[BGSTR_MAX_LENGTH + 1] = { 0, };
350 va_list vlist;
351 va_start(vlist, format);
352 (void)OS_VSNPrintf(tmp, sizeof(tmp), format, vlist);
353 va_end(vlist);
354 y = y * 32 + x;
355 for (i = 0; (i < BGSTR_MAX_LENGTH) && tmp[i]; ++i)
356 {
357 vscr[(y + i) & ((32 * 32) - 1)] = (u16)((palette << 12) | tmp[i]);
358 }
359 }
360
361 /*---------------------------------------------------------------------------*
362 Name: WaitNextFrame
363
364 Description: Initializes rendering while waiting for the next picture frame.
365
366 Arguments: None.
367
368 Returns: Returns TRUE when key input is updated.
369 *---------------------------------------------------------------------------*/
WaitNextFrame(void)370 BOOL WaitNextFrame(void)
371 {
372 BOOL retval;
373 /* Standby for next picture frame */
374 OS_WaitVBlankIntr();
375 /* Updates key input */
376 retval = UpdateInput();
377 /* Clears the text */
378 MI_CpuClearFast(vscr, sizeof(vscr));
379 /* Displays the link strength icon */
380 LoadLinkIcon(512, PLTT_LINK_ICON, WM_GetLinkLevel());
381 G2_SetOBJAttr(&oamBak[64], 3, 3, 0,
382 GX_OAM_MODE_NORMAL, FALSE, GX_OAM_EFFECT_NONE,
383 GX_OAM_SHAPE_16x16, GX_OAM_COLOR_16, 512, PLTT_LINK_ICON, 0);
384 return retval;
385 }
386
387 /*---------------------------------------------------------------------------*
388 Name: WaitWHState
389
390 Description: Waits until entering the specified WH state.
391
392 Arguments: state: The state whose transition is awaited
393
394 Returns: None.
395 *---------------------------------------------------------------------------*/
WaitWHState(int state)396 void WaitWHState(int state)
397 {
398 while (WH_GetSystemState() != state)
399 {
400 (void)WaitNextFrame();
401 PrintString(3, 10, PLTT_WHITE, "WH working...");
402 PrintString(10, 16, PLTT_WHITE, "( to state %d )", state);
403 }
404 }
405