1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - MB - demos - multiboot-PowerSave
3   File:     dispfunc.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 "dispfunc.h"
25 
26 
27 /*****************************************************************************/
28 /* Constants */
29 
30 /* Constant array for each type of rendering */
31 extern const u32 sampleCharData[8 * 0xe0];
32 extern const u16 samplePlttData[16][16];
33 
34 
35 /*****************************************************************************/
36 /* Variables */
37 
38 /* Virtual BG screen for V-Blank transfer */
39 static u16 g_screen[2][32 * 32] ATTRIBUTE_ALIGN(32);
40 
41 /* Current drawing target */
42 static u16 *draw_target;
43 
44 /* Newest line number in message log */
45 static int cur_line = 0;
46 
47 
48 /*****************************************************************************/
49 /* Functions */
50 
51 /*---------------------------------------------------------------------------*
52   Name:         BgiGetTargetScreen
53 
54   Description:  Gets pointer to the main/sub screen's BG screen.
55 
56   Arguments:    is_lcd_main: If main screen, TRUE; if sub-screen, FALSE.
57 
58   Returns:      Pointer to BG screen.
59  *---------------------------------------------------------------------------*/
BgiGetTargetScreen(BOOL is_lcd_main)60 static  inline u16 *BgiGetTargetScreen(BOOL is_lcd_main)
61 {
62     return g_screen[!is_lcd_main];
63 }
64 
65 /*---------------------------------------------------------------------------*
66   Name:         BgiSetTargetScreen
67 
68   Description:  Switches between the main/sub-screen BG screen for the display of character strings.
69 
70   Arguments:    is_lcd_main: If main screen, TRUE; if sub-screen, FALSE.
71 
72   Returns:      None.
73  *---------------------------------------------------------------------------*/
BgiSetTargetScreen(BOOL is_lcd_main)74 static  inline void BgiSetTargetScreen(BOOL is_lcd_main)
75 {
76     draw_target = BgiGetTargetScreen(is_lcd_main);
77 }
78 
79 /*---------------------------------------------------------------------------*
80   Name:         BgInit
81 
82   Description:  Initializes BG for display of character strings.
83 
84   Arguments:    None.
85 
86   Returns:      None.
87  *---------------------------------------------------------------------------*/
BgInit(void)88 void BgInit(void)
89 {
90     /* Initialize internal variables */
91     cur_line = 0;
92     MI_CpuClearFast(g_screen, sizeof(g_screen));
93     DC_StoreRange(g_screen, sizeof(g_screen));
94     DC_WaitWriteBufferEmpty();
95     draw_target = BgiGetTargetScreen(TRUE);
96 
97     /*
98      * Configure the main LCD.
99      * BG0: Use to display ASCII characters.
100      *   -256x256x16 text BG
101      *   -Screen base 30 (0F000-0F800)
102      *   -Character base 0 (00000-04000)
103      */
104     GX_SetBankForBG(GX_VRAM_BG_64_E);
105     G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16,
106                      GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
107     G2_SetBG0Priority(0);
108     G2_SetBG0Offset(0, 0);
109     G2_BG0Mosaic(FALSE);
110     GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
111     GX_LoadBG0Scr(g_screen[0], 0, sizeof(g_screen[0]));
112     GX_LoadBG0Char(sampleCharData, 0, sizeof(sampleCharData));
113     GX_LoadBGPltt(samplePlttData, 0, sizeof(samplePlttData));
114     GX_SetVisiblePlane(GX_PLANEMASK_BG0);
115 
116     /*
117      * Configure the sub-LCD.
118      * BG0: Use to display ASCII characters.
119      *   -256x256x16 text BG
120      *   -Screen base 31 (0F800-10000)
121      *   -Character base 4 (10000-14000)
122      */
123     GX_SetBankForSubBG(GX_VRAM_SUB_BG_128_C);
124     G2S_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16,
125                       GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x10000, GX_BG_EXTPLTT_01);
126     G2S_SetBG0Priority(0);
127     G2S_SetBG0Offset(0, 0);
128     G2S_BG0Mosaic(FALSE);
129     GXS_SetGraphicsMode(GX_BGMODE_0);
130     GXS_LoadBG0Scr(g_screen[1], 0, sizeof(g_screen[1]));
131     GXS_LoadBG0Char(sampleCharData, 0, sizeof(sampleCharData));
132     GXS_LoadBGPltt(samplePlttData, 0, sizeof(samplePlttData));
133     GXS_SetVisiblePlane(GX_PLANEMASK_BG0);
134 }
135 
136 /*---------------------------------------------------------------------------*
137   Name:         BgClear
138 
139   Description:  Initializes BG screen of the main screen so that all chars are set to 0
140 
141   Arguments:    None.
142 
143   Returns:      None.
144  *---------------------------------------------------------------------------*/
BgClear(void)145 void BgClear(void)
146 {
147     MI_CpuClearFast(g_screen[0], sizeof(g_screen[0]));
148 }
149 
150 /*---------------------------------------------------------------------------*
151   Name:         BgUpdate
152 
153   Description:  Reflect BG screen in real memory
154 
155   Arguments:    None.
156 
157   Returns:      None.
158  *---------------------------------------------------------------------------*/
BgUpdate(void)159 void BgUpdate(void)
160 {
161     /* Reflect BG in real memory */
162     DC_FlushRange(g_screen, sizeof(g_screen));
163     /* I/O register is accessed using DMA operation, so cache wait is not needed */
164     // DC_WaitWriteBufferEmpty();
165     GX_LoadBG0Scr(g_screen[0], 0, sizeof(g_screen[0]));
166     GXS_LoadBG0Scr(g_screen[1], 0, sizeof(g_screen[1]));
167 }
168 
169 /*---------------------------------------------------------------------------*
170   Name:         BgPutString
171 
172   Description:  Displays ASCII characters horizontally from BG's specified grid.
173 
174   Arguments:    x: Upper left X grid to display (8 pixel units)
175                 y: Upper left Y grid to display (8 pixel units)
176                 pal: Palette number (0-15)
177                 str: ASCII character string to display
178                 len: Length of character string to display
179                      (If str contains a NULL in a location less than len, length up to that position will be used)
180 
181 
182   Returns:      None.
183  *---------------------------------------------------------------------------*/
BgPutString(int x,int y,int pal,const char * str,int len)184 void BgPutString(int x, int y, int pal, const char *str, int len)
185 {
186     u16    *const dst = draw_target;
187     x += y * 32;
188     str -= x, len += x;
189     for (; str[x] && (x < len); ++x)
190     {
191         dst[x & ((32 * 32) - 1)] = (u16)((pal << 12) | (u8)str[x]);
192     }
193 }
194 
195 /*---------------------------------------------------------------------------*
196   Name:         BgPrintf
197 
198   Description:  Displays formatted ASCII character string horizontally from BG's specified grid.
199 
200   Arguments:    x: Upper left X grid to display (8 pixel units)
201                 y: Upper left Y grid to display (8 pixel units)
202                 pal: Palette number (0-15)
203                 str: ASCII character string to display
204                      (The supported format is that of OS_VSNPrintf)
205 
206   Returns:      None.
207  *---------------------------------------------------------------------------*/
BgPrintf(int x,int y,int pal,const char * str,...)208 void BgPrintf(int x, int y, int pal, const char *str, ...)
209 {
210     char    tmp[32 + 1];
211     va_list vlist;
212     va_start(vlist, str);
213     (void)OS_VSNPrintf(tmp, sizeof(tmp), str, vlist);
214     va_end(vlist);
215     BgPutString(x, y, pal, tmp, sizeof(tmp));
216 }
217 
218 /*---------------------------------------------------------------------------*
219   Name:         BgSetMessage
220 
221   Description:  Displays character string at the (4, 22) position of both main and sub screens.
222 
223   Arguments:    pal: Palette number (0-15)
224                 str: ASCII character string to display
225                      (The supported format is that of OS_VSNPrintf)
226 
227   Returns:      None.
228  *---------------------------------------------------------------------------*/
BgSetMessage(int pal,const char * str,...)229 void BgSetMessage(int pal, const char *str, ...)
230 {
231     char    tmp[32 + 1];
232     va_list vlist;
233     va_start(vlist, str);
234     (void)OS_VSNPrintf(tmp, sizeof(tmp), str, vlist);
235     va_end(vlist);
236 
237     /* Display character string at the (4, 22) position of main screen */
238     BgPutString(4, 22, pal, "                            ", 28);
239     BgPutString(4, 22, pal, tmp, 28);
240     /* Display another character string at newest line of sub screen */
241     {
242         /* Scroll as necessary */
243         const int BG_LINES = 24;
244         if (cur_line == BG_LINES)
245         {
246             u16    *const sub_screen = BgiGetTargetScreen(FALSE);
247             MI_CpuCopy16(&sub_screen[32 * 1], sub_screen, sizeof(u16) * 32 * (BG_LINES - 1));
248             MI_CpuClear16(&sub_screen[32 * (BG_LINES - 1)], sizeof(u16) * 32 * 1);
249             --cur_line;
250         }
251         /* Switch the output destination temporarily */
252         BgiSetTargetScreen(FALSE);
253         BgPutString(0, cur_line, pal, tmp, sizeof(tmp));
254         BgiSetTargetScreen(TRUE);
255         if (cur_line < BG_LINES)
256             ++cur_line;
257     }
258 }
259