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: //�@ (double-byte space)
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