source: ps2launchargs/source/uLaunchELF/draw.c@ 1194

Last change on this file since 1194 was 1101, checked in by iritscen, 7 years ago

Added following to ps2launchargs:\n-Source code.\n-DLL needed to run ps2client.\n-Instructions for building uLaunchELF.

  • Property svn:executable set to *
File size: 38.5 KB
Line 
1//--------------------------------------------------------------
2//File name: draw.c
3//--------------------------------------------------------------
4#include "launchelf.h"
5
6GSGLOBAL *gsGlobal;
7GSTEXTURE TexSkin, TexPreview, TexPicture, TexThumb[MAX_ENTRY], TexIcon[2];
8int testskin, testsetskin, testjpg, testthumb;
9int SCREEN_WIDTH = 640;
10int SCREEN_HEIGHT = 448;
11int SCREEN_X = 632;
12int SCREEN_Y = 50;
13//dlanor: values shown above are defaults for NTSC mode
14u64 BrightColor;
15
16int updateScr_1; //dlanor: flags screen updates for drawScr()
17int updateScr_2; //dlanor: used for anti-flicker delay in drawScr()
18u64 updateScr_t = 0; //dlanor: exit time of last drawScr()
19int Old_Interlace;
20
21char LastMessage[MAX_TEXT_LINE+2];
22
23int Menu_start_x = SCREEN_MARGIN + LINE_THICKNESS + FONT_WIDTH;
24int Menu_title_y = SCREEN_MARGIN;
25int Menu_message_y = SCREEN_MARGIN + FONT_HEIGHT;
26int Frame_start_y = SCREEN_MARGIN + 2*FONT_HEIGHT + 2; //First line of menu frame
27int Menu_start_y = SCREEN_MARGIN + 2*FONT_HEIGHT + LINE_THICKNESS + 5;
28//dlanor: Menu_start_y is the 1st pixel line that may be used for main content of a menu
29//dlanor: values below are only calculated when a rez is activated
30int Menu_end_y; //Normal menu display should not use pixels at this line or beyond
31int Frame_end_y; //first line of frame bottom
32int Menu_tooltip_y; //Menus may also use this row for tooltips
33
34
35//The font file ELISA100.FNT is needed to display MC save titles in japanese
36//and the arrays defined here are needed to find correct data in that file
37const u16 font404[] = {
38 0xA2AF, 11,
39 0xA2C2, 8,
40 0xA2D1, 11,
41 0xA2EB, 7,
42 0xA2FA, 4,
43 0xA3A1, 15,
44 0xA3BA, 7,
45 0xA3DB, 6,
46 0xA3FB, 4,
47 0xA4F4, 11,
48 0xA5F7, 8,
49 0xA6B9, 8,
50 0xA6D9, 38,
51 0xA7C2, 15,
52 0xA7F2, 13,
53 0xA8C1, 720,
54 0xCFD4, 43,
55 0xF4A5, 1030,
56 0,0
57};
58
59// ASCII‚ÆSJIS‚Ì•ÏŠ·—p”z—ñ
60const unsigned char sjis_lookup_81[256] = {
61 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x00
62 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x10
63 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x20
64 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x30
65 ' ', ',', '.', ',', '.', 0xFF,':', ';', '?', '!', 0xFF,0xFF,'´', '`', 0xFF,'^', // 0x40
66 0xFF,'_', 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,'0', 0xFF,'-', '-', 0xFF,0xFF, // 0x50
67 0xFF,0xFF,0xFF,0xFF,0xFF,'\'','\'','"', '"', '(', ')', 0xFF,0xFF,'[', ']', '{', // 0x60
68 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,'+', '-', 0xFF,'*', 0xFF, // 0x70
69 '/', '=', 0xFF,'<', '>', 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,'°', 0xFF,0xFF,'°', 0xFF, // 0x80
70 '$', 0xFF,0xFF,'%', '#', '&', '*', '@', 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x90
71 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xA0
72 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xB0
73 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,'&', '|', '!', 0xFF,0xFF,0xFF,0xFF,0xFF, // 0xC0
74 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xD0
75 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xE0
76 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xF0
77};
78const unsigned char sjis_lookup_82[256] = {
79 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x00
80 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x10
81 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x20
82 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x30
83 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,'0', // 0x40
84 '1', '2', '3', '4', '5', '6', '7', '8', '9', 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x50
85 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 0x60
86 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x70
87 0xFF,'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', // 0x80
88 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0xFF,0xFF,0xFF,0xFF,0xFF, // 0x90
89 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xA0
90 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xB0
91 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xC0
92 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xD0
93 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xE0
94 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xF0
95};
96//--------------------------------------------------------------
97int *CreateCoeffInt( int nLen, int nNewLen, int bShrink ) {
98
99 int nSum = 0;
100 int nSum2 = 0;
101 int *pRes = (int*) malloc( 2 * nLen * sizeof(int) );
102 int *pCoeff = pRes;
103 int nNorm = (bShrink) ? (nNewLen << 12) / nLen : 0x1000;
104 int nDenom = (bShrink) ? nLen : nNewLen;
105 int i;
106
107 memset( pRes, 0, 2 * nLen * sizeof(int) );
108
109 for( i = 0; i < nLen; i++, pCoeff += 2 ) {
110
111 nSum2 = nSum + nNewLen;
112
113 if(nSum2 > nLen) {
114
115 *pCoeff = ((nLen - nSum) << 12) / nDenom;
116 pCoeff[1] = ((nSum2 - nLen) << 12) / nDenom;
117 nSum2 -= nLen;
118
119 } else {
120
121 *pCoeff = nNorm;
122
123 if(nSum2 == nLen) {
124 pCoeff[1] = -1;
125 nSum2 = 0;
126
127 } /* end if */
128
129 } /* end else */
130
131 nSum = nSum2;
132
133 } /* end for */
134
135 return pRes;
136
137} /* CreateCoeffInt */
138
139//--------------------------------------------------------------
140int ShrinkData( u8 *pInBuff, u16 wWidth, u16 wHeight, u8 *pOutBuff, u16 wNewWidth, u16 wNewHeight ) {
141
142 u8 *pLine = pInBuff, *pPix;
143 u8 *pOutLine = pOutBuff;
144 u32 dwInLn = ( 3 * wWidth + 3 ) & ~3;
145 u32 dwOutLn = ( 3 * wNewWidth + 3 ) & ~3;
146
147 int x, y, i, ii;
148 int bCrossRow, bCrossCol;
149 int *pRowCoeff = CreateCoeffInt( wWidth, wNewWidth, 1 );
150 int *pColCoeff = CreateCoeffInt( wHeight, wNewHeight, 1 );
151
152 int *pXCoeff, *pYCoeff = pColCoeff;
153 u32 dwBuffLn = 3 * wNewWidth * sizeof( u32 );
154 u32 *pdwBuff = ( u32* ) malloc( 6 * wNewWidth * sizeof( u32 ) );
155 u32 *pdwCurrLn = pdwBuff;
156 u32 *pdwNextLn = pdwBuff + 3 * wNewWidth;
157 u32 *pdwCurrPix;
158 u32 dwTmp, *pdwNextPix;
159
160 memset( pdwBuff, 0, 2 * dwBuffLn );
161
162 y = 0;
163
164 while( y < wNewHeight ) {
165
166 pPix = pLine;
167 pLine += dwInLn;
168
169 pdwCurrPix = pdwCurrLn;
170 pdwNextPix = pdwNextLn;
171
172 x = 0;
173 pXCoeff = pRowCoeff;
174 bCrossRow = pYCoeff[ 1 ] > 0;
175
176 while( x < wNewWidth ) {
177
178 dwTmp = *pXCoeff * *pYCoeff;
179 for ( i = 0; i < 3; i++ )
180 pdwCurrPix[ i ] += dwTmp * pPix[i];
181
182 bCrossCol = pXCoeff[ 1 ] > 0;
183
184 if ( bCrossCol ) {
185
186 dwTmp = pXCoeff[ 1 ] * *pYCoeff;
187 for ( i = 0, ii = 3; i < 3; i++, ii++ )
188 pdwCurrPix[ ii ] += dwTmp * pPix[ i ];
189
190 } /* end if */
191
192 if ( bCrossRow ) {
193
194 dwTmp = *pXCoeff * pYCoeff[ 1 ];
195 for( i = 0; i < 3; i++ )
196 pdwNextPix[ i ] += dwTmp * pPix[ i ];
197
198 if ( bCrossCol ) {
199
200 dwTmp = pXCoeff[ 1 ] * pYCoeff[ 1 ];
201 for ( i = 0, ii = 3; i < 3; i++, ii++ )
202 pdwNextPix[ ii ] += dwTmp * pPix[ i ];
203
204 } /* end if */
205
206 } /* end if */
207
208 if ( pXCoeff[ 1 ] ) {
209
210 x++;
211 pdwCurrPix += 3;
212 pdwNextPix += 3;
213
214 } /* end if */
215
216 pXCoeff += 2;
217 pPix += 3;
218
219 } /* end while */
220
221 if ( pYCoeff[ 1 ] ) {
222
223 // set result line
224 pdwCurrPix = pdwCurrLn;
225 pPix = pOutLine;
226
227 for ( i = 3 * wNewWidth; i > 0; i--, pdwCurrPix++, pPix++ )
228 *pPix = ((u8*)pdwCurrPix)[3];
229
230 // prepare line buffers
231 pdwCurrPix = pdwNextLn;
232 pdwNextLn = pdwCurrLn;
233 pdwCurrLn = pdwCurrPix;
234
235 memset( pdwNextLn, 0, dwBuffLn );
236
237 y++;
238 pOutLine += dwOutLn;
239
240 } /* end if */
241
242 pYCoeff += 2;
243
244 } /* end while */
245
246 free( pRowCoeff );
247 free( pColCoeff );
248 free( pdwBuff );
249
250 return 1;
251
252} /* end ShrinkData */
253
254//--------------------------------------------------------------
255int EnlargeData( u8 *pInBuff, u16 wWidth, u16 wHeight, u8 *pOutBuff, u16 wNewWidth, u16 wNewHeight ) {
256
257 u8 *pLine = pInBuff,
258 *pPix = pLine,
259 *pPixOld,
260 *pUpPix,
261 *pUpPixOld;
262 u8 *pOutLine = pOutBuff, *pOutPix;
263 u32 dwInLn = ( 3 * wWidth + 3 ) & ~3;
264 u32 dwOutLn = ( 3 * wNewWidth + 3 ) & ~3;
265
266 int x, y, i;
267 int bCrossRow, bCrossCol;
268
269 int *pRowCoeff = CreateCoeffInt( wNewWidth, wWidth, 0 );
270 int *pColCoeff = CreateCoeffInt( wNewHeight, wHeight, 0 );
271 int *pXCoeff, *pYCoeff = pColCoeff;
272
273 u32 dwTmp, dwPtTmp[ 3 ];
274
275 y = 0;
276
277 while( y < wHeight ) {
278
279 bCrossRow = pYCoeff[ 1 ] > 0;
280 x = 0;
281 pXCoeff = pRowCoeff;
282 pOutPix = pOutLine;
283 pOutLine += dwOutLn;
284 pUpPix = pLine;
285
286 if ( pYCoeff[ 1 ] ) {
287
288 y++;
289 pLine += dwInLn;
290 pPix = pLine;
291
292 } /* end if */
293
294 while( x < wWidth ) {
295
296 bCrossCol = pXCoeff[ 1 ] > 0;
297 pUpPixOld = pUpPix;
298 pPixOld = pPix;
299
300 if( pXCoeff[ 1 ] ) {
301
302 x++;
303 pUpPix += 3;
304 pPix += 3;
305
306 } /* end if */
307
308 dwTmp = *pXCoeff * *pYCoeff;
309
310 for ( i = 0; i < 3; i++ )
311 dwPtTmp[ i ] = dwTmp * pUpPixOld[ i ];
312
313 if ( bCrossCol ) {
314
315 dwTmp = pXCoeff[ 1 ] * *pYCoeff;
316 for ( i = 0; i < 3; i++ )
317 dwPtTmp[ i ] += dwTmp * pUpPix[ i ];
318
319 } /* end if */
320
321 if ( bCrossRow ) {
322
323 dwTmp = *pXCoeff * pYCoeff[ 1 ];
324 for ( i = 0; i < 3; i++ )
325 dwPtTmp[ i ] += dwTmp * pPixOld[ i ];
326
327 if ( bCrossCol ) {
328
329 dwTmp = pXCoeff[ 1 ] * pYCoeff[ 1 ];
330 for(i = 0; i < 3; i++)
331 dwPtTmp[ i ] += dwTmp * pPix[ i ];
332
333 } /* end if */
334
335 } /* end if */
336
337 for ( i = 0; i < 3; i++, pOutPix++ )
338 *pOutPix = ( ( u8* )( dwPtTmp + i ) )[ 3 ];
339
340 pXCoeff += 2;
341
342 } /* end while */
343
344 pYCoeff += 2;
345
346 } /* end while */
347
348 free( pRowCoeff );
349 free( pColCoeff );
350
351 return 1;
352
353} /* end EnlargeData */
354
355//--------------------------------------------------------------
356int ScaleBitmap( u8* pInBuff, u16 wWidth, u16 wHeight, u8** pOutBuff, u16 wNewWidth, u16 wNewHeight ) {
357
358 int lRet;
359
360 // check for valid size
361 if( (wWidth > wNewWidth && wHeight < wNewHeight) ||
362 (wHeight > wNewHeight && wWidth < wNewWidth ) ) return 0;
363
364 // allocate memory
365 *pOutBuff = ( u8* ) memalign( 128, ( ( 3 * wNewWidth + 3 ) & ~3 ) * wNewHeight );
366
367 if( !*pOutBuff )return 0;
368
369 if( wWidth >= wNewWidth && wHeight >= wNewHeight )
370 lRet = ShrinkData( pInBuff, wWidth, wHeight, *pOutBuff, wNewWidth, wNewHeight );
371 else
372 lRet = EnlargeData( pInBuff, wWidth, wHeight, *pOutBuff, wNewWidth, wNewHeight );
373
374 return lRet;
375
376} /* end ScaleBitmap */
377
378//--------------------------------------------------------------
379void RotateBitmap(u8* InBuff, u16 Width, u16 Height, u8* OutBuff, int Way) {
380
381 int i, j, k, l;
382 int Byte;
383 u8 pixels[Width][Height][3];
384 u8 newpixels[Height][Width][3];
385
386 Byte=0;
387 for( i = 0; i < Height; i++ ){
388 for( j = 0; j < Width; j++ ){
389 pixels[j][i][0] = InBuff[Byte];
390 pixels[j][i][1] = InBuff[Byte+1];
391 pixels[j][i][2] = InBuff[Byte+2];
392 Byte+=3;
393 }
394 }
395 if(Way==1){ // +90°
396 for( i = 0, l = 0; i < Width; i++, l++ ){
397 for( j = 0, k = Height-1; j < Height; j++, k-- ){
398 newpixels[j][i][0] = pixels[l][k][0];
399 newpixels[j][i][1] = pixels[l][k][1];
400 newpixels[j][i][2] = pixels[l][k][2];
401 }
402 }
403 }else if(Way==3){ // -90°
404 for( i = 0, l = Width-1; i < Width; i++, l-- ){
405 for( j = 0, k = 0; j < Height; j++, k++ ){
406 newpixels[j][i][0] = pixels[l][k][0];
407 newpixels[j][i][1] = pixels[l][k][1];
408 newpixels[j][i][2] = pixels[l][k][2];
409 }
410 }
411 } /* end if */
412
413 Byte=0;
414 for( i = 0; i < Width; i++ ){
415 for( j = 0; j < Height; j++ ){
416 OutBuff[Byte] = newpixels[j][i][0];
417 OutBuff[Byte+1] = newpixels[j][i][1];
418 OutBuff[Byte+2] = newpixels[j][i][2];
419 Byte+=3;
420 }
421 }
422
423 free( pixels );
424 free( newpixels );
425
426} /* end RotateBitmap */
427
428//--------------------------------------------------------------
429void setScrTmp(const char *msg0, const char *msg1)
430{
431 int x, y;
432 char temp_txt[64];
433
434 x = SCREEN_MARGIN;
435 y = Menu_title_y;
436 printXY(setting->Menu_Title, x, y, setting->color[3], TRUE, 0);
437 sprintf(temp_txt, " ÿ4 LaunchELF %s ÿ4", ULE_VERSION);
438 printXY(temp_txt, SCREEN_WIDTH-SCREEN_MARGIN-FONT_WIDTH*strlen(temp_txt), y,
439 setting->color[1], TRUE, 0);
440
441 strncpy(LastMessage, msg0, MAX_TEXT_LINE);
442 LastMessage[MAX_TEXT_LINE] = '\0';
443 printXY(msg0, x, Menu_message_y, setting->color[2], TRUE, 0);
444
445 if(setting->Menu_Frame)
446 drawFrame(SCREEN_MARGIN, Frame_start_y,
447 SCREEN_WIDTH-SCREEN_MARGIN, Frame_end_y, setting->color[1]);
448
449 printXY(msg1, x, Menu_tooltip_y, setting->color[2], TRUE, 0);
450}
451//--------------------------------------------------------------
452void drawSprite( u64 color, int x1, int y1, int x2, int y2 ){
453 int y_off = (setting->interlace) ? 0 : (y1 & 1);
454 y1 -= y_off;
455 y2 -= y_off;
456
457 if ( testskin == 1 ) {
458 setBrightness(setting->Brightness);
459 gsKit_prim_sprite_texture(gsGlobal, &TexSkin, x1, y1, x1, y1, x2, y2, x2, y2, 0, BrightColor);
460 setBrightness(50);
461 } else {
462 gsKit_prim_sprite(gsGlobal, x1, y1, x2, y2, 0, color);
463 }
464}
465//--------------------------------------------------------------
466void drawPopSprite( u64 color, int x1, int y1, int x2, int y2 ){
467 int y_off = (setting->interlace) ? 0 : (y1 & 1);
468 y1 -= y_off;
469 y2 -= y_off;
470
471 if ( testskin == 1 && !setting->Popup_Opaque) {
472 setBrightness(setting->Brightness);
473 gsKit_prim_sprite_texture(gsGlobal, &TexSkin, x1, y1, x1, y1, x2, y2, x2, y2, 0, BrightColor);
474 setBrightness(50);
475 } else {
476 gsKit_prim_sprite(gsGlobal, x1, y1, x2, y2, 0, color);
477 }
478}
479//--------------------------------------------------------------
480//drawOpSprite exists only to eliminate the use of primitive sprite functions
481//that are specific to the graphics lib used (currently gsKit). So normally
482//it will merely be a 'wrapper' function for one of the lib calls, except
483//that it will also perform any coordinate adjustments (if any)implemented for
484//the functions drawSprite and drawPopSprite, to keep all of them compatible.
485//
486void drawOpSprite( u64 color, int x1, int y1, int x2, int y2 ){
487 int y_off = (setting->interlace) ? 0 : (y1 & 1);
488 y1 -= y_off;
489 y2 -= y_off;
490
491 gsKit_prim_sprite(gsGlobal, x1, y1, x2, y2, 0, color);
492}
493//--------------------------------------------------------------
494void drawMsg(const char *msg)
495{
496 strncpy(LastMessage, msg, MAX_TEXT_LINE);
497 LastMessage[MAX_TEXT_LINE] = '\0';
498 drawSprite(setting->color[0], 0, Menu_message_y-1,
499 SCREEN_WIDTH, Frame_start_y);
500 printXY(msg, SCREEN_MARGIN, Menu_message_y, setting->color[2], TRUE, 0);
501 drawScr();
502}
503//--------------------------------------------------------------
504void drawLastMsg(void)
505{
506 drawSprite(setting->color[0], 0, Menu_message_y-1,
507 SCREEN_WIDTH, Frame_start_y);
508 printXY(LastMessage, SCREEN_MARGIN, Menu_message_y, setting->color[2], TRUE, 0);
509 drawScr();
510}
511//--------------------------------------------------------------
512void setupGS(int gs_vmode)
513{
514 // GS Init
515 gsGlobal = gsKit_init_global_custom(
516 GS_RENDER_QUEUE_OS_POOLSIZE+GS_RENDER_QUEUE_OS_POOLSIZE/2, //eliminates overflow
517 GS_RENDER_QUEUE_PER_POOLSIZE);
518
519 // GS video mode
520 gsGlobal->Mode = gs_vmode;
521
522 // Screen size and Interlace Init
523 gsGlobal->Width = SCREEN_WIDTH;
524 if(setting->interlace){
525 gsGlobal->Height = SCREEN_HEIGHT;
526 gsGlobal->Interlace = GS_INTERLACED;
527 gsGlobal->Field = GS_FIELD;
528 gsGlobal->MagV = 0;
529 }else{
530 gsGlobal->Height = SCREEN_HEIGHT/2;
531 gsGlobal->Interlace = GS_NONINTERLACED;
532 gsGlobal->Field = GS_FRAME;
533 gsGlobal->MagV = 0;
534 }
535 Old_Interlace = setting->interlace;
536
537 // Clear Screen
538 gsKit_clear(gsGlobal, GS_SETREG_RGBAQ(0x00,0x00,0x00,0x00,0x00));
539
540 // Screen Position Init
541 gsGlobal->StartX = setting->screen_x;
542 gsGlobal->StartY = setting->screen_y;
543
544 // Buffer Init
545 gsGlobal->PrimAAEnable = GS_SETTING_ON;
546 gsGlobal->DoubleBuffering = GS_SETTING_OFF;
547 gsGlobal->ZBuffering = GS_SETTING_OFF;
548
549 // DMAC Init
550 dmaKit_init(D_CTRL_RELE_OFF,D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC, D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF);
551 dmaKit_chan_init(DMA_CHANNEL_GIF);
552 dmaKit_chan_init(DMA_CHANNEL_FROMSPR);
553 dmaKit_chan_init(DMA_CHANNEL_TOSPR);
554
555 // Screen Init
556 gsKit_init_screen(gsGlobal);
557 gsKit_mode_switch(gsGlobal, GS_ONESHOT);
558 gsKit_clear(gsGlobal, GS_SETREG_RGBAQ(0x00,0x00,0x00,0x00,0x00));
559}
560//--------------------------------------------------------------
561void updateScreenMode(int adapt_XY)
562{
563 int setGS_flag = 0;
564 int New_TV_mode = setting->TV_mode;
565
566 if((New_TV_mode!=TV_mode_NTSC)&&(New_TV_mode!=TV_mode_PAL)){ //If no forced request
567 New_TV_mode = uLE_detect_TV_mode(); //Let console region decide TV_mode
568 }
569
570 if(New_TV_mode != TV_mode){
571 setGS_flag = 1;
572 TV_mode = New_TV_mode;
573
574 if(TV_mode == TV_mode_PAL){ //Use PAL mode if chosen (forced or auto)
575 gsGlobal->Mode = GS_MODE_PAL;
576 SCREEN_WIDTH = 640;
577 SCREEN_HEIGHT = 512;
578 if(adapt_XY){
579 setting->screen_x+=20;
580 if(setting->interlace)
581 setting->screen_y+=22;
582 else
583 setting->screen_y+=11;
584 }
585 Menu_end_y = Menu_start_y + 26*FONT_HEIGHT;
586 }else{ //else use NTSC mode (forced or auto)
587 gsGlobal->Mode = GS_MODE_NTSC;
588 SCREEN_WIDTH = 640;
589 SCREEN_HEIGHT = 448;
590 if(adapt_XY){
591 setting->screen_x-=20;
592 if(setting->interlace)
593 setting->screen_y-=22;
594 else
595 setting->screen_y-=11;
596 }
597 Menu_end_y = Menu_start_y + 22*FONT_HEIGHT;
598 } /* end else */
599 Frame_end_y = Menu_end_y + 3;
600 Menu_tooltip_y = Frame_end_y + LINE_THICKNESS + 2;
601
602 } // end TV_Mode change
603
604 if(setting->interlace != Old_Interlace){
605 setGS_flag = 1;
606 Old_Interlace = setting->interlace;
607
608 // Interlace Init
609 if(setting->interlace){
610 gsGlobal->Interlace = GS_INTERLACED;
611 gsGlobal->Field = GS_FIELD;
612 if(adapt_XY){
613 setting->screen_y = (setting->screen_y-1)*2;
614 }
615 }else{
616 gsGlobal->Interlace = GS_NONINTERLACED;
617 gsGlobal->Field = GS_FRAME;
618 if(adapt_XY){
619 setting->screen_y = setting->screen_y/2+1;
620 }
621 }
622 } // end Interlace change
623
624 // Init screen size
625 gsGlobal->Width = SCREEN_WIDTH;
626 gsGlobal->MagH = 3;
627 if(setting->interlace){
628 gsGlobal->Height = SCREEN_HEIGHT;
629 gsGlobal->MagV = 0;
630 } else {
631 gsGlobal->Height = SCREEN_HEIGHT/2;
632 gsGlobal->MagV = 0;
633 }
634
635 // Init screen position
636 gsGlobal->StartX = setting->screen_x;
637 gsGlobal->StartY = setting->screen_y;
638
639 if(setGS_flag){
640 // Clear screen before setting GS
641 gsKit_clear(gsGlobal, GS_SETREG_RGBAQ(0x00,0x00,0x00,0x00,0x00));
642 // Init screen modes
643 SetGsCrt(gsGlobal->Interlace, gsGlobal->Mode, gsGlobal->Field);
644 }
645
646 GS_SET_DISPLAY1(gsGlobal->StartX, // X position in the display area (in VCK unit
647 gsGlobal->StartY, // Y position in the display area (in Raster u
648 gsGlobal->MagH, // Horizontal Magnification
649 gsGlobal->MagV, // Vertical Magnification
650 (gsGlobal->Width * 4) -1, // Display area width
651 (gsGlobal->Height-1)); // Display area height
652
653 GS_SET_DISPLAY2(gsGlobal->StartX, // X position in the display area (in VCK units)
654 gsGlobal->StartY, // Y position in the display area (in Raster units)
655 gsGlobal->MagH, // Horizontal Magnification
656 gsGlobal->MagV, // Vertical Magnification
657 (gsGlobal->Width * 4) -1, // Display area width
658 (gsGlobal->Height-1)); // Display area height
659}
660//--------------------------------------------------------------
661void loadSkin(int Picture, char *Path, int ThumbNum)
662{
663 char tmpPath[MAX_PATH], skinpath[MAX_PATH];
664
665 strcpy(tmpPath, "\0");
666 if( Picture == BACKGROUND_PIC ){
667 if (GUI_active == 1){
668 strcpy(tmpPath, setting->GUI_skin);
669 }
670 else{
671 strcpy(tmpPath, setting->skin);
672 }
673 testskin = 0;
674 }else if( Picture == PREVIEW_PIC ){
675 strcpy(tmpPath, setting->skin);
676 testsetskin = 0;
677 }else if( Picture == JPG_PIC ){
678 strcpy(tmpPath, Path);
679 testjpg = 0;
680 }else if( Picture == THUMB_PIC ){
681 strcpy(tmpPath, Path);
682 testthumb = 0;
683 }else if( Picture == PREVIEW_GUI ){
684 strcpy(tmpPath, setting->GUI_skin);
685 testsetskin = 0;
686 }
687
688 genFixPath(tmpPath, skinpath);
689 FILE *File = fopen(skinpath, "r");
690
691 PicW=0, PicH=0, PicCoeff=0;
692
693 if( File != NULL ) {
694
695 jpgData *Jpg;
696 u8 *ImgData, *ImgData1, *ImgData2;
697 int W=0;
698
699 if( ( Jpg = jpgOpenFILE ( File, JPG_WIDTH_FIX ) ) > 0 ){
700 if( (ImgData = malloc( Jpg->width * Jpg->height * ( Jpg->bpp / 8 ) ) ) > 0){
701 if( ( jpgReadImage( Jpg, ImgData ) ) != -1 ){
702 if( Picture == BACKGROUND_PIC ){
703 if( ( ScaleBitmap ( ImgData, Jpg->width, Jpg->height, (void*)&TexSkin.Mem, SCREEN_WIDTH, SCREEN_HEIGHT ) ) != 0 ){
704 TexSkin.PSM = GS_PSM_CT24;
705 TexSkin.VramClut = 0;
706 TexSkin.Clut = NULL;
707 TexSkin.Width = SCREEN_WIDTH;
708 TexSkin.Height = SCREEN_HEIGHT;
709 TexSkin.Filter = GS_FILTER_NEAREST;
710 gsGlobal->CurrentPointer=0x140000;
711 TexSkin.Vram = gsKit_vram_alloc(gsGlobal,
712 gsKit_texture_size(TexSkin.Width, TexSkin.Height, TexSkin.PSM),
713 GSKIT_ALLOC_USERBUFFER);
714 gsKit_texture_upload(gsGlobal, &TexSkin);
715 free(TexSkin.Mem);
716 testskin = 1;
717 } /* end if */
718 } else if((Picture==PREVIEW_PIC)||(Picture==PREVIEW_GUI)){
719 if( ( ScaleBitmap ( ImgData, Jpg->width, Jpg->height, (void*)&TexPreview.Mem, SCREEN_WIDTH, SCREEN_HEIGHT ) ) != 0 ){
720 TexPreview.PSM = GS_PSM_CT24;
721 TexPreview.VramClut = 0;
722 TexPreview.Clut = NULL;
723 TexPreview.Width = SCREEN_WIDTH;
724 TexPreview.Height = SCREEN_HEIGHT;
725 TexPreview.Filter = GS_FILTER_NEAREST;
726 gsGlobal->CurrentPointer=0x280000;
727 TexPreview.Vram = gsKit_vram_alloc(gsGlobal,
728 gsKit_texture_size(TexPreview.Width, TexPreview.Height, TexPreview.PSM),
729 GSKIT_ALLOC_USERBUFFER);
730 gsKit_texture_upload(gsGlobal, &TexPreview);
731 free(TexPreview.Mem);
732 testsetskin = 1;
733 } /* end if */
734 } else if( Picture == JPG_PIC ){
735 PicW=Jpg->width;
736 PicH=Jpg->height;
737 if(TV_mode == TV_mode_NTSC)
738 PicCoeff=(PicW/PicH)+(1.0f/10.5f);
739 else if(TV_mode == TV_mode_PAL)
740 PicCoeff=(PicW/PicH)-(1.0f/12.0f);
741 if(FullScreen){
742 if(Jpg->width > Jpg->height){
743 PicWidth=928;
744 PicHeight=696;
745 }else{
746 PicHeight=928;
747 PicWidth=696;
748 }
749 }else{
750 if(Jpg->width > Jpg->height){
751 PicWidth=640;
752 PicHeight=512;
753 }else{
754 PicHeight=640;
755 PicWidth=512;
756 }
757 }
758 if((ScaleBitmap(ImgData, Jpg->width, Jpg->height, &ImgData1, (int)PicWidth, Jpg->height))!=0){
759 if((ScaleBitmap(ImgData1, (int)PicWidth, Jpg->height, &ImgData2, (int)PicWidth, (int)PicHeight))!=0){
760 if((PicRotate==1) || (PicRotate==3)){ // Rotate picture
761 (void*)TexPicture.Mem = malloc(((int)PicWidth * (int)PicHeight * 3) + 1);
762 RotateBitmap(ImgData2, (int)PicWidth, (int)PicHeight, (void*)TexPicture.Mem, PicRotate);
763 W=PicW;
764 PicW=PicH;
765 PicH=W;
766 if(TV_mode == TV_mode_NTSC)
767 PicCoeff=(PicW/PicH)+(1.0f/10.5f);
768 else if(TV_mode == TV_mode_PAL)
769 PicCoeff=(PicW/PicH)-(1.0f/12.0f);
770 W=PicWidth;
771 PicWidth=PicHeight;
772 PicHeight=W;
773 }else{
774 memcpy((void*)&TexPicture.Mem, &ImgData2, sizeof(ImgData2));
775 }
776 TexPicture.PSM = GS_PSM_CT24;
777 TexPicture.VramClut = 0;
778 TexPicture.Clut = NULL;
779 TexPicture.Filter = GS_FILTER_NEAREST;
780 TexPicture.Width = PicWidth;
781 TexPicture.Height = PicHeight;
782 if(FullScreen)
783 gsGlobal->CurrentPointer=0x140000;
784 else
785 gsGlobal->CurrentPointer=0x288000;
786 TexPicture.Vram = gsKit_vram_alloc(gsGlobal,
787 gsKit_texture_size(TexPicture.Width, TexPicture.Height, TexPicture.PSM),
788 GSKIT_ALLOC_USERBUFFER);
789 gsKit_texture_upload(gsGlobal, &TexPicture);
790 free(TexPicture.Mem);
791 testjpg = 1;
792 } /* end if */
793 } /* end if */
794 } else if( Picture == THUMB_PIC ){
795 if( ( ScaleBitmap ( ImgData, Jpg->width, Jpg->height, (void*)&TexThumb[ThumbNum].Mem, 64, 32 ) ) != 0 ){
796 TexThumb[ThumbNum].PSM = GS_PSM_CT24;
797 TexThumb[ThumbNum].VramClut = 0;
798 TexThumb[ThumbNum].Clut = NULL;
799 TexThumb[ThumbNum].Width = 64;
800 TexThumb[ThumbNum].Height = 32;
801 TexThumb[ThumbNum].Filter = GS_FILTER_NEAREST;
802 TexThumb[ThumbNum].Vram = gsKit_vram_alloc(gsGlobal,
803 gsKit_texture_size(TexThumb[ThumbNum].Width,
804 TexThumb[ThumbNum].Height, TexThumb[ThumbNum].PSM),
805 GSKIT_ALLOC_USERBUFFER);
806 gsKit_texture_upload(gsGlobal, &TexThumb[ThumbNum]);
807 free(TexThumb[ThumbNum].Mem);
808 testthumb = 1;
809 } /* end if */
810 } /* end else */
811 jpgClose( Jpg );//This really should be moved, but jpg funcs may object
812 } /* end if((jpgReadImage(...)) != -1) */
813 free(ImgData);
814 free(ImgData1);
815 free(ImgData2);
816 } /* end if( (ImgData = malloc(...)) > 0 ) */
817 } /* end if( (Jpg=jpgOpenRAW(...)) > 0 ) */
818 fclose( File );
819 } /* end if( File != NULL ) */
820 if(!strncmp(tmpPath, "cdfs", 4)) CDVD_Stop();
821 if(!strncmp(tmpPath, "hdd0:/", 6))
822 unmountParty(0);
823}
824//--------------------------------------------------------------
825void loadIcon(void)
826{
827 TexIcon[0].Width = 16;
828 TexIcon[0].Height = 16;
829 TexIcon[0].PSM = GS_PSM_CT32;
830 TexIcon[0].Mem = (void*)icon_folder;
831 gsGlobal->CurrentPointer=0x280000;
832 TexIcon[0].Vram = gsKit_vram_alloc(gsGlobal, gsKit_texture_size(TexIcon[0].Width, TexIcon[0].Height, TexIcon[0].PSM), GSKIT_ALLOC_USERBUFFER);
833 TexIcon[0].Filter = GS_FILTER_LINEAR;
834 gsKit_texture_upload(gsGlobal, &TexIcon[0]);
835 free(TexIcon[0].Mem);
836
837 TexIcon[1].Width = 16;
838 TexIcon[1].Height = 16;
839 TexIcon[1].PSM = GS_PSM_CT32;
840 TexIcon[1].Mem = (void*)icon_warning;
841 gsGlobal->CurrentPointer=0x284000;
842 TexIcon[1].Vram = gsKit_vram_alloc(gsGlobal, gsKit_texture_size(TexIcon[0].Width, TexIcon[0].Height, TexIcon[0].PSM), GSKIT_ALLOC_USERBUFFER);
843 TexIcon[1].Filter = GS_FILTER_LINEAR;
844 gsKit_texture_upload(gsGlobal, &TexIcon[1]);
845 free(TexIcon[1].Mem);
846}
847//--------------------------------------------------------------
848int loadFont(char *path_arg)
849{
850 int fd;
851
852 if(strlen(path_arg) != 0 ){
853 char FntPath[MAX_PATH];
854 genFixPath(path_arg, FntPath);
855 fd = genOpen( FntPath, O_RDONLY );
856 if(fd < 0){
857 genClose( fd );
858 goto use_default;
859 } // end if failed open file
860 genLseek( fd, 0, SEEK_SET );
861 if(genLseek( fd, 0, SEEK_END ) > 4700){
862 genClose( fd );
863 goto use_default;
864 }
865 genLseek( fd, 0, SEEK_SET );
866 u8 FontHeader[100];
867 genRead( fd, FontHeader, 100 );
868 if((FontHeader[ 0]==0x00) &&
869 (FontHeader[ 1]==0x02) &&
870 (FontHeader[70]==0x60) &&
871 (FontHeader[72]==0x60) &&
872 (FontHeader[83]==0x90)){
873 genLseek( fd, 1018, SEEK_SET );
874 memset( FontBuffer, 0, 32*16 );
875 genRead( fd, FontBuffer+32*16, 224*16 ); //.fnt files skip 1st 32 chars
876 genClose( fd );
877 return 1;
878 }else{ // end if good fnt file
879 genClose( fd );
880 goto use_default;
881 } // end else bad fnt file
882 }else{ // end if external font file
883use_default:
884 memcpy( FontBuffer, &font_uLE, 4096 );
885 } // end else build-in font
886 return 0;
887}
888//------------------------------
889//endfunc loadFont
890//--------------------------------------------------------------
891// Set Skin Brightness
892void setBrightness(int Brightness)
893{
894 float adjustBright = 128.0F;
895
896 if ( Brightness == 50 ) adjustBright = 128.0F;
897 else adjustBright = (((256.0F/100.0F)*Brightness) + (32.0F*((50.0F-Brightness)/50)));
898
899 if ( adjustBright <= 16.0F ) adjustBright = 16.0F;
900 if ( adjustBright >= 240.0F ) adjustBright = 240.0F;
901
902 BrightColor = GS_SETREG_RGBAQ( adjustBright, adjustBright, adjustBright, 0x80, 0x00 );
903}
904
905//--------------------------------------------------------------
906void clrScr(u64 color)
907{
908 if ( testskin == 1 ) {
909 setBrightness(setting->Brightness);
910 gsKit_clear(gsGlobal, GS_SETREG_RGBAQ(0x00,0x00,0x00,0x00,0x00));
911 gsKit_prim_sprite_texture(gsGlobal,
912 &TexSkin, 0, 0, 0, 0,
913 SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT,
914 0, BrightColor);
915 setBrightness(50);
916 } else {
917 gsKit_prim_sprite(gsGlobal, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, color);
918 } /* end else */
919}
920
921//--------------------------------------------------------------
922void drawScr(void)
923{
924 int sanity_check = 0;
925
926 if(updateScr_2){ //Did we render anything last time
927 while((Timer() < updateScr_t+5) && (sanity_check++ < 10000));
928 //if so, delay to complete rendering
929 }
930 gsKit_sync_flip(gsGlobal); //Await sync and flip buffers
931 gsKit_queue_exec(gsGlobal); //Start rendering recent transfers for NEXT time
932 updateScr_t = Timer(); //Note the time when the rendering started
933 updateScr_2 = updateScr_1; //Note if this rendering had expected updates
934 updateScr_1 = 0; //Note that we've nothing expected for next time
935} //NB: Apparently the GS keeps rendering while we continue with other work
936//--------------------------------------------------------------
937void drawFrame(int x1, int y1, int x2, int y2, u64 color)
938{
939 int y_off = (setting->interlace) ? 0 : (y1 & 1);
940 y1 -= y_off;
941 y2 -= y_off;
942
943 updateScr_1 = 1;
944
945 //Top horizontal edge
946 gsKit_prim_sprite(gsGlobal, x1, y1, x2, y1+LINE_THICKNESS-1, 1, color);
947
948 //Bottom horizontal
949 gsKit_prim_sprite(gsGlobal, x1, y2-LINE_THICKNESS+1, x2, y2, 1, color);
950
951 //Left vertical edge
952 gsKit_prim_sprite(gsGlobal, x1, y1, x1+LINE_THICKNESS-1, y2, 1, color);
953
954 //Right vertical edge
955 gsKit_prim_sprite(gsGlobal, x2-LINE_THICKNESS+1, y1, x2, y2, 1, color);
956}
957
958//--------------------------------------------------------------
959// draw a char using the system font (16x16)
960void drawChar(unsigned int c, int x, int y, u64 colour)
961{
962 int i, j, pixBase, pixMask;
963 u8 *cm;
964
965 updateScr_1 = 1;
966
967 if(!setting->interlace){
968 y = y & -2;
969 }
970
971 if(c >= FONT_COUNT) c = '_';
972 if(c > 0xFF) //if char is beyond normal ascii range
973 cm = &font_uLE[c*16]; // cm points to special char def in default font
974 else //else char is inside normal ascii range
975 cm = &FontBuffer[c*16]; // cm points to normal char def in active font
976
977 pixMask = 0x80;
978 for(i=0; i<8; i++){ //for i == each pixel column
979 pixBase = -1;
980 for(j=0; j<16; j++){ //for j == each pixel row
981 if((pixBase < 0) && (cm[j] & pixMask)){ //if start of sequence
982 pixBase = j;
983 } else if((pixBase > -1) && !(cm[j] & pixMask)){ //if end of sequence
984 gsKit_prim_sprite(gsGlobal, x+i, y+pixBase-1, x+i+1, y+j-1, 1, colour);
985 pixBase = -1;
986 }
987 }//ends for j == each pixel row
988 if(pixBase > -1) //if end of sequence including final row
989 gsKit_prim_sprite(gsGlobal, x+i, y+pixBase-1, x+i+1, y+j-1, 1, colour);
990 pixMask >>= 1;
991 }//ends for i == each pixel column
992}
993//------------------------------
994//endfunc drawChar
995//--------------------------------------------------------------
996// draw a char using the ELISA font (16x16)
997void drawChar2(int n, int x, int y, u64 colour)
998{
999 unsigned int i, j;
1000 u8 b;
1001
1002 updateScr_1 = 1;
1003
1004 if(!setting->interlace){
1005 y = y & -2;
1006 }
1007
1008 for(i=0; i<8; i++)
1009 {
1010 b = elisaFnt[n+i];
1011 for(j=0; j<8; j++)
1012 {
1013 if(b & 0x80) {
1014 gsKit_prim_sprite(gsGlobal, x+j, y+i*2-2, x+j+1, y+i*2, 1, colour);
1015 }
1016 b = b << 1;
1017 }
1018 }
1019}
1020//------------------------------
1021//endfunc drawChar2
1022//--------------------------------------------------------------
1023// draw a string of characters, without shift-JIS support
1024int printXY(const unsigned char *s, int x, int y, u64 colour, int draw, int space)
1025{
1026 unsigned int c1, c2;
1027 int i;
1028 int text_spacing=8;
1029
1030 if(space>0){
1031 while((strlen(s)*text_spacing) > space)
1032 if(--text_spacing<=5)
1033 break;
1034 }else{
1035 while((strlen(s)*text_spacing) > SCREEN_WIDTH-SCREEN_MARGIN-FONT_WIDTH*2)
1036 if(--text_spacing<=5)
1037 break;
1038 }
1039
1040 i=0;
1041 while((c1=s[i++])!=0) {
1042 if(c1 != 0xFF) { // Normal character
1043 if(draw) drawChar(c1, x, y, colour);
1044 x += text_spacing;
1045 if(x > SCREEN_WIDTH-SCREEN_MARGIN-FONT_WIDTH)
1046 break;
1047 continue;
1048 } //End if for normal character
1049 // Here we got a sequence starting with 0xFF ('ÿ')
1050 if((c2=s[i++])==0)
1051 break;
1052 if((c2 < '0') || (c2 > '='))
1053 continue;
1054 c1=(c2-'0')*2+0x100;
1055 if(draw) {
1056 //expand sequence ÿ0=Circle ÿ1=Cross ÿ2=Square ÿ3=Triangle ÿ4=FilledBox
1057 //"ÿ:"=Pad_Right "ÿ;"=Pad_Down "ÿ<"=Pad_Left "ÿ="=Pad_Up
1058 drawChar(c1, x, y, colour);
1059 x += 8;
1060 if(x > SCREEN_WIDTH-SCREEN_MARGIN-FONT_WIDTH)
1061 break;
1062 drawChar(c1+1, x, y, colour);
1063 x += 8;
1064 if(x > SCREEN_WIDTH-SCREEN_MARGIN-FONT_WIDTH)
1065 break;
1066 }
1067 } // ends while(1)
1068 return x;
1069}
1070//------------------------------
1071//endfunc printXY
1072//--------------------------------------------------------------
1073// draw a string of characters, with shift-JIS support (only for gamesave titles)
1074int printXY_sjis(const unsigned char *s, int x, int y, u64 colour, int draw)
1075{
1076 int n;
1077 unsigned char ascii;
1078 u16 code;
1079 int i, j, tmp;
1080
1081 i=0;
1082 while(s[i]){
1083 if((s[i] & 0x80) && s[i+1]) { //we have top bit and some more char ?
1084 // SJIS
1085 code = s[i++];
1086 code = (code<<8) + s[i++];
1087
1088 switch(code){
1089 // Circle == "›"
1090 case 0x819B:
1091 if(draw){
1092 drawChar(0x100, x, y, colour);
1093 drawChar(0x101, x+8, y, colour);
1094 }
1095 x+=16;
1096 break;
1097 // Cross == "~"
1098 case 0x817E:
1099 if(draw){
1100 drawChar(0x102, x, y, colour);
1101 drawChar(0x103, x+8, y, colour);
1102 }
1103 x+=16;
1104 break;
1105 // Square == " "
1106 case 0x81A0:
1107 if(draw){
1108 drawChar(0x104, x, y, colour);
1109 drawChar(0x105, x+8, y, colour);
1110 }
1111 x+=16;
1112 break;
1113 // Triangle == "¢"
1114 case 0x81A2:
1115 if(draw){
1116 drawChar(0x106, x, y, colour);
1117 drawChar(0x107, x+8, y, colour);
1118 }
1119 x+=16;
1120 break;
1121 // FilledBox == "¡"
1122 case 0x81A1:
1123 if(draw){
1124 drawChar(0x108, x, y, colour);
1125 drawChar(0x109, x+8, y, colour);
1126 }
1127 x+=16;
1128 break;
1129 default:
1130 if(elisaFnt!=NULL){ // elisa font is available ?
1131 tmp=y;
1132 if(code<=0x829A) tmp++;
1133 // SJIS‚©‚çEUC‚É•ÏŠ·
1134 if(code >= 0xE000) code-=0x4000;
1135 code = ((((code>>8)&0xFF)-0x81)<<9) + (code&0x00FF);
1136 if((code & 0x00FF) >= 0x80) code--;
1137 if((code & 0x00FF) >= 0x9E) code+=0x62;
1138 else code-=0x40;
1139 code += 0x2121 + 0x8080;
1140
1141 // EUC‚©‚çŒb—œ¹ƒtƒHƒ“ƒg‚̔ԍ†‚𐶐¬
1142 n = (((code>>8)&0xFF)-0xA1)*(0xFF-0xA1)
1143 + (code&0xFF)-0xA1;
1144 j=0;
1145 while(font404[j]) {
1146 if(code >= font404[j]) {
1147 if(code <= font404[j]+font404[j+1]-1) {
1148 n = -1;
1149 break;
1150 } else {
1151 n-=font404[j+1];
1152 }
1153 }
1154 j+=2;
1155 }
1156 n*=8;
1157
1158 if(n>=0 && n<=55008) {
1159 if(draw) drawChar2(n, x, tmp, colour);
1160 x+=9;
1161 }else{
1162 if(draw) drawChar('_', x, y, colour);
1163 x+=8;
1164 }
1165 }else{ //elisa font is not available
1166 ascii=0xFF;
1167 if(code>>8==0x81)
1168 ascii = sjis_lookup_81[code & 0x00FF];
1169 else if(code>>8==0x82)
1170 ascii = sjis_lookup_82[code & 0x00FF];
1171 if(ascii!=0xFF){
1172 if(draw) drawChar(ascii, x, y, colour);
1173 }else{
1174 if(draw) drawChar('_', x, y, colour);
1175 }
1176 x+=8;
1177 }
1178 break;
1179 }
1180 }else{ //First char does not have top bit set or no following char
1181 if(draw) drawChar(s[i], x, y, colour);
1182 i++;
1183 x += 8;
1184 }
1185 if(x > SCREEN_WIDTH-SCREEN_MARGIN-FONT_WIDTH){
1186 //x=16; y=y+8;
1187 return x;
1188 }
1189 }
1190 return x;
1191}
1192//------------------------------
1193//endfunc printXY_sjis
1194//--------------------------------------------------------------
1195//translate a string from shift-JIS to ascii (for gamesave titles)
1196u8 *transcpy_sjis(u8 *d, u8 *s)
1197{
1198 u8 ascii;
1199 u16 code1, code2;
1200 int i, j;
1201
1202 for(i=0, j=0; s[i];){
1203 code1 = s[i++];
1204 if((code1 & 0x80) && s[i]) { //we have top bit and some more char (SJIS) ?
1205 // SJIS
1206 code2 = s[i++];
1207 ascii=0xFF;
1208 if(code1==0x81)
1209 ascii = sjis_lookup_81[code2];
1210 else if(code1==0x82)
1211 ascii = sjis_lookup_82[code2];
1212 if(ascii!=0xFF){
1213 d[j++]=ascii;
1214 }else{
1215 d[j++]='_';
1216 }
1217 }else{ //First char lacks top bit set or no following char (non-SJIS)
1218 d[j++] = code1;
1219 }
1220 }//ends for
1221 d[j] = '\0'; //terminate result string
1222 return d;
1223}
1224//------------------------------
1225//endfunc transcpy_sjis
1226//--------------------------------------------------------------
1227//WriteFont_C is used to save the current font as C source code
1228//Comment it out if not used
1229/*
1230int WriteFont_C(char *path_arg)
1231{
1232 u8 path[MAX_PATH];
1233 u8 text[80*2], char_info[80];
1234 u8 *p;
1235 int ret, tst, i, fd=-1;
1236
1237 ret=-1; tst=genFixPath(path_arg, path);
1238 if(tst < 0) goto finish;
1239 ret=-2; tst=genOpen(path,O_CREAT|O_WRONLY|O_TRUNC);
1240 if(tst < 0) goto finish;
1241 fd = tst;
1242 sprintf(text, "unsigned char font_uLE[] = {\r\n");
1243 ret=-3; tst = genWrite(fd, text, strlen(text));
1244 if(tst != strlen(text)) goto finish;
1245 for(i=0x000; i<0x10A; i++){
1246 p = font_uLE + i*16;
1247 text[0] = '\0';
1248 if((i & 0x07) == 0)
1249 sprintf(text, "//Font position 0x%03X\r\n", i);
1250 if((i < 0x20) || (i>0x80 && i<0xA0))
1251 sprintf(char_info, "//char 0x%03X == '_' (free for use)", i);
1252 else if(i < 0x100)
1253 sprintf(char_info, "//char 0x%03X == '%c'", i, i);
1254 else //(i > 0x0FF)
1255 sprintf(char_info, "//char 0x%03X == special for uLE", i);
1256 sprintf(text+strlen(text),
1257 " 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, %s\r\n"
1258 " 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X"
1259 , p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7], char_info
1260 , p[8],p[9], p[10],p[11], p[12],p[13], p[14],p[15]
1261 );
1262 if(i<0x109) strcat(text, ",");
1263 strcat(text, "\r\n");
1264 ret=-4; tst = genWrite(fd, text, strlen(text));
1265 if(tst != strlen(text)) break;
1266 ret = 0;
1267 } //ends for
1268 if(ret == 0){
1269 sprintf(text,
1270 "//Font position 0x%03X\r\n"
1271 "}; //ends font_uLE\r\n", i);
1272 ret=-5; tst = genWrite(fd, text, strlen(text));
1273 if(tst == strlen(text)) ret = 0;
1274 }
1275finish:
1276 if(fd >= 0) genClose(fd);
1277 sprintf(text,"Saving %s => %d\nChoose either option to continue", path, ret);
1278 ynDialog(text);
1279 return ret;
1280}
1281*/
1282//------------------------------
1283//endfunc WriteFont_C
1284//--------------------------------------------------------------
1285//End of file: draw.c
1286//--------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.