1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - MB - demos - multiboot-wfs - common
3   File:     util.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-09-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 
19 #ifdef SDK_TWL
20 #include	<twl.h>
21 #else
22 #include	<nitro.h>
23 #endif
24 
25 #include    "util.h"
26 
27 
28 /*---------------------------------------------------------------------------*
29     Internal Variable Definitions
30  *---------------------------------------------------------------------------*/
31 
32 static u16 gScreen[32 * 32];           /* Virtual screen */
33 static u16 repeat_count[12];           /* Key repeat */
34 static char recent_output[24][32 + 1];
35 
36 
37 /*---------------------------------------------------------------------------*
38   Name:         InitializeAllocateSystem
39 
40   Description:  Initializes memory allocation system in the main memory arena.
41 
42   Arguments:    None.
43 
44   Returns:      None.
45  *---------------------------------------------------------------------------*/
InitializeAllocateSystem(void)46 static void InitializeAllocateSystem(void)
47 {
48     void   *tempLo;
49     OSHeapHandle hh;
50 
51     tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
52     OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
53     hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
54     if (hh < 0)
55     {
56         OS_Panic("ARM9: Fail to create heap...\n");
57     }
58     hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
59 }
60 
61 
62 /*---------------------------------------------------------------------------*
63   Name:         VBlankIntr
64 
65   Description:  V-Blank interrupt vector.
66 
67   Arguments:    None.
68 
69   Returns:      None.
70  *---------------------------------------------------------------------------*/
VBlankIntr(void)71 static void VBlankIntr(void)
72 {
73     /* Reflect virtual screen in VRAM */
74     DC_FlushRange(gScreen, sizeof(gScreen));
75     /* I/O register is accessed using DMA operation, so cache wait is not needed */
76     // DC_WaitWriteBufferEmpty();
77     GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
78 
79     /* Sets the IRQ check flag */
80     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
81 }
82 
83 
84 /*---------------------------------------------------------------------------*
85   Name:         UTIL_Init
86 
87   Description:  Initializes sample framework
88 
89   Arguments:    None.
90 
91   Returns:      None.
92  *---------------------------------------------------------------------------*/
UTIL_Init(void)93 void UTIL_Init(void)
94 {
95     /* Various types of initialization */
96     OS_Init();
97     OS_InitTick();
98 
99     FX_Init();
100     GX_Init();
101     GX_DispOff();
102     GXS_DispOff();
103 
104     /* Initializes display settings */
105     GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
106     MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
107     (void)GX_DisableBankForLCDC();
108     MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
109     MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
110     MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
111     MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
112 
113     /* 2D display settings for text string display */
114     GX_SetBankForBG(GX_VRAM_BG_128_A);
115     G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256,
116                      GX_BG_COLORMODE_16,
117                      GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
118     G2_SetBG0Priority(0);
119     G2_BG0Mosaic(FALSE);
120     GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
121     GX_SetVisiblePlane(GX_PLANEMASK_BG0);
122     GX_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
123     GX_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
124 
125     MI_CpuFillFast((void *)gScreen, 0, sizeof(gScreen));
126     DC_FlushRange(gScreen, sizeof(gScreen));
127     /* I/O register is accessed using DMA operation, so cache wait is not needed */
128     // DC_WaitWriteBufferEmpty();
129     GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
130 
131     /* Interrupt settings */
132     OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
133     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
134     (void)GX_VBlankIntr(TRUE);
135     (void)OS_EnableIrq();
136     (void)OS_EnableInterrupts();
137 
138     /* Memory allocation */
139     InitializeAllocateSystem();
140 }
141 
142 
143 /*---------------------------------------------------------------------------*
144   Name:         KeyRead
145 
146   Description:  Gets key data
147 
148   Arguments:    pKey: Address at which key information is stored
149 
150   Returns:      None.
151  *---------------------------------------------------------------------------*/
KeyRead(KeyInfo * pKey)152 void KeyRead(KeyInfo * pKey)
153 {
154     enum
155     {
156         KEY_BIT_MAX = 12,
157         KEY_REPEAT_START = 25,         /* Number of frames until key repeat starts */
158         KEY_REPEAT_SPAN = 10           /* Number of frames between key repeats */
159     };
160 
161     int     i;
162     const u16 r = PAD_Read();
163     pKey->trg = 0x0000;
164     pKey->up = 0x0000;
165     pKey->rep = 0x0000;
166 
167     for (i = 0; i < KEY_BIT_MAX; ++i)
168     {
169         const u16 bit = (u16)(1 << i);
170         if ((r & bit) != 0)
171         {
172             if (!(pKey->cnt & bit))
173             {
174                 pKey->trg |= bit;
175                 repeat_count[i] = 1;
176             }
177             else if (repeat_count[i] > KEY_REPEAT_START)
178             {
179                 pKey->rep |= bit;
180                 repeat_count[i] = KEY_REPEAT_START - KEY_REPEAT_SPAN;
181             }
182             else
183             {
184                 ++repeat_count[i];
185             }
186         }
187         else if ((pKey->cnt & bit) != 0)
188         {
189             pKey->up |= bit;
190         }
191     }
192     pKey->cnt = r;
193 }
194 
195 /*---------------------------------------------------------------------------*
196   Name:         ClearString
197 
198   Description:  Initializes the virtual screen for display.
199 
200   Arguments:    None.
201 
202   Returns:      None.
203  *---------------------------------------------------------------------------*/
ClearString(void)204 void ClearString(void)
205 {
206     MI_CpuClearFast(gScreen, sizeof(gScreen));
207 }
208 
209 /*---------------------------------------------------------------------------*
210   Name:         PrintString
211 
212   Description:  Displays a character string of up to 32 characters on the virtual screen
213 
214   Arguments:    x: The X coordinate that positions the start of the character string / 8 dot
215                 y: The y coordinate that positions the start of the character string / 8 dot
216                 palette: The palette number that designates the character color
217                 text: The displayed character string
218                 ...: Subsequent variable arguments
219 
220   Returns:      None.
221  *---------------------------------------------------------------------------*/
PrintString(int x,int y,int palette,const char * text,...)222 void PrintString(int x, int y, int palette, const char *text, ...)
223 {
224     va_list vlist;
225     static char temp[64 + 2];
226     u8      d;
227     int     i;
228 
229     va_start(vlist, text);
230     (void)OS_VSNPrintf(temp, sizeof(temp) - 1, text, vlist);
231     va_end(vlist);
232     *(u16 *)&temp[32] = 0x0000;
233     for (i = 0; (d = MI_ReadByte(temp + i)) != '\0'; ++i)
234     {
235         if ((d == '\r') || (d == '\n'))
236             break;
237         gScreen[((y * 32) + x + i) % (32 * 32)] = (u16)((palette << 12) | d);
238     }
239 }
240 
241 /*---------------------------------------------------------------------------*
242   Name:         ColorString
243 
244   Description:  Changes the color of the character string shown on the virtual screen.
245 
246   Arguments:    x: X coordinate for the beginning of the color change / 8 dot
247                 y: Y coordinate for the beginning of the color change / 8 dot
248                 length: Number of characters to change the color of
249                 palette: The palette number that designates the character color
250 
251   Returns:      None.
252  *---------------------------------------------------------------------------*/
ColorString(int x,int y,int length,int palette)253 void ColorString(int x, int y, int length, int palette)
254 {
255     int     i;
256     for (i = 0; i < length; ++i)
257     {
258         const int index = ((y * 32) + x + i) % (32 * 32);
259         gScreen[index] = (u16)((gScreen[index] & 0x0FFF) | (palette << 12));
260     }
261 }
262 
263 /*---------------------------------------------------------------------------*
264   Name:         ClearLine
265 
266   Description:  Initializes string rendering.
267 
268   Arguments:    None.
269 
270   Returns:      None.
271  *---------------------------------------------------------------------------*/
ClearLine(void)272 void ClearLine(void)
273 {
274     MI_CpuClear8(recent_output, sizeof(recent_output));
275 }
276 
277 /*---------------------------------------------------------------------------*
278   Name:         PrintLine
279 
280   Description:  In a specified line, renders a nonvolatile character string that will remain for at least one frame.
281 
282   Arguments:    x: Display position X grid (8 pixel units)
283                 y: Display position Y grid (8 pixel units)
284                 text: Formatted character string that receives the variable argument that follows
285 
286   Returns:      None.
287  *---------------------------------------------------------------------------*/
PrintLine(int x,int y,const char * text,...)288 void PrintLine(int x, int y, const char *text, ...)
289 {
290     va_list va;
291     va_start(va, text);
292     MI_CpuFill8(recent_output[y], ' ', sizeof(recent_output[y]));
293     (void)OS_VSNPrintf(&recent_output[y][x], (size_t) (32 - x), text, va);
294     va_end(va);
295 }
296 
297 /*---------------------------------------------------------------------------*
298   Name:         FlushLine
299 
300   Description:  The PrintLine nonvolatile character string is overwritten by PrintString.
301 
302   Arguments:    None.
303 
304   Returns:      None.
305  *---------------------------------------------------------------------------*/
FlushLine(void)306 void FlushLine(void)
307 {
308     int     y;
309     for (y = 0; y < 24; ++y)
310     {
311         PrintString(0, y, COLOR_WHITE, recent_output[y]);
312     }
313 }
314 
315 
316 /*---------------------------------------------------------------------------*
317   End of file
318  *---------------------------------------------------------------------------*/
319