1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - MB - demos - multiboot
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 #include <nitro.h>
19 #include <string.h>
20 
21 #include "dispfunc.h"
22 
23 /*
24 	=================================================================================
25 
26 	OBJ character drawing
27 
28 	=================================================================================
29 */
30 
31 // --- global value
32 GXOamAttr oamBak[128];
33 
34 // --- constant value
35 static const char NumString[] = "0123456789ABCDEF";
36 
37 
38 //      Set OBJ
ObjSet(int objNo,int x,int y,int charNo,int paletteNo)39 void ObjSet(int objNo, int x, int y, int charNo, int paletteNo)
40 {
41     G2_SetOBJAttr((GXOamAttr *)&oamBak[objNo],
42                   x,
43                   y,
44                   0,
45                   GX_OAM_MODE_NORMAL,
46                   FALSE,
47                   GX_OAM_EFFECT_NONE, GX_OAM_SHAPE_8x8, GX_OAM_COLOR_16, charNo, paletteNo, 0);
48 }
49 
50 //      Set OBJ character string
ObjSetString(int startobjNo,int x,int y,char * string,int paletteNo)51 void ObjSetString(int startobjNo, int x, int y, char *string, int paletteNo)
52 {
53     int     i;
54     for (i = 0; string[i] != 0 && i < 24; i++)
55     {
56         ObjSet(startobjNo + i, x + i * 8, y, (int)string[i], paletteNo);
57     }
58 }
59 
60 //      Clears OBJ
ObjClear(int objNo)61 void ObjClear(int objNo)
62 {
63     ObjSet(objNo, 256 * 8, 192 * 8, 0, 0);
64 }
65 
66 //      Clears OBJ (specified range)
ObjClearRange(int start,int end)67 void ObjClearRange(int start, int end)
68 {
69     int     i;
70     for (i = start; i <= end; i++)
71         ObjClear(i);
72 }
73 
74 
75 //      Set message
ObjSetMessage(int objNo,char * message)76 void ObjSetMessage(int objNo, char *message)
77 {
78     ObjSetString(objNo, 4 * 8, 22 * 8, message, WHITE);
79 }
80 
81 /*
82 	=================================================================================
83 
84 	BG character drawing (BG0 fixed)
85 
86 	=================================================================================
87 */
88 
89 
90 #define BG_LINES	(24)
91 #define PROMPT		">"
92 
93 // --- static value
94 static u16 vscr[32 * 32] ATTRIBUTE_ALIGN(32);   // Virtual screen
95 static u16 vscr_sub[32 * 32] ATTRIBUTE_ALIGN(32);       // Virtual screen (sub)
96 static u16 cur_line = 0;
97 
98 // --- static functions
99 static void BgiPutChar(s16 x, s16 y, u8 palette, char c, u8 lcd);
100 static void BgiPutStringN(s16 x, s16 y, u8 palette, char *text, u32 num, u8 lcd);
101 
102 
BgiPutChar(s16 x,s16 y,u8 palette,char c,u8 lcd)103 static void BgiPutChar(s16 x, s16 y, u8 palette, char c, u8 lcd)
104 {
105     if (lcd)
106     {
107         vscr[((y * 32) + x) % (32 * 32)] = (u16)((palette << 12) | c);
108     }
109     else
110     {
111         vscr_sub[((y * 32) + x) % (32 * 32)] = (u16)((palette << 12) | c);
112     }
113 }
114 
BgiPutStringN(s16 x,s16 y,u8 palette,char * text,u32 num,u8 lcd)115 static void BgiPutStringN(s16 x, s16 y, u8 palette, char *text, u32 num, u8 lcd)
116 {
117     s32     i;
118 
119     for (i = 0; i < num; i++)
120     {
121         if (text[i] == 0x00)
122         {
123             break;
124         }
125 
126         BgiPutChar((s16)(x + i), y, palette, text[i], lcd);
127     }
128 
129 }
130 
131 /*
132 	--- initialize
133 */
BgInitForPrintStr(void)134 void BgInitForPrintStr(void)
135 {
136     // Main lcd
137     GX_SetBankForBG(GX_VRAM_BG_64_E);
138     G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0xf000,      // SCR base block 31
139                      GX_BG_CHARBASE_0x00000,    // CHR base block 0
140                      GX_BG_EXTPLTT_01);
141     G2_SetBG0Priority(0);
142     G2_BG0Mosaic(FALSE);
143     GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
144 
145     GX_LoadBG0Char(sampleCharData, 0, sizeof(sampleCharData));
146     GX_LoadBGPltt(samplePlttData, 0, sizeof(samplePlttData));
147 
148     MI_CpuFillFast((void *)vscr, 0, sizeof(vscr));
149     DC_FlushRange(vscr, sizeof(vscr));
150     /* I/O register is accessed using DMA operation, so cache wait is not needed */
151     // DC_WaitWriteBufferEmpty();
152     GX_LoadBG0Scr(vscr, 0, sizeof(vscr));
153 
154     // Sub lcd
155     GX_SetBankForSubBG(GX_VRAM_SUB_BG_128_C);
156     G2S_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0xf800,     // SCR base block 31
157                       GX_BG_CHARBASE_0x10000,   // CHR base block 0
158                       GX_BG_EXTPLTT_01);
159     G2S_SetBG0Priority(0);
160     G2S_BG0Mosaic(FALSE);
161     GXS_SetGraphicsMode(GX_BGMODE_0);
162 
163     GXS_LoadBG0Char(sampleCharData, 0, sizeof(sampleCharData));
164     GXS_LoadBGPltt(samplePlttData, 0, sizeof(samplePlttData));
165     MI_CpuFillFast((void *)vscr_sub, 0, sizeof(vscr_sub));
166     DC_FlushRange(vscr_sub, sizeof(vscr_sub));
167     /* I/O register is accessed using DMA operation, so cache wait is not needed */
168     // DC_WaitWriteBufferEmpty();
169     GXS_LoadBG0Scr(vscr_sub, 0, sizeof(vscr_sub));
170 
171     cur_line = 0;
172 }
173 
174 /*
175 	--- for main LCD
176 */
177 
178 // Formatted character string output
BgPrintf(s16 x,s16 y,u8 palette,char * text,...)179 void BgPrintf(s16 x, s16 y, u8 palette, char *text, ...)
180 {
181     va_list vlist;
182     char    temp[32 * 2 + 2];
183 
184     MI_CpuClear8(&temp[0], sizeof(temp));
185 
186     va_start(vlist, text);
187     (void)OS_VSNPrintf(temp, 32 * 2 + 2, text, vlist);
188     va_end(vlist);
189 
190     BgPutString(x, y, palette, temp);
191 }
192 
193 
194 // String output
BgPutString(s16 x,s16 y,u8 palette,char * text)195 void BgPutString(s16 x, s16 y, u8 palette, char *text)
196 {
197     BgPutStringN(x, y, palette, text, 32);
198 }
199 
200 // Character string output with the character number restriction
BgPutStringN(s16 x,s16 y,u8 palette,char * text,u32 num)201 void BgPutStringN(s16 x, s16 y, u8 palette, char *text, u32 num)
202 {
203     BgiPutStringN(x, y, palette, text, num, 1);
204 }
205 
206 
207 // 1 character output
BgPutChar(s16 x,s16 y,u8 palette,char c)208 void BgPutChar(s16 x, s16 y, u8 palette, char c)
209 {
210     BgiPutChar(x, y, palette, c, 1);
211 }
212 
213 // Clear BG
BgClear(void)214 void BgClear(void)
215 {
216     MI_CpuClearFast((void *)vscr, sizeof(vscr));
217 }
218 
219 /*
220 	--- for sub LCD
221 */
222 
223 // Formatted character string output
BgPrintfSub(s16 x,s16 y,u8 palette,char * text,...)224 void BgPrintfSub(s16 x, s16 y, u8 palette, char *text, ...)
225 {
226     va_list vlist;
227     char    temp[32 + 2];
228 
229     MI_CpuClear8(&temp[0], sizeof(temp));
230 
231     va_start(vlist, text);
232     (void)OS_VSNPrintf(temp, 33, text, vlist);
233     va_end(vlist);
234 
235     BgPutStringSub(x, y, palette, temp);
236 }
237 
238 // String output
BgPutStringSub(s16 x,s16 y,u8 palette,char * text)239 void BgPutStringSub(s16 x, s16 y, u8 palette, char *text)
240 {
241     BgPutStringNSub(x, y, palette, text, 32);
242 }
243 
244 // Character string output with the character number restriction
BgPutStringNSub(s16 x,s16 y,u8 palette,char * text,u32 num)245 void BgPutStringNSub(s16 x, s16 y, u8 palette, char *text, u32 num)
246 {
247     BgiPutStringN(x, y, palette, text, num, 0);
248 }
249 
250 // 1 character output
BgPutCharSub(s16 x,s16 y,u8 palette,char c)251 void BgPutCharSub(s16 x, s16 y, u8 palette, char c)
252 {
253     BgiPutChar(x, y, palette, c, 0);
254 }
255 
256 // Clear BG
BgClearSub(void)257 void BgClearSub(void)
258 {
259     MI_CpuClearFast((void *)vscr_sub, sizeof(vscr_sub));
260 }
261 
262 /*
263 	--- v blank process
264 */
265 
BgScrSetVblank(void)266 void BgScrSetVblank(void)
267 {
268     // Reflect virtual screen in VRAM
269     DC_FlushRange(vscr, sizeof(vscr));
270     /* I/O register is accessed using DMA operation, so cache wait is not needed */
271     // DC_WaitWriteBufferEmpty();
272     GX_LoadBG0Scr(vscr, 0, sizeof(vscr));
273     DC_FlushRange(vscr_sub, sizeof(vscr_sub));
274     /* I/O register is accessed using DMA operation, so cache wait is not needed */
275     // DC_WaitWriteBufferEmpty();
276     GXS_LoadBG0Scr(vscr_sub, 0, sizeof(vscr_sub));
277 }
278 
279 
280 /*
281 	--- message print
282 */
283 
284 // Output message
BgSetMessage(u8 palette,char * message,...)285 void BgSetMessage(u8 palette, char *message, ...)
286 {
287     va_list vlist;
288     char    temp[32 * 2 + 2];
289     MI_CpuClear8(&temp[0], sizeof(temp));
290 
291     va_start(vlist, message);
292     (void)OS_VSNPrintf(temp, 32 * 2 + 2, message, vlist);
293     va_end(vlist);
294 
295     BgPutString(4, 22, palette, "                            ");
296     BgPutString(4, 22, palette, temp);
297 
298 
299     BgSetMessageLogSub(palette, temp);
300 
301 }
302 
BgSetMessageSub(u8 palette,char * message,...)303 void BgSetMessageSub(u8 palette, char *message, ...)
304 {
305     va_list vlist;
306     char    temp[32 + 2];
307     MI_CpuClear8(&temp[0], sizeof(temp));
308 
309     va_start(vlist, message);
310     (void)OS_VSNPrintf(temp, 33, message, vlist);
311     va_end(vlist);
312 
313     BgSetMessageLogSub(palette, temp);
314 }
315 
316 // Output message log on sub LCD
BgSetMessageLogSub(u8 palette,char * text)317 void BgSetMessageLogSub(u8 palette, char *text)
318 {
319     if (cur_line == BG_LINES)
320     {
321         MI_CpuCopy16((void *)&vscr_sub[1 * 32], (void *)vscr_sub,
322                      sizeof(u16) * 32 * (BG_LINES - 1));
323         cur_line--;
324     }
325 
326     BgPutStringSub(0, (s16)cur_line, palette, "                                ");
327     BgPutStringSub(0, (s16)cur_line, palette, PROMPT);
328     BgPutStringSub((s16)(1 + strlen(PROMPT)), (s16)cur_line, palette, text);
329 
330     if (cur_line < BG_LINES)
331         cur_line++;
332 }
333 
334 // Get main LCD screen buffer
BgGetScreenBuf(void)335 u16    *BgGetScreenBuf(void)
336 {
337     return (u16 *)vscr;
338 }
339 
340 // Get sub LCD screen buffer
BgGetScreenBufSub(void)341 u16    *BgGetScreenBufSub(void)
342 {
343     return (u16 *)vscr_sub;
344 }
345