1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - PRC - demo - characterRecognition-2
3 File: main.c
4
5 Copyright 2007-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-17#$
14 $Rev: 8556 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 #include <nitro.h>
19 #include <nitro/prc/algo_standard.h>
20 #include <nitro/prc/algo_light.h>
21 #include <nitro/prc/algo_fine.h>
22 #include <nitro/prc/algo_superfine.h>
23
24 #include "patterns.h"
25
26 //----- Specify how many places to output recognition result
27 #define RESULT_NUM 3
28
29 //----- Maximum number of points per input
30 //----- * As a standard, 60 points are entered each second
31 #define POINT_PER_INPUT_MAX 1024
32 //----- Maximum stroke count per input
33 #define STROKE_PER_INPUT_MAX 20
34 //----- Maximum number of points after resampling
35 #define POINT_AFTER_RESAMPLING_MAX 40
36
37 #define VRAM_BASE_ADDR ((u16*)HW_LCDC_VRAM_C)
38 #define VRAM_LINE_SIZE 256
39 #define DRAW_COLOR 0
40
41 #define MEMORY_MAIN_MAX_HEAPS 1
42 #define MEMORY_MAIN_HEAP_SIZE 0x200000
43
44 #define N_INPUT_PARAM 8
45
46 static void InitOS(void);
47 static void InitTP(void);
48 static void InitDisplay(void);
49 static void DrawLine(int x1, int y1, int x2, int y2, u16 col);
50 static void PutDot(int x, int y, u16 col);
51 static void ClearScreen(void);
52 void DrawStrokes(const PRCStrokes *strokes, int sx, int sy);
53 static void PrintRecognitionResult(const char *name, PRCPrototypeEntry **result, fx32 *scores);
54 static void VBlankIntr(void);
55 void PrintStrokesAsEntryData(const PRCStrokes *strokes,
56 const char *name, u32 kind, fx16 correction, int normalizeSize);
57
58 static int sInputPatternParamThresholds[N_INPUT_PARAM][3] = {
59 {6, 2048, 1},
60 {8, 3072, 2},
61 {12, 4096, 3},
62 {16, 6144, 4},
63 {24, 8192, 5},
64 {32, 12288, 8},
65 {48, 16384, 12},
66 {64, 21846, 16},
67 };
68
NitroMain(void)69 void NitroMain(void)
70 {
71 InitOS();
72 InitDisplay();
73 InitTP();
74
75 OS_InitTick();
76 OS_InitAlarm();
77 OS_InitThread();
78
79 {
80 PRCPrototypeDB_Common protoDB;
81 int normalizeSize;
82 PRCPoint points[POINT_PER_INPUT_MAX];
83 PRCStrokes strokes;
84 u16 prevKey, currKey, trgKey;
85 BOOL touching = FALSE;
86 TPData prevSample = { 0, 0, 0, 0 };
87 void *prototypeListBuffer;
88 void *patternBuffer;
89 void *recognitionBuffer;
90 int dictIndex = 0;
91 int inputParamIndex = N_INPUT_PARAM / 2;
92 BOOL fDictShown = FALSE;
93 int maxPointCount;
94
95 PRC_Init();
96
97 // Expand the sample database
98 // PrototypeList is a list of the sample patterns defined in a separate file
99 {
100 // Store the entry number in entry.data to facilitate subsequent reverse lookup
101 int iEntry;
102 for (iEntry = 0; iEntry < PrototypeList.entrySize; iEntry++)
103 {
104 ((PRCPrototypeEntry *)&PrototypeList.entries[iEntry])->data = (void *)iEntry;
105 }
106 }
107 {
108 u32 size;
109 size = PRC_GetPrototypeDBBufferSize_Common(&PrototypeList);
110 OS_Printf("required buffer for InitPrototypeDB: %d bytes\n", size);
111 if (size == 0)
112 size = 1;
113 prototypeListBuffer = OS_Alloc(size);
114 SDK_ASSERT(prototypeListBuffer);
115 }
116 if (!PRC_InitPrototypeDB_Common(&protoDB, prototypeListBuffer, &PrototypeList))
117 {
118 OS_Printf("cannot initialize the prototype DB.\n");
119 OS_Terminate();
120 }
121
122 normalizeSize = protoDB.normalizeSize;
123 maxPointCount = POINT_AFTER_RESAMPLING_MAX;
124 while (TRUE)
125 {
126 {
127 u32 size, maxSize;;
128 size = PRC_GetInputPatternBufferSize_Common(maxPointCount, STROKE_PER_INPUT_MAX);
129 OS_Printf("maxPointCount: %d, maxStrokeCount: %d\n", maxPointCount,
130 STROKE_PER_INPUT_MAX);
131 OS_Printf("required buffer for InitInputPattern: %d bytes\n", size);
132 if (size == 0)
133 size = 1;
134 patternBuffer = OS_Alloc(size);
135 if (patternBuffer == NULL)
136 {
137 OS_Printf("OS_Alloc failed.\n");
138 maxPointCount = POINT_AFTER_RESAMPLING_MAX;
139 continue;
140 }
141 size =
142 PRC_GetRecognitionBufferSize_Light(maxPointCount, STROKE_PER_INPUT_MAX,
143 &protoDB);
144 OS_Printf("required buffer for Recognition of 'Light': %d bytes\n", size);
145 maxSize = size;
146 size =
147 PRC_GetRecognitionBufferSize_Standard(maxPointCount, STROKE_PER_INPUT_MAX,
148 &protoDB);
149 OS_Printf("required buffer for Recognition of 'Standard': %d bytes\n", size);
150 if (maxSize < size)
151 maxSize = size;
152 size =
153 PRC_GetRecognitionBufferSize_Fine(maxPointCount, STROKE_PER_INPUT_MAX,
154 &protoDB);
155 OS_Printf("required buffer for Recognition of 'Fine': %d bytes\n", size);
156 if (maxSize < size)
157 maxSize = size;
158 size =
159 PRC_GetRecognitionBufferSize_Superfine(maxPointCount, STROKE_PER_INPUT_MAX,
160 &protoDB);
161 OS_Printf("required buffer for Recognition of 'Superfine': %d bytes\n", size);
162 if (maxSize < size)
163 maxSize = size;
164 if (maxSize == 0)
165 maxSize = 1;
166 recognitionBuffer = OS_Alloc(maxSize);
167 if (recognitionBuffer == NULL)
168 {
169 OS_Printf("OS_Alloc failed.\n");
170 maxPointCount = POINT_AFTER_RESAMPLING_MAX;
171 OS_Free(patternBuffer);
172 continue;
173 }
174 }
175
176 PRC_InitStrokes(&strokes, points, POINT_PER_INPUT_MAX);
177
178 ClearScreen();
179 fDictShown = FALSE;
180
181 //---- Dummy READ workaround for pushing 'A' at IPL
182 currKey = PAD_Read();
183
184 while (TRUE)
185 {
186 BOOL fClearScreen = FALSE;
187 BOOL fClearScreenAfterRecognition = FALSE;
188 BOOL fRecognizeChar = FALSE;
189 BOOL fShowPrototypeList = FALSE;
190 BOOL fPrintPattern = FALSE;
191 TPData sample;
192
193 prevKey = currKey;
194 currKey = PAD_Read();
195 trgKey = (u16)(currKey & ~prevKey);
196
197 (void)TP_RequestCalibratedSampling(&sample);
198
199 if (sample.touch && (sample.validity == 0))
200 {
201 // Pen is touching the screen
202 if (!PRC_IsFull(&strokes))
203 {
204 if (touching)
205 {
206 // Writing
207 DrawLine(prevSample.x, prevSample.y, sample.x, sample.y, DRAW_COLOR);
208 }
209 else
210 {
211 // The moment pen touches the screen
212 PutDot(sample.x, sample.y, DRAW_COLOR);
213 touching = TRUE;
214 }
215 // Store stroke data
216 PRC_AppendPoint(&strokes, sample.x, sample.y);
217 }
218 }
219 else
220 {
221 // Pen is off the screen
222 if (touching)
223 {
224 // The moment the pen comes off the screen
225 if (!PRC_IsFull(&strokes))
226 {
227 PRC_AppendPenUpMarker(&strokes);
228 }
229 touching = FALSE;
230 }
231 }
232
233 // Recognition begins when A button is pressed
234 if (trgKey & PAD_BUTTON_A)
235 {
236 fRecognizeChar = TRUE;
237 fClearScreenAfterRecognition = TRUE;
238 }
239
240 // Clear screen when B button is pressed
241 if (trgKey & (PAD_BUTTON_START | PAD_BUTTON_B))
242 {
243 fClearScreen = TRUE;
244 }
245
246 // If the X Button is pressed, although recognition occurs, the screen is not cleared
247 if (trgKey & PAD_BUTTON_X)
248 {
249 fRecognizeChar = TRUE;
250 }
251
252 // If the Y Button is pressed, pattern data is exported to debug while being recognized
253 if (trgKey & PAD_BUTTON_Y)
254 {
255 fRecognizeChar = TRUE;
256 fPrintPattern = TRUE;
257 }
258
259 // Pressing L button displays the previous entry in the sample DB
260 if (trgKey & PAD_BUTTON_L)
261 {
262 if (fDictShown)
263 {
264 dictIndex--;
265 if (dictIndex < 0)
266 {
267 dictIndex = protoDB.patternCount - 1;
268 }
269 }
270 fShowPrototypeList = TRUE;
271 }
272
273 // Pressing R button displays the next entry in the sample DB
274 if (trgKey & PAD_BUTTON_R)
275 {
276 if (fDictShown)
277 {
278 dictIndex++;
279 if (dictIndex >= protoDB.patternCount)
280 {
281 dictIndex = 0;
282 }
283 }
284 fShowPrototypeList = TRUE;
285 }
286
287 // If UP key is pressed, increment maxPointCount by 4
288 if (trgKey & PAD_KEY_UP)
289 {
290 maxPointCount += 4;
291 break;
292 }
293
294 // If DOWN key is pressed, decrement maxPointCount by 4
295 if (trgKey & PAD_KEY_DOWN)
296 {
297 maxPointCount -= 4;
298 if (maxPointCount < 4)
299 {
300 maxPointCount = 4;
301 }
302 break;
303 }
304
305 // If RIGHT key is pressed, change the resampling parameter to coarser
306 if (trgKey & PAD_KEY_RIGHT)
307 {
308 if (inputParamIndex < N_INPUT_PARAM - 1)
309 {
310 inputParamIndex++;
311 OS_Printf("change InputPatternParam.\n");
312 }
313 if (!PRC_IsEmpty(&strokes))
314 {
315 // If there is input, perform recognition
316 fRecognizeChar = TRUE;
317 }
318 }
319
320 // If LEFT key is pressed, change the resampling parameter to finer
321 if (trgKey & PAD_KEY_LEFT)
322 {
323 if (inputParamIndex > 0)
324 {
325 inputParamIndex--;
326 OS_Printf("change InputPatternParam.\n");
327 }
328 if (!PRC_IsEmpty(&strokes))
329 {
330 // If there is input, perform recognition
331 fRecognizeChar = TRUE;
332 }
333 }
334
335 if (fRecognizeChar)
336 {
337 if (PRC_IsEmpty(&strokes))
338 {
339 OS_Printf("***********************************************\n");
340 OS_Printf("No input.\n");
341 }
342 else
343 {
344 // Pattern Recognition
345 int iParamType;
346 OSTick start, end, initPatternTime, recognizeTime_Light,
347 recognizeTime_Standard, recognizeTime_Fine, recognizeTime_Superfine;
348 PRCInputPattern_Common inputPattern;
349 PRCInputPatternParam_Common inputParam;
350 PRCPrototypeEntry *results[RESULT_NUM];
351 fx32 scores[RESULT_NUM];
352 fx32 maxScore;
353 int maxDictIndex;
354
355 ClearScreen();
356 fDictShown = FALSE;
357 if (!fClearScreenAfterRecognition)
358 {
359 DrawStrokes(&strokes, 0, 0);
360 }
361
362 maxScore = 0;
363 maxDictIndex = -1;
364
365 OS_Printf("***********************************************\n");
366 for (iParamType = 0; iParamType < 3; iParamType++)
367 {
368 OS_Printf("===============================================\n");
369 inputParam.normalizeSize = normalizeSize;
370 switch (iParamType)
371 {
372 case 0:
373 inputParam.resampleMethod = PRC_RESAMPLE_METHOD_DISTANCE;
374 inputParam.resampleThreshold =
375 sInputPatternParamThresholds[inputParamIndex][iParamType];
376 OS_Printf("Resample Method: PRC_RESAMPLE_METHOD_DISTANCE\n");
377 break;
378 case 1:
379 inputParam.resampleMethod = PRC_RESAMPLE_METHOD_ANGLE;
380 inputParam.resampleThreshold =
381 sInputPatternParamThresholds[inputParamIndex][iParamType];
382 OS_Printf("Resample Method: PRC_RESAMPLE_METHOD_ANGLE\n");
383 break;
384 case 2:
385 inputParam.resampleMethod = PRC_RESAMPLE_METHOD_RECURSIVE;
386 inputParam.resampleThreshold =
387 sInputPatternParamThresholds[inputParamIndex][iParamType];
388 OS_Printf("Resample Method: PRC_RESAMPLE_METHOD_RECURSIVE\n");
389 break;
390 }
391 OS_Printf("Resample Threshold: %d\n", inputParam.resampleThreshold);
392
393 start = OS_GetTick();
394 if (PRC_InitInputPatternEx_Common
395 (&inputPattern, patternBuffer, &strokes, maxPointCount,
396 STROKE_PER_INPUT_MAX, &inputParam) == FALSE)
397 {
398 end = OS_GetTick();
399 initPatternTime = end - start;
400 OS_Printf(" time: %lldus.\n",
401 OS_TicksToMicroSeconds(initPatternTime));
402 OS_Printf(" fail to initialize the input pattern.\n");
403 continue;
404 }
405 end = OS_GetTick();
406 initPatternTime = end - start;
407 OS_Printf(" time: %lldus.\n", OS_TicksToMicroSeconds(initPatternTime));
408
409 if (fPrintPattern)
410 {
411 PRCStrokes outputStrokes;
412 PRC_GetInputPatternStrokes(&outputStrokes, &inputPattern);
413 PrintStrokesAsEntryData(
414 &outputStrokes,
415 (fDictShown) ? PatternName[PrototypeList.entries[dictIndex].code] : "<New Pattern>",
416 (fDictShown) ? PrototypeList.entries[dictIndex].kind : 1,
417 (fx16)((fDictShown) ? PrototypeList.entries[dictIndex].correction : 0),
418 normalizeSize);
419 }
420 else
421 {
422 // Compare prototypeList and inputPattern and perform recognition
423 start = OS_GetTick();
424 (void)PRC_GetRecognizedEntriesEx_Light(results, scores, RESULT_NUM,
425 recognitionBuffer,
426 &inputPattern, &protoDB,
427 PRC_KIND_ALL, NULL);
428 end = OS_GetTick();
429 recognizeTime_Light = end - start;
430 PrintRecognitionResult("Light", results, scores);
431 OS_Printf(" time: %lldus ( + %lldus (resample) ).\n",
432 OS_TicksToMicroSeconds(recognizeTime_Light),
433 OS_TicksToMicroSeconds(initPatternTime));
434
435 start = OS_GetTick();
436 (void)PRC_GetRecognizedEntriesEx_Standard(results, scores,
437 RESULT_NUM,
438 recognitionBuffer,
439 &inputPattern, &protoDB,
440 PRC_KIND_ALL, NULL);
441 end = OS_GetTick();
442 recognizeTime_Standard = end - start;
443 PrintRecognitionResult("Standard", results, scores);
444 OS_Printf(" time: %lldus ( + %lldus (resample) ).\n",
445 OS_TicksToMicroSeconds(recognizeTime_Standard),
446 OS_TicksToMicroSeconds(initPatternTime));
447
448 start = OS_GetTick();
449 (void)PRC_GetRecognizedEntriesEx_Fine(results, scores, RESULT_NUM,
450 recognitionBuffer,
451 &inputPattern, &protoDB,
452 PRC_KIND_ALL, NULL);
453 end = OS_GetTick();
454 recognizeTime_Fine = end - start;
455 PrintRecognitionResult("Fine", results, scores);
456 OS_Printf(" time: %lldus ( + %lldus (resample) ).\n",
457 OS_TicksToMicroSeconds(recognizeTime_Fine),
458 OS_TicksToMicroSeconds(initPatternTime));
459 if (results[0] != NULL && scores[0] > maxScore)
460 {
461 maxScore = scores[0];
462 maxDictIndex = (int)results[0]->data;
463 }
464
465 start = OS_GetTick();
466 (void)PRC_GetRecognizedEntriesEx_Superfine(results, scores,
467 RESULT_NUM,
468 recognitionBuffer,
469 &inputPattern, &protoDB,
470 PRC_KIND_ALL, NULL);
471 end = OS_GetTick();
472 recognizeTime_Superfine = end - start;
473 PrintRecognitionResult("Superfine", results, scores);
474 OS_Printf(" time: %lldus ( + %lldus (resample) ).\n",
475 OS_TicksToMicroSeconds(recognizeTime_Superfine),
476 OS_TicksToMicroSeconds(initPatternTime));
477 if (results[0] != NULL && scores[0] > maxScore)
478 {
479 maxScore = scores[0];
480 maxDictIndex = (int)results[0]->data;
481 }
482 }
483
484 {
485 PRCStrokes drawingStrokes;
486 PRC_GetInputPatternStrokes(&drawingStrokes, &inputPattern);
487 DrawStrokes(&drawingStrokes, iParamType * 64, 0); // normalizeSize <= 128
488 }
489 }
490 if (maxDictIndex >= 0)
491 {
492 PRCStrokes drawingStrokes;
493 dictIndex = maxDictIndex;
494 PRC_GetEntryStrokes(&drawingStrokes, &PrototypeList,
495 &PrototypeList.entries[dictIndex]);
496 DrawStrokes(&drawingStrokes, 256 - normalizeSize, 0);
497 fDictShown = TRUE;
498 }
499 if (fClearScreenAfterRecognition)
500 {
501 PRC_Clear(&strokes);
502 }
503 }
504 }
505
506 if (fShowPrototypeList && PrototypeList.entrySize > 0)
507 {
508 // Display the sample pattern
509 PRCStrokes drawingStrokes;
510 ClearScreen();
511 PRC_Clear(&strokes);
512
513 PRC_GetEntryStrokes(&drawingStrokes, &PrototypeList,
514 &PrototypeList.entries[dictIndex]);
515 DrawStrokes(&drawingStrokes, 256 - normalizeSize, 0);
516 OS_Printf("***********************************************\n");
517 OS_Printf("#%d: '%s'\n", dictIndex,
518 PatternName[PrototypeList.entries[dictIndex].code]);
519 // PRCi_PrintPatternData_Common(&protoDB.patterns[dictIndex].data);
520 fDictShown = TRUE;
521 }
522
523 if (fPrintPattern && fDictShown && PrototypeList.entrySize > 0)
524 {
525 PRCStrokes outputStrokes;
526 PRC_GetEntryStrokes(&outputStrokes, &PrototypeList,
527 &PrototypeList.entries[dictIndex]);
528 OS_Printf("===============================================\n");
529 OS_Printf("Original PrototypeList:\n");
530 PrintStrokesAsEntryData(&outputStrokes,
531 PatternName[PrototypeList.entries[dictIndex].code],
532 PrototypeList.entries[dictIndex].kind,
533 PrototypeList.entries[dictIndex].correction,
534 normalizeSize);
535 }
536
537 // Wait for V-Blank interrupt
538 OS_WaitVBlankIntr();
539
540 if (fClearScreen)
541 {
542 ClearScreen();
543 fDictShown = FALSE;
544 PRC_Clear(&strokes);
545 }
546
547 prevSample = sample;
548 }
549 OS_Free(recognitionBuffer);
550 OS_Free(patternBuffer);
551 }
552
553 OS_Free(prototypeListBuffer);
554 }
555 }
556
InitOS(void)557 void InitOS(void)
558 {
559 void *nstart;
560 void *heapStart;
561 OSHeapHandle handle;
562
563 OS_Init();
564
565 nstart =
566 OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(),
567 MEMORY_MAIN_MAX_HEAPS);
568 OS_SetMainArenaLo(nstart);
569
570 heapStart = OS_AllocFromMainArenaLo(MEMORY_MAIN_HEAP_SIZE, 32);
571 handle =
572 OS_CreateHeap(OS_ARENA_MAIN, heapStart, (void *)((u32)heapStart + MEMORY_MAIN_HEAP_SIZE));
573
574 (void)OS_SetCurrentHeap(OS_ARENA_MAIN, handle);
575
576 }
577
InitDisplay(void)578 void InitDisplay(void)
579 {
580
581 GX_Init();
582 FX_Init();
583
584 GX_DispOff();
585 GXS_DispOff();
586
587 GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
588
589 OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
590 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
591 (void)GX_VBlankIntr(TRUE); // To generate V-Blank interrupt request
592 (void)OS_EnableIrq();
593
594 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
595 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
596
597 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE); // Clear OAM
598 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE); // Clear the standard palette
599
600 MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE); // Clear OAM
601 MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE); // Clear the standard palette
602 MI_DmaFill32(3, (void *)HW_LCDC_VRAM_C, 0x7FFF7FFF, 256 * 192 * sizeof(u16));
603
604 GX_SetGraphicsMode(GX_DISPMODE_VRAM_C, // VRAM mode
605 (GXBGMode)0, // Dummy
606 (GXBG0As)0); // Dummy
607
608 OS_WaitVBlankIntr(); // Waiting for the end of the V-Blank interrupt
609 GX_DispOn();
610 }
611
InitTP(void)612 void InitTP(void)
613 {
614 TPCalibrateParam calibrate;
615
616 TP_Init();
617
618 // Get CalibrateParameter from FlashMemory
619 if (!TP_GetUserInfo(&calibrate))
620 {
621 OS_Panic("Can't get Calibration Parameter from NVRAM\n");
622 }
623 else
624 {
625 OS_Printf("Get Calibration Parameter from NVRAM\n");
626 }
627
628 TP_SetCalibrateParam(&calibrate);
629 }
630
DrawLine(int x1,int y1,int x2,int y2,u16 col)631 void DrawLine(int x1, int y1, int x2, int y2, u16 col)
632 {
633 u16 sx, sy, ey, wx, wy;
634 u16 i;
635 int err, plus, minus;
636 u16 *point = VRAM_BASE_ADDR;
637
638 SDK_ASSERT(x1 >= 0 && y1 >= 0 && x2 >= 0 && y2 >= 0);
639
640 // Swap (x1, y1) <-> (x2, y2) if x1 > x2
641 if (x1 <= x2)
642 {
643 sx = (u16)x1;
644 sy = (u16)y1;
645 ey = (u16)y2;
646 wx = (u16)(x2 - x1); // Width
647 }
648 else
649 {
650 sx = (u16)x2;
651 sy = (u16)y2;
652 ey = (u16)y1;
653 wx = (u16)(x1 - x2); // Width
654 }
655
656 point += sy * VRAM_LINE_SIZE + sx;
657 if (sy <= ey)
658 {
659 /* Line goes to upper */
660 wy = (u16)(ey - sy); // Height
661 if (wx > wy)
662 {
663 /* If (X size > Y size) draw a Dot per Xdot */
664 plus = wy * 2;
665 minus = -wx * 2;
666 err = -wx;
667 for (i = 0; i <= wx; i++)
668 {
669 *point = col; // PutDot
670 ++point;
671 err += plus;
672 if (err >= 0)
673 {
674 point += VRAM_LINE_SIZE;
675 err += minus;
676 }
677 }
678
679 }
680 else
681 {
682 /* If (X size <= Y size) draw a Dot per Ydot */
683 plus = wx * 2;
684 minus = -wy * 2;
685 err = -wy;
686 for (i = 0; i <= wy; i++)
687 {
688 *point = col; // PutDot
689 point += VRAM_LINE_SIZE;
690 err += plus;
691 if (err >= 0)
692 {
693 ++point;
694 err += minus;
695 }
696 }
697 }
698 }
699 else
700 {
701 /* line goes to lower */
702 wy = (u16)(sy - ey); // Height
703 if (wx > wy)
704 {
705 /* If (X size > Y size) draw a Dot per Xdot */
706 plus = wy * 2;
707 minus = -wx * 2;
708 err = -wx;
709 for (i = 0; i <= wx; i++)
710 {
711 *point = col; // PutDot
712 ++point;
713 err += plus;
714 if (err >= 0)
715 {
716 point -= VRAM_LINE_SIZE;
717 err += minus;
718 }
719 }
720
721 }
722 else
723 {
724 /* If (X size <= Y size) draw a Dot per Ydot */
725 plus = wx * 2;
726 minus = -wy * 2;
727 err = -wy;
728 for (i = 0; i <= wy; i++)
729 {
730 *point = col; // PutDot
731 point -= VRAM_LINE_SIZE;
732 err += plus;
733 if (err >= 0)
734 {
735 ++point;
736 err += minus;
737 }
738 }
739 }
740 }
741 }
742
PutDot(int x,int y,u16 col)743 void PutDot(int x, int y, u16 col)
744 {
745 *(u16 *)((u32)VRAM_BASE_ADDR + y * 256 * 2 + x * 2) = col;
746 }
747
ClearScreen(void)748 void ClearScreen(void)
749 {
750 MI_DmaFill32(3, (void *)HW_LCDC_VRAM_C, 0x7FFF7FFF, 256 * 192 * sizeof(u16));
751 }
752
DrawStrokes(const PRCStrokes * strokes,int sx,int sy)753 void DrawStrokes(const PRCStrokes *strokes, int sx, int sy)
754 {
755 int iPoint;
756 PRCPoint prev;
757 BOOL newFlag;
758 const PRCPoint *point;
759
760 newFlag = TRUE;
761 point = strokes->points;
762 for (iPoint = 0; iPoint < strokes->size; iPoint++, point++)
763 {
764 if (!PRC_IsPenUpMarker(point))
765 {
766 if (newFlag)
767 {
768 PutDot(sx + point->x, sy + point->y, 1);
769 }
770 else
771 {
772 DrawLine(sx + prev.x, sy + prev.y, sx + point->x, sy + point->y, 1);
773 }
774 prev = *point;
775 newFlag = FALSE;
776 }
777 else
778 {
779 newFlag = TRUE;
780 }
781 }
782 }
783
PrintRecognitionResult(const char * name,PRCPrototypeEntry ** results,fx32 * scores)784 void PrintRecognitionResult(const char *name, PRCPrototypeEntry **results, fx32 *scores)
785 {
786 int iResult;
787 (void)name;
788 (void)scores;
789
790 OS_Printf("-----------------------------------------------\n");
791 OS_Printf("Result(%s):\n", name);
792 // PRCi_PrintPatternData_Common(&inputPattern.data);
793
794 // Recognition results output
795 if (results[0] == NULL)
796 {
797 OS_Printf(" can't recognize as char\n");
798 }
799 else
800 {
801 for (iResult = 0; iResult < RESULT_NUM; iResult++)
802 {
803 int code;
804
805 if (results[iResult] == NULL)
806 break;
807
808 code = PRC_GetEntryCode(results[iResult]);
809 OS_Printf(" '%s' (score: %d.%03d)\n", PatternName[code], FX_Whole(scores[iResult]),
810 (scores[iResult] & FX16_DEC_MASK) * 1000 / (1 << FX16_DEC_SIZE));
811 }
812 }
813 }
814
PrintStrokesAsEntryData(const PRCStrokes * strokes,const char * name,u32 kind,fx16 correction,int normalizeSize)815 void PrintStrokesAsEntryData(const PRCStrokes *strokes,
816 const char *name, u32 kind, fx16 correction, int normalizeSize)
817 {
818 int iPoint;
819 BOOL newFlag;
820 const PRCPoint *point;
821 (void)name;
822 (void)kind;
823 (void)correction;
824 (void)normalizeSize;
825
826 OS_Printf("\"%s\" %d %d %d |", name, kind, correction, normalizeSize);
827
828 newFlag = TRUE;
829 point = strokes->points;
830 for (iPoint = 0; iPoint < strokes->size; iPoint++, point++)
831 {
832 if (!PRC_IsPenUpMarker(point))
833 {
834 OS_Printf(" (%d, %d)", point->x, point->y);
835 newFlag = FALSE;
836 }
837 else
838 {
839 OS_Printf(" |");
840 newFlag = TRUE;
841 }
842 }
843 if (!newFlag)
844 {
845 OS_Printf(" |");
846 }
847 OS_Printf("\n");
848 }
849
VBlankIntr(void)850 void VBlankIntr(void)
851 {
852 // Set IRQ check flag
853 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
854 }
855