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