1 /*---------------------------------------------------------------------------*
2 Project: Dolphin
3 File: DEMOPuts.c
4
5 Copyright 1998-2006 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 $Log: DEMOPuts.c,v $
14 Revision 1.9 2008/07/29 07:26:38 nakano_yoshinobu
15 Added comments for ASSERT.
16
17 Revision 1.8 2008/07/29 07:19:07 nakano_yoshinobu
18 Changed vsprintf of DEMORFPrintf to vsnprintf for the buffer overflow measures.
19
20 Revision 1.7 2008/07/23 06:01:47 nakano_yoshinobu
21 Changed vsprintf of DEMOPrintf to vsnprintf for the buffer overflow measures.
22
23 Revision 1.6 2008/05/23 07:34:32 nakano_yoshinobu
24 Fixed ASSERT in DEMOPrintf.
25
26 Revision 1.5 2008/05/22 08:29:35 nakano_yoshinobu
27 Added ASSERT in DEMOPrintf.
28
29 Revision 1.4 2006/08/07 00:08:00 tojo
30 Allocated memory for ROM font by MEM.
31
32 Revision 1.3 2006/02/20 04:19:58 mitu
33 Changed include path from dolphin/ to revolution/.
34
35 Revision 1.2 2006/01/07 07:14:44 hirose
36 Deleted obsolete target codes.
37
38 Revision 1.1.1.1 2005/05/12 02:15:48 yasuh-to
39 Ported from dolphin source tree.
40
41 22 2004/03/10 17:53 Shiki
42 Added support for UTF code.
43
44 21 2003/04/08 21:25 Hirose
45 Fixed a problem with field-rendering mode.
46
47 20 2002/08/22 20:33 Shiki
48 Modified DEMORFPuts() to process tab character.
49
50 19 2001/12/14 9:46 Shiki
51 Fixed DEMODumpROMFont().
52
53 18 2001/07/12 18:02 Shiki
54 Added DEMOGetROMFontSize() and DEMOGetRFTextHeight().
55
56 17 2001/06/11 4:08p Hirose
57 Fixed text alignment problem again.
58
59 16 2001/05/09 10:11p Hirose
60 Renamed some ROM font functions
61
62 15 2001/04/28 1:07p John
63 Fixed MAC build errors:
64 Renamed Size to FontSize
65 Renamed DrawChar to DrawFontChar
66
67 14 2001/04/25 14:29 Shiki
68 Revised ROM font API interface. Added DEMOGetTextWidth().
69
70 13 2001/04/25 11:32 Shiki
71 Added DEMOSetFontSize().
72
73 12 2001/04/19 13:41 Shiki
74 Added ROM font functions.
75
76 11 2000/10/27 3:47p Hirose
77 Fixed build flags
78
79 10 2000/07/07 7:09p Dante
80 PC Compatibility
81
82 9 2000/06/13 5:17p Shiki
83 Fixed DEMOPrintf().
84
85 8 2000/06/06 8:58p Carl
86 Fixed text alignment problem.
87
88 7 2000/05/20 4:57a Hirose
89 Fixed TevOrder and NumChans for drawing captions
90
91 6 2000/05/17 9:08p Hirose
92 Deleted tab codes
93
94 5 2000/05/17 8:53p Hirose
95 Fixed pixel processing mode setting defined in DEMOInitCaption
96
97 4 2000/03/06 11:54a Alligator
98 Changed GXSetDefaultMtx to GXSetCurrentMtx
99
100 3 2000/01/13 5:55p Alligator
101 Integrated with ArtX GX library code
102
103 2 1999/12/10 4:48p Carl
104 Fixed Z compare stuff.
105
106 21 1999/11/12 4:31p Yasu
107 Added GXSetNumTexGens
108
109 20 1999/11/09 7:47p Hirose
110 Added GXSetNumTexGens and GXSetTevOrder
111
112 19 1999/10/29 3:45p Hirose
113 Replaced GXSetTevStages(GXTevStageID) by GXSetNumTevStages(u8)
114
115 18 1999/10/13 6:38p Yasu
116 Rollback 1 level
117
118 16 1999/09/30 10:32p Yasu
119 Renamed and clean up functions and enums.
120
121 15 1999/09/29 10:29p Yasu
122 Parameter of GXSetFogRangeAdj was changed
123
124 14 1999/09/28 6:56p Yasu
125 Changed calling parameter of DEMOInitCaption
126
127 13 1999/09/28 2:46a Yasu
128 Added more initialize works in DEMOInitCaption
129
130 12 1999/09/27 11:03p Yasu
131 Z scale was inversed in DEMOSetupScrnSpc
132
133 11 1999/09/24 6:47p Yasu
134 Changed the parameter of DEMOsetuoScrnSpc().
135
136 10 1999/09/24 6:34p Yasu
137 Let DEMOSetupScrnSpc() out of DEMOInitCaption()
138
139 9 1999/09/21 5:24p Yasu
140 Changed function name cmMtxScreen -> DEMOMtxScreen.
141
142 8 1999/09/14 5:12p Yasu
143 Fixed small bug.
144
145 7 1999/09/14 4:57p Yasu
146 Moved it into the demo library.
147 Changed APIs to simpler.
148
149 6 1999/09/10 6:38a Yasu
150 Added small letters.
151 Added some type cast to avoid warning message
152
153 5 1999/09/07 9:52p Yasu
154 Changed file name and prefix
155
156 4 1999/09/01 5:45p Ryan
157
158 3 1999/08/28 12:08a Yasu
159 Changed enum name GX_MAT_3x4 -> GX_MTX3x4
160
161 2 1999/08/26 7:55p Yasu
162 Changed function name.
163
164 1 1999/08/25 6:21p Yasu
165 Initial version
166 $NoKeywords: $
167 *---------------------------------------------------------------------------*/
168 #include <revolution.h>
169 #include <stdio.h>
170 #include <stdarg.h>
171 #include <string.h>
172 #include <demo.h>
173
174 extern u32 DemoUseMEMHeap;
175
176 extern MEMAllocator DemoAllocator1;
177 extern MEMAllocator DemoAllocator2;
178
179
180 //============================================================================
181 // Font data
182 //============================================================================
183 static s32 fontShift = 0;
184 static GXTexObj fontTexObj;
185
186 //============================================================================
187 // Functions
188 //============================================================================
189
190 /*---------------------------------------------------------------------------*
191 Name: DEMOSetFontType
192 Description: Set font type
193 Arguments: s32 attr: Font attribute id
194 Returns: None.
195 *---------------------------------------------------------------------------*/
DEMOSetFontType(s32 attr)196 void DEMOSetFontType( s32 attr )
197 {
198 // Font type
199 switch ( attr )
200 {
201 case DM_FT_RVS:
202 // Reverse mode
203 GXSetBlendMode( GX_BM_LOGIC, GX_BL_ZERO, GX_BL_ZERO, GX_LO_INVCOPY );
204 break;
205
206 case DM_FT_XLU:
207 // Translucent mode
208 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR );
209 break;
210
211 case DM_FT_OPQ:
212 default:
213 // Normal mode
214 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR );
215 break;
216 }
217 return;
218 }
219
220 /*---------------------------------------------------------------------------*
221 Name: DEMOLoadFont
222 Description: Prepare font texture
223 Arguments: DMTexFlt texFlt: DMTF_BILERP/DMTF_POINTSAMPLE
224 GXBool bilerp: if you need bilerp image, set this
225 Returns: None.
226 *---------------------------------------------------------------------------*/
DEMOLoadFont(GXTexMapID texMap,GXTexMtx texMtx,DMTexFlt texFlt)227 void DEMOLoadFont( GXTexMapID texMap, GXTexMtx texMtx, DMTexFlt texFlt )
228 {
229 Mtx fontTMtx;
230 u16 width = 64;
231 u16 height = (u16)( (0x80-0x20)*8*8 / width );
232
233 // Set up and load texture object
234 GXInitTexObj( &fontTexObj, // obj
235 DEMOFontBitmap, // image_ptr
236 width, // weight
237 height, // height
238 GX_TF_I4, // format
239 GX_CLAMP, // wrap_s (don't care)
240 GX_CLAMP, // wrap_t (don't care)
241 GX_FALSE ); // mipmap (don't care)
242
243 if ( texFlt == DMTF_POINTSAMPLE )
244 {
245 GXInitTexObjLOD( &fontTexObj,
246 GX_NEAR, // min_filt
247 GX_NEAR, // max_filt
248 0.0f, // min_lod (don't care)
249 0.0f, // max_lod (don't care)
250 0.0f, // lod_bias (don't care)
251 GX_DISABLE, // bias_clamp (don't care)
252 GX_FALSE, // do_edge_lod (don't care)
253 GX_ANISO_1 ); // max_aniso (don't care)
254 fontShift = 0;
255 }
256 else
257 {
258 fontShift = 1;
259 }
260
261 GXLoadTexObj( &fontTexObj, texMap );
262
263 // Set texture matrix to fit texture coordinate to texel (1:1)
264 // Set up texture coord-gen
265 MTXScale( fontTMtx, 1.0f/(float)width, 1.0f/(float)height, 1.0f );
266
267 GXLoadTexMtxImm( fontTMtx, texMtx, GX_MTX2x4 );
268 GXSetNumTexGens( 1 );
269 GXSetTexCoordGen( GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, texMtx );
270
271 return;
272 }
273
274 /*---------------------------------------------------------------------------*
275 Name: DEMOSetupScrnSpc
276 Description: Set matrices up to screen coordinates system
277 Arguments:
278
279 Returns: None.
280 *---------------------------------------------------------------------------*/
DEMOSetupScrnSpc(s32 width,s32 height,float depth)281 void DEMOSetupScrnSpc( s32 width, s32 height, float depth )
282 {
283 Mtx44 pMtx;
284 Mtx mMtx;
285 f32 top;
286
287 if ( DEMOGetRenderModeObj()->field_rendering && !VIGetNextField() )
288 {
289 top = -0.667F;
290 }
291 else
292 {
293 top = 0.00F;
294 }
295
296 MTXOrtho( pMtx, top, (float)height, 0.0f, (float)width, 0.0f, -depth );
297 GXSetProjection( pMtx, GX_ORTHOGRAPHIC );
298 MTXIdentity( mMtx );
299 GXLoadPosMtxImm( mMtx, GX_PNMTX0 );
300 GXSetCurrentMtx( GX_PNMTX0 );
301
302 return;
303 }
304
305 /*---------------------------------------------------------------------------*
306 Name: DEMOInitCaption
307 Description: Set rendering pipe to default caption drawing mode
308 Arguments:
309
310 Returns: None.
311 *---------------------------------------------------------------------------*/
DEMOInitCaption(s32 font_type,s32 width,s32 height)312 void DEMOInitCaption( s32 font_type, s32 width, s32 height )
313 {
314 // Set matrices
315 DEMOSetupScrnSpc( width, height, 100.0f );
316
317 // Set pixel processing mode
318 GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE );
319
320 // Set TEV parameters to "REPLACE COLOR"
321 GXSetNumChans( 0 );
322 GXSetNumTevStages( 1 );
323 GXSetTevOp( GX_TEVSTAGE0, GX_REPLACE );
324 GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL );
325
326 // Load Font
327 DEMOLoadFont( GX_TEXMAP0, GX_TEXMTX0, DMTF_POINTSAMPLE );
328
329 // Set font attr to normal
330 DEMOSetFontType( font_type );
331
332 return;
333 }
334
335 /*---------------------------------------------------------------------------*
336 Name: DEMOPuts
337 Description: Output strings until detects NULL code
338 Arguments: s16 x, y, z: Coordinate at the origin
339 char *string: Output strings
340 Returns: None.
341 *---------------------------------------------------------------------------*/
DEMOPuts(s16 x,s16 y,s16 z,char * string)342 void DEMOPuts( s16 x, s16 y, s16 z, char* string )
343 {
344 char* str = string;
345 s32 s, t;
346 s32 c, w, len, i;
347
348 // Set up vertex descriptors
349 GXClearVtxDesc();
350 GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
351 GXSetVtxDesc( GX_VA_TEX0, GX_DIRECT );
352 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0 );
353 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 1 );
354
355 len = 0;
356 while (1)
357 {
358 // Search visible letters
359 c = *str ++;
360 if ( ' ' <= c && c <= 0x7f )
361 {
362 len ++;
363 }
364 // Check if end of line
365 else
366 {
367 if ( len > 0 )
368 {
369 // Put a line
370 GXBegin( GX_QUADS, GX_VTXFMT0, (u16)(len*4) );
371 for ( i = 0; i < len; i ++ )
372 {
373 // Draw a letter
374 w = string[i] - ' ';
375 s = ( w % 8 ) * 16 + fontShift;
376 t = ( w / 8 ) * 16 + fontShift;
377 GXPosition3s16( (s16)(i*8+x ), (s16)(y ), z );
378 GXTexCoord2s16( (s16)(s ), (s16)(t ) );
379 GXPosition3s16( (s16)(i*8+x+8), (s16)(y ), z );
380 GXTexCoord2s16( (s16)(s+16 ), (s16)(t ) );
381 GXPosition3s16( (s16)(i*8+x+8), (s16)(y+8 ), z );
382 GXTexCoord2s16( (s16)(s+16 ), (s16)(t+16) );
383 GXPosition3s16( (s16)(i*8+x ), (s16)(y+8 ), z );
384 GXTexCoord2s16( (s16)(s ), (s16)(t+16) );
385 }
386 GXEnd( );
387 len = 0;
388 }
389 string = str;
390 // Continue if CR/LF
391 if ( c == '\n' ) y += 8;
392 // Terminate if else
393 else break;
394 }
395 }
396 return;
397 }
398
399 /*---------------------------------------------------------------------------*
400 Name: DEMOPrintf
401 Description: Output formatted strings
402 Strings must be shorter than 256 words.
403 Arguments: s16 x, y, z: Coordinate at the origin.
404 char *fmt: Format string
405 ...: Any other parameter
406 Returns: None.
407 *---------------------------------------------------------------------------*/
DEMOPrintf(s16 x,s16 y,s16 z,char * fmt,...)408 void DEMOPrintf( s16 x, s16 y, s16 z, char* fmt, ... )
409 {
410 va_list vlist;
411 char buf[256];
412 int stringSize;
413
414 // Get output string
415 va_start( vlist, fmt );
416 stringSize = vsnprintf( buf, 256, fmt, vlist );
417 // Assert for over string size
418 ASSERT( stringSize < 256 );
419 va_end( vlist );
420
421 // Feed to puts
422 DEMOPuts( x, y, z, buf );
423
424 return;
425 }
426
427 //============================================================================
428 //
429 // ROM Font data and functions
430 //
431 //============================================================================
432
433 static OSFontHeader* FontData;
434 static void* LastSheet;
435 static s16 FontSize; // GX_S16, 4
436 static s16 FontSpace; // GX_S16, 4
437
438 /*---------------------------------------------------------------------------*
439 Name: DEMOInitROMFont
440
441 Description: Allocates font buffer from the heap and initializes ROM
442 font
443
444 Arguments: None
445
446 Returns: Pointer to font data
447 *---------------------------------------------------------------------------*/
DEMOInitROMFont(void)448 OSFontHeader* DEMOInitROMFont(void)
449 {
450 switch (OSGetFontEncode())
451 {
452 case OS_FONT_ENCODE_SJIS:
453 if (DemoUseMEMHeap)
454 {
455 FontData = MEMAllocFromAllocator(&DemoAllocator1, OS_FONT_SIZE_SJIS);
456 }
457 else
458 {
459 FontData = OSAlloc(OS_FONT_SIZE_SJIS);
460 }
461 break;
462 case OS_FONT_ENCODE_ANSI:
463 if (DemoUseMEMHeap)
464 {
465 FontData = MEMAllocFromAllocator(&DemoAllocator1, OS_FONT_SIZE_ANSI);
466 }
467 else
468 {
469 FontData = OSAlloc(OS_FONT_SIZE_ANSI);
470 }
471 break;
472 default:
473 if (DemoUseMEMHeap)
474 {
475 FontData = MEMAllocFromAllocator(&DemoAllocator1, OS_FONT_SIZE_UTF);
476 }
477 else
478 {
479 FontData = OSAlloc(OS_FONT_SIZE_UTF);
480 }
481 break;
482 }
483 if (!FontData)
484 {
485 OSHalt("Ins. memory to load ROM font.");
486 }
487 if (!OSInitFont(FontData))
488 {
489 OSHalt("ROM font is available in boot ROM ver 0.8 or later.");
490 }
491
492 FontSize = (s16) (FontData->cellWidth * 16);
493 FontSpace = -16;
494
495 return FontData;
496 }
497
498 /*---------------------------------------------------------------------------*
499 Name: DEMOSetROMFontSize
500
501 Description: Specifies the font size
502
503 Arguments: size Font size
504 space Character space
505
506 Returns: None
507 *---------------------------------------------------------------------------*/
DEMOSetROMFontSize(s16 size,s16 space)508 void DEMOSetROMFontSize(s16 size, s16 space)
509 {
510 FontSize = (s16) (size * 16);
511 FontSpace = (s16) (space * 16);
512 }
513
514 /*---------------------------------------------------------------------------*
515 Name: DEMOGetROMFontSize
516
517 Description: Gets the current font size
518
519 Arguments: size Font size
520 space Character space
521
522 Returns: None
523 *---------------------------------------------------------------------------*/
DEMOGetROMFontSize(s16 * size,s16 * space)524 void DEMOGetROMFontSize(s16* size, s16* space)
525 {
526 if (size)
527 {
528 *size = (s16) (FontSize / 16);
529 }
530 if (space)
531 {
532 *space = (s16) (FontSpace / 16);
533 }
534 }
535
DrawFontChar(int x,int y,int z,int xChar,int yChar)536 static void DrawFontChar(int x, int y, int z, int xChar, int yChar)
537 {
538 s16 posLeft = (s16) x;
539 s16 posRight = (s16) (posLeft + FontSize);
540 s16 posTop = (s16) (y - (FontData->ascent * FontSize / FontData->cellWidth));
541 s16 posBottom = (s16) (y + (FontData->descent * FontSize / FontData->cellWidth));
542
543 s16 texLeft = (s16) xChar;
544 s16 texRight = (s16) (xChar + FontData->cellWidth);
545 s16 texTop = (s16) yChar;
546 s16 texBottom = (s16) (yChar + FontData->cellHeight);
547
548 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
549 GXPosition3s16(posLeft , posTop , (s16) z);
550 GXTexCoord2s16(texLeft , texTop );
551
552 GXPosition3s16(posRight, posTop , (s16) z);
553 GXTexCoord2s16(texRight, texTop );
554
555 GXPosition3s16(posRight, posBottom, (s16) z);
556 GXTexCoord2s16(texRight, texBottom );
557
558 GXPosition3s16(posLeft , posBottom, (s16) z);
559 GXTexCoord2s16(texLeft , texBottom );
560 GXEnd();
561 }
562
LoadSheet(void * image,GXTexMapID texMapID)563 static void LoadSheet(void* image, GXTexMapID texMapID)
564 {
565 Mtx mtx;
566 GXTexObj texObj;
567
568 if (LastSheet == image)
569 {
570 return;
571 }
572 LastSheet = image;
573
574 // Set up and load texture object
575 GXInitTexObj(&texObj, // obj
576 image, // image_ptr
577 FontData->sheetWidth, // weight
578 FontData->sheetHeight, // height
579 (GXTexFmt) FontData->sheetFormat, // format
580 GX_CLAMP, // wrap_s (don't care)
581 GX_CLAMP, // wrap_t (don't care)
582 GX_FALSE); // mipmap (don't care)
583
584 GXInitTexObjLOD(&texObj,
585 GX_LINEAR, // min_filt
586 GX_LINEAR, // max_filt
587 0.0f, // min_lod (don't care)
588 0.0f, // max_lod (don't care)
589 0.0f, // lod_bias (don't care)
590 GX_DISABLE, // bias_clamp (don't care)
591 GX_FALSE, // do_edge_lod (don't care)
592 GX_ANISO_1); // max_aniso (don't care)
593
594 GXLoadTexObj(&texObj, texMapID);
595 MTXScale(mtx, 1.0f / FontData->sheetWidth,
596 1.0f / FontData->sheetHeight,
597 1.0f);
598 GXLoadTexMtxImm(mtx, GX_TEXMTX0, GX_MTX2x4);
599 GXSetNumTexGens(1);
600 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0);
601 }
602
603 /*---------------------------------------------------------------------------*
604 Name: DEMORFPuts
605
606 Description: Draw the specified string with ROM font
607
608 Arguments: x Baseline horizontal position
609 y Baseline vertical position
610 string Output strings
611
612 Returns: Total string width in texels
613 *---------------------------------------------------------------------------*/
DEMORFPuts(s16 x,s16 y,s16 z,char * string)614 int DEMORFPuts(s16 x, s16 y, s16 z, char* string)
615 {
616 s32 cx;
617 void* image;
618 s32 xChar;
619 s32 yChar;
620 s32 width;
621
622 ASSERT(FontData);
623
624 LastSheet = 0;
625
626 // Set up vertex descriptors
627 GXClearVtxDesc();
628 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
629 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
630 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 4);
631 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
632
633 // Convert to GX_S16, 4 format
634 x *= 16;
635 y *= 16;
636 z *= 16;
637
638 width = 0;
639 while (*string)
640 {
641 if (*string == '\n')
642 {
643 width = 0;
644 y += FontData->leading * FontSize / FontData->cellWidth;
645 ++string;
646 continue;
647 }
648
649 if (*string == '\t')
650 {
651 width += 8 * (FontSize + FontSpace);
652 width -= width % (8 * (FontSize + FontSpace));
653 ++string;
654 continue;
655 }
656
657 string = OSGetFontTexture(string, &image, &xChar, &yChar, &cx);
658
659 LoadSheet(image, GX_TEXMAP0);
660 DrawFontChar(x + width, y, z, xChar, yChar);
661 width += FontSize * cx / FontData->cellWidth + FontSpace;
662 }
663 return (width + 15) / 16;
664 }
665
DEMORFPutsEx(s16 x,s16 y,s16 z,char * string,s16 maxWidth,int length)666 int DEMORFPutsEx(s16 x, s16 y, s16 z, char* string, s16 maxWidth, int length)
667 {
668 s32 cx;
669 void* image;
670 s32 xChar;
671 s32 yChar;
672 s32 width;
673 char* end;
674
675 ASSERT(FontData);
676
677 LastSheet = 0;
678
679 // Set up vertex descriptors
680 GXClearVtxDesc();
681 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
682 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
683 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 4);
684 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
685
686 // Convert to GX_S16, 4 format
687 x *= 16;
688 y *= 16;
689 z *= 16;
690 maxWidth *= 16;
691
692 end = string + length;
693 width = 0;
694 while (*string && string < end)
695 {
696 // Line break
697 if (*string == '\n')
698 {
699 width = 0;
700 y += FontData->leading * FontSize / FontData->cellWidth;
701 ++string;
702 continue;
703 }
704
705 string = OSGetFontTexture(string, &image, &xChar, &yChar, &cx);
706
707 // Line break
708 if (maxWidth < width + FontSize * cx / FontData->cellWidth + FontSpace)
709 {
710 width = 0;
711 y += FontData->leading * FontSize / FontData->cellWidth;
712 }
713
714 LoadSheet(image, GX_TEXMAP0);
715 DrawFontChar(x + width, y, z, xChar, yChar);
716 width += FontSize * cx / FontData->cellWidth + FontSpace;
717 }
718 return (width + 15) / 16;
719 }
720
721 /*---------------------------------------------------------------------------*
722 Name: DEMORFPrintf
723
724 Description: Output formatted strings with ROM font
725 Strings must be shorter than 256 words.
726
727 Arguments: s16 x, y, z: Coordinate at the origin.
728 char *fmt: Format string
729 ...: Any other parameter
730
731 Returns: Total string width in texels
732 *---------------------------------------------------------------------------*/
DEMORFPrintf(s16 x,s16 y,s16 z,char * fmt,...)733 int DEMORFPrintf(s16 x, s16 y, s16 z, char* fmt, ...)
734 {
735 va_list vlist;
736 char buf[256];
737 int stringSize;
738
739 // Get output string
740 va_start( vlist, fmt );
741 stringSize = vsnprintf( buf, 256, fmt, vlist );
742 // Assert for over string size
743 ASSERT( stringSize < 256 );
744 va_end( vlist );
745
746 // Feed to puts
747 return DEMORFPuts(x, y, z, buf);
748 }
749
750 /*---------------------------------------------------------------------------*
751 Name: DEMODumpROMFont
752
753 Description: Dumps the ROM font data to debug output
754
755 Arguments: string Output strings
756
757 Returns: Pointer to the next character
758 *---------------------------------------------------------------------------*/
DEMODumpROMFont(char * string)759 char* DEMODumpROMFont(char* string)
760 {
761 u32 image[48/2*48/4]; // 48 x 48
762 void* temp;
763 int i, j;
764 s32 width;
765
766 ASSERT(FontData);
767
768 switch (OSGetFontEncode())
769 {
770 case OS_FONT_ENCODE_SJIS:
771 temp = (u8*) FontData + OS_FONT_SIZE_SJIS - OS_FONT_ROM_SIZE_SJIS;
772 break;
773 case OS_FONT_ENCODE_ANSI:
774 temp = (u8*) FontData + OS_FONT_SIZE_ANSI - OS_FONT_ROM_SIZE_ANSI;
775 break;
776 default:
777 temp = (u8*) FontData + OS_FONT_SIZE_UTF - OS_FONT_ROM_SIZE_UTF;
778 break;
779 }
780 temp = (void*) OSRoundDown32B(temp);
781 OSLoadFont(FontData, temp);
782
783 // Clear image buffer by zero since OSGetFontTexel() copies out
784 // font texels using logical OR.
785 memset(image, 0x00, sizeof(image));
786
787 // OSGetFontTexel() only works with the compressed font data
788 // read by OSLoadFont().
789 string = OSGetFontTexel(string, image, 0, 48 / 4, &width);
790
791 for (i = 0; i < 48; i++)
792 {
793 j = 48 * (i / 8) + (i % 8);
794 OSReport("%08x%08x%08x%08x%08x%08x\n",
795 image[j], image[j + 32/4], image[j + 64/4],
796 image[j + 96/4], image[j + 128/4], image[j + 160/4]);
797 }
798
799 OSReport("\nwidth %d\n", width);
800
801 OSInitFont(FontData); // To re-expand compressed data
802
803 return string;
804 }
805
806 /*---------------------------------------------------------------------------*
807 Name: DEMOGetRFTextWidth
808
809 Description: Computes the width of the specified string
810
811 Arguments: string Point to character string
812
813 Returns: Total string width in texels
814 *---------------------------------------------------------------------------*/
DEMOGetRFTextWidth(char * string)815 int DEMOGetRFTextWidth(char* string)
816 {
817 s32 cx;
818 s32 width;
819 s32 maxWidth;
820
821 ASSERT(FontData);
822
823 maxWidth = width = 0;
824 while (*string)
825 {
826 if (*string == '\n')
827 {
828 if (maxWidth < width)
829 {
830 maxWidth = width;
831 }
832 width = 0;
833 }
834 string = OSGetFontWidth(string, &cx);
835 width += FontSize * cx / FontData->cellWidth + FontSpace;
836 }
837 if (maxWidth < width)
838 {
839 maxWidth = width;
840 }
841 return (maxWidth + 15) / 16;
842 }
843
844 /*---------------------------------------------------------------------------*
845 Name: DEMOGetRFTextHeight
846
847 Description: Computes the height of the specified string
848
849 Arguments: string Point to character string
850
851 Returns: Total string height in texels
852 *---------------------------------------------------------------------------*/
DEMOGetRFTextHeight(char * string)853 int DEMOGetRFTextHeight(char* string)
854 {
855 s32 height;
856
857 ASSERT(FontData);
858
859 height = 1;
860 while (*string)
861 {
862 if (*string == '\n')
863 {
864 ++height;
865 }
866 ++string;
867 }
868 height *= FontData->leading * FontSize / FontData->cellWidth;
869 return (height + 15) / 16;
870 }
871
872 /*======== End of DEMOPuts.c ========*/
873