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