1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - WXC - demos - unregister-1
3   File:     main.c
4 
5   Copyright 2005-2009 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:: 2007-11-15#$
14   $Rev: 2414 $
15   $Author: hatamoto_minoru $
16  *---------------------------------------------------------------------------*/
17 
18 /*---------------------------------------------------------------------------*
19     This sample runs chance encounter communications over a wireless connection.
20     It automatically connects to the unregister-1 demo in the area.
21  *---------------------------------------------------------------------------*/
22 
23 #include <nitro.h>
24 
25 #include <nitro/wxc.h>
26 #include "user.h"
27 #include "font.h"
28 #include "text.h"
29 
30 /*---------------------------------------------------------------------------*
31     Constant Definitions
32  *---------------------------------------------------------------------------*/
33 #define     KEY_REPEAT_START    25     // Number of frames until key repeat starts
34 #define     KEY_REPEAT_SPAN     10     // Number of frames between key repeats
35 
36 
37 /*---------------------------------------------------------------------------*
38     Structure Definitions
39  *---------------------------------------------------------------------------*/
40 // Key input data
41 typedef struct KeyInfo
42 {
43     u16     cnt;                       // Unprocessed input value
44     u16     trg;                       // Push trigger input
45     u16     up;                        // Release trigger input
46     u16     rep;                       // Press and hold repeat input
47 
48 }
49 KeyInfo;
50 
51 /*---------------------------------------------------------------------------*
52     Internal Function Definitions
53  *---------------------------------------------------------------------------*/
54 static void ModeSelect(void);          // Parent/child select screen
55 static void VBlankIntr(void);          // V-Blank interrupt handler
56 
57 
58 
59 // General purpose subroutines
60 static void KeyRead(KeyInfo * pKey);
61 static void ClearString(int vram_num);
62 static void PrintString(s16 x, s16 y, u8 palette, char *text, ...);
63 static void InitializeAllocateSystem(void);
64 
65 
66 /*---------------------------------------------------------------------------*
67     Internal Variable Definitions
68  *---------------------------------------------------------------------------*/
69 static KeyInfo gKey;                   // Key input
70 static s32 gFrame;                     // Frame counter
71 
72 #define VRAM_SIZE 2*32*32
73 static u8 g_screen[NUM_OF_SCREEN][VRAM_SIZE] ATTRIBUTE_ALIGN(32);
74 
75 static TEXT_CTRL textctrl[NUM_OF_SCREEN];       // Number of text screens
76 TEXT_CTRL *tc[NUM_OF_SCREEN];          // Handled by the above pointer
77 
78 static int vram_num[2];                // Target text number of each of the upper and lower screens
79 
80 #define TEXT_HEAPBUF_SIZE 0x10000      // 2005/01/12 Redefined quite a bit (Terui)
81 static u8 text_heap_buffer[TEXT_HEAPBUF_SIZE] ATTRIBUTE_ALIGN(32);      // Buffer for text display
82 
83 
84 /*---------------------------------------------------------------------------*
85   Name:         NitroMain
86 
87   Description:  Initialization and main loop.
88 
89   Arguments:    None.
90 
91   Returns:      None.
92  *---------------------------------------------------------------------------*/
NitroMain(void)93 void NitroMain(void)
94 {
95     int     i;
96     // Various types of initialization
97     OS_Init();
98     OS_InitTick();
99 
100     (void)init_text_buf_sys((void *)&(text_heap_buffer[0]),
101                             (void *)&(text_heap_buffer[TEXT_HEAPBUF_SIZE]));
102 
103 
104     for (i = 0; i < NUM_OF_SCREEN; i++)
105     {
106         tc[i] = &(textctrl[i]);
107         init_text(tc[i], (u16 *)&(g_screen[i]), FONT_YELLOW /* Pal no. */ );
108     }
109 
110     FX_Init();
111 
112     /* Initializes display settings */
113 	{
114 		GX_Init();
115 		GX_DispOff();
116 		GXS_DispOff();
117         /* Clears VRAM. */
118 		GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
119 		MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
120 		(void)GX_DisableBankForLCDC();
121 		MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
122 		MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
123 		MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
124 		MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
125 		/*
126 		 * VRAM-A  = main-background
127 		 * VRAM-B  = main-OBJ
128 		 * VRAM-HI = sub-background
129 		 * VRAM-J  = sub-OBJ
130 		 */
131 		GX_SetBankForBG(GX_VRAM_BG_128_A);
132 		GX_SetBankForOBJ(GX_VRAM_OBJ_128_B);
133 		GX_SetBankForSubBG(GX_VRAM_SUB_BG_48_HI);
134 		GX_SetBankForSubOBJ(GX_VRAM_SUB_OBJ_128_D);
135 		/*
136 		 * Main screen:
137 		 *   BG0 = text-background
138 		 *   OBJ = 2D mode
139 		 */
140 		GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
141 		GX_SetVisiblePlane(GX_PLANEMASK_BG0 | GX_PLANEMASK_OBJ);
142 		GX_SetOBJVRamModeChar(GX_OBJVRAMMODE_CHAR_2D);
143 		G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16,
144                          GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x00000,
145 						 GX_BG_EXTPLTT_01);
146 		G2_SetBG0Priority(0);
147 		G2_BG0Mosaic(FALSE);
148 	    G2_SetBG0Offset(0, 0);
149 		GX_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
150 		GX_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
151 		/*
152 		 * Sub-screen:
153 		 *   BG0 = text-background
154 		 *   OBJ = 2D mode
155 		 */
156 		GXS_SetGraphicsMode(GX_BGMODE_0);
157 		GXS_SetVisiblePlane(GX_PLANEMASK_BG0 | GX_PLANEMASK_OBJ);
158 		GXS_SetOBJVRamModeChar(GX_OBJVRAMMODE_CHAR_2D);
159 		G2S_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16,
160                           GX_BG_SCRBASE_0xb800, GX_BG_CHARBASE_0x00000,
161 						  GX_BG_EXTPLTT_01);
162 		G2S_SetBG0Priority(0);
163 		G2S_BG0Mosaic(FALSE);
164         G2S_SetBG0Offset(0, 0);
165 		GXS_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
166 		GXS_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
167         /* Enable display */
168 		GX_DispOn();
169 		GXS_DispOn();
170 	}
171     /* V-Blank settings */
172     (void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
173     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
174     (void)OS_EnableIrq();
175     (void)OS_EnableInterrupts();
176     (void)GX_VBlankIntr(TRUE);
177 
178     /* Memory allocation initialization */
179     InitializeAllocateSystem();
180 
181     vram_num[0] = 0;                   /* Text number of the upper screen */
182     vram_num[1] = 1;                   /* Text number of the lower screen */
183 
184     /* Main loop */
185     for (gFrame = 0; TRUE; gFrame++)
186     {
187         text_buf_to_vram(tc[vram_num[0]]);
188         text_buf_to_vram(tc[vram_num[1]]);
189 
190         /* Get key input data */
191         KeyRead(&gKey);
192 
193         /* Distributes processes based on communication status */
194         switch (WXC_GetStateCode())
195         {
196         case WXC_STATE_END:
197             ModeSelect();
198             break;
199         case WXC_STATE_READY:
200 	        PrintString(9, 11, 0xf, "WXC ready.");
201             break;
202         case WXC_STATE_ACTIVE:
203 			if (WXC_IsParentMode())
204 			{
205 	            PrintString(9, 11, 0xf, "Now parent...");
206 			}
207 			else
208 			{
209 				PrintString(9, 11, 0xf, "Now child...");
210 			}
211             break;
212         case WXC_STATE_ENDING:
213 	        PrintString(9, 11, 0xf, "WXC ending...");
214             break;
215         }
216         if (gKey.trg & PAD_BUTTON_START)
217         {
218             //********************************
219             (void)WXC_End();
220             //********************************
221         }
222 
223         // Waiting for the V-Blank
224         OS_WaitVBlankIntr();
225     }
226 }
227 
228 /*---------------------------------------------------------------------------*
229   Name:         ModeSelect
230 
231   Description:  Processing in parent/child selection screen.
232 
233   Arguments:    None.
234 
235   Returns:      None.
236  *---------------------------------------------------------------------------*/
ModeSelect(void)237 static void ModeSelect(void)
238 {
239     PrintString(3, 10, 0xf, "Push A to start");
240 
241     if (gKey.trg & PAD_BUTTON_A)
242     {
243         /* Initializes, registers, and runs chance encounter communications */
244         User_Init();
245     }
246 }
247 
248 /*---------------------------------------------------------------------------*
249   Name:         VBlankIntr
250 
251   Description:  V-Blank interrupt handler.
252 
253   Arguments:    None.
254 
255   Returns:      None.
256  *---------------------------------------------------------------------------*/
VBlankIntr(void)257 static void VBlankIntr(void)
258 {
259     DC_FlushRange(&(g_screen[vram_num[0]]), VRAM_SIZE);
260     GX_LoadBG0Scr(&(g_screen[vram_num[0]]), 0, VRAM_SIZE);
261 
262     DC_FlushRange(&(g_screen[vram_num[1]]), VRAM_SIZE);
263     GXS_LoadBG0Scr(&(g_screen[vram_num[1]]), 0, VRAM_SIZE);
264 
265     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
266 }
267 
268 /*---------------------------------------------------------------------------*
269   Name:         KeyRead
270 
271   Description:  Edits key input data.
272                 Detects press trigger, release trigger, and press-and-hold repeat.
273 
274   Arguments:    pKey: Structure that holds key input data to be edited
275 
276   Returns:      None.
277  *---------------------------------------------------------------------------*/
KeyRead(KeyInfo * pKey)278 static void KeyRead(KeyInfo * pKey)
279 {
280     static u16 repeat_count[12];
281     int     i;
282     u16     r;
283 
284     r = PAD_Read();
285     pKey->trg = 0x0000;
286     pKey->up = 0x0000;
287     pKey->rep = 0x0000;
288 
289     for (i = 0; i < 12; i++)
290     {
291         if (r & (0x0001 << i))
292         {
293             if (!(pKey->cnt & (0x0001 << i)))
294             {
295                 pKey->trg |= (0x0001 << i);     // Press trigger
296                 repeat_count[i] = 1;
297             }
298             else
299             {
300                 if (repeat_count[i] > KEY_REPEAT_START)
301                 {
302                     pKey->rep |= (0x0001 << i); // Press-and-hold repeat
303                     repeat_count[i] = KEY_REPEAT_START - KEY_REPEAT_SPAN;
304                 }
305                 else
306                 {
307                     repeat_count[i]++;
308                 }
309             }
310         }
311         else
312         {
313             if (pKey->cnt & (0x0001 << i))
314             {
315                 pKey->up |= (0x0001 << i);      // Release trigger
316             }
317         }
318     }
319     pKey->cnt = r;                     // Unprocessed key input
320 }
321 
322 /*---------------------------------------------------------------------------*
323   Name:         ClearString
324 
325   Description:  Clears the virtual screen.
326 
327   Arguments:    None.
328 
329   Returns:      None.
330  *---------------------------------------------------------------------------*/
ClearString(int vram_num)331 static void ClearString(int vram_num)
332 {
333     MI_DmaClear32(0, (void *)&(g_screen[vram_num]), VRAM_SIZE);
334 }
335 
336 
337 /*---------------------------------------------------------------------------*
338   Name:         PrintString
339 
340   Description:  Positions the text string on the virtual screen. The string can be up to 32 chars.
341 
342   Arguments:    x: X-coordinate where character string starts (x 8 dots)
343                 y: Y-coordinate where character string starts (x 8 dots)
344                 palette: Specify text color by palette number
345                 text: Text string to position. Null-terminated.
346                 ...: Virtual argument
347 
348   Returns:      None.
349  *---------------------------------------------------------------------------*/
PrintString(s16 x,s16 y,u8 palette,char * text,...)350 static void PrintString(s16 x, s16 y, u8 palette, char *text, ...)
351 {
352     va_list vlist;
353     char    temp[32 + 2];
354     s32     i;
355 
356     va_start(vlist, text);
357     (void)OS_VSNPrintf(temp, 32, text, vlist);
358     va_end(vlist);
359     *(u16 *)(&temp[31]) = 0x0000;
360     for (i = 0;; i++)
361     {
362         if (temp[i] == 0x00)
363         {
364             break;
365         }
366         tc[1]->screen[(y * 32) + x + i] = (u16)((palette << 12) | temp[i]);
367     }
368 }
369 
370 
371 /*---------------------------------------------------------------------------*
372   Name:         InitializeAllocateSystem
373 
374   Description:  Initializes the memory allocation system in the main memory arena.
375 
376   Arguments:    None.
377 
378   Returns:      None.
379  *---------------------------------------------------------------------------*/
InitializeAllocateSystem(void)380 static void InitializeAllocateSystem(void)
381 {
382     void   *tempLo;
383     OSHeapHandle hh;
384 
385     mprintf(" arena lo = %08x\n", OS_GetMainArenaLo());
386     mprintf(" arena hi = %08x\n", OS_GetMainArenaHi());
387 
388     tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
389     OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
390     hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
391     if (hh < 0)
392     {
393         OS_Panic("ARM9: Fail to create heap...\n");
394     }
395     hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
396 }
397 
398 
399 /*---------------------------------------------------------------------------*
400   End of file
401  *---------------------------------------------------------------------------*/
402