1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - WM - demos - dataShare-Model
3   File:     print.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 #include "print.h"
24 #include "wh.h"
25 
26 static u16 PRi_GetFontIndex(u16 sjisCode);
27 static u16 PRi_SplitCharShiftJIS(const void **ppChar);
28 
PR_ClearScreen(PRScreen * scr)29 void PR_ClearScreen(PRScreen * scr)
30 {
31     MI_CpuClear16((void *)scr->screen, PR_SCREEN_SIZE * sizeof(u16));
32     scr->curx = 0;
33     scr->cury = 0;
34 }
35 
PR_Locate(PRScreen * scr,int x,int y)36 void PR_Locate(PRScreen * scr, int x, int y)
37 {
38     scr->curx = x;
39     scr->cury = y;
40 }
41 
PR_ScrollUp(PRScreen * scr)42 static void PR_ScrollUp(PRScreen * scr)
43 {
44     int     y;
45 
46     if (!scr->scroll)
47     {
48         PR_ClearScreen(scr);
49         return;
50     }
51 
52     for (y = 0; y < PR_SCREEN_HEIGHT - 1; ++y)
53     {
54         MI_CpuCopy16((void *)(scr->screen + (y + 1) * PR_SCREEN_WIDTH),
55                      (void *)(scr->screen + y * PR_SCREEN_WIDTH), PR_SCREEN_WIDTH * sizeof(u16));
56     }
57 
58     (void)MI_CpuClear16((void *)(scr->screen
59                                  + (PR_SCREEN_HEIGHT - 1) * PR_SCREEN_WIDTH),
60                         PR_SCREEN_WIDTH * sizeof(u16));
61 }
62 
PR_PutString(PRScreen * scr,const char * text)63 void PR_PutString(PRScreen * scr, const char *text)
64 {
65     const char *p;
66     u8      pal;
67     u16     code;
68 
69     p = text;
70     pal = 0x0f;
71 
72     while ((code = PRi_SplitCharShiftJIS((const void **)&p)) != '\0')
73     {
74         if (code == '\n')
75         {
76             scr->curx = 0;
77             ++scr->cury;
78             if (scr->cury > PR_SCREEN_HEIGHT - 1)
79             {
80                 scr->cury = PR_SCREEN_HEIGHT - 1;
81                 PR_ScrollUp(scr);
82             }
83             continue;
84         }
85         else if (code == '\\')
86         {
87             if (('0' <= *p) && (*p <= '9'))
88             {
89                 pal = (u8)(*p - '0');
90                 ++p;
91 
92             }
93             else if (('a' <= *p) && (*p <= 'f'))
94             {
95                 pal = (u8)(*p - 'a' + 10);
96                 ++p;
97             }
98             continue;
99         }
100         scr->screen[scr->cury * PR_SCREEN_WIDTH + scr->curx] =
101             (u16)((pal << 12) | (0x0fff & PRi_GetFontIndex(code)));
102 
103         ++scr->curx;
104         if (scr->curx > PR_SCREEN_WIDTH - 1)
105         {
106             scr->curx = 0;
107             ++scr->cury;
108             if (scr->cury > PR_SCREEN_HEIGHT - 1)
109             {
110                 scr->cury = PR_SCREEN_HEIGHT - 1;
111                 PR_ScrollUp(scr);
112             }
113         }
114     }
115 }
116 
PR_VPrintString(PRScreen * scr,const char * fmt,va_list vlist)117 void PR_VPrintString(PRScreen * scr, const char *fmt, va_list vlist)
118 {
119     char    buf[256];
120 
121     // Will not work if vsnprintf
122     // (void)vsnprintf(buf, 256 - 2, fmt, vlist);
123 
124     (void)OS_VSNPrintf(buf, 256 - 2, fmt, vlist);
125     buf[255] = '\0';
126 
127     PR_PutString(scr, buf);
128     // OS_Printf("%s", buf);
129 }
130 
PR_PrintString(PRScreen * scr,const char * fmt,...)131 void PR_PrintString(PRScreen * scr, const char *fmt, ...)
132 {
133     va_list vlist;
134     va_start(vlist, fmt);
135     PR_VPrintString(scr, fmt, vlist);
136     va_end(vlist);
137 }
138 
PR_GetStringLengthA(const char * str)139 int PR_GetStringLengthA(const char *str)
140 {
141     int     n = 0;
142     while (PRi_SplitCharShiftJIS((const void **)&str))
143     {
144         n++;
145     }
146     return n;
147 }
148 
PRi_GetFontIndex(u16 sjisCode)149 static u16 PRi_GetFontIndex(u16 sjisCode)
150 {
151     //sjis to sdkcode
152     const static u8 table[0x100 - 0x40] = {
153         //   0     1     2     3     4     5     6     7
154 /*0x40*/ 0xa7, 0xb1, 0xa8, 0xb2, 0xa9, 0xb3, 0xaa, 0xb4,
155         0xab, 0xb5, 0xb6, 0xf2, 0xb7, 0xf3, 0xb8, 0xf4,
156         //   8     9     a     b     c     d     e     f
157 
158         //   0     1     2     3     4     5     6     7
159 /*0x50*/ 0xb9, 0xf5, 0xba, 0xf6, 0xbb, 0xf7, 0xbc, 0xf8,
160         0xbd, 0xf9, 0xbe, 0xfa, 0xbf, 0xfb, 0xc0, 0xfc,
161         //   8     9     a     b     c     d     e     f
162 
163         //   0     1     2     3     4     5     6     7
164 /*0x60*/ 0xc1, 0xfd, 0xaf, 0xc2, 0xfe, 0xc3, 0xff, 0xc4,
165         0x01, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0x02,
166         //   8     9     a     b     c     d     e     f
167 
168         //   0     1     2     3     4     5     6     7
169 /*0x70*/ 0x02, 0xcb, 0x03, 0x03, 0xcc, 0x04, 0x04, 0xcd,
170         0x05, 0x1e, 0xce, 0x06, 0x06, 0xcf, 0xd0, 0x00,
171         //   8     9     a     b     c     d     e     f
172 
173         //   0     1     2     3     4     5     6     7
174 /*0x80*/ 0xd1, 0xd2, 0xd3, 0xac, 0xd4, 0xad, 0xd5, 0xae,
175         0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0x00, 0xdc,
176         //   8     9     a     b     c     d     e     f
177 
178         //   0     1     2     3     4     5     6     7
179 /*0x90*/ 0x00, 0x00, 0xa6, 0xdd, 0x00, 0x00, 0x00, 0x00,
180         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
181         //   8     9     a     b     c     d     e     f
182 
183         //   0     1     2     3     4     5     6     7
184 /*0xa0*/ 0x86, 0x7d, 0x87, 0x7e, 0x88, 0x7f, 0x89, 0x80,
185         0x8a, 0x8b, 0x07, 0x8c, 0x08, 0x8d, 0x09, 0x8e,
186         //   8     9     a     b     c     d     e     f
187 
188         //   0     1     2     3     4     5     6     7
189 /*0xb0*/ 0x0a, 0x8f, 0x0b, 0x90, 0x0c, 0x91, 0x0d, 0x92,
190         0x0e, 0x93, 0x0f, 0x94, 0x10, 0x95, 0x11, 0x96,
191         //   8     9     a     b     c     d     e     f
192 
193         //   0     1     2     3     4     5     6     7
194 /*0xc0*/ 0x12, 0x84, 0x97, 0x13, 0x98, 0x14, 0x99, 0x15,
195         0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x16, 0x1b,
196         //   8     9     a     b     c     d     e     f
197 
198         //   0     1     2     3     4     5     6     7
199 /*0xd0*/ 0xa0, 0x17, 0x1c, 0xe0, 0x18, 0x1d, 0xe1, 0x19,
200         0x1e, 0xe2, 0x1a, 0x1f, 0xe3, 0xe4, 0xe5, 0xe6,
201         //   8     9     a     b     c     d     e     f
202 
203         //   0     1     2     3     4     5     6     7
204 /*0xe0*/ 0xe7, 0x81, 0xe8, 0x82, 0xe9, 0x83, 0xea, 0xeb,
205         0xec, 0xed, 0xee, 0xef, 0x00, 0xf0, 0x00, 0x00,
206         //   8     9     a     b     c     d     e     f
207 
208         //   0     1     2     3     4     5     6     7
209 /*0xf0*/ 0x7b, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
211             //   8     9     a     b     c     d     e     f
212     };
213     if (sjisCode <= 0xff)
214     {
215         return sjisCode;
216     }
217 
218     switch (sjisCode)
219     {
220     case 0x8140:                      //
221         return ' ';
222     case 0x8141:                      //�A
223         return 0xa4;
224     case 0x8142:                      //�B
225         return 0xa1;
226     case 0x815e:                      //�^
227         return '/';
228     case 0x8175:                      //�u
229         return 0xa2;
230     case 0x8176:                      //�v
231         return 0xa3;
232     case 0x8145:                      //�v
233         return 0xa5;
234     case 0x815b:                      //- (double-byte)
235         return 0xb0;
236     case 0x8160:                      //�`
237         return 0x85;
238     case 0x818f:                      //��
239         return '\\';
240     }
241     return table[(sjisCode - 0x40) & 0xff];
242 }
243 
244 // Code from NitroSystem
245 ///////////////////////////////////////////////////////////////////////////////
246 
247 /*---------------------------------------------------------------------------*
248   Name:         IsSjisLeadByte
249 
250   Description:  Determines whether it is an SJIS lead byte.
251 
252   Arguments:    c:  The byte data to be assessed
253 
254   Returns:      Returns TRUE if c is an SJIS lead byte.
255  *---------------------------------------------------------------------------*/
256 #define SJIS_LOW_WIDTH  0xBC
257 #define SJIS_LOW_BASE   0x40
258 #define SJIS_HIGH_BASE  0x81
259 #define SHIGH_AREA0_ST  0x81
260 #define SHIGH_AREA0_ED  0x85
261 #define SHIGH_AREA1     0x87
262 #define SHIGH_AREA2_ST  0x88
263 #define SHIGH_AREA2_ED  0xA0
264 #define SHIGH_AREA3_ST  0xE0
265 #define SHIGH_AREA3_ED  0x100
266 #define ASCII_ST    0x20
267 #define ASCII_ED    0x80
268 #define HANKANA_ST  0xA0
269 #define HANKANA_ED  0xE0
270 
IsSjisLeadByte(u8 c)271 static inline BOOL IsSjisLeadByte(u8 c)
272 {
273     return (((SJIS_HIGH_BASE <= c) && (c < SHIGH_AREA2_ED))
274             || (SHIGH_AREA3_ST <= c)) ? TRUE : FALSE;
275 }
276 
277 /*---------------------------------------------------------------------------*
278   Name:         PRi_SplitCharShiftJIS
279 
280   Description:  This is a function that starts the character code.
281                 Gets the character code of the first character from the byte stream and, at the same time, moves the stream pointer to the next character.
282 
283 
284   Arguments:    ppChar: The pointer to the buffer where the pointer to the byte array is stored.
285                         If returning from a function, the pointer to the beginning of the next character is stored in the buffer indicated by this pointer.
286 
287 
288   Returns:      The character code of the first character of *ppChar.
289  *---------------------------------------------------------------------------*/
290 
291 // Shift_JIS
PRi_SplitCharShiftJIS(const void ** ppChar)292 static u16 PRi_SplitCharShiftJIS(const void **ppChar)
293 {
294     const u8 *pChar;
295     u16     c;
296 
297     SDK_NULL_ASSERT(ppChar);
298     SDK_NULL_ASSERT(*ppChar);
299 
300     pChar = (const u8 *)*ppChar;
301 
302     if (IsSjisLeadByte(*pChar))
303     {
304         c = (u16)(((*pChar) << 8) | (*(pChar + 1)));
305         *(u32 *)ppChar += 2;
306     }
307     else
308     {
309         c = *pChar;
310         *(u32 *)ppChar += 1;
311     }
312 
313     return c;
314 }
315