1 /*---------------------------------------------------------------------------*
2   Project:  TWLSDK - demos - FS - overlay-staticinit
3   File:     main.c
4 
5   Copyright 2007-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-11-14 #$
14   $Rev: 9314 $
15   $Author: yosizaki $
16  *---------------------------------------------------------------------------*/
17 
18 
19 #include <nitro.h>
20 
21 #include "DEMO.h"
22 
23 /* Interface for each mode */
24 #include "mode.h"
25 
26 
27 /*---------------------------------------------------------------------------*/
28 /* Constants */
29 
30 // Constants for automatic sampling
31 #define     SAMPLING_FREQUENCE      4
32 #define     SAMPLING_BUFSIZE        (SAMPLING_FREQUENCE + 1)
33 #define     SAMPLING_START_VCOUNT   0
34 
35 
36 /*---------------------------------------------------------------------------*/
37 /* Variables */
38 
39 // Interface for each mode
40 BOOL    (*UpdateFrame) (int frame_count, const InputData * input, int player_count,
41                         int own_player_id);
42 void    (*DrawFrame) (int frame);
43 void    (*EndFrame) (FSOverlayID *p_next_mode);
44 
45 // Automatic sampling buffer for the touch panel
46 static TPData tp_auto_buf[SAMPLING_BUFSIZE];
47 
48 
49 /*---------------------------------------------------------------------------*/
50 /* functions */
51 
52 /*---------------------------------------------------------------------------*
53   Name:         InitApp
54 
55   Description:  Initialize the basic parts of the application.
56 
57   Arguments:    None.
58 
59   Returns:      None.
60  *---------------------------------------------------------------------------*/
InitApp(void)61 static void InitApp(void)
62 {
63     OS_Init();
64     (void)OS_EnableIrq();
65     (void)OS_EnableInterrupts();
66     FS_Init(FS_DMA_NOT_USE);
67 
68     // Initialize the touch panel
69     {
70         TPCalibrateParam calibrate;
71         TP_Init();
72         if (TP_GetUserInfo(&calibrate))
73         {
74             TP_SetCalibrateParam(&calibrate);
75         }
76         (void)TP_RequestAutoSamplingStart(SAMPLING_START_VCOUNT, SAMPLING_FREQUENCE, tp_auto_buf,
77                                           SAMPLING_BUFSIZE);
78     }
79 
80     DEMOInitCommon();
81     DEMOInitVRAM();
82     DEMOInitDisplayBitmap();
83     DEMOHookConsole();
84 
85     // Switch the GX settings to use the Touch Screen for the main display
86     GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
87 
88     DEMOSetBitmapTextColor(GX_RGBA(31, 31, 0, 1));
89     DEMOSetBitmapGroundColor(DEMO_RGB_CLEAR);
90     DEMOStartDisplay();
91 }
92 
93 /*---------------------------------------------------------------------------*
94   Name:         GetInput
95 
96   Description:  Gets the current input state.
97 
98   Arguments:    input: Location that stores the obtained information
99 
100   Returns:      None.
101  *---------------------------------------------------------------------------*/
GetInput(InputData * input)102 static void GetInput(InputData * input)
103 {
104     if (input)
105     {
106         const u16 hold_bak = input->hold_bits;
107         u16     hold_bits;
108         // Update the touch panel information
109         const TPData *const cur_tp = tp_auto_buf + TP_GetLatestIndexInAuto();
110         if (cur_tp->touch == TP_TOUCH_OFF)
111         {
112             input->tp.touch = TP_TOUCH_OFF;
113         }
114         else if (cur_tp->validity == TP_VALIDITY_VALID)
115         {
116             TP_GetCalibratedPoint(&input->tp, cur_tp);
117         }
118         // Update the pad information (and the stylus touch bit)
119         hold_bits = (u16)(PAD_Read() | (input->tp.touch ? PAD_BUTTON_TP : 0));
120         input->push_bits = (u16)(~hold_bak & hold_bits);
121         input->hold_bits = hold_bits;
122         input->release_bits = (u16)(hold_bak & ~hold_bits);
123     }
124 }
125 
126 /*---------------------------------------------------------------------------*
127   Name:         NitroMain
128 
129   Description:  Main entry point to application.
130 
131   Arguments:    None.
132 
133   Returns:      None.
134  *---------------------------------------------------------------------------*/
NitroMain(void)135 void NitroMain(void)
136 {
137     // Initialize the application framework and screen transition state
138     int         player_count = 1;
139     int         own_player_id;
140     InputData   input[1];
141     FSOverlayID cur_mode;
142     FSOverlayID prev_mode;
143     FS_EXTERN_OVERLAY(top_menu);
144 
145     InitApp();
146     cur_mode = FS_OVERLAY_ID(top_menu);
147     prev_mode = FS_OVERLAY_ID(top_menu);
148     UpdateFrame = NULL;
149     DrawFrame = NULL;
150     EndFrame = NULL;
151     MI_CpuClear8(input, sizeof(input));
152     player_count = 1;
153     own_player_id = 0;
154 
155     // Create each mode as overlay and repeatedly change between them
156     for (;;)
157     {
158         // Start the current mode.
159         // As loading completes, automatic initialization will be run in NitroStaticInit() and the required interfaces will configure themselves.
160         // In UpdateFrame, the current mode will return conditions for ending the mode.
161         //
162         {
163             int     frame = 0;
164             if (!FS_LoadOverlay(MI_PROCESSOR_ARM9, cur_mode))
165             {
166                 OS_TPanic("failed to load specified mode(%08X)", cur_mode);
167             }
168             GetInput(&input[own_player_id]);
169             for (;;)
170             {
171                 GetInput(&input[own_player_id]);
172                 if (!UpdateFrame(frame, input, player_count, own_player_id))
173                 {
174                     break;
175                 }
176                 DrawFrame(frame);
177                 DEMO_DrawFlip();
178                 OS_WaitVBlankIntr();
179                 ++frame;
180             }
181         }
182         // End the current mode and transition to the next one.
183         // If the current mode has not explicitly set a mode to transition to, it will return to the previous mode.
184         //
185         {
186             FSOverlayID next_mode = prev_mode;
187             EndFrame(&next_mode);
188             if (!FS_UnloadOverlay(MI_PROCESSOR_ARM9, cur_mode))
189             {
190                 OS_TPanic("failed to unload specified mode(%08X)", cur_mode);
191             }
192             prev_mode = cur_mode;
193             cur_mode = next_mode;
194         }
195     }
196 
197 }
198