1#!/usr/bin/perl
2#---------------------------------------------------------------------------
3#  Project:  TwlSDK - tools
4#  File:     pdic2c.pl
5#
6#  Copyright 2007 Nintendo.  All rights reserved.
7#
8#  These coded instructions, statements, and computer programs contain
9#  proprietary information of Nintendo of America Inc. and/or Nintendo
10#  Company Ltd., and are protected by Federal copyright law.  They may
11#  not be disclosed to third parties or copied or duplicated in any form,
12#  in whole or in part, without the prior written consent of Nintendo.
13#
14#  $Date:: 2008-01-23#$
15#  $Rev: 3786 $
16#  $Author: seiki_masashi $
17#---------------------------------------------------------------------------
18
19use strict;
20use vars qw($VERSION);
21use vars qw($HEADER_FILE_NAME $PREFIX);
22
23$VERSION = do { my @r = q$Revision: 3786 $ =~ /\d+/g; sprintf '%d.'.('%02d'x$#r), @r };
24
25use Fcntl qw(:DEFAULT);
26use Getopt::Std;
27$Getopt::Std::STANDARD_HELP_VERSION = 1;
28use File::Basename;
29
30sub HELP_MESSAGE
31{
32    my $handler = shift || \*STDOUT;
33    print $handler "Usage: pdic2c.pl [-ch] [-C OUTPUT_SOURCE] [-H OUTPUT_HEADER] [-i INCLUDE_FILE] [-p PREFIX] NORMALIZE_SIZE PATTERNS.TXT\n";
34}
35
36sub VERSION_MESSAGE
37{
38    my $handler = shift || \*STDOUT;
39    print $handler "pdic2c.pl $VERSION\n";
40}
41
42my %opts;
43getopts('chC:H:i:p:', \%opts);
44
45if (!$opts{c} && !$opts{h})
46{
47    $opts{c} = 1;
48    $opts{h} = 1;
49}
50
51if ($opts{i})
52{
53    $HEADER_FILE_NAME = $opts{i};
54}
55elsif ($opts{H})
56{
57    $HEADER_FILE_NAME = basename($opts{H});
58}
59else
60{
61    $HEADER_FILE_NAME = "patternDict.h";
62}
63
64if ($opts{p})
65{
66    $PREFIX = $opts{p};
67}
68else
69{
70    $PREFIX = "";
71}
72
73if ( $#ARGV < 0 )
74{
75    HELP_MESSAGE();
76    exit 1;
77}
78
79my $outputNormalizeSize = shift @ARGV;
80if ( $outputNormalizeSize == 0 )
81{
82    print STDERR "error: normalizeSize must be > 0\n";
83    exit 1;
84}
85
86binmode STDIN;
87
88my %nameMap = ();
89my @nameArray = ();
90my @patterns = ();
91my $wholePointNum = 0;
92my $wholeStrokeNum = 0;
93
94while (<>)
95{
96    s/\x0D?\x0A?$//; # chomp
97    my ($data, $comment) = /^([^#]*?)\s*(?:#\s*(.*))?$/;
98    my ($name, $kind, $correction, $normalizeSize, $pointsString) = $data =~ /^"([^"]+)" (\d+) (-?\d+) (\d+) (.*)|\s*$/; #"
99    my $index = $wholePointNum;
100    my $pointCount = 0;
101    $pointsString =~ s/^|//;
102    if ( not exists $nameMap{$name} )
103    {
104        push @nameArray, $name;
105        $nameMap{$name} = $#nameArray;
106    }
107    my @strokesString = split /\|/, $pointsString;
108    my @strokes = ();
109    foreach my $strokeString ( @strokesString )
110    {
111        my @points = map {/\(\s*(\d+)\s*,\s*(\d+)\s*\)/; [$1, $2]} ($strokeString =~ /\(\s*\d+\s*,\s*\d+\s*\)/g);
112        next if (!@points);
113        push @strokes, \@points;
114#print "$points[0]->[0] $points[0]->[1]\n";
115        $pointCount += $#points + 1;
116        $pointCount ++ ; # PenUpMarker
117    }
118    push @patterns,
119    {
120        name => $name,
121        code => $nameMap{$name},
122        correction => $correction,
123        kind => $kind,
124        normalizeSize => $normalizeSize,
125        index => $index,
126        pointCount => $pointCount,
127        strokes => \@strokes,
128        comment => $comment,
129    };
130    $wholePointNum += $pointCount;
131    $wholeStrokeNum += $#strokes + 1;
132}
133
134my $header_text = '';
135my $source_text = '';
136
137$header_text .= <<"EOT";
138/*---------------------------------------------------------------------------*
139  Header File
140 *---------------------------------------------------------------------------*/
141
142#ifndef ${PREFIX}PATTERN_DICT_H_
143#define ${PREFIX}PATTERN_DICT_H_
144
145#ifdef __cplusplus
146extern "C" {
147#endif
148
149EOT
150
151my $patternNum = $#patterns + 1;
152my $codeNum    = $#nameArray + 1;
153
154$header_text .= <<"EOT";
155#include <nitro/prc/types.h>
156
157
158#define ${PREFIX}PDIC_WHOLE_POINT_NUM             $wholePointNum
159#define ${PREFIX}PDIC_WHOLE_STROKE_NUM            $wholeStrokeNum
160#define ${PREFIX}PDIC_PATTERN_NUM                 $patternNum
161#define ${PREFIX}PDIC_CODE_NUM                    $codeNum
162#define ${PREFIX}PDIC_NORMALIZE_SIZE              $outputNormalizeSize
163
164
165extern PRCPrototypeList ${PREFIX}PrototypeList;
166extern char *${PREFIX}PatternName[${PREFIX}PDIC_CODE_NUM];
167
168
169#ifdef __cplusplus
170} /* extern "C" */
171#endif
172
173/* ${PREFIX}PATTERN_DICT_H_ */
174#endif
175
176/*---------------------------------------------------------------------------*
177  End of File
178 *---------------------------------------------------------------------------*/
179EOT
180
181$source_text .= <<"EOT";
182/*---------------------------------------------------------------------------*
183  Source File
184 *---------------------------------------------------------------------------*/
185
186#include <nitro.h>
187#include <nitro/prc/types.h>
188
189#include "$HEADER_FILE_NAME"
190
191PRCPoint ${PREFIX}PrototypeListPointArray[${PREFIX}PDIC_WHOLE_POINT_NUM] =
192{
193EOT
194
195foreach my $pattern (@patterns)
196{
197    my $strokes = $pattern->{strokes};
198    my $normalizeSize = $pattern->{normalizeSize};
199    foreach my $points (@$strokes)
200    {
201        foreach my $point (@$points)
202        {
203            my ($x, $y);
204            $x = int($point->[0] * $outputNormalizeSize / $normalizeSize);
205            $y = int($point->[1] * $outputNormalizeSize / $normalizeSize);
206            $source_text .= <<"EOT";
207    {$x, $y},
208EOT
209        }
210        $source_text .= <<"EOT";
211    {-1, -1},
212EOT
213    }
214}
215
216$source_text .= <<"EOT";
217};
218
219PRCPrototypeEntry ${PREFIX}PrototypeListEntries[${PREFIX}PDIC_PATTERN_NUM] =
220{
221EOT
222
223foreach my $pattern (@patterns)
224{
225    my $strokeCount = $#{$pattern->{strokes}}+1;
226    $source_text .= <<"EOT";
227    {
228        TRUE, $pattern->{kind}, $pattern->{code}, $pattern->{correction}, NULL,        // $pattern->{comment}
229        $pattern->{index}, $pattern->{pointCount}, $strokeCount
230    },
231EOT
232}
233
234$source_text .= <<"EOT";
235};
236
237PRCPrototypeList ${PREFIX}PrototypeList =
238{
239    ${PREFIX}PrototypeListEntries,              /* entries */
240    ${PREFIX}PDIC_PATTERN_NUM,                  /* entrySize */
241    ${PREFIX}PrototypeListPointArray,           /* pointArray */
242    ${PREFIX}PDIC_WHOLE_POINT_NUM,              /* pointArraySize */
243
244    ${PREFIX}PDIC_NORMALIZE_SIZE,               /* normalizeSize */
245};
246
247char *${PREFIX}PatternName[${PREFIX}PDIC_CODE_NUM] =
248{
249EOT
250
251foreach my $name (@nameArray)
252{
253    $source_text .= <<"EOT";
254    "$name",
255EOT
256}
257
258$source_text .= <<'EOT';
259};
260
261/*---------------------------------------------------------------------------*
262  End of File
263 *---------------------------------------------------------------------------*/
264EOT
265
266if ($opts{h})
267{
268    output_source($header_text, $opts{H});
269}
270if ($opts{c})
271{
272    output_source($source_text, $opts{C});
273}
274
275exit 0;
276
277sub output_source
278{
279    my $text = shift;
280    my $file = shift;
281    my $handle;
282    if ($file)
283    {
284        sysopen OFH, $file, O_CREAT|O_TRUNC|O_WRONLY or die "error: can't open $file.\n";
285        $handle = \*OFH;
286    }
287    else
288    {
289        $handle = \*STDOUT;
290    }
291    binmode $handle;
292    $text =~ s/\x0D\x0A|\x0D|\x0A/\x0D\x0A/g;
293    print $handle $text;
294    if ($file)
295    {
296        close $handle;
297    }
298}
299
300#---------------------------------------------------------------------------
301