1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - CHT - demos - catch-2
3   File:     main.c
4 
5   Copyright 2003-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     This demo uses the PictoChat search feature to detect the beacon from the PictoChat parent
20  *---------------------------------------------------------------------------*/
21 
22 #include    <nitro.h>
23 #include    <nitro/wm.h>
24 #include    <nitro/cht.h>
25 
26 #include    "font.h"
27 #include    "icon.h"
28 #include    "wh.h"
29 
30 
31 /*---------------------------------------------------------------------------*
32     Constant Definitions
33  *---------------------------------------------------------------------------*/
34 #define     KEY_REPEAT_START    25     // Number of frames until key repeat starts
35 #define     KEY_REPEAT_SPAN     10     // Number of frames between key repeats
36 
37 #define     DEFAULT_GGID            0x003fff62
38 #define     NUM_MAX_CHILD           15
39 #define     DEFAULT_CHAN            1
40 #define     PARENT_DATA_SIZE        4
41 #define     CHILD_DATA_SIZE         4
42 
43 #define     PICTO_CATCH_LIFETIME    300 // 5 seconds
44 
45 
46 /*---------------------------------------------------------------------------*
47     Structure Definitions
48  *---------------------------------------------------------------------------*/
49 // Key input data
50 typedef struct KeyInfo
51 {
52     u16     cnt;                       // Unprocessed input value
53     u16     trg;                       // Push trigger input
54     u16     up;                        // Release trigger input
55     u16     rep;                       // Press and hold repeat input
56 
57 }
58 KeyInfo;
59 
60 typedef struct PictoCatchInfo
61 {
62     int     lifeTime;
63     int     clientNum;
64 
65 }
66 PictoCatchInfo;
67 
68 
69 /*---------------------------------------------------------------------------*
70     Internal Function Definitions
71  *---------------------------------------------------------------------------*/
72 // Parent discovery callback
73 static void FoundParentCallback(WMBssDesc *pBssDesc);
74 
75 // V-Blank interrupt handler
76 static void VBlankIntr(void);
77 
78 // General purpose subroutines
79 static void KeyRead(KeyInfo * pKey);
80 static void ClearString(void);
81 static void PrintString(s16 x, s16 y, u8 palette, char *text, ...);
82 static void ColorString(s16 x, s16 y, s16 length, u8 palette);
83 static void InitializeAllocateSystem(void);
84 static void DrawIcon(u8 index, int charName, int x, int y);
85 
86 
87 /*---------------------------------------------------------------------------*
88     Internal Variable Definitions
89  *---------------------------------------------------------------------------*/
90 static u16 gScreen[32 * 32] ATTRIBUTE_ALIGN(32);
91 static GXOamAttr gOam[128] ATTRIBUTE_ALIGN(32);
92 static KeyInfo gKey;                   // Key input
93 static s32 gFrame;                     // Frame counter
94 
95 static PictoCatchInfo gRoom[4];
96 
97 
98 /*---------------------------------------------------------------------------*
99   Name:         NitroMain
100 
101   Description:  Initialization and main loop.
102 
103   Arguments:    None.
104 
105   Returns:      None.
106  *---------------------------------------------------------------------------*/
NitroMain(void)107 void NitroMain(void)
108 {
109     // Various types of initialization
110     OS_Init();
111     FX_Init();
112     GX_Init();
113     GX_DispOff();
114     GXS_DispOff();
115 
116     // Initializes display settings
117     GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
118     MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
119     (void)GX_DisableBankForLCDC();
120     MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
121     MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
122     MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
123     MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
124 
125     // 2D display settings for text string display
126     GX_SetBankForBG(GX_VRAM_BG_128_A);
127     G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0xf800,      // SCR base block 31
128                      GX_BG_CHARBASE_0x00000,    // CHR base block 0
129                      GX_BG_EXTPLTT_01);
130     GX_SetBankForOBJ(GX_VRAM_OBJ_16_F);
131     GX_SetOBJVRamModeChar(GX_OBJVRAMMODE_CHAR_1D_32K);
132     G2_SetBG0Priority(0);
133     G2_BG0Mosaic(FALSE);
134     GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
135     GX_SetVisiblePlane(GX_PLANEMASK_BG0 | GX_PLANEMASK_OBJ);
136     GX_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
137     GX_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
138     GX_LoadOBJ(icons_character, 0, sizeof(icons_character));
139     GX_LoadOBJPltt(icons_palette, 0, sizeof(icons_palette));
140     MI_CpuFillFast((void *)gScreen, 0, sizeof(gScreen));
141     DC_FlushRange(gScreen, sizeof(gScreen));
142     /* I/O register is accessed using DMA operation, so cache wait is not needed */
143     // DC_WaitWriteBufferEmpty();
144     GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
145 
146     // Interrupt settings
147     OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
148     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
149     (void)GX_VBlankIntr(TRUE);
150     (void)OS_EnableIrq();
151     (void)OS_EnableInterrupts();
152 
153     // Memory allocation
154     InitializeAllocateSystem();
155 
156     //********************************
157     // Initialize wireless
158     if (!WH_Initialize())
159     {
160         OS_Panic("WH_Initialize failed.");
161     }
162 
163     WH_SetGgid(DEFAULT_GGID);
164     // Enable PictoChat search feature
165     WH_TurnOnPictoCatch();
166 
167     //
168     while (WH_GetSystemState() != WH_SYSSTATE_IDLE) {}
169 
170     // Start search for parent
171     {
172         static const u8 ANY_PARENT[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
173         (void)WH_StartScan(FoundParentCallback, ANY_PARENT, 0);
174     }
175     //********************************
176 
177     // LCD display start
178     GX_DispOn();
179     GXS_DispOn();
180 
181     // Debug string output
182     OS_Printf("ARM9: CHT catch-2 demo started.\n");
183 
184     // Empty call for getting key input data (strategy for pressing A Button in the IPL)
185     KeyRead(&gKey);
186 
187     // Main loop
188     for (gFrame = 0; TRUE; gFrame++)
189     {
190         // Get key input data
191         KeyRead(&gKey);
192 
193         // Clear the screen
194         ClearString();
195 
196         // Display
197         PrintString(1, 1, 0xf, "frame: %d", gFrame);
198         {
199             s32     i;
200 
201             for (i = 0; i < 4; i++)
202             {
203                 if (gRoom[i].lifeTime > 0)
204                 {
205                     gRoom[i].lifeTime--;
206                     PrintString(1, (s16)(6 + (3 * i)), 0xf, "Discover pictochat room%d", i);
207                     PrintString(2, (s16)(7 + (3 * i)), 0x2, "%d members", gRoom[i].clientNum);
208                     // Display icon
209                     DrawIcon((u8)i, 9, 208, (s16)(48 + (24 * i)));
210                 }
211                 else
212                 {
213                     PrintString(10, (s16)(6 + (3 * i)), 0xe, "pictochat room%d", i);
214                 }
215             }
216         }
217 
218         // Waiting for the V-Blank
219         OS_WaitVBlankIntr();
220     }
221 }
222 
223 /*---------------------------------------------------------------------------*
224   Name:         FoundParentCallback
225 
226   Description:  The callback function that is invoked when a parent is found.
227 
228   Arguments:    pBssDesc:      Pointer to beacon information of found parent.
229 
230   Returns:      None.
231  *---------------------------------------------------------------------------*/
FoundParentCallback(WMBssDesc * pBssDesc)232 static void FoundParentCallback(WMBssDesc *pBssDesc)
233 {
234     if (CHT_IsPictochatParent(pBssDesc))
235     {
236         int     clientNum;
237         int     roomNumber;
238 
239         clientNum = CHT_GetPictochatClientNum(pBssDesc);
240         roomNumber = CHT_GetPictochatRoomNumber(pBssDesc);
241         if (roomNumber < 4)
242         {
243             if (gRoom[roomNumber].lifeTime == 0)
244             {
245                 /* SE should start here */
246             }
247             gRoom[roomNumber].clientNum = clientNum;
248             gRoom[roomNumber].lifeTime = PICTO_CATCH_LIFETIME;
249         }
250     }
251 }
252 
253 /*---------------------------------------------------------------------------*
254   Name:         VBlankIntr
255 
256   Description:  V-Blank interrupt vector.
257 
258   Arguments:    None.
259 
260   Returns:      None.
261  *---------------------------------------------------------------------------*/
VBlankIntr(void)262 static void VBlankIntr(void)
263 {
264     // Reflect virtual screen in VRAM
265     DC_FlushRange(gScreen, sizeof(gScreen));
266     /* I/O register is accessed using DMA operation, so cache wait is not needed */
267     // DC_WaitWriteBufferEmpty();
268     GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
269 
270     // Reflect virtual OAM in OAM
271     DC_FlushRange(gOam, sizeof(gOam));
272     /* I/O register is accessed using DMA operation, so cache wait is not needed */
273     // DC_WaitWriteBufferEmpty();
274     GX_LoadOAM(gOam, 0, sizeof(gOam));
275 
276     // sets the IRQ check flag
277     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
278 }
279 
280 /*---------------------------------------------------------------------------*
281   Name:         KeyRead
282 
283   Description:  Edits key input data.
284                 Detects press trigger, release trigger, and press-and-hold repeat.
285 
286   Arguments:    pKey:   Structure that holds key input data to be edited.
287 
288   Returns:      None.
289  *---------------------------------------------------------------------------*/
KeyRead(KeyInfo * pKey)290 static void KeyRead(KeyInfo * pKey)
291 {
292     static u16 repeat_count[12];
293     int     i;
294     u16     r;
295 
296     r = PAD_Read();
297     pKey->trg = 0x0000;
298     pKey->up = 0x0000;
299     pKey->rep = 0x0000;
300 
301     for (i = 0; i < 12; i++)
302     {
303         if (r & (0x0001 << i))
304         {
305             if (!(pKey->cnt & (0x0001 << i)))
306             {
307                 pKey->trg |= (0x0001 << i);     // Press trigger
308                 repeat_count[i] = 1;
309             }
310             else
311             {
312                 if (repeat_count[i] > KEY_REPEAT_START)
313                 {
314                     pKey->rep |= (0x0001 << i); // Press-and-hold repeat
315                     repeat_count[i] = KEY_REPEAT_START - KEY_REPEAT_SPAN;
316                 }
317                 else
318                 {
319                     repeat_count[i]++;
320                 }
321             }
322         }
323         else
324         {
325             if (pKey->cnt & (0x0001 << i))
326             {
327                 pKey->up |= (0x0001 << i);      // Release trigger
328             }
329         }
330     }
331     pKey->cnt = r;                     // Unprocessed key input
332 }
333 
334 /*---------------------------------------------------------------------------*
335   Name:         ClearString
336 
337   Description:  Clears the virtual screen.
338 
339   Arguments:    None.
340 
341   Returns:      None.
342  *---------------------------------------------------------------------------*/
ClearString(void)343 static void ClearString(void)
344 {
345     s32     i;
346 
347     MI_CpuClearFast((void *)gScreen, sizeof(gScreen));
348     for (i = 0; i < 128; i++)
349     {
350         G2_SetOBJPosition(&gOam[i], 256, 192);
351     }
352 }
353 
354 /*---------------------------------------------------------------------------*
355   Name:         PrintString
356 
357   Description:  Positions the text string on the virtual screen. The string can be up to 32 chars.
358 
359   Arguments:    x:         X-coordinate where character string starts (x 8 dots).
360                 y:         Y-coordinate where character string starts (x 8 dots).
361                 palette:   Specify text color by palette number.
362                 text:      Text string to position. Null-terminated.
363                 ...:       Virtual argument.
364 
365   Returns:      None.
366  *---------------------------------------------------------------------------*/
PrintString(s16 x,s16 y,u8 palette,char * text,...)367 static void PrintString(s16 x, s16 y, u8 palette, char *text, ...)
368 {
369     va_list vlist;
370     char    temp[32 + 2];
371     s32     i;
372 
373     va_start(vlist, text);
374     (void)vsnprintf(temp, 33, text, vlist);
375     va_end(vlist);
376 
377     *(u16 *)(&temp[32]) = 0x0000;
378     for (i = 0;; i++)
379     {
380         if (temp[i] == 0x00)
381         {
382             break;
383         }
384         gScreen[((y * 32) + x + i) % (32 * 32)] = (u16)((palette << 12) | temp[i]);
385     }
386 }
387 
388 /*---------------------------------------------------------------------------*
389   Name:         ColorString
390 
391   Description:  Changes the color of character strings printed on the virtual screen.
392 
393   Arguments:    x:        X-coordinate (x 8 dots ) from which to start color change.
394                 y:        Y-coordinate (x 8 dots ) from which to start color change.
395                 length:   Number of characters to continue the color change for.
396                 palette:  Specify text color by palette number.
397 
398   Returns:      None.
399  *---------------------------------------------------------------------------*/
ColorString(s16 x,s16 y,s16 length,u8 palette)400 static void ColorString(s16 x, s16 y, s16 length, u8 palette)
401 {
402     s32     i;
403     u16     temp;
404     s32     index;
405 
406     if (length < 0)
407         return;
408 
409     for (i = 0; i < length; i++)
410     {
411         index = ((y * 32) + x + i) % (32 * 32);
412         temp = gScreen[index];
413         temp &= 0x0fff;
414         temp |= (palette << 12);
415         gScreen[index] = temp;
416     }
417 }
418 
419 /*---------------------------------------------------------------------------*
420   Name:         DrawIcon
421 
422   Description:  Display icon.
423 
424   Arguments:    index:       Virtual OAM array index.
425                 charName:    Icon number.
426                                 0 - 3: Icons of signal strength against white background.
427                                 4 - 7: Icons of signal strength against black background.
428                                 8: Communications icon
429                                 9: PictoChat icon
430                 x:           X-coordinate position in dots
431                 y:           Y-coordinate position in dots
432 
433   Returns:      None.
434  *---------------------------------------------------------------------------*/
DrawIcon(u8 index,int charName,int x,int y)435 static void DrawIcon(u8 index, int charName, int x, int y)
436 {
437     G2_SetOBJAttr(&gOam[index],        // Pointer to OAM structure to edit
438                   x,                   // X position
439                   y,                   // Y position
440                   0,                   // Highest display priority
441                   GX_OAM_MODE_NORMAL,  // Normal OBJ
442                   FALSE,               // No mosaic
443                   GX_OAM_EFFECT_NONE,  // No effects
444                   GX_OAM_SHAPE_16x16,  // 2 x 2 character
445                   GX_OAM_COLORMODE_16, // 16-color palette
446                   charName * 4,        // Character number
447                   0,                   // Palette number 0
448                   0                    // Affine transformation index (disabled)
449         );
450 }
451 
452 /*---------------------------------------------------------------------------*
453   Name:         InitializeAllocateSystem
454 
455   Description:  Initializes the memory allocation system within the main memory arena.
456 
457   Arguments:    None.
458 
459   Returns:      None.
460  *---------------------------------------------------------------------------*/
InitializeAllocateSystem(void)461 static void InitializeAllocateSystem(void)
462 {
463     void   *tempLo;
464     OSHeapHandle hh;
465 
466     // Based on the premise that OS_Init has been already called
467     tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
468     OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
469     hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
470     if (hh < 0)
471     {
472         OS_Panic("ARM9: Fail to create heap...\n");
473     }
474     hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
475 }
476 
477 /*---------------------------------------------------------------------------*
478   End of file
479  *---------------------------------------------------------------------------*/
480