1 /*---------------------------------------------------------------------------*
2
3 Copyright (C) Nintendo. All rights reserved.
4
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10
11 *---------------------------------------------------------------------------*/
12 ////===========================================================================
13 /// demoFont.c
14 ///
15 /// This is font code for the demo library.
16 ///
17 ////===========================================================================
18 #include <stdarg.h>
19 #include <stdio.h>
20
21 #include <cafe/demo.h>
22 #include <cafe/demo/demoFontData.h> // Font Data
23 #include <cafe/gfd.h>
24
25 //---------------------------------------------------------------------------
26 // Shader Data
27 //---------------------------------------------------------------------------
28 static const char * const FONT_GSH_SHADER_FILE = "shaders/lib_demo/cafe/demoFont.gsh";
29
30 // --------------------------------------------------------------------------
31 // Macro definitions
32 // --------------------------------------------------------------------------
33 // Max Buffer Size for vsnprintf_s
34 #define FONT_MAX_BUFSIZ 512
35
36
37 // Simple structure that contains all the data
38 // we need to know about characters in the font texture
39 typedef struct
40 {
41 u32 id;
42 s32 minS;
43 s32 minT;
44 s32 maxS;
45 s32 maxT;
46 s32 minX;
47 s32 minY;
48 s32 maxX;
49 s32 maxY;
50 s32 xAdvance;
51 } CharContainer_t;
52
53 typedef struct
54 {
55 // Contains all the data we need to render each character
56 CharContainer_t* pCharDataBuffer;
57
58 // Font texture height
59 f32 fontTextureWidth;
60
61 // Font texture width
62 f32 fontTextureHeight;
63
64 // The number of characters stored in the raw char data
65 u32 numCharData;
66
67 // The offset height of grid
68 f32 gridOffsetY;
69
70 // The offset width of grid
71 f32 gridOffsetX;
72
73 // Pointer to Font Image Data
74 u8* pFontImageData;
75
76 // --- GPU MEM ---
77 // includes pointer to buffer containing the Texture image Data
78 GX2Texture TexData;
79 } FontData_t;
80
81 // DEMO Font Context State
82 static GX2ContextState *DEMOFontContextState;
83
84 // P: Proportional, F: Fixed mono_space
85 static FontData_t s_FontP, s_FontF;
86 static GX2Sampler s_sampler = {0};
87 static DEMOGfxShader s_Shader = {0};
88 static BOOL s_enabled=TRUE;
89
90 // Max number of unique characters defined in each font
91 #define MAX_NUM_CHARS 100
92 static CharContainer_t s_CharDataBufferP[MAX_NUM_CHARS];
93 static CharContainer_t s_CharDataBufferF[MAX_NUM_CHARS];
94
95 // Instance
96 static DEMOFontInstance* gDemoFontCurInstance = NULL;
97
98 //--------------------------------------------------------------------------
99 // Forward references
100 //--------------------------------------------------------------------------
101 static FontData_t* GetCurrentFont(void);
102 static void UpdateScale(DEMOFontFontData* pFont, f32 scaleX, f32 scaleY);
103 static void SetFontTexture(DEMOGfxShader* pShader, FontData_t* pFont);
104 static void GetFontCharData(FontData_t* pFont,
105 const u32* pFontHeader,
106 const u32* pCharData,
107 const u8* pFontImageData);
108 static void InitFontTexture(DEMOGfxShader* pShader, FontData_t* pFont);
109 static void InitShader(DEMOGfxShader* pShader);
110 static u32 BSearchIndex(FontData_t* pFont, u32 id);
111
112 // --------------------------------------------------------------------------
113 // Init
114 // --------------------------------------------------------------------------
DEMOFontInit()115 DEMOFontInstance* DEMOFontInit()
116 {
117 // Get Font char data
118 GetFontCharData(&s_FontF,
119 s_FontHeaderF, (u32*)s_CharDataF, s_FontImageDataF);
120
121 GetFontCharData(&s_FontP,
122 s_FontHeaderP, (u32*)s_CharDataP, s_FontImageDataP);
123
124 // Initialise Shader
125 InitShader(&s_Shader);
126
127 // Initialize Font Texture
128 InitFontTexture(&s_Shader, &s_FontP);
129 InitFontTexture(&s_Shader, &s_FontF);
130
131 DEMOFontAddInstance();
132
133 // Restore state
134 DEMOGfxSetContextState();
135
136 return gDemoFontCurInstance;
137 }
138
139 // --------------------------------------------------------------------------
140 // ShutDown
141 // --------------------------------------------------------------------------
DEMOFontShutdown(void)142 void DEMOFontShutdown(void)
143 {
144 // Delete the instance
145 DEMOFontDeleteInstance(gDemoFontCurInstance);
146
147 // Free shaders
148 DEMOGfxFreeShaders(&s_Shader);
149
150 // Free texture
151 if (s_FontP.TexData.surface.imagePtr) {
152 DEMOGfxFreeMEM2(s_FontP.TexData.surface.imagePtr);
153 }
154 if (s_FontF.TexData.surface.imagePtr) {
155 DEMOGfxFreeMEM2(s_FontF.TexData.surface.imagePtr);
156 }
157 }
158
159 // --------------------------------------------------------------------------
160 // Context State
161 // --------------------------------------------------------------------------
DEMOFontSetContextState(void)162 void DEMOFontSetContextState(void)
163 {
164 GX2UTDebugTagIndent("DEMOFontSetContextState()");
165 GX2SetContextState(DEMOFontContextState);
166 GX2UTDebugTagUndent();
167 }
168
169 // --------------------------------------------------------------------------
170 // Enable
171 // --------------------------------------------------------------------------
DEMOFontDrawEnable(BOOL enable)172 void DEMOFontDrawEnable(BOOL enable)
173 {
174 s_enabled = enable;
175
176 // MUST verify the instance exists before setting it!
177 if (gDemoFontCurInstance)
178 gDemoFontCurInstance->enabled = enable;
179 }
180
181 // --------------------------------------------------------------------------
182 // Printf
183 // --------------------------------------------------------------------------
DEMOFontPrintf(f32 column,f32 line,const char * pFmt,...)184 void DEMOFontPrintf(f32 column, f32 line, const char* pFmt, ... )
185 {
186 char str[FONT_MAX_BUFSIZ];
187 va_list args;
188 s32 stringSize;
189
190 // Don't draw if fonts are disabled
191 if (!gDemoFontCurInstance->enabled) return;
192
193 // Get string
194 va_start(args, pFmt);
195 stringSize = vsnprintf( str, FONT_MAX_BUFSIZ, pFmt, args );
196
197 // Assert for over string size
198 if ( stringSize < 0 )
199 {
200 DEMOAssert(!"String is too long\n");
201 }
202
203 va_end(args);
204
205 DEMOFontPuts( column, line, str );
206 }
207
DEMOFontPuts(f32 column,f32 line,const char * pStr)208 void DEMOFontPuts(f32 column, f32 line, const char* pStr)
209 {
210 u32 stringLength;
211 s32 offsetX;
212 s32 offsetY;
213 FontData_t* pFont = GetCurrentFont();
214 DEMOFontFontData* pFontData = &gDemoFontCurInstance->font;
215 f32 basePos[3];
216 u32 advanceX = 0;
217 u32 indices[FONT_MAX_BUFSIZ*4];
218 u32 indCount;
219 u32 cIn = 0;
220
221 // Don't draw if fonts are disabled
222 if (!gDemoFontCurInstance->enabled) return;
223
224 // Check the initialize
225 DEMOAssert(pStr &&
226 "Need to initialize pStr.\n");
227 DEMOAssert(pFont->pCharDataBuffer &&
228 "Need to call DEMOFontInit(). Before this function.\n");
229
230 stringLength = (u32)(strlen((const char *)pStr));
231
232 // Calc offsets
233 offsetX = (s32)(column * pFont->gridOffsetX);
234 offsetY = -(s32)((line + 1) * pFont->gridOffsetY);
235
236 // Set up rendering state
237 SetFontTexture(&s_Shader, pFont);
238
239 // Update scale
240 GX2SetVertexUniformReg(s_Shader.uniformsVS.location[1], 1*4, &pFontData->charMagScale[0]);
241
242 // Update color uniform
243 GX2SetPixelUniformReg(s_Shader.uniformsPS.location[0], 1*4, &pFontData->color);
244
245 basePos[2] = pFontData->depth;
246
247 while (cIn < stringLength) {
248
249 basePos[0] = (f32) offsetX;
250 basePos[1] = (f32) offsetY;
251
252 indCount = 0;
253
254 for(; cIn < stringLength; cIn++) {
255
256 u32 id = (u32) pStr[cIn];
257 u32 index = 0;
258 u32 px1, px2, py1, py2;
259 u32 ps1, ps2, pt1, pt2;
260
261 if(id == 10)
262 {
263 advanceX = 0;
264 offsetY -= pFont->gridOffsetY;
265 cIn++;
266 break;
267 }
268 else if(id >= 32 && id <= 127)
269 {
270 // Get index of character id
271 index = BSearchIndex(pFont,id);
272 }
273
274 px1 = (u32)(pFont->pCharDataBuffer[index].minX + advanceX);
275 px2 = (u32)(pFont->pCharDataBuffer[index].maxX + advanceX);
276 py1 = (u32)(pFont->pCharDataBuffer[index].minY);
277 py2 = (u32)(pFont->pCharDataBuffer[index].maxY);
278
279 // If we exceed the bitfield for advanceX, reset base
280 if (px2 > 0xfff) {
281 offsetX += advanceX;
282 advanceX = 0;
283 break;
284 }
285
286 ps1 = (u32)pFont->pCharDataBuffer[index].minS;
287 ps2 = (u32)pFont->pCharDataBuffer[index].maxS;
288 pt1 = (u32)pFont->pCharDataBuffer[index].minT;
289 pt2 = (u32)pFont->pCharDataBuffer[index].maxT;
290
291 #define CHECK(px, py, tx, ty) \
292 DEMOAssert(!((px)&~0xfff)&&!((py)&~0x1f)&&!((tx)&~0xff)&&!((ty)&~0x7f))
293 #define PACK(px, py, tx, ty) (((px)<<20)|((py)<<15)|((tx)<<7)|(ty))
294
295 CHECK(px1, py1, ps1, pt1);
296 CHECK(px2, py2, ps2, pt2);
297
298 indices[indCount++] = PACK(px1, py1, ps1, pt1);
299 indices[indCount++] = PACK(px1, py2, ps1, pt2);
300 indices[indCount++] = PACK(px2, py2, ps2, pt2);
301 indices[indCount++] = PACK(px2, py1, ps2, pt1);
302
303 advanceX += pFont->pCharDataBuffer[index].xAdvance;
304 }
305
306 // Skip blank lines
307 if (indCount == 0) continue;
308
309 // Set base position
310 GX2SetVertexUniformReg(s_Shader.uniformsVS.location[0], 1*4, &basePos);
311
312 // Draw the characters
313 GX2DrawIndexedImmediate(GX2_PRIMITIVE_QUADS,
314 indCount,
315 GX2_INDEX_FORMAT_U32,
316 indices);
317 }
318 }
319
320 // --------------------------------------------------------------------------
321 // Update
322 // --------------------------------------------------------------------------
DEMOFontSetSpacing(BOOL proportional)323 void DEMOFontSetSpacing(BOOL proportional)
324 {
325 // Check the initialize
326 DEMOAssert(s_FontP.pCharDataBuffer &&
327 "Need to call DEMOFontInit(). Before this function.\n");
328
329 // Update proportional boolean
330 gDemoFontCurInstance->proportional = proportional;
331
332 // Switch which scale we use
333 if (proportional)
334 gDemoFontCurInstance->font.charMagScale = gDemoFontCurInstance->font.charMagScaleP;
335 else
336 gDemoFontCurInstance->font.charMagScale = gDemoFontCurInstance->font.charMagScaleF;
337 }
338
DEMOFontSetGridSize(f32 xGrid,f32 yGrid)339 void DEMOFontSetGridSize(f32 xGrid, f32 yGrid)
340 {
341 // Check the initialize
342 DEMOAssert(s_FontP.pCharDataBuffer &&
343 "Need to call DEMOFontInit(). Before this function.\n");
344
345 // Update scale
346 UpdateScale(&gDemoFontCurInstance->font, xGrid, yGrid);
347 }
348
DEMOFontSetColor(f32 r,f32 g,f32 b,f32 a)349 void DEMOFontSetColor(f32 r, f32 g, f32 b, f32 a)
350 {
351 // Check the initialize
352 DEMOAssert(s_FontP.pCharDataBuffer &&
353 "Need to call DEMOFontInit(). Before this function.\n");
354
355 // Update color
356 gDemoFontCurInstance->font.color[0] = r;
357 gDemoFontCurInstance->font.color[1] = g;
358 gDemoFontCurInstance->font.color[2] = b;
359 gDemoFontCurInstance->font.color[3] = a;
360 }
361
DEMOFontSetZValue(f32 zValue)362 void DEMOFontSetZValue(f32 zValue)
363 {
364 // Check the initialize
365 DEMOAssert(s_FontP.pCharDataBuffer &&
366 "Need to call DEMOFontInit(). Before this function.\n");
367
368 // Update depth value
369 gDemoFontCurInstance->font.depth = zValue;
370 }
371
372 // --------------------------------------------------------------------------
373 // Getter
374 // --------------------------------------------------------------------------
375
DEMOFontGetCharSize(f32 * pCharWidth,f32 * pCharHeight)376 void DEMOFontGetCharSize(f32 *pCharWidth, f32 *pCharHeight)
377 {
378 FontData_t* pFont = GetCurrentFont();
379
380 // Get size of font
381 *pCharWidth = pFont->gridOffsetX;
382 *pCharHeight = pFont->gridOffsetY;
383 }
384
385 // --------------------------------------------------------------------------
386 // Private Functions
387 // --------------------------------------------------------------------------
388 /// Check Proportional boolean and return Font handle
GetCurrentFont(void)389 static FontData_t* GetCurrentFont(void)
390 {
391 if(gDemoFontCurInstance->proportional)
392 {
393 return &s_FontP;
394 }
395 else
396 {
397 return &s_FontF;
398 }
399 }
400
401 /// Update scale
UpdateScale(DEMOFontFontData * pFont,f32 scaleX,f32 scaleY)402 static void UpdateScale(DEMOFontFontData* pFont, f32 scaleX, f32 scaleY)
403 {
404 // Calculate char scale
405 pFont->charMagScaleF[0] = 2.0f/(scaleX * s_FontF.gridOffsetX);
406 pFont->charMagScaleF[1] = 2.0f/(scaleY * s_FontF.gridOffsetY);
407
408 pFont->charMagScaleP[0] = 2.0f/(scaleX * s_FontP.gridOffsetX);
409 pFont->charMagScaleP[1] = 2.0f/(scaleY * s_FontP.gridOffsetY);
410 }
411
412 /// Get Font char data from demoFontData.h
GetFontCharData(FontData_t * pFont,const u32 * pFontHeader,const u32 * pCharData,const u8 * pFontImageData)413 static void GetFontCharData(FontData_t* pFont,
414 const u32* pFontHeader,
415 const u32* pCharData,
416 const u8* pFontImageData)
417 {
418 u32 i;
419 f32 lineHeight;
420 f32 maxCharWidth = 0.0f;
421 f32 maxCharHeight = 0.0f;
422
423 // Check Font Texture Data
424 DEMOAssert(pFontHeader != NULL && pCharData != NULL &&
425 pFontImageData != NULL && "No texture data.\n");
426
427 // Check char data buffer
428 if (pFont->pCharDataBuffer)
429 {
430 // Skip Data Initialization
431 return;
432 }
433
434 // Set Font Texture Data Information
435 pFont->fontTextureWidth = (f32)pFontHeader[0];
436 pFont->fontTextureHeight = (f32)pFontHeader[1];
437 lineHeight = (f32)pFontHeader[4];
438 pFont->numCharData = pFontHeader[5];
439 pFont->gridOffsetX = 0;
440 pFont->gridOffsetY = 0;
441
442 if(pFont == &s_FontP)
443 {
444 pFont->pCharDataBuffer = s_CharDataBufferP;
445 }
446 else
447 {
448 pFont->pCharDataBuffer = s_CharDataBufferF;
449 }
450
451 // Check the max number
452 DEMOAssert(pFont->numCharData <= MAX_NUM_CHARS &&
453 "Font has over the max number of characters.\n");
454
455 // Format of data is: id, x, y, width, height, xOffset, yOffset, xAdvance
456 for(i = 0; i < pFont->numCharData; ++i)
457 {
458 u32 id = pCharData[i*8 + 0];
459 u32 x = pCharData[i*8 + 1];
460 u32 y = pCharData[i*8 + 2];
461 u32 w = pCharData[i*8 + 3];
462 u32 h = pCharData[i*8 + 4];
463 // +3 below is a hack to deal with negative offsets
464 s32 xOffset = (s32)pCharData[i*8 + 5] + 3;
465 s32 yOffset = (s32)pCharData[i*8 + 6];
466 u32 xAdvance = pCharData[i*8 + 7];
467 f32 charHeight = (f32)(h + yOffset);
468
469 pFont->pCharDataBuffer[i].id = id;
470 pFont->pCharDataBuffer[i].minS = (s32)x;
471 pFont->pCharDataBuffer[i].minT = (s32)(pFont->fontTextureHeight - h - y - 1);
472 pFont->pCharDataBuffer[i].maxS = (s32)(x + w);
473 pFont->pCharDataBuffer[i].maxT = (s32)(pFont->fontTextureHeight - y - 1);
474 pFont->pCharDataBuffer[i].minX = (s32)xOffset;
475 pFont->pCharDataBuffer[i].minY = (s32)(lineHeight - yOffset - h);
476 pFont->pCharDataBuffer[i].maxX = (s32)(xOffset + w);
477 pFont->pCharDataBuffer[i].maxY = (s32)(lineHeight - yOffset);
478 pFont->pCharDataBuffer[i].xAdvance = (s32)xAdvance;
479
480 // Set max height of char in GL cordinate space
481 if(charHeight > maxCharHeight)
482 {
483 maxCharHeight = charHeight;
484 }
485
486 if(pFont->pCharDataBuffer[i].xAdvance > maxCharWidth)
487 {
488 maxCharWidth = (f32)pFont->pCharDataBuffer[i].xAdvance;
489 }
490 }
491
492 // Set grid offsetX
493 pFont->gridOffsetX = maxCharWidth;
494
495 // Set grid offsetY
496 pFont->gridOffsetY = maxCharHeight;
497
498 // Set pointer of Font Image Data
499 pFont->pFontImageData = (u8*)pFontImageData;
500 }
501
502 /// Init Font Texture
InitFontTexture(DEMOGfxShader * pShader,FontData_t * pFont)503 static void InitFontTexture(DEMOGfxShader* pShader, FontData_t* pFont)
504 {
505 // Texture setup
506 u32 width =(u32)pFont->fontTextureWidth;
507 u32 height=(u32)pFont->fontTextureHeight;
508
509 GX2InitTexture(&pFont->TexData,
510 width, // width
511 height, // height
512 1, // depth
513 0, // num mips
514 GX2_SURFACE_FORMAT_TC_R8_UNORM,
515 GX2_SURFACE_DIM_2D);
516
517 // Allocate from graphics memory
518 GX2InitTexturePtrs(&pFont->TexData,
519 DEMOGfxAllocMEM2(pFont->TexData.surface.imageSize,
520 pFont->TexData.surface.alignment), 0);
521
522 // add dummy alloc notify because invalidate inside GX2TileTexture creates orphaned upload otherwise
523 GX2NotifyMemAlloc(pFont->pFontImageData, width*height, 32);
524 // Then we retile the image
525 // This function calls Invalidate for us
526 GX2TileTexture(&pFont->TexData, // dst
527 pFont->pFontImageData); // src
528 GX2NotifyMemFree(pFont->pFontImageData);
529
530 // Set up the sampler object
531 GX2InitSampler(&s_sampler,
532 GX2_TEX_CLAMP_WRAP,
533 GX2_TEX_XY_FILTER_BILINEAR);
534 }
535
536 // Set Font Texture
SetFontTexture(DEMOGfxShader * pShader,FontData_t * pFont)537 static void SetFontTexture(DEMOGfxShader* pShader, FontData_t* pFont)
538 {
539 // Set Texture
540 GX2SetPixelTexture(&pFont->TexData, pShader->samplersPS.location[0]);
541 }
542
543
544 /// Initialize Font shader
InitShader(DEMOGfxShader * pShader)545 static void InitShader(DEMOGfxShader* pShader)
546 {
547 void * gshBuf;
548 u32 gshLen;
549
550 // Load shader binary to memory
551 gshBuf = DEMOGfxLoadAssetFile(FONT_GSH_SHADER_FILE, &gshLen);
552
553 // Load demoFont shader
554 DEMOGfxLoadShaders(pShader, 0, gshBuf);
555
556 GX2RSetBufferName(&pShader->pVertexShader->shaderProgram, "demoFont VS");
557 GX2RSetBufferName(&pShader->pPixelShader->shaderProgram, "demoFont PS");
558
559 // Free memory used to load the shader file
560 DEMOFree(gshBuf);
561
562 // Init attribute to shader
563 DEMOGfxGetVertexShaderUniformLocation(pShader, "u_BasePosition");
564 DEMOGfxGetVertexShaderUniformLocation(pShader, "u_Scale");
565 DEMOGfxGetPixelShaderUniformLocation(pShader, "u_Color");
566 DEMOGfxGetPixelShaderSamplerLocation(pShader, "u_CharTex");
567
568 // Set fetch Shader buffer
569 DEMOGfxInitFetchShader(pShader);
570 }
571
572 // Search index of character id
BSearchIndex(FontData_t * pFont,u32 id)573 static u32 BSearchIndex(FontData_t* pFont, u32 id)
574 {
575 u32 first;
576 u32 last;
577 u32 index = 0;
578
579 // quick check for sanely-ordered fonts
580 if (id >= 32 && id < 32+pFont->numCharData &&
581 pFont->pCharDataBuffer[id-32].id == id )
582 return id-32;
583
584 first = 0;
585 last = pFont->numCharData-1;
586
587 while(first <= last)
588 {
589 u32 mid = first + (last - first) / 2;
590
591 if( pFont->pCharDataBuffer[mid].id < id )
592 {
593 first = mid + 1;
594 }
595 else if( id < pFont->pCharDataBuffer[mid].id )
596 {
597 last = mid - 1;
598 }
599 else
600 {
601 index = mid;
602 break;
603 }
604 }
605 return index;
606 }
607
608
DEMOFontAddInstance(void)609 DEMOFontInstance* DEMOFontAddInstance(void)
610 {
611 // Setup Context State buffer
612 DEMOFontContextState = DEMOGfxAllocMEM2(sizeof(GX2ContextState), GX2_CONTEXT_STATE_ALIGNMENT);
613
614 // Create a state context with profiling disabled
615 // GX2SetupContextState will invalidate CPU cache for us
616 GX2SetupContextStateEx(DEMOFontContextState, GX2_DISABLE);
617
618 // Setup default render buffers to be used now
619 DEMOFontSetTarget(&DEMOColorBuffer);
620
621 // Set Depth Control
622 GX2SetDepthOnlyControl(GX2_DISABLE,
623 GX2_DISABLE,
624 GX2_COMPARE_LESS);
625
626 // Set Blend Enable
627 GX2SetColorControl(GX2_LOGIC_OP_COPY,
628 GX2_ENABLE,
629 GX2_DISABLE,
630 GX2_ENABLE);
631
632 // Set Blend Function & Combine Mode
633 GX2SetBlendControl(GX2_RENDER_TARGET_0,
634 GX2_BLEND_SRC_ALPHA,
635 GX2_BLEND_ONE_MINUS_SRC_ALPHA,
636 GX2_BLEND_COMBINE_ADD,
637 GX2_ENABLE,
638 GX2_BLEND_SRC_ALPHA,
639 GX2_BLEND_ONE_MINUS_SRC_ALPHA,
640 GX2_BLEND_COMBINE_ADD
641 );
642
643 /////////////////////////////////////////////////////////////////////////////
644 // Create the new instance
645 gDemoFontCurInstance = DEMOAlloc(sizeof(DEMOFontInstance));
646 memset(gDemoFontCurInstance, 0, sizeof(DEMOFontInstance));
647 gDemoFontCurInstance->contextState = DEMOFontContextState;
648
649 /////////////////////////////////////////////////////////////////////////////
650 // Set shaders
651 GX2SetShaders(&s_Shader.fetchShader,
652 s_Shader.pVertexShader,
653 s_Shader.pPixelShader);
654
655 // Set up sampler
656 GX2SetPixelSampler(&s_sampler, s_Shader.samplersPS.location[0]);
657
658 // Initialize Proportional Font
659 DEMOFontSetSpacing(1);
660 DEMOFontSetGridSize(60, 24);
661 DEMOFontSetColor(1.0f, 1.0f, 1.0f, 1.0f);
662 DEMOFontSetZValue(-1.0f);
663
664 gDemoFontCurInstance->enabled = s_enabled;
665 s_enabled = TRUE;
666
667 return gDemoFontCurInstance;
668 }
669
DEMOFontDeleteInstance(DEMOFontInstance * instance)670 void DEMOFontDeleteInstance(DEMOFontInstance *instance)
671 {
672 DEMOGfxFreeMEM2(instance->contextState);
673 DEMOFree(instance);
674
675 // Edge case: delete current
676 if (gDemoFontCurInstance == instance) {
677 gDemoFontCurInstance = NULL;
678 DEMOFontContextState = NULL;
679 }
680 }
681
682
DEMOFontSetInstance(DEMOFontInstance * instance)683 void DEMOFontSetInstance(DEMOFontInstance *instance)
684 {
685 gDemoFontCurInstance = instance;
686
687 DEMOFontContextState = instance->contextState;
688 GX2SetContextState(DEMOFontContextState);
689 }
690
DEMOFontGetInstance(void)691 DEMOFontInstance* DEMOFontGetInstance(void)
692 {
693 return gDemoFontCurInstance;
694 }
695
696