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