summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-04-01 18:38:34 +0000
committerDave Chapman <dave@dchapman.com>2006-04-01 18:38:34 +0000
commit0f619c65bab2465ffa84eb64cc62fe56506121f8 (patch)
treef8a9387673b1f6f7764620cbf10978e3b05d26f4 /apps/plugins
parent9fad701934a784e110edbff5556e21efe9c059d9 (diff)
downloadrockbox-0f619c65bab2465ffa84eb64cc62fe56506121f8.zip
rockbox-0f619c65bab2465ffa84eb64cc62fe56506121f8.tar.gz
rockbox-0f619c65bab2465ffa84eb64cc62fe56506121f8.tar.bz2
rockbox-0f619c65bab2465ffa84eb64cc62fe56506121f8.tar.xz
Move Sudoku plugin into its own subdirectory and add a random game generator.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9407 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/SOURCES4
-rw-r--r--apps/plugins/SUBDIRS4
-rw-r--r--apps/plugins/sudoku/Makefile117
-rw-r--r--apps/plugins/sudoku/SOURCES3
-rw-r--r--apps/plugins/sudoku/generator.c1097
-rw-r--r--apps/plugins/sudoku/generator.h1
-rw-r--r--apps/plugins/sudoku/sudoku.c (renamed from apps/plugins/sudoku.c)128
-rw-r--r--apps/plugins/sudoku/sudoku.h104
-rw-r--r--apps/plugins/sudoku/templates.c2877
-rw-r--r--apps/plugins/sudoku/templates.h8
10 files changed, 4254 insertions, 89 deletions
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index 27dfc75..ba489d0 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -58,10 +58,6 @@ solitaire.c
sokoban.c
star.c
starfield.c
-#if (LCD_WIDTH != 176) && (LCD_WIDTH != 138)
-/* These need adjusting for the iPod Nano and Mini */
-sudoku.c
-#endif
#if (LCD_WIDTH != 240) && (LCD_WIDTH != 138) && (LCD_WIDTH != 128)
tetrox.c
#endif
diff --git a/apps/plugins/SUBDIRS b/apps/plugins/SUBDIRS
index 01d9540..922d562 100644
--- a/apps/plugins/SUBDIRS
+++ b/apps/plugins/SUBDIRS
@@ -16,6 +16,10 @@ rockboy
/* For all targets with a bitmap display */
#ifdef HAVE_LCD_BITMAP
chessbox
+#if (LCD_WIDTH != 176) && (LCD_WIDTH != 138)
+/* This needs adjusting for the iPod Nano and Mini */
+sudoku
+#endif
#endif
/* For all the colour targets and iriver H1x0 */
diff --git a/apps/plugins/sudoku/Makefile b/apps/plugins/sudoku/Makefile
new file mode 100644
index 0000000..9b9c1c6
--- /dev/null
+++ b/apps/plugins/sudoku/Makefile
@@ -0,0 +1,117 @@
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+# $Id$
+#
+
+INCLUDES = -I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
+ -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(OUTDIR) -I$(BUILDDIR)
+CFLAGS = $(GCCOPTS) $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) \
+ -DTARGET_ID=$(TARGET_ID) -DMEM=${MEMORYSIZE} -DPLUGIN
+
+ifdef APPEXTRA
+ INCLUDES += $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
+endif
+
+LINKFILE := $(OBJDIR)/link.lds
+DEPFILE = $(OBJDIR)/dep-sudoku
+
+# This sets up 'SRC' based on the files mentioned in SOURCES
+include $(TOOLSDIR)/makesrc.inc
+
+SOURCES = $(SRC)
+OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
+DIRS = .
+
+ifndef SIMVER
+ LDS := ../plugin.lds
+ OUTPUT = $(OUTDIR)/sudoku.rock
+else ## simulators
+ OUTPUT = $(OUTDIR)/sudoku.rock
+endif
+
+all: $(OUTPUT)
+
+ifndef SIMVER
+$(OBJDIR)/sudoku.elf: $(OBJS) $(LINKFILE) $(BITMAPLIBS)
+ @echo "LD "`basename $@`
+ @$(CC) $(GCCOPTS) -O -nostdlib -o $@ $(OBJS) -L$(BUILDDIR) -lplugin -lgcc \
+ $(LINKBITMAPS) -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/sudoku.map
+
+$(OUTPUT): $(OBJDIR)/sudoku.elf
+ @echo "OBJCOPY "`basename $@`
+ @$(OC) -O binary $< $@
+else
+
+ifeq ($(SIMVER), x11)
+###################################################
+# This is the X11 simulator version
+
+$(OUTPUT): $(OBJS)
+ @echo "LD $<"
+ @$(CC) $(CFLAGS) -shared $(OBJS) -L$(BUILDDIR) -lplugin $(LINKBITMAPS) -o $@
+ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
+# 'x' must be kept or you'll have "Win32 error 5"
+# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
+# #define ERROR_ACCESS_DENIED 5L
+else
+ @chmod -x $@
+endif
+
+else # end of x11-simulator
+ifeq ($(SIMVER), sdl)
+###################################################
+# This is the SDL simulator version
+
+$(OUTPUT): $(OBJS)
+ @echo "LD $<"
+ @$(CC) $(CFLAGS) -shared $(OBJS) -L$(BUILDDIR) -lplugin $(LINKBITMAPS) -o $@
+ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
+# 'x' must be kept or you'll have "Win32 error 5"
+# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
+# #define ERROR_ACCESS_DENIED 5L
+else
+ @chmod -x $@
+endif
+
+else # end of sdl-simulator
+###################################################
+# This is the win32 simulator version
+DLLTOOLFLAGS = --export-all
+DLLWRAPFLAGS = -s --entry _DllMain@12 --target=i386-mingw32 -mno-cygwin
+
+$(OUTPUT): $(OBJS)
+ @echo "DLL "`basename $@`
+ @$(DLLTOOL) $(DLLTOOLFLAGS) -z $(OBJDIR)/$*.def $(OBJS)
+ @$(DLLWRAP) $(DLLWRAPFLAGS) --def $(OBJDIR)/$*.def $(OBJS) \
+ $(BUILDDIR)/libplugin.a $(BITMAPLIBS) -o $@
+ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
+# 'x' must be kept or you'll have "Win32 error 5"
+# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
+# #define ERROR_ACCESS_DENIED 5L
+else
+ @chmod -x $@
+endif
+endif # end of win32-simulator
+endif
+endif # end of simulator section
+
+
+include $(TOOLSDIR)/make.inc
+
+# MEMORYSIZE should be passed on to this makefile with the chosen memory size
+# given in number of MB
+$(LINKFILE): $(LDS)
+ @echo "build "`basename $@`
+ @cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) \
+ $(DEFINES) -E -P - >$@
+
+clean:
+ @echo "cleaning sudoku"
+ @rm -rf $(OBJDIR)/sudoku
+ @rm -f $(OBJDIR)/sudoku.* $(DEPFILE)
+
+-include $(DEPFILE)
diff --git a/apps/plugins/sudoku/SOURCES b/apps/plugins/sudoku/SOURCES
new file mode 100644
index 0000000..7cce555
--- /dev/null
+++ b/apps/plugins/sudoku/SOURCES
@@ -0,0 +1,3 @@
+sudoku.c
+generator.c
+templates.c
diff --git a/apps/plugins/sudoku/generator.c b/apps/plugins/sudoku/generator.c
new file mode 100644
index 0000000..d43e970
--- /dev/null
+++ b/apps/plugins/sudoku/generator.c
@@ -0,0 +1,1097 @@
+/* sudoku.c - sudoku game
+ *
+ * Writing a fun Su-Do-Ku game has turned out to be a difficult exercise.
+ * The biggest difficulty is keeping the game fun - and this means allowing
+ * the user to make mistakes. The game is not much fun if it prevents the
+ * user from making moves, or if it informs them of an incorrect move.
+ * With movement constraints, the 'game' is little more than an automated
+ * solver (and no fun at all).
+ *
+ * Another challenge is generating good puzzles that are entertaining to
+ * solve. It is certainly true that there is an art to creating good
+ * Su-Do-Ku puzzles, and that good hand generated puzzles are more
+ * entertaining than many computer generated puzzles - I just hope that
+ * the algorithm implemented here provides fun puzzles. It is an area
+ * that needs work. The puzzle classification is very simple, and could
+ * also do with work. Finally, understanding the automatically generated
+ * hints is sometimes more work than solving the puzzle - a better, and
+ * more human friendly, mechanism is needed.
+ *
+ * Comments, suggestions, and contributions are always welcome - send email
+ * to: mike 'at' laurasia.com.au. Note that this code assumes a single
+ * threaded process, makes extensive use of global variables, and has
+ * not been written to be reused in other applications. The code makes no
+ * use of dynamic memory allocation, and hence, requires no heap. It should
+ * also run with minimal stack space.
+ *
+ * This code and accompanying files have been placed into the public domain
+ * by Michael Kennett, July 2005. It is provided without any warranty
+ * whatsoever, and in no event shall Michael Kennett be liable for
+ * any damages of any kind, however caused, arising from this software.
+ */
+
+#include "plugin.h"
+
+#include "sudoku.h"
+#include "templates.h"
+
+extern struct plugin_api* rb;
+
+#define assert(x)
+
+/* Common state encoding in a 32-bit integer:
+ * bits 0-6 index
+ * 7-15 state [bit high signals digits not possible]
+ * 16-19 digit
+ * 20 fixed [set if digit initially fixed]
+ * 21 choice [set if solver chose this digit]
+ * 22 ignore [set if ignored by reapply()]
+ * 23 unused
+ * 24-26 hint
+ * 27-31 unused
+ */
+#define INDEX_MASK 0x0000007f
+#define GET_INDEX(val) (INDEX_MASK&(val))
+#define SET_INDEX(val) (val)
+
+#define STATE_MASK 0x0000ff80
+#define STATE_SHIFT (7-1) /* digits 1..9 */
+#define DIGIT_STATE(digit) (1<<(STATE_SHIFT+(digit)))
+
+#define DIGIT_MASK 0x000f0000
+#define DIGIT_SHIFT 16
+#define GET_DIGIT(val) (((val)&DIGIT_MASK)>>(DIGIT_SHIFT))
+#define SET_DIGIT(val) ((val)<<(DIGIT_SHIFT))
+
+#define FIXED 0x00100000
+#define CHOICE 0x00200000
+#define IGNORED 0x00400000
+
+/* Hint codes (c.f. singles(), pairs(), findmoves()) */
+#define HINT_ROW 0x01000000
+#define HINT_COLUMN 0x02000000
+#define HINT_BLOCK 0x04000000
+
+/* For a general board it may be necessary to do backtracking (i.e. to
+ * rewind the board to an earlier state), and make choices during the
+ * solution process. This can be implemented naturally using recursion,
+ * but it is more efficient to maintain a single board.
+ */
+static int board[ 81 ];
+
+/* Addressing board elements: linear array 0..80 */
+#define ROW(idx) ((idx)/9)
+#define COLUMN(idx) ((idx)%9)
+#define BLOCK(idx) (3*(ROW(idx)/3)+(COLUMN(idx)/3))
+#define INDEX(row,col) (9*(row)+(col))
+
+/* Blocks indexed 0..9 */
+#define IDX_BLOCK(row,col) (3*((row)/3)+((col)/3))
+#define TOP_LEFT(block) (INDEX(block/3,block%3))
+
+/* Board state */
+#define STATE(idx) ((board[idx])&STATE_MASK)
+#define DIGIT(idx) (GET_DIGIT(board[idx]))
+#define HINT(idx) ((board[idx])&HINT_MASK)
+#define IS_EMPTY(idx) (0 == DIGIT(idx))
+#define DISALLOWED(idx,digit) ((board[idx])&DIGIT_STATE(digit))
+#define IS_FIXED(idx) (board[idx]&FIXED)
+
+/* Record move history, and maintain a counter for the current
+ * move number. Concessions are made for the user interface, and
+ * allow digit 0 to indicate clearing a square. The move history
+ * is used to support 'undo's for the user interface, and hence
+ * is larger than required - there is sufficient space to solve
+ * the puzzle, undo every move, and then redo the puzzle - and
+ * if the user requires more space, then the full history will be
+ * lost.
+ */
+static int idx_history;
+static int history[ 3 * 81 ];
+
+/* Possible moves for a given board (c.f. fillmoves()).
+ * Also used by choice() when the deterministic solver has failed,
+ * and for calculating user hints. The number of hints is stored
+ * in num_hints, or -1 if no hints calculated. The number of hints
+ * requested by the user since their last move is stored in req_hints;
+ * if the user keeps requesting hints, start giving more information.
+ * Finally, record the last hint issued to the user; attempt to give
+ * different hints each time.
+ */
+static int idx_possible;
+static int possible[ 81 ];
+
+static int pass; /* count # passes of deterministic solver */
+
+/* Support for template file */
+static int tmplt[ 81 ]; /* Template indices */
+static int len_tmplt; /* Number of template indices */
+
+/* Reset global state */
+static
+void
+reset( void )
+{
+ rb->memset( board, 0x00, sizeof( board ) );
+ rb->memset( history, 0x00, sizeof( history ) );
+ idx_history = 0;
+ pass = 0;
+}
+
+/* Management of the move history - compression */
+static
+void
+compress( int limit )
+{
+ int i, j;
+ for( i = j = 0 ; i < idx_history && j < limit ; ++i )
+ if( !( history[ i ] & IGNORED ) )
+ history[ j++ ] = history[ i ];
+ for( ; i < idx_history ; ++i )
+ history[ j++ ] = history[ i ];
+ idx_history = j;
+}
+
+/* Management of the move history - adding a move */
+static
+void
+add_move( int idx, int digit, int choice )
+{
+ int i;
+
+ if( sizeof( history ) / sizeof( int ) == idx_history )
+ compress( 81 );
+
+ /* Never ignore the last move */
+ history[ idx_history++ ] = SET_INDEX( idx ) | SET_DIGIT( digit ) | choice;
+
+ /* Ignore all previous references to idx */
+ for( i = idx_history - 2 ; 0 <= i ; --i )
+ if( GET_INDEX( history[ i ] ) == idx )
+ {
+ history[ i ] |= IGNORED;
+ break;
+ }
+}
+
+/* Iteration over rows/columns/blocks handled by specialised code.
+ * Each function returns a block index - call must manage element/idx.
+ */
+static
+int
+idx_row( int el, int idx ) /* Index within a row */
+{
+ return INDEX( el, idx );
+}
+
+static
+int
+idx_column( int el, int idx ) /* Index within a column */
+{
+ return INDEX( idx, el );
+}
+
+static
+int
+idx_block( int el, int idx ) /* Index within a block */
+{
+ return INDEX( 3 * ( el / 3 ) + idx / 3, 3 * ( el % 3 ) + idx % 3 );
+}
+
+/* Update board state after setting a digit (clearing not handled)
+ */
+static
+void
+update( int idx )
+{
+ const int row = ROW( idx );
+ const int col = COLUMN( idx );
+ const int block = IDX_BLOCK( row, col );
+ const int mask = DIGIT_STATE( DIGIT( idx ) );
+ int i;
+
+ board[ idx ] |= STATE_MASK; /* filled - no choice possible */
+
+ /* Digit cannot appear in row, column or block */
+ for( i = 0 ; i < 9 ; ++i )
+ {
+ board[ idx_row( row, i ) ] |= mask;
+ board[ idx_column( col, i ) ] |= mask;
+ board[ idx_block( block, i ) ] |= mask;
+ }
+}
+
+/* Refresh board state, given move history. Note that this can yield
+ * an incorrect state if the user has made errors - return -1 if an
+ * incorrect state is generated; else return 0 for a correct state.
+ */
+static
+int
+reapply( void )
+{
+ int digit, idx, j;
+ int allok = 0;
+ rb->memset( board, 0x00, sizeof( board ) );
+ for( j = 0 ; j < idx_history ; ++j )
+ if( !( history[ j ] & IGNORED ) && 0 != GET_DIGIT( history[ j ] ) )
+ {
+ idx = GET_INDEX( history[ j ] );
+ digit = GET_DIGIT( history[ j ] );
+ if( !IS_EMPTY( idx ) || DISALLOWED( idx, digit ) )
+ allok = -1;
+ board[ idx ] = SET_DIGIT( digit );
+ if( history[ j ] & FIXED )
+ board[ idx ] |= FIXED;
+ update( idx );
+ }
+ return allok;
+}
+
+/* Clear moves, leaving fixed squares
+ */
+static
+void
+clear_moves( void )
+{
+ for( idx_history = 0 ; history[ idx_history ] & FIXED ; ++idx_history )
+ ;
+ reapply( );
+}
+
+static int digits[ 9 ]; /* # digits expressed in element square */
+static int counts[ 9 ]; /* Count of digits (c.f. count_set_digits()) */
+
+/* Count # set bits (within STATE_MASK) */
+static
+int
+numset( int mask )
+{
+ int i, n = 0;
+ for( i = STATE_SHIFT + 1 ; i <= STATE_SHIFT + 9 ; ++i )
+ if( mask & (1<<i) )
+ ++n;
+ else
+ ++counts[ i - STATE_SHIFT - 1 ];
+ return n;
+}
+
+static
+void
+count_set_digits( int el, int (*idx_fn)( int, int ) )
+{
+ int i;
+ rb->memset( counts, 0x00, sizeof( counts ) );
+ for( i = 0 ; i < 9 ; ++i )
+ digits[ i ] = numset( board[ (*idx_fn)( el, i ) ] );
+}
+
+/* Fill square with given digit, and update state.
+ * Returns 0 on success, else -1 on error (i.e. invalid fill)
+ */
+static
+int
+fill( int idx, int digit )
+{
+ assert( 0 != digit );
+
+ if( !IS_EMPTY( idx ) )
+ return ( DIGIT( idx ) == digit ) ? 0 : -1;
+
+ if( DISALLOWED( idx, digit ) )
+ return -1;
+
+ board[ idx ] = SET_DIGIT( digit );
+ update( idx );
+ add_move( idx, digit, 0 );
+
+ return 0;
+}
+
+/* Find all squares with a single digit allowed -- do not mutate board */
+static
+void
+singles( int el, int (*idx_fn)( int, int ), int hintcode )
+{
+ int i, j, idx;
+
+ count_set_digits( el, idx_fn );
+
+ for( i = 0 ; i < 9 ; ++i )
+ {
+ if( 1 == counts[ i ] )
+ {
+ /* Digit 'i+1' appears just once in the element */
+ for( j = 0 ; j < 9 ; ++j )
+ {
+ idx = (*idx_fn)( el, j );
+ if( !DISALLOWED( idx, i + 1 ) && idx_possible < 81 )
+ possible[ idx_possible++ ] = SET_INDEX( idx )
+ | SET_DIGIT( i + 1 )
+ | hintcode;
+ }
+ }
+ if( 8 == digits[ i ] )
+ {
+ /* 8 digits are masked at this position - just one remaining */
+ idx = (*idx_fn)( el, i );
+ for( j = 1 ; j <= 9 ; ++j )
+ if( 0 == ( STATE( idx ) & DIGIT_STATE( j ) ) && idx_possible < 81 )
+ possible[ idx_possible++ ] = SET_INDEX( idx )
+ | SET_DIGIT( j )
+ | hintcode;
+ }
+ }
+}
+
+/* Given the board state, find all possible 'moves' (i.e. squares with just
+ * a single digit).
+ *
+ * Returns the number of (deterministic) moves (and fills the moves array),
+ * or 0 if no moves are possible. This function does not mutate the board
+ * state, and hence, can return the same move multiple times (with
+ * different hints).
+ */
+static
+int
+findmoves( void )
+{
+ int i;
+
+ idx_possible = 0;
+ for( i = 0 ; i < 9 ; ++i )
+ {
+ singles( i, idx_row, HINT_ROW );
+ singles( i, idx_column, HINT_COLUMN );
+ singles( i, idx_block, HINT_BLOCK );
+ }
+ return idx_possible;
+}
+
+/* Strategies for refining the board state
+ * - 'pairs' if there are two unfilled squares in a given row/column/
+ * block with the same state, and just two possibilities,
+ * then all other unfilled squares in the row/column/block
+ * CANNOT be either of these digits.
+ * - 'block' if the unknown squares in a block all appear in the same
+ * row or column, then all unknown squares outside the block
+ * and in the same row/column cannot be any of the unknown
+ * squares in the block.
+ * - 'common' if all possible locations for a digit in a block appear
+ * in a row or column, then that digit cannot appear outside
+ * the block in the same row or column.
+ * - 'position2' if the positions of 2 unknown digits in a block match
+ * identically in precisely 2 positions, then those 2 positions
+ * can only contain the 2 unknown digits.
+ *
+ * Recall that each state bit uses a 1 to prevent a digit from
+ * filling that square.
+ */
+
+static
+void
+pairs( int el, int (*idx_fn)( int, int ) )
+{
+ int i, j, k, mask, idx;
+ for( i = 0 ; i < 8 ; ++i )
+ if( 7 == digits[ i ] ) /* 2 digits unknown */
+ for( j = i + 1 ; j < 9 ; ++j )
+ {
+ idx = (*idx_fn)( el, i );
+ if( STATE( idx ) == STATE( (*idx_fn)( el, j ) ) )
+ {
+ /* Found a row/column pair - mask other entries */
+ mask = STATE_MASK ^ (STATE_MASK & board[ idx ] );
+ for( k = 0 ; k < i ; ++k )
+ board[ (*idx_fn)( el, k ) ] |= mask;
+ for( k = i + 1 ; k < j ; ++k )
+ board[ (*idx_fn)( el, k ) ] |= mask;
+ for( k = j + 1 ; k < 9 ; ++k )
+ board[ (*idx_fn)( el, k ) ] |= mask;
+ digits[ j ] = -1; /* now processed */
+ }
+ }
+}
+
+/* Worker: mask elements outside block */
+static
+void
+exmask( int mask, int block, int el, int (*idx_fn)( int, int ) )
+{
+ int i, idx;
+
+ for( i = 0 ; i < 9 ; ++i )
+ {
+ idx = (*idx_fn)( el, i );
+ if( block != BLOCK( idx ) && IS_EMPTY( idx ) )
+ board[ idx ] |= mask;
+ }
+}
+
+/* Worker for block() */
+static
+void
+exblock( int block, int el, int (*idx_fn)( int, int ) )
+{
+ int i, idx, mask;
+
+ /* By assumption, all unknown squares in the block appear in the
+ * same row/column, so to construct a mask for these squares, it
+ * is sufficient to invert the mask for the known squares in the
+ * block.
+ */
+ mask = 0;
+ for( i = 0 ; i < 9 ; ++i )
+ {
+ idx = idx_block( block, i );
+ if( !IS_EMPTY( idx ) )
+ mask |= DIGIT_STATE( DIGIT( idx ) );
+ }
+ exmask( mask ^ STATE_MASK, block, el, idx_fn );
+}
+
+static
+void
+block( int el )
+{
+ int i, idx = 0, row, col;
+
+ /* Find first unknown square */
+ for( i = 0 ; i < 9 && !IS_EMPTY( idx = idx_block( el, i ) ) ; ++i )
+ ;
+ if( i < 9 )
+ {
+ assert( IS_EMPTY( idx ) );
+ row = ROW( idx );
+ col = COLUMN( idx );
+ for( ++i ; i < 9 ; ++i )
+ {
+ idx = idx_block( el, i );
+ if( IS_EMPTY( idx ) )
+ {
+ if( ROW( idx ) != row )
+ row = -1;
+ if( COLUMN( idx ) != col )
+ col = -1;
+ }
+ }
+ if( 0 <= row )
+ exblock( el, row, idx_row );
+ if( 0 <= col )
+ exblock( el, col, idx_column );
+ }
+}
+
+static
+void
+common( int el )
+{
+ int i, idx, row, col, digit, mask;
+
+ for( digit = 1 ; digit <= 9 ; ++digit )
+ {
+ mask = DIGIT_STATE( digit );
+ row = col = -1; /* Value '9' indicates invalid */
+ for( i = 0 ; i < 9 ; ++i )
+ {
+ /* Digit possible? */
+ idx = idx_block( el, i );
+ if( IS_EMPTY( idx ) && 0 == ( board[ idx ] & mask ) )
+ {
+ if( row < 0 )
+ row = ROW( idx );
+ else
+ if( row != ROW( idx ) )
+ row = 9; /* Digit appears in multiple rows */
+ if( col < 0 )
+ col = COLUMN( idx );
+ else
+ if( col != COLUMN( idx ) )
+ col = 9; /* Digit appears in multiple columns */
+ }
+ }
+ if( -1 != row && row < 9 )
+ exmask( mask, el, row, idx_row );
+ if( -1 != col && col < 9 )
+ exmask( mask, el, col, idx_column );
+ }
+}
+
+/* Encoding of positions of a digit (c.f. position2()) - abuse DIGIT_STATE */
+static int posn_digit[ 10 ];
+
+static
+void
+position2( int el )
+{
+ int digit, digit2, i, mask, mask2, posn, count, idx;
+
+ /* Calculate positions of each digit within block */
+ for( digit = 1 ; digit <= 9 ; ++digit )
+ {
+ mask = DIGIT_STATE( digit );
+ posn_digit[ digit ] = count = posn = 0;
+ for( i = 0 ; i < 9 ; ++i )
+ if( 0 == ( mask & board[ idx_block( el, i ) ] ) )
+ {
+ ++count;
+ posn |= DIGIT_STATE( i );
+ }
+ if( 2 == count )
+ posn_digit[ digit ] = posn;
+ }
+ /* Find pairs of matching positions, and mask */
+ for( digit = 1 ; digit < 9 ; ++digit )
+ if( 0 != posn_digit[ digit ] )
+ for( digit2 = digit + 1 ; digit2 <= 9 ; ++digit2 )
+ if( posn_digit[ digit ] == posn_digit[ digit2 ] )
+ {
+ mask = STATE_MASK
+ ^ ( DIGIT_STATE( digit ) | DIGIT_STATE( digit2 ) );
+ mask2 = DIGIT_STATE( digit );
+ for( i = 0 ; i < 9 ; ++i )
+ {
+ idx = idx_block( el, i );
+ if( 0 == ( mask2 & board[ idx ] ) )
+ {
+ assert( 0 == (DIGIT_STATE(digit2) & board[idx]) );
+ board[ idx ] |= mask;
+ }
+ }
+ posn_digit[ digit ] = posn_digit[ digit2 ] = 0;
+ break;
+ }
+}
+
+/* Find some moves for the board; starts with a simple approach (finding
+ * singles), and if no moves found, starts using more involved strategies
+ * until a move is found. The more advanced strategies can mask states
+ * in the board, making this an efficient mechanism, but difficult for
+ * a human to understand.
+ */
+static
+int
+allmoves( void )
+{
+ int i, n;
+
+ n = findmoves( );
+ if( 0 < n )
+ return n;
+
+ for( i = 0 ; i < 9 ; ++i )
+ {
+ count_set_digits( i, idx_row );
+ pairs( i, idx_row );
+
+ count_set_digits( i, idx_column );
+ pairs( i, idx_column );
+
+ count_set_digits( i, idx_block );
+ pairs( i, idx_block );
+ }
+ n = findmoves( );
+ if( 0 < n )
+ return n;
+
+ for( i = 0 ; i < 9 ; ++i )
+ {
+ block( i );
+ common( i );
+ position2( i );
+ }
+ return findmoves( );
+}
+
+/* Helper: sort based on index */
+static
+int
+cmpindex( const void * a, const void * b )
+{
+ return GET_INDEX( *((const int *)b) ) - GET_INDEX( *((const int *)a) );
+}
+
+/* Return number of hints. The hints mechanism should attempt to find
+ * 'easy' moves first, and if none are possible, then try for more
+ * cryptic moves.
+ */
+int
+findhints( void )
+{
+ int i, n, mutated = 0;
+
+ n = findmoves( );
+ if( n < 2 )
+ {
+ /* Each call to pairs() can mutate the board state, making the
+ * hints very, very cryptic... so later undo the mutations.
+ */
+ for( i = 0 ; i < 9 ; ++i )
+ {
+ count_set_digits( i, idx_row );
+ pairs( i, idx_row );
+
+ count_set_digits( i, idx_column );
+ pairs( i, idx_column );
+
+ count_set_digits( i, idx_block );
+ pairs( i, idx_block );
+ }
+ mutated = 1;
+ n = findmoves( );
+ }
+ if( n < 2 )
+ {
+ for( i = 0 ; i < 9 ; ++i )
+ {
+ block( i );
+ common( i );
+ }
+ mutated = 1;
+ n = findmoves( );
+ }
+
+ /* Sort the possible moves, and allow just one hint per square */
+ if( 0 < n )
+ {
+ int i, j;
+
+ rb->qsort( possible, n, sizeof( int ), cmpindex );
+ for( i = 0, j = 1 ; j < n ; ++j )
+ {
+ if( GET_INDEX( possible[ i ] ) == GET_INDEX( possible[ j ] ) )
+ {
+ /* Let the user make mistakes - do not assume the
+ * board is in a consistent state.
+ */
+ if( GET_DIGIT( possible[i] ) == GET_DIGIT( possible[j] ) )
+ possible[ i ] |= possible[ j ];
+ }
+ else
+ i = j;
+ }
+ n = i + 1;
+ }
+
+ /* Undo any mutations of the board state */
+ if( mutated )
+ reapply( );
+
+ return n;
+}
+
+/* Deterministic solver; return 0 on success, else -1 on error.
+ */
+static
+int
+deterministic( void )
+{
+ int i, n;
+
+ n = allmoves( );
+ while( 0 < n )
+ {
+ ++pass;
+ for( i = 0 ; i < n ; ++i )
+ if( -1 == fill( GET_INDEX( possible[ i ] ),
+ GET_DIGIT( possible[ i ] ) ) )
+ return -1;
+ n = allmoves( );
+ }
+ return 0;
+}
+
+/* Return index of square for choice.
+ *
+ * If no choice is possible (i.e. board solved or inconsistent),
+ * return -1.
+ *
+ * The current implementation finds a square with the minimum
+ * number of unknown digits (i.e. maximum # masked digits).
+ */
+static
+int
+cmp( const void * e1, const void * e2 )
+{
+ return GET_DIGIT( *(const int *)e2 ) - GET_DIGIT( *(const int *)e1 );
+}
+
+static
+int
+choice( void )
+{
+ int i, n;
+ for( n = i = 0 ; i < 81 ; ++i )
+ if( IS_EMPTY( i ) )
+ {
+ possible[ n ] = SET_INDEX( i ) | SET_DIGIT( numset( board[ i ] ) );
+
+ /* Inconsistency if square unknown, but nothing possible */
+ if( 9 == GET_DIGIT( possible[ n ] ) )
+ return -2;
+ ++n;
+ }
+
+ if( 0 == n )
+ return -1; /* All squares known */
+
+ rb->qsort( possible, n, sizeof( possible[ 0 ] ), cmp );
+ return GET_INDEX( possible[ 0 ] );
+}
+
+/* Choose a digit for the given square.
+ * The starting digit is passed as a parameter.
+ * Returns -1 if no choice possible.
+ */
+static
+int
+choose( int idx, int digit )
+{
+ for( ; digit <= 9 ; ++digit )
+ if( !DISALLOWED( idx, digit ) )
+ {
+ board[ idx ] = SET_DIGIT( digit );
+ update( idx );
+ add_move( idx, digit, CHOICE );
+ return digit;
+ }
+
+ return -1;
+}
+
+/* Backtrack to a previous choice point, and attempt to reseed
+ * the search. Return -1 if no further choice possible, or
+ * the index of the changed square.
+ *
+ * Assumes that the move history and board are valid.
+ */
+static
+int
+backtrack( void )
+{
+ int digit, idx;
+
+ for( ; 0 <= --idx_history ; )
+ if( history[ idx_history ] & CHOICE )
+ {
+ /* Remember the last choice, and advance */
+ idx = GET_INDEX( history[ idx_history ] );
+ digit = GET_DIGIT( history[ idx_history ] ) + 1;
+ reapply( );
+ if( -1 != choose( idx, digit ) )
+ return idx;
+ }
+
+ return -1;
+}
+
+/* Attempt to solve 'board'; return 0 on success else -1 on error.
+ *
+ * The solution process attempts to fill-in deterministically as
+ * much of the board as possible. Once that is no longer possible,
+ * need to choose a square to fill in.
+ */
+static
+int
+solve( void )
+{
+ int idx;
+
+ while( 1 )
+ {
+ if( 0 == deterministic( ) )
+ {
+ /* Solved, make a new choice, or rewind a previous choice */
+ idx = choice( );
+ if( -1 == idx )
+ return 0;
+ else
+ if( ( idx < 0 || -1 == choose( idx, 1 ) ) && -1 == backtrack( ) )
+ return -1;
+ }
+ else /* rewind to a previous choice */
+ if( -1 == backtrack( ) )
+ return -1;
+ }
+ return -1;
+}
+
+static
+int
+init_template( int template )
+{
+ int i, row, col;
+ int mask;
+
+ reset( );
+ len_tmplt = 0;
+
+ /* Consume grid - allow leading spaces and comments at end */
+ for( row = 0 ; row < 9 ; ++row )
+ {
+ mask=0x100;
+ for( col = 0 ; col < 9 ; ++col )
+ {
+ if (templates[template][row] & mask)
+ tmplt[ len_tmplt++ ] = INDEX( row, col );
+ mask /= 2;
+ }
+ }
+
+ /* Construct move history for a template */
+ idx_history = 0;
+ for( i = 0 ; i < 81 ; ++i )
+ if( 0 != DIGIT( i ) )
+ history[ idx_history++ ] = i | (DIGIT( i )<<8);
+
+ /* Finally, markup all of these moves as 'fixed' */
+ for( i = 0 ; i < idx_history ; ++i )
+ history[ i ] |= FIXED;
+
+ return 0;
+}
+
+/* Classify a SuDoKu, given its solution.
+ *
+ * The classification is based on the average number of possible moves
+ * for each pass of the deterministic solver - it is a rather simplistic
+ * measure, but gives reasonable results. Note also that the classification
+ * is based on the first solution found (but does handle the pathological
+ * case of multiple solutions). Note that the average moves per pass
+ * depends just on the number of squares initially set... this simplifies
+ * the statistics collection immensely, requiring just the number of passes
+ * to be counted.
+ *
+ * Return 0 on error, else a string classification.
+ */
+
+static
+char *
+classify( void )
+{
+ int i, score;
+
+ pass = 0;
+ clear_moves( );
+ if( -1 == solve( ) )
+ return 0;
+
+ score = 81;
+ for( i = 0 ; i < 81 ; ++i )
+ if( IS_FIXED( i ) )
+ --score;
+
+ assert( 81 == idx_history );
+
+ for( i = 0 ; i < 81 ; ++i )
+ if( history[ i ] & CHOICE )
+ score -= 5;
+
+ if( 15 * pass < score )
+ return "very easy";
+ else
+ if( 11 * pass < score )
+ return "easy";
+ else
+ if( 7 * pass < score )
+ return "medium";
+ else
+ if( 4 * pass < score )
+ return "hard";
+ else
+ return "fiendish";
+}
+
+/* exchange disjoint, identical length blocks of data */
+static
+void
+exchange( int * a, int * b, int len )
+{
+ int i, tmp;
+ for( i = 0 ; i < len ; ++i )
+ {
+ tmp = a[ i ];
+ a[ i ] = b[ i ];
+ b[ i ] = tmp;
+ }
+}
+
+/* rotate left */
+static
+void
+rotate1_left( int * a, int len )
+{
+ int i, tmp;
+ tmp = a[ 0 ];
+ for( i = 1 ; i < len ; ++i )
+ a[ i - 1 ] = a[ i ];
+ a[ len - 1 ] = tmp;
+}
+
+/* rotate right */
+static
+void
+rotate1_right( int * a, int len )
+{
+ int i, tmp;
+ tmp = a[ len - 1 ];
+ for( i = len - 1 ; 0 < i ; --i )
+ a[ i ] = a[ i - 1 ];
+ a[ 0 ] = tmp;
+}
+
+/* Generalised left rotation - there is a naturally recursive
+ * solution that is best implementation using iteration.
+ * Note that it is not necessary to do repeated unit rotations.
+ *
+ * This function is analogous to 'cutting' a 'pack of cards'.
+ *
+ * On entry: 0 < idx < len
+ */
+static
+void
+rotate( int * a, int len, int idx )
+{
+ int xdi = len - idx;
+ int delta = idx - xdi;
+
+ while( 0 != delta && 0 != idx )
+ {
+ if( delta < 0 )
+ {
+ if( 1 == idx )
+ {
+ rotate1_left( a, len );
+ idx = 0;
+ }
+ else
+ {
+ exchange( a, a + xdi, idx );
+ len = xdi;
+ }
+ }
+ else /* 0 < delta */
+ {
+ if( 1 == xdi )
+ {
+ rotate1_right( a, len );
+ idx = 0;
+ }
+ else
+ {
+ exchange( a, a + idx, xdi );
+ a += xdi;
+ len = idx;
+ idx -= xdi;
+ }
+ }
+ xdi = len - idx;
+ delta = idx - xdi;
+ }
+ if( 0 < idx )
+ exchange( a, a + idx, idx );
+}
+
+/* Shuffle an array of integers */
+static
+void
+shuffle( int * a, int len )
+{
+ int i, j, tmp;
+
+ i = len;
+ while( 1 <= i )
+ {
+ j = rb->rand( ) % i;
+ tmp = a[ --i ];
+ a[ i ] = a[ j ];
+ a[ j ] = tmp;
+ }
+}
+
+/* Generate a SuDoKu puzzle
+ *
+ * The generation process selects a random template, and then attempts
+ * to fill in the exposed squares to generate a board. The order of the
+ * digits and of filling in the exposed squares are random.
+ */
+
+/* Select random template; sets tmplt, len_tmplt */
+static
+void
+select_template( void )
+{
+ int i = rb->rand( ) % NUM_TEMPLATES;
+ init_template( i );
+}
+
+
+static
+void
+generate( void )
+{
+ static int digits[ 9 ];
+
+ int i;
+
+start:
+ for( i = 0 ; i < 9 ; ++i )
+ digits[ i ] = i + 1;
+
+ rotate( digits, 9, 1 + rb->rand( ) % 8 );
+ shuffle( digits, 9 );
+ select_template( );
+
+ rotate( tmplt, len_tmplt, 1 + rb->rand( ) % ( len_tmplt - 1 ) );
+ shuffle( tmplt, len_tmplt );
+
+ reset( ); /* construct a new board */
+
+ for( i = 0 ; i < len_tmplt ; ++i )
+ fill( tmplt[ i ], digits[ i % 9 ] );
+
+ if( 0 != solve( ) || idx_history < 81 )
+ goto start;
+
+ for( i = 0 ; i < len_tmplt ; ++i )
+ board[ tmplt[ i ] ] |= FIXED;
+
+ /* Construct fixed squares */
+ for( idx_history = i = 0 ; i < 81 ; ++i )
+ if( IS_FIXED( i ) )
+ history[ idx_history++ ] = SET_INDEX( i )
+ | SET_DIGIT( DIGIT( i ) )
+ | FIXED;
+ clear_moves( );
+
+ if( 0 != solve( ) || idx_history < 81 )
+ goto start;
+ if( -1 != backtrack( ) && 0 == solve( ) )
+ goto start;
+
+ clear_moves( );
+}
+
+bool sudoku_generate_board(struct sudoku_state_t* state, char** difficulty)
+{
+ int r,c,i;
+
+ rb->srand(*rb->current_tick);
+
+ generate();
+
+ i=0;
+ for (r=0;r<9;r++) {
+ for (c=0;c<9;c++) {
+ if( IS_EMPTY( i ) )
+ state->startboard[r][c]='0';
+ else
+ state->startboard[r][c]='0'+GET_DIGIT( board[ i ] );
+
+ state->currentboard[r][c]=state->startboard[r][c];
+ i++;
+ }
+ }
+
+ *difficulty = classify( );
+ return true;
+}
diff --git a/apps/plugins/sudoku/generator.h b/apps/plugins/sudoku/generator.h
new file mode 100644
index 0000000..3caa98e
--- /dev/null
+++ b/apps/plugins/sudoku/generator.h
@@ -0,0 +1 @@
+bool sudoku_generate_board(struct sudoku_state_t* state, char** difficulty);
diff --git a/apps/plugins/sudoku.c b/apps/plugins/sudoku/sudoku.c
index ece0fbb..798936b 100644
--- a/apps/plugins/sudoku.c
+++ b/apps/plugins/sudoku/sudoku.c
@@ -60,69 +60,12 @@ Example ".ss" file, and one with a saved state:
#ifdef HAVE_LCD_BITMAP
+#include "sudoku.h"
+#include "generator.h"
+
PLUGIN_HEADER
-#define STATE_FILE PLUGIN_DIR "/sudoku.state"
-#define GAMES_FILE PLUGIN_DIR "/sudoku.levels"
-
-/* variable button definitions */
-#if CONFIG_KEYPAD == RECORDER_PAD
-#define SUDOKU_BUTTON_QUIT BUTTON_OFF
-#define SUDOKU_BUTTON_UP BUTTON_UP
-#define SUDOKU_BUTTON_DOWN BUTTON_DOWN
-#define SUDOKU_BUTTON_TOGGLE BUTTON_PLAY
-#define SUDOKU_BUTTON_MENU BUTTON_F1
-#define SUDOKU_BUTTON_POSSIBLE BUTTON_F2
-
-#elif CONFIG_KEYPAD == ONDIO_PAD
-#define SUDOKU_BUTTON_QUIT BUTTON_OFF
-#define SUDOKU_BUTTON_UP BUTTON_UP
-#define SUDOKU_BUTTON_DOWN BUTTON_DOWN
-#define SUDOKU_BUTTON_ALTTOGGLE (BUTTON_MENU | BUTTON_DOWN)
-#define SUDOKU_BUTTON_TOGGLE_PRE BUTTON_MENU
-#define SUDOKU_BUTTON_TOGGLE (BUTTON_MENU | BUTTON_REL)
-#define SUDOKU_BUTTON_MENU_PRE BUTTON_MENU
-#define SUDOKU_BUTTON_MENU (BUTTON_MENU | BUTTON_REPEAT)
-#define SUDOKU_BUTTON_POSSIBLE (BUTTON_MENU | BUTTON_LEFT)
-
-#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
- (CONFIG_KEYPAD == IRIVER_H300_PAD)
-#define SUDOKU_BUTTON_QUIT BUTTON_OFF
-#define SUDOKU_BUTTON_UP BUTTON_UP
-#define SUDOKU_BUTTON_DOWN BUTTON_DOWN
-#define SUDOKU_BUTTON_ALTTOGGLE BUTTON_ON
-#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT
-#define SUDOKU_BUTTON_MENU BUTTON_MODE
-#define SUDOKU_BUTTON_POSSIBLE BUTTON_REC
-
-#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
- (CONFIG_KEYPAD == IPOD_3G_PAD)
-#define SUDOKU_BUTTON_QUIT (BUTTON_SELECT | BUTTON_MENU)
-#define SUDOKU_BUTTON_UP BUTTON_SCROLL_BACK
-#define SUDOKU_BUTTON_DOWN BUTTON_SCROLL_FWD
-#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT
-#define SUDOKU_BUTTON_MENU BUTTON_MENU
-#define SUDOKU_BUTTON_POSSIBLE (BUTTON_SELECT | BUTTON_LEFT)
-
-#elif (CONFIG_KEYPAD == IAUDIO_X5_PAD)
-#define SUDOKU_BUTTON_QUIT BUTTON_POWER
-#define SUDOKU_BUTTON_UP BUTTON_UP
-#define SUDOKU_BUTTON_DOWN BUTTON_DOWN
-#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT
-#define SUDOKU_BUTTON_MENU BUTTON_PLAY
-#define SUDOKU_BUTTON_POSSIBLE BUTTON_REC
-
-#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
-#define SUDOKU_BUTTON_QUIT BUTTON_A
-#define SUDOKU_BUTTON_UP BUTTON_UP
-#define SUDOKU_BUTTON_DOWN BUTTON_DOWN
-#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT
-#define SUDOKU_BUTTON_MENU BUTTON_MENU
-#define SUDOKU_BUTTON_POSSIBLE BUTTON_POWER
-
-#elif
- #error SUDOKU: Unsupported keypad
-#endif
+struct plugin_api* rb;
/* The bitmaps */
extern const fb_data sudoku_normal[];
@@ -204,23 +147,6 @@ static unsigned char cellypos[9]={ 2, 19, 36, 54, 71, 88, 106, 123, 140 };
#error SUDOKU: Unsupported LCD size
#endif
-/* here is a global api struct pointer. while not strictly necessary,
- it's nice not to have to pass the api pointer in all function calls
- in the plugin */
-static struct plugin_api* rb;
-
-struct sudoku_state_t {
- char filename[MAX_PATH]; /* Filename */
- char startboard[9][9]; /* The initial state of the game */
- char currentboard[9][9]; /* The current state of the game */
- char savedboard[9][9]; /* Cached copy of saved state */
- int x,y; /* Cursor position */
- int editmode; /* We are editing the start board */
-#ifdef SUDOKU_BUTTON_POSSIBLE
- short possiblevals[9][9]; /* possible values a cell could be, user sets them */
-#endif
-};
-
/****** Solver routine by Tom Shackell <shackell@cs.york.ac.uk>
Downloaded from:
@@ -541,7 +467,6 @@ bool load_sudoku(struct sudoku_state_t* state, char* filename)
fd=rb->open(filename, O_RDONLY);
if (fd < 0) {
- rb->splash(HZ*2, true, "Can not open");
LOGF("Invalid sudoku file: %s\n",filename);
return(false);
}
@@ -617,8 +542,8 @@ bool save_sudoku(struct sudoku_state_t* state)
int fd;
int r,c;
int i;
- char line[16];
- char sep[16];
+ char line[13];
+ char sep[13];
rb->memcpy(line,"...|...|...\r\n",13);
rb->memcpy(sep,"-----------\r\n",13);
@@ -644,9 +569,9 @@ bool save_sudoku(struct sudoku_state_t* state)
i++;
}
}
- rb->write(fd,line,sizeof(line)-1);
+ rb->write(fd,line,sizeof(line));
if ((r==2) || (r==5)) {
- rb->write(fd,sep,sizeof(sep)-1);
+ rb->write(fd,sep,sizeof(sep));
}
}
/* Add a blank line at end */
@@ -899,6 +824,23 @@ bool check_status(struct sudoku_state_t* state)
return false;
}
+void sudoku_generate(struct sudoku_state_t* state)
+{
+ char* difficulty;
+ char str[80];
+
+ clear_state(state);
+ display_board(state);
+ rb->splash(0, true, "Generating...");
+
+ sudoku_generate_board(state,&difficulty);
+
+ rb->snprintf(str,sizeof(str),"Difficulty: %s",difficulty);
+ display_board(state);
+ rb->splash(3*HZ, true, str);
+ rb->strncpy(state->filename,GAME_FILE,MAX_PATH);
+}
+
int sudoku_menu_cb(int key, int m)
{
(void)m;
@@ -932,7 +874,9 @@ bool sudoku_menu(struct sudoku_state_t* state)
{ "Reload", NULL },
{ "Clear", NULL },
{ "Solve", NULL },
+ { "Generate", NULL },
{ "New", NULL },
+ { "Quit", NULL },
};
m = rb->menu_init(items, sizeof(items) / sizeof(*items),
@@ -957,11 +901,21 @@ bool sudoku_menu(struct sudoku_state_t* state)
sudoku_solve(state);
break;
- case 4: /* Create a new game manually */
+ case 4: /* Generate Game */
+ sudoku_generate(state);
+ break;
+
+ case 5: /* Create a new game manually */
clear_state(state);
state->editmode=1;
break;
+ case 6: /* Quit */
+ save_sudoku(state);
+ rb->menu_exit(m);
+ return true;
+ break;
+
default:
break;
}
@@ -1010,7 +964,11 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
clear_state(&state);
if (parameter==NULL) {
- state.editmode=1;
+ /* We have been started as a plugin - try default sudoku.ss */
+ if (!load_sudoku(&state,GAME_FILE)) {
+ /* No previous game saved, generate one */
+ sudoku_generate(&state);
+ }
} else {
if (!load_sudoku(&state,(char*)parameter)) {
rb->splash(HZ*2, true, "Load error");
diff --git a/apps/plugins/sudoku/sudoku.h b/apps/plugins/sudoku/sudoku.h
new file mode 100644
index 0000000..cdad581
--- /dev/null
+++ b/apps/plugins/sudoku/sudoku.h
@@ -0,0 +1,104 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 Dave Chapman
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _SUDOKU_H
+#define _SUDOKU_H
+
+#include "plugin.h"
+
+/* here is a global api struct pointer. while not strictly necessary,
+ it's nice not to have to pass the api pointer in all function calls
+ in the plugin */
+
+#define STATE_FILE PLUGIN_DIR "/sudoku.state"
+#define GAME_FILE PLUGIN_DIR "/sudoku.ss"
+
+/* variable button definitions */
+#if CONFIG_KEYPAD == RECORDER_PAD
+#define SUDOKU_BUTTON_QUIT BUTTON_OFF
+#define SUDOKU_BUTTON_UP BUTTON_UP
+#define SUDOKU_BUTTON_DOWN BUTTON_DOWN
+#define SUDOKU_BUTTON_TOGGLE BUTTON_PLAY
+#define SUDOKU_BUTTON_MENU BUTTON_F1
+#define SUDOKU_BUTTON_POSSIBLE BUTTON_F2
+
+#elif CONFIG_KEYPAD == ONDIO_PAD
+#define SUDOKU_BUTTON_QUIT BUTTON_OFF
+#define SUDOKU_BUTTON_UP BUTTON_UP
+#define SUDOKU_BUTTON_DOWN BUTTON_DOWN
+#define SUDOKU_BUTTON_ALTTOGGLE (BUTTON_MENU | BUTTON_DOWN)
+#define SUDOKU_BUTTON_TOGGLE_PRE BUTTON_MENU
+#define SUDOKU_BUTTON_TOGGLE (BUTTON_MENU | BUTTON_REL)
+#define SUDOKU_BUTTON_MENU_PRE BUTTON_MENU
+#define SUDOKU_BUTTON_MENU (BUTTON_MENU | BUTTON_REPEAT)
+#define SUDOKU_BUTTON_POSSIBLE (BUTTON_MENU | BUTTON_LEFT)
+
+#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
+ (CONFIG_KEYPAD == IRIVER_H300_PAD)
+#define SUDOKU_BUTTON_QUIT BUTTON_OFF
+#define SUDOKU_BUTTON_UP BUTTON_UP
+#define SUDOKU_BUTTON_DOWN BUTTON_DOWN
+#define SUDOKU_BUTTON_ALTTOGGLE BUTTON_ON
+#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT
+#define SUDOKU_BUTTON_MENU BUTTON_MODE
+#define SUDOKU_BUTTON_POSSIBLE BUTTON_REC
+
+#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
+ (CONFIG_KEYPAD == IPOD_3G_PAD)
+#define SUDOKU_BUTTON_QUIT (BUTTON_SELECT | BUTTON_MENU)
+#define SUDOKU_BUTTON_UP BUTTON_SCROLL_BACK
+#define SUDOKU_BUTTON_DOWN BUTTON_SCROLL_FWD
+#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT
+#define SUDOKU_BUTTON_MENU BUTTON_MENU
+#define SUDOKU_BUTTON_POSSIBLE (BUTTON_SELECT | BUTTON_LEFT)
+
+#elif (CONFIG_KEYPAD == IAUDIO_X5_PAD)
+#define SUDOKU_BUTTON_QUIT BUTTON_POWER
+#define SUDOKU_BUTTON_UP BUTTON_UP
+#define SUDOKU_BUTTON_DOWN BUTTON_DOWN
+#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT
+#define SUDOKU_BUTTON_MENU BUTTON_PLAY
+#define SUDOKU_BUTTON_POSSIBLE BUTTON_REC
+
+#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
+#define SUDOKU_BUTTON_QUIT BUTTON_A
+#define SUDOKU_BUTTON_UP BUTTON_UP
+#define SUDOKU_BUTTON_DOWN BUTTON_DOWN
+#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT
+#define SUDOKU_BUTTON_MENU BUTTON_MENU
+#define SUDOKU_BUTTON_POSSIBLE BUTTON_POWER
+
+#elif
+ #error SUDOKU: Unsupported keypad
+#endif
+
+struct sudoku_state_t {
+ char filename[MAX_PATH]; /* Filename */
+ char startboard[9][9]; /* The initial state of the game */
+ char currentboard[9][9]; /* The current state of the game */
+ char savedboard[9][9]; /* Cached copy of saved state */
+ int x,y; /* Cursor position */
+ int editmode; /* We are editing the start board */
+#ifdef SUDOKU_BUTTON_POSSIBLE
+ short possiblevals[9][9]; /* possible values a cell could be, user sets them */
+#endif
+};
+
+
+#endif
diff --git a/apps/plugins/sudoku/templates.c b/apps/plugins/sudoku/templates.c
new file mode 100644
index 0000000..9f2117d
--- /dev/null
+++ b/apps/plugins/sudoku/templates.c
@@ -0,0 +1,2877 @@
+/* Template boards for the game generator */
+
+#include "templates.h"
+
+const unsigned short templates[NUM_TEMPLATES][9] = {
+{
+ 0x016d, /* #.##.##.# */
+ 0x006c, /* ..##.##.. */
+ 0x0089, /* .#...#..# */
+ 0x0116, /* #...#.##. */
+ 0x0082, /* .#.....#. */
+ 0x00d1, /* .##.#...# */
+ 0x0122, /* #..#...#. */
+ 0x006c, /* ..##.##.. */
+ 0x016d, /* #.##.##.# */
+},
+{
+ 0x0143, /* #.#....## */
+ 0x0031, /* ...##...# */
+ 0x01d1, /* ###.#...# */
+ 0x0023, /* ...#...## */
+ 0x016d, /* #.##.##.# */
+ 0x0188, /* ##...#... */
+ 0x0117, /* #...#.### */
+ 0x0118, /* #...##... */
+ 0x0185, /* ##....#.# */
+},
+{
+ 0x0185, /* ##....#.# */
+ 0x00e3, /* .###...## */
+ 0x0132, /* #..##..#. */
+ 0x002e, /* ...#.###. */
+ 0x0054, /* ..#.#.#.. */
+ 0x00e8, /* .###.#... */
+ 0x0099, /* .#..##..# */
+ 0x018e, /* ##...###. */
+ 0x0143, /* #.#....## */
+},
+{
+ 0x0189, /* ##...#..# */
+ 0x001a, /* ....##.#. */
+ 0x01e2, /* ####...#. */
+ 0x0055, /* ..#.#.#.# */
+ 0x0129, /* #..#.#..# */
+ 0x0154, /* #.#.#.#.. */
+ 0x008f, /* .#...#### */
+ 0x00b0, /* .#.##.... */
+ 0x0123, /* #..#...## */
+},
+{
+ 0x018b, /* ##...#.## */
+ 0x0199, /* ##..##..# */
+ 0x0014, /* ....#.#.. */
+ 0x008e, /* .#...###. */
+ 0x006c, /* ..##.##.. */
+ 0x00e2, /* .###...#. */
+ 0x0050, /* ..#.#.... */
+ 0x0133, /* #..##..## */
+ 0x01a3, /* ##.#...## */
+},
+{
+ 0x002e, /* ...#.###. */
+ 0x018a, /* ##...#.#. */
+ 0x0164, /* #.##..#.. */
+ 0x01ad, /* ##.#.##.# */
+ 0x0000, /* ......... */
+ 0x016b, /* #.##.#.## */
+ 0x004d, /* ..#..##.# */
+ 0x00a3, /* .#.#...## */
+ 0x00e8, /* .###.#... */
+},
+{
+ 0x005c, /* ..#.###.. */
+ 0x01a8, /* ##.#.#... */
+ 0x00d4, /* .##.#.#.. */
+ 0x0195, /* ##..#.#.# */
+ 0x0082, /* .#.....#. */
+ 0x0153, /* #.#.#..## */
+ 0x0056, /* ..#.#.##. */
+ 0x002b, /* ...#.#.## */
+ 0x0074, /* ..###.#.. */
+},
+{
+ 0x006c, /* ..##.##.. */
+ 0x00e2, /* .###...#. */
+ 0x0113, /* #...#..## */
+ 0x0113, /* #...#..## */
+ 0x006c, /* ..##.##.. */
+ 0x0191, /* ##..#...# */
+ 0x0191, /* ##..#...# */
+ 0x008e, /* .#...###. */
+ 0x006c, /* ..##.##.. */
+},
+{
+ 0x0098, /* .#..##... */
+ 0x0195, /* ##..#.#.# */
+ 0x0066, /* ..##..##. */
+ 0x00cb, /* .##..#.## */
+ 0x0028, /* ...#.#... */
+ 0x01a6, /* ##.#..##. */
+ 0x00cc, /* .##..##.. */
+ 0x0153, /* #.#.#..## */
+ 0x0032, /* ...##..#. */
+},
+{
+ 0x0164, /* #.##..#.. */
+ 0x00a5, /* .#.#..#.# */
+ 0x00aa, /* .#.#.#.#. */
+ 0x005c, /* ..#.###.. */
+ 0x0183, /* ##.....## */
+ 0x0074, /* ..###.#.. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x014a, /* #.#..#.#. */
+ 0x004d, /* ..#..##.# */
+},
+{
+ 0x0144, /* #.#...#.. */
+ 0x00dc, /* .##.###.. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x01a2, /* ##.#...#. */
+ 0x0038, /* ...###... */
+ 0x008b, /* .#...#.## */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0076, /* ..###.##. */
+ 0x0045, /* ..#...#.# */
+},
+{
+ 0x0113, /* #...#..## */
+ 0x01a2, /* ##.#...#. */
+ 0x006c, /* ..##.##.. */
+ 0x0056, /* ..#.#.##. */
+ 0x0129, /* #..#.#..# */
+ 0x00d4, /* .##.#.#.. */
+ 0x006c, /* ..##.##.. */
+ 0x008b, /* .#...#.## */
+ 0x0191, /* ##..#...# */
+},
+{
+ 0x006a, /* ..##.#.#. */
+ 0x0174, /* #.###.#.. */
+ 0x0083, /* .#.....## */
+ 0x012b, /* #..#.#.## */
+ 0x0092, /* .#..#..#. */
+ 0x01a9, /* ##.#.#..# */
+ 0x0182, /* ##.....#. */
+ 0x005d, /* ..#.###.# */
+ 0x00ac, /* .#.#.##.. */
+},
+{
+ 0x00aa, /* .#.#.#.#. */
+ 0x0129, /* #..#.#..# */
+ 0x0092, /* .#..#..#. */
+ 0x0044, /* ..#...#.. */
+ 0x0183, /* ##.....## */
+ 0x0044, /* ..#...#.. */
+ 0x0092, /* .#..#..#. */
+ 0x0129, /* #..#.#..# */
+ 0x00aa, /* .#.#.#.#. */
+},
+{
+ 0x00aa, /* .#.#.#.#. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x00ba, /* .#.###.#. */
+ 0x0082, /* .#.....#. */
+ 0x00ba, /* .#.###.#. */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x00aa, /* .#.#.#.#. */
+},
+{
+ 0x00ba, /* .#.###.#. */
+ 0x0101, /* #.......# */
+ 0x0044, /* ..#...#.. */
+ 0x01ab, /* ##.#.#.## */
+ 0x0010, /* ....#.... */
+ 0x01ab, /* ##.#.#.## */
+ 0x0044, /* ..#...#.. */
+ 0x0101, /* #.......# */
+ 0x00ba, /* .#.###.#. */
+},
+{
+ 0x0082, /* .#.....#. */
+ 0x00d6, /* .##.#.##. */
+ 0x0129, /* #..#.#..# */
+ 0x006c, /* ..##.##.. */
+ 0x0000, /* ......... */
+ 0x006c, /* ..##.##.. */
+ 0x0129, /* #..#.#..# */
+ 0x00d6, /* .##.#.##. */
+ 0x0082, /* .#.....#. */
+},
+{
+ 0x000a, /* .....#.#. */
+ 0x018c, /* ##...##.. */
+ 0x00a4, /* .#.#..#.. */
+ 0x009a, /* .#..##.#. */
+ 0x0101, /* #.......# */
+ 0x00b2, /* .#.##..#. */
+ 0x004a, /* ..#..#.#. */
+ 0x0063, /* ..##...## */
+ 0x00a0, /* .#.#..... */
+},
+{
+ 0x00aa, /* .#.#.#.#. */
+ 0x0101, /* #.......# */
+ 0x0054, /* ..#.#.#.. */
+ 0x00d6, /* .##.#.##. */
+ 0x0092, /* .#..#..#. */
+ 0x00d6, /* .##.#.##. */
+ 0x0054, /* ..#.#.#.. */
+ 0x0101, /* #.......# */
+ 0x00aa, /* .#.#.#.#. */
+},
+{
+ 0x00c6, /* .##...##. */
+ 0x0028, /* ...#.#... */
+ 0x0193, /* ##..#..## */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0193, /* ##..#..## */
+ 0x0028, /* ...#.#... */
+ 0x00c6, /* .##...##. */
+},
+{
+ 0x01b8, /* ##.###... */
+ 0x0001, /* ........# */
+ 0x00e4, /* .###..#.. */
+ 0x0111, /* #...#...# */
+ 0x0044, /* ..#...#.. */
+ 0x0111, /* #...#...# */
+ 0x004e, /* ..#..###. */
+ 0x0100, /* #........ */
+ 0x003b, /* ...###.## */
+},
+{
+ 0x0000, /* ......... */
+ 0x00aa, /* .#.#.#.#. */
+ 0x00ee, /* .###.###. */
+ 0x0129, /* #..#.#..# */
+ 0x006c, /* ..##.##.. */
+ 0x0129, /* #..#.#..# */
+ 0x00ee, /* .###.###. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0000, /* ......... */
+},
+{
+ 0x0031, /* ...##...# */
+ 0x0154, /* #.#.#.#.. */
+ 0x0009, /* .....#..# */
+ 0x00f4, /* .####.#.. */
+ 0x0044, /* ..#...#.. */
+ 0x005e, /* ..#.####. */
+ 0x0120, /* #..#..... */
+ 0x0055, /* ..#.#.#.# */
+ 0x0118, /* #...##... */
+},
+{
+ 0x00b0, /* .#.##.... */
+ 0x00a3, /* .#.#...## */
+ 0x0064, /* ..##..#.. */
+ 0x0007, /* ......### */
+ 0x0111, /* #...#...# */
+ 0x01c0, /* ###...... */
+ 0x004c, /* ..#..##.. */
+ 0x018a, /* ##...#.#. */
+ 0x001a, /* ....##.#. */
+},
+{
+ 0x0129, /* #..#.#..# */
+ 0x0048, /* ..#..#... */
+ 0x0012, /* ....#..#. */
+ 0x0191, /* ##..#...# */
+ 0x006c, /* ..##.##.. */
+ 0x0113, /* #...#..## */
+ 0x0090, /* .#..#.... */
+ 0x0024, /* ...#..#.. */
+ 0x0129, /* #..#.#..# */
+},
+{
+ 0x00a0, /* .#.#..... */
+ 0x0051, /* ..#.#...# */
+ 0x005e, /* ..#.####. */
+ 0x0041, /* ..#.....# */
+ 0x00d6, /* .##.#.##. */
+ 0x0104, /* #.....#.. */
+ 0x00f4, /* .####.#.. */
+ 0x0114, /* #...#.#.. */
+ 0x000a, /* .....#.#. */
+},
+{
+ 0x0008, /* .....#... */
+ 0x0090, /* .#..#.... */
+ 0x001f, /* ....##### */
+ 0x00d3, /* .##.#..## */
+ 0x006c, /* ..##.##.. */
+ 0x0196, /* ##..#.##. */
+ 0x01f0, /* #####.... */
+ 0x0012, /* ....#..#. */
+ 0x0020, /* ...#..... */
+},
+{
+ 0x0145, /* #.#...#.# */
+ 0x0155, /* #.#.#.#.# */
+ 0x0028, /* ...#.#... */
+ 0x006c, /* ..##.##.. */
+ 0x0000, /* ......... */
+ 0x006c, /* ..##.##.. */
+ 0x0028, /* ...#.#... */
+ 0x0155, /* #.#.#.#.# */
+ 0x0145, /* #.#...#.# */
+},
+{
+ 0x0006, /* ......##. */
+ 0x0170, /* #.###.... */
+ 0x0031, /* ...##...# */
+ 0x00c3, /* .##....## */
+ 0x0101, /* #.......# */
+ 0x0186, /* ##....##. */
+ 0x0118, /* #...##... */
+ 0x001d, /* ....###.# */
+ 0x00c0, /* .##...... */
+},
+{
+ 0x0038, /* ...###... */
+ 0x0129, /* #..#.#..# */
+ 0x0044, /* ..#...#.. */
+ 0x0145, /* #.#...#.# */
+ 0x0082, /* .#.....#. */
+ 0x0145, /* #.#...#.# */
+ 0x0044, /* ..#...#.. */
+ 0x0129, /* #..#.#..# */
+ 0x0038, /* ...###... */
+},
+{
+ 0x0082, /* .#.....#. */
+ 0x0111, /* #...#...# */
+ 0x0129, /* #..#.#..# */
+ 0x006c, /* ..##.##.. */
+ 0x0010, /* ....#.... */
+ 0x006c, /* ..##.##.. */
+ 0x0129, /* #..#.#..# */
+ 0x0111, /* #...#...# */
+ 0x0082, /* .#.....#. */
+},
+{
+ 0x0183, /* ##.....## */
+ 0x0092, /* .#..#..#. */
+ 0x006c, /* ..##.##.. */
+ 0x0028, /* ...#.#... */
+ 0x0101, /* #.......# */
+ 0x0028, /* ...#.#... */
+ 0x006c, /* ..##.##.. */
+ 0x0092, /* .#..#..#. */
+ 0x0183, /* ##.....## */
+},
+{
+ 0x00d0, /* .##.#.... */
+ 0x0109, /* #....#..# */
+ 0x0184, /* ##....#.. */
+ 0x0160, /* #.##..... */
+ 0x0044, /* ..#...#.. */
+ 0x000d, /* .....##.# */
+ 0x0043, /* ..#....## */
+ 0x0121, /* #..#....# */
+ 0x0016, /* ....#.##. */
+},
+{
+ 0x0060, /* ..##..... */
+ 0x0140, /* #.#...... */
+ 0x0093, /* .#..#..## */
+ 0x010e, /* #....###. */
+ 0x0054, /* ..#.#.#.. */
+ 0x00e1, /* .###....# */
+ 0x0192, /* ##..#..#. */
+ 0x0005, /* ......#.# */
+ 0x000c, /* .....##.. */
+},
+{
+ 0x001a, /* ....##.#. */
+ 0x0091, /* .#..#...# */
+ 0x00a1, /* .#.#....# */
+ 0x00c2, /* .##....#. */
+ 0x0028, /* ...#.#... */
+ 0x0086, /* .#....##. */
+ 0x010a, /* #....#.#. */
+ 0x0112, /* #...#..#. */
+ 0x00b0, /* .#.##.... */
+},
+{
+ 0x0162, /* #.##...#. */
+ 0x0049, /* ..#..#..# */
+ 0x004c, /* ..#..##.. */
+ 0x0016, /* ....#.##. */
+ 0x0000, /* ......... */
+ 0x00d0, /* .##.#.... */
+ 0x0064, /* ..##..#.. */
+ 0x0124, /* #..#..#.. */
+ 0x008d, /* .#...##.# */
+},
+{
+ 0x0025, /* ...#..#.# */
+ 0x0050, /* ..#.#.... */
+ 0x0053, /* ..#.#..## */
+ 0x0032, /* ...##..#. */
+ 0x0028, /* ...#.#... */
+ 0x0098, /* .#..##... */
+ 0x0194, /* ##..#.#.. */
+ 0x0014, /* ....#.#.. */
+ 0x0148, /* #.#..#... */
+},
+{
+ 0x0129, /* #..#.#..# */
+ 0x0000, /* ......... */
+ 0x00c6, /* .##...##. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0092, /* .#..#..#. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x00c6, /* .##...##. */
+ 0x0000, /* ......... */
+ 0x0129, /* #..#.#..# */
+},
+{
+ 0x0095, /* .#..#.#.# */
+ 0x002b, /* ...#.#.## */
+ 0x0000, /* ......... */
+ 0x00ca, /* .##..#.#. */
+ 0x0028, /* ...#.#... */
+ 0x00a6, /* .#.#..##. */
+ 0x0000, /* ......... */
+ 0x01a8, /* ##.#.#... */
+ 0x0153, /* #.#.#..## */
+},
+{
+ 0x0008, /* .....#... */
+ 0x0153, /* #.#.#..## */
+ 0x0070, /* ..###.... */
+ 0x0141, /* #.#.....# */
+ 0x0082, /* .#.....#. */
+ 0x0105, /* #.....#.# */
+ 0x001c, /* ....###.. */
+ 0x0195, /* ##..#.#.# */
+ 0x0020, /* ...#..... */
+},
+{
+ 0x000c, /* .....##.. */
+ 0x0100, /* #........ */
+ 0x0076, /* ..###.##. */
+ 0x0013, /* ....#..## */
+ 0x0101, /* #.......# */
+ 0x0190, /* ##..#.... */
+ 0x00dc, /* .##.###.. */
+ 0x0001, /* ........# */
+ 0x0060, /* ..##..... */
+},
+{
+ 0x00ba, /* .#.###.#. */
+ 0x0101, /* #.......# */
+ 0x0044, /* ..#...#.. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0000, /* ......... */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0044, /* ..#...#.. */
+ 0x0101, /* #.......# */
+ 0x00ba, /* .#.###.#. */
+},
+{
+ 0x0189, /* ##...#..# */
+ 0x00a3, /* .#.#...## */
+ 0x0010, /* ....#.... */
+ 0x0102, /* #......#. */
+ 0x0054, /* ..#.#.#.. */
+ 0x0081, /* .#......# */
+ 0x0010, /* ....#.... */
+ 0x018a, /* ##...#.#. */
+ 0x0123, /* #..#...## */
+},
+{
+ 0x0189, /* ##...#..# */
+ 0x00a3, /* .#.#...## */
+ 0x0010, /* ....#.... */
+ 0x0102, /* #......#. */
+ 0x0054, /* ..#.#.#.. */
+ 0x0081, /* .#......# */
+ 0x0010, /* ....#.... */
+ 0x018a, /* ##...#.#. */
+ 0x0123, /* #..#...## */
+},
+{
+ 0x0044, /* ..#...#.. */
+ 0x00ee, /* .###.###. */
+ 0x0183, /* ##.....## */
+ 0x0038, /* ...###... */
+ 0x0010, /* ....#.... */
+ 0x0038, /* ...###... */
+ 0x0183, /* ##.....## */
+ 0x00ee, /* .###.###. */
+ 0x0044, /* ..#...#.. */
+},
+{
+ 0x0064, /* ..##..#.. */
+ 0x0096, /* .#..#.##. */
+ 0x0081, /* .#......# */
+ 0x010a, /* #....#.#. */
+ 0x0010, /* ....#.... */
+ 0x00a1, /* .#.#....# */
+ 0x0102, /* #......#. */
+ 0x00d2, /* .##.#..#. */
+ 0x004c, /* ..#..##.. */
+},
+{
+ 0x0180, /* ##....... */
+ 0x0190, /* ##..#.... */
+ 0x00a8, /* .#.#.#... */
+ 0x0124, /* #..#..#.. */
+ 0x0145, /* #.#...#.# */
+ 0x0049, /* ..#..#..# */
+ 0x002a, /* ...#.#.#. */
+ 0x0013, /* ....#..## */
+ 0x0003, /* .......## */
+},
+{
+ 0x010d, /* #....##.# */
+ 0x0104, /* #.....#.. */
+ 0x00a2, /* .#.#...#. */
+ 0x0038, /* ...###... */
+ 0x0044, /* ..#...#.. */
+ 0x0038, /* ...###... */
+ 0x008a, /* .#...#.#. */
+ 0x0041, /* ..#.....# */
+ 0x0161, /* #.##....# */
+},
+{
+ 0x004c, /* ..#..##.. */
+ 0x00b2, /* .#.##..#. */
+ 0x0165, /* #.##..#.# */
+ 0x0116, /* #...#.##. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x00d1, /* .##.#...# */
+ 0x014d, /* #.#..##.# */
+ 0x009a, /* .#..##.#. */
+ 0x0064, /* ..##..#.. */
+},
+{
+ 0x0111, /* #...#...# */
+ 0x0092, /* .#..#..#. */
+ 0x0129, /* #..#.#..# */
+ 0x0145, /* #.#...#.# */
+ 0x006c, /* ..##.##.. */
+ 0x0145, /* #.#...#.# */
+ 0x0129, /* #..#.#..# */
+ 0x0092, /* .#..#..#. */
+ 0x0111, /* #...#...# */
+},
+{
+ 0x00ac, /* .#.#.##.. */
+ 0x0182, /* ##.....#. */
+ 0x0032, /* ...##..#. */
+ 0x001c, /* ....###.. */
+ 0x0000, /* ......... */
+ 0x0070, /* ..###.... */
+ 0x0098, /* .#..##... */
+ 0x0083, /* .#.....## */
+ 0x006a, /* ..##.#.#. */
+},
+{
+ 0x0052, /* ..#.#..#. */
+ 0x0008, /* .....#... */
+ 0x012a, /* #..#.#.#. */
+ 0x01a4, /* ##.#..#.. */
+ 0x0082, /* .#.....#. */
+ 0x004b, /* ..#..#.## */
+ 0x00a9, /* .#.#.#..# */
+ 0x0020, /* ...#..... */
+ 0x0094, /* .#..#.#.. */
+},
+{
+ 0x0049, /* ..#..#..# */
+ 0x0030, /* ...##.... */
+ 0x0026, /* ...#..##. */
+ 0x00c6, /* .##...##. */
+ 0x0010, /* ....#.... */
+ 0x00c6, /* .##...##. */
+ 0x00c8, /* .##..#... */
+ 0x0018, /* ....##... */
+ 0x0124, /* #..#..#.. */
+},
+{
+ 0x0029, /* ...#.#..# */
+ 0x01a4, /* ##.#..#.. */
+ 0x00a0, /* .#.#..... */
+ 0x0005, /* ......#.# */
+ 0x0183, /* ##.....## */
+ 0x0140, /* #.#...... */
+ 0x000a, /* .....#.#. */
+ 0x004b, /* ..#..#.## */
+ 0x0128, /* #..#.#... */
+},
+{
+ 0x0014, /* ....#.#.. */
+ 0x0164, /* #.##..#.. */
+ 0x0161, /* #.##....# */
+ 0x0040, /* ..#...... */
+ 0x0038, /* ...###... */
+ 0x0004, /* ......#.. */
+ 0x010d, /* #....##.# */
+ 0x004d, /* ..#..##.# */
+ 0x0050, /* ..#.#.... */
+},
+{
+ 0x0101, /* #.......# */
+ 0x00c6, /* .##...##. */
+ 0x0038, /* ...###... */
+ 0x007c, /* ..#####.. */
+ 0x0183, /* ##.....## */
+ 0x007c, /* ..#####.. */
+ 0x0038, /* ...###... */
+ 0x00c6, /* .##...##. */
+ 0x0101, /* #.......# */
+},
+{
+ 0x0020, /* ...#..... */
+ 0x0054, /* ..#.#.#.. */
+ 0x0063, /* ..##...## */
+ 0x0149, /* #.#..#..# */
+ 0x0101, /* #.......# */
+ 0x0125, /* #..#..#.# */
+ 0x018c, /* ##...##.. */
+ 0x0054, /* ..#.#.#.. */
+ 0x0008, /* .....#... */
+},
+{
+ 0x00aa, /* .#.#.#.#. */
+ 0x0044, /* ..#...#.. */
+ 0x002a, /* ...#.#.#. */
+ 0x0081, /* .#......# */
+ 0x0038, /* ...###... */
+ 0x0102, /* #......#. */
+ 0x00a8, /* .#.#.#... */
+ 0x0044, /* ..#...#.. */
+ 0x00aa, /* .#.#.#.#. */
+},
+{
+ 0x0014, /* ....#.#.. */
+ 0x0140, /* #.#...... */
+ 0x000f, /* .....#### */
+ 0x0003, /* .......## */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0180, /* ##....... */
+ 0x01e0, /* ####..... */
+ 0x0005, /* ......#.# */
+ 0x0050, /* ..#.#.... */
+},
+{
+ 0x002d, /* ...#.##.# */
+ 0x0010, /* ....#.... */
+ 0x0091, /* .#..#...# */
+ 0x0074, /* ..###.#.. */
+ 0x0101, /* #.......# */
+ 0x005c, /* ..#.###.. */
+ 0x0112, /* #...#..#. */
+ 0x0010, /* ....#.... */
+ 0x0168, /* #.##.#... */
+},
+{
+ 0x0096, /* .#..#.##. */
+ 0x009a, /* .#..##.#. */
+ 0x00e4, /* .###..#.. */
+ 0x0190, /* ##..#.... */
+ 0x01ab, /* ##.#.#.## */
+ 0x0013, /* ....#..## */
+ 0x004e, /* ..#..###. */
+ 0x00b2, /* .#.##..#. */
+ 0x00d2, /* .##.#..#. */
+},
+{
+ 0x0150, /* #.#.#.... */
+ 0x0022, /* ...#...#. */
+ 0x0094, /* .#..#.#.. */
+ 0x016c, /* #.##.##.. */
+ 0x0082, /* .#.....#. */
+ 0x006d, /* ..##.##.# */
+ 0x0052, /* ..#.#..#. */
+ 0x0088, /* .#...#... */
+ 0x0015, /* ....#.#.# */
+},
+{
+ 0x000d, /* .....##.# */
+ 0x01b1, /* ##.##...# */
+ 0x0080, /* .#....... */
+ 0x014c, /* #.#..##.. */
+ 0x0101, /* #.......# */
+ 0x0065, /* ..##..#.# */
+ 0x0002, /* .......#. */
+ 0x011b, /* #...##.## */
+ 0x0160, /* #.##..... */
+},
+{
+ 0x0016, /* ....#.##. */
+ 0x0160, /* #.##..... */
+ 0x010a, /* #....#.#. */
+ 0x0052, /* ..#.#..#. */
+ 0x0129, /* #..#.#..# */
+ 0x0094, /* .#..#.#.. */
+ 0x00a1, /* .#.#....# */
+ 0x000d, /* .....##.# */
+ 0x00d0, /* .##.#.... */
+},
+{
+ 0x00e9, /* .###.#..# */
+ 0x00c1, /* .##.....# */
+ 0x0120, /* #..#..... */
+ 0x0188, /* ##...#... */
+ 0x00c6, /* .##...##. */
+ 0x0023, /* ...#...## */
+ 0x0009, /* .....#..# */
+ 0x0106, /* #.....##. */
+ 0x012e, /* #..#.###. */
+},
+{
+ 0x000d, /* .....##.# */
+ 0x0090, /* .#..#.... */
+ 0x0188, /* ##...#... */
+ 0x0059, /* ..#.##..# */
+ 0x0028, /* ...#.#... */
+ 0x0134, /* #..##.#.. */
+ 0x0023, /* ...#...## */
+ 0x0012, /* ....#..#. */
+ 0x0160, /* #.##..... */
+},
+{
+ 0x0108, /* #....#... */
+ 0x0116, /* #...#.##. */
+ 0x0148, /* #.#..#... */
+ 0x01c4, /* ###...#.. */
+ 0x0101, /* #.......# */
+ 0x0047, /* ..#...### */
+ 0x0025, /* ...#..#.# */
+ 0x00d1, /* .##.#...# */
+ 0x0021, /* ...#....# */
+},
+{
+ 0x0151, /* #.#.#...# */
+ 0x0024, /* ...#..#.. */
+ 0x004a, /* ..#..#.#. */
+ 0x0042, /* ..#....#. */
+ 0x006c, /* ..##.##.. */
+ 0x0084, /* .#....#.. */
+ 0x00a4, /* .#.#..#.. */
+ 0x0048, /* ..#..#... */
+ 0x0115, /* #...#.#.# */
+},
+{
+ 0x00aa, /* .#.#.#.#. */
+ 0x0044, /* ..#...#.. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x00c6, /* .##...##. */
+ 0x0101, /* #.......# */
+ 0x00c6, /* .##...##. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0044, /* ..#...#.. */
+ 0x00aa, /* .#.#.#.#. */
+},
+{
+ 0x0004, /* ......#.. */
+ 0x0061, /* ..##....# */
+ 0x0023, /* ...#...## */
+ 0x0184, /* ##....#.. */
+ 0x0139, /* #..###..# */
+ 0x0043, /* ..#....## */
+ 0x0188, /* ##...#... */
+ 0x010c, /* #....##.. */
+ 0x0040, /* ..#...... */
+},
+{
+ 0x0141, /* #.#.....# */
+ 0x0082, /* .#.....#. */
+ 0x00a2, /* .#.#...#. */
+ 0x003d, /* ...####.# */
+ 0x0010, /* ....#.... */
+ 0x0178, /* #.####... */
+ 0x008a, /* .#...#.#. */
+ 0x0082, /* .#.....#. */
+ 0x0105, /* #.....#.# */
+},
+{
+ 0x01a3, /* ##.#...## */
+ 0x01ac, /* ##.#.##.. */
+ 0x0049, /* ..#..#..# */
+ 0x0106, /* #.....##. */
+ 0x0129, /* #..#.#..# */
+ 0x00c1, /* .##.....# */
+ 0x0124, /* #..#..#.. */
+ 0x006b, /* ..##.#.## */
+ 0x018b, /* ##...#.## */
+},
+{
+ 0x0044, /* ..#...#.. */
+ 0x0015, /* ....#.#.# */
+ 0x0132, /* #..##..#. */
+ 0x0021, /* ...#....# */
+ 0x006c, /* ..##.##.. */
+ 0x0108, /* #....#... */
+ 0x0099, /* .#..##..# */
+ 0x0150, /* #.#.#.... */
+ 0x0044, /* ..#...#.. */
+},
+{
+ 0x0112, /* #...#..#. */
+ 0x0024, /* ...#..#.. */
+ 0x014c, /* #.#..##.. */
+ 0x0041, /* ..#.....# */
+ 0x016d, /* #.##.##.# */
+ 0x0104, /* #.....#.. */
+ 0x0065, /* ..##..#.# */
+ 0x0048, /* ..#..#... */
+ 0x0091, /* .#..#...# */
+},
+{
+ 0x0139, /* #..###..# */
+ 0x008c, /* .#...##.. */
+ 0x0010, /* ....#.... */
+ 0x0142, /* #.#....#. */
+ 0x00c6, /* .##...##. */
+ 0x0085, /* .#....#.# */
+ 0x0010, /* ....#.... */
+ 0x0062, /* ..##...#. */
+ 0x0139, /* #..###..# */
+},
+{
+ 0x00e9, /* .###.#..# */
+ 0x0078, /* ..####... */
+ 0x00a0, /* .#.#..... */
+ 0x0047, /* ..#...### */
+ 0x0000, /* ......... */
+ 0x01c4, /* ###...#.. */
+ 0x000a, /* .....#.#. */
+ 0x003c, /* ...####.. */
+ 0x012e, /* #..#.###. */
+},
+{
+ 0x0004, /* ......#.. */
+ 0x0087, /* .#....### */
+ 0x0023, /* ...#...## */
+ 0x0025, /* ...#..#.# */
+ 0x0111, /* #...#...# */
+ 0x0148, /* #.#..#... */
+ 0x0188, /* ##...#... */
+ 0x01c2, /* ###....#. */
+ 0x0040, /* ..#...... */
+},
+{
+ 0x010e, /* #....###. */
+ 0x0096, /* .#..#.##. */
+ 0x0121, /* #..#....# */
+ 0x0013, /* ....#..## */
+ 0x0044, /* ..#...#.. */
+ 0x0190, /* ##..#.... */
+ 0x0109, /* #....#..# */
+ 0x00d2, /* .##.#..#. */
+ 0x00e1, /* .###....# */
+},
+{
+ 0x010c, /* #....##.. */
+ 0x0034, /* ...##.#.. */
+ 0x0094, /* .#..#.#.. */
+ 0x0138, /* #..###... */
+ 0x0000, /* ......... */
+ 0x0039, /* ...###..# */
+ 0x0052, /* ..#.#..#. */
+ 0x0058, /* ..#.##... */
+ 0x0061, /* ..##....# */
+},
+{
+ 0x0112, /* #...#..#. */
+ 0x01a1, /* ##.#....# */
+ 0x0048, /* ..#..#... */
+ 0x0190, /* ##..#.... */
+ 0x0082, /* .#.....#. */
+ 0x0013, /* ....#..## */
+ 0x0024, /* ...#..#.. */
+ 0x010b, /* #....#.## */
+ 0x0091, /* .#..#...# */
+},
+{
+ 0x0031, /* ...##...# */
+ 0x0004, /* ......#.. */
+ 0x00a9, /* .#.#.#..# */
+ 0x00c4, /* .##...#.. */
+ 0x0054, /* ..#.#.#.. */
+ 0x0046, /* ..#...##. */
+ 0x012a, /* #..#.#.#. */
+ 0x0040, /* ..#...... */
+ 0x0118, /* #...##... */
+},
+{
+ 0x01b0, /* ##.##.... */
+ 0x010e, /* #....###. */
+ 0x0000, /* ......... */
+ 0x0102, /* #......#. */
+ 0x00ba, /* .#.###.#. */
+ 0x0081, /* .#......# */
+ 0x0000, /* ......... */
+ 0x00e1, /* .###....# */
+ 0x001b, /* ....##.## */
+},
+{
+ 0x006c, /* ..##.##.. */
+ 0x00d2, /* .##.#..#. */
+ 0x0147, /* #.#...### */
+ 0x0129, /* #..#.#..# */
+ 0x0092, /* .#..#..#. */
+ 0x0129, /* #..#.#..# */
+ 0x01c5, /* ###...#.# */
+ 0x0096, /* .#..#.##. */
+ 0x006c, /* ..##.##.. */
+},
+{
+ 0x0111, /* #...#...# */
+ 0x008e, /* .#...###. */
+ 0x00b0, /* .#.##.... */
+ 0x0084, /* .#....#.. */
+ 0x0145, /* #.#...#.# */
+ 0x0042, /* ..#....#. */
+ 0x001a, /* ....##.#. */
+ 0x00e2, /* .###...#. */
+ 0x0111, /* #...#...# */
+},
+{
+ 0x0040, /* ..#...... */
+ 0x0096, /* .#..#.##. */
+ 0x00cd, /* .##..##.# */
+ 0x0050, /* ..#.#.... */
+ 0x00ba, /* .#.###.#. */
+ 0x0014, /* ....#.#.. */
+ 0x0166, /* #.##..##. */
+ 0x00d2, /* .##.#..#. */
+ 0x0004, /* ......#.. */
+},
+{
+ 0x000f, /* .....#### */
+ 0x0152, /* #.#.#..#. */
+ 0x011c, /* #...###.. */
+ 0x00b1, /* .#.##...# */
+ 0x0145, /* #.#...#.# */
+ 0x011a, /* #...##.#. */
+ 0x0071, /* ..###...# */
+ 0x0095, /* .#..#.#.# */
+ 0x01e0, /* ####..... */
+},
+{
+ 0x0128, /* #..#.#... */
+ 0x0183, /* ##.....## */
+ 0x0094, /* .#..#.#.. */
+ 0x00b1, /* .#.##...# */
+ 0x0044, /* ..#...#.. */
+ 0x011a, /* #...##.#. */
+ 0x0052, /* ..#.#..#. */
+ 0x0183, /* ##.....## */
+ 0x0029, /* ...#.#..# */
+},
+{
+ 0x0081, /* .#......# */
+ 0x0060, /* ..##..... */
+ 0x0159, /* #.#.##..# */
+ 0x000b, /* .....#.## */
+ 0x0054, /* ..#.#.#.. */
+ 0x01a0, /* ##.#..... */
+ 0x0135, /* #..##.#.# */
+ 0x000c, /* .....##.. */
+ 0x0102, /* #......#. */
+},
+{
+ 0x00dc, /* .##.###.. */
+ 0x0089, /* .#...#..# */
+ 0x0030, /* ...##.... */
+ 0x0046, /* ..#...##. */
+ 0x0028, /* ...#.#... */
+ 0x00c4, /* .##...#.. */
+ 0x0018, /* ....##... */
+ 0x0122, /* #..#...#. */
+ 0x0076, /* ..###.##. */
+},
+{
+ 0x00e0, /* .###..... */
+ 0x0082, /* .#.....#. */
+ 0x0081, /* .#......# */
+ 0x0149, /* #.#..#..# */
+ 0x0092, /* .#..#..#. */
+ 0x0125, /* #..#..#.# */
+ 0x0102, /* #......#. */
+ 0x0082, /* .#.....#. */
+ 0x000e, /* .....###. */
+},
+{
+ 0x0199, /* ##..##..# */
+ 0x0025, /* ...#..#.# */
+ 0x0010, /* ....#.... */
+ 0x00a2, /* .#.#...#. */
+ 0x0044, /* ..#...#.. */
+ 0x008a, /* .#...#.#. */
+ 0x0010, /* ....#.... */
+ 0x0148, /* #.#..#... */
+ 0x0133, /* #..##..## */
+},
+{
+ 0x0101, /* #.......# */
+ 0x0129, /* #..#.#..# */
+ 0x007c, /* ..#####.. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0082, /* .#.....#. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x007c, /* ..#####.. */
+ 0x0129, /* #..#.#..# */
+ 0x0101, /* #.......# */
+},
+{
+ 0x0112, /* #...#..#. */
+ 0x014e, /* #.#..###. */
+ 0x0002, /* .......#. */
+ 0x0108, /* #....#... */
+ 0x0038, /* ...###... */
+ 0x0021, /* ...#....# */
+ 0x0080, /* .#....... */
+ 0x00e5, /* .###..#.# */
+ 0x0091, /* .#..#...# */
+},
+{
+ 0x01c3, /* ###....## */
+ 0x0032, /* ...##..#. */
+ 0x0008, /* .....#... */
+ 0x00c4, /* .##...#.. */
+ 0x0028, /* ...#.#... */
+ 0x0046, /* ..#...##. */
+ 0x0020, /* ...#..... */
+ 0x0098, /* .#..##... */
+ 0x0187, /* ##....### */
+},
+{
+ 0x00e2, /* .###...#. */
+ 0x0001, /* ........# */
+ 0x00e0, /* .###..... */
+ 0x0052, /* ..#.#..#. */
+ 0x0145, /* #.#...#.# */
+ 0x0094, /* .#..#.#.. */
+ 0x000e, /* .....###. */
+ 0x0100, /* #........ */
+ 0x008e, /* .#...###. */
+},
+{
+ 0x0185, /* ##....#.# */
+ 0x0124, /* #..#..#.. */
+ 0x0060, /* ..##..... */
+ 0x0011, /* ....#...# */
+ 0x016d, /* #.##.##.# */
+ 0x0110, /* #...#.... */
+ 0x000c, /* .....##.. */
+ 0x0049, /* ..#..#..# */
+ 0x0143, /* #.#....## */
+},
+{
+ 0x0082, /* .#.....#. */
+ 0x0155, /* #.#.#.#.# */
+ 0x006c, /* ..##.##.. */
+ 0x0082, /* .#.....#. */
+ 0x0028, /* ...#.#... */
+ 0x0082, /* .#.....#. */
+ 0x006c, /* ..##.##.. */
+ 0x0155, /* #.#.#.#.# */
+ 0x0082, /* .#.....#. */
+},
+{
+ 0x008a, /* .#...#.#. */
+ 0x0169, /* #.##.#..# */
+ 0x014d, /* #.#..##.# */
+ 0x0118, /* #...##... */
+ 0x00c6, /* .##...##. */
+ 0x0031, /* ...##...# */
+ 0x0165, /* #.##..#.# */
+ 0x012d, /* #..#.##.# */
+ 0x00a2, /* .#.#...#. */
+},
+{
+ 0x0145, /* #.#...#.# */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0129, /* #..#.#..# */
+ 0x006c, /* ..##.##.. */
+ 0x0000, /* ......... */
+ 0x006c, /* ..##.##.. */
+ 0x0129, /* #..#.#..# */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0145, /* #.#...#.# */
+},
+{
+ 0x0122, /* #..#...#. */
+ 0x0011, /* ....#...# */
+ 0x010a, /* #....#.#. */
+ 0x0154, /* #.#.#.#.. */
+ 0x0000, /* ......... */
+ 0x0055, /* ..#.#.#.# */
+ 0x00a1, /* .#.#....# */
+ 0x0110, /* #...#.... */
+ 0x0089, /* .#...#..# */
+},
+{
+ 0x01c9, /* ###..#..# */
+ 0x00e6, /* .###..##. */
+ 0x0114, /* #...#.#.. */
+ 0x001e, /* ....####. */
+ 0x0028, /* ...#.#... */
+ 0x00f0, /* .####.... */
+ 0x0051, /* ..#.#...# */
+ 0x00ce, /* .##..###. */
+ 0x0127, /* #..#..### */
+},
+{
+ 0x0117, /* #...#.### */
+ 0x0009, /* .....#..# */
+ 0x005c, /* ..#.###.. */
+ 0x011c, /* #...###.. */
+ 0x0000, /* ......... */
+ 0x0071, /* ..###...# */
+ 0x0074, /* ..###.#.. */
+ 0x0120, /* #..#..... */
+ 0x01d1, /* ###.#...# */
+},
+{
+ 0x0091, /* .#..#...# */
+ 0x0023, /* ...#...## */
+ 0x0044, /* ..#...#.. */
+ 0x0031, /* ...##...# */
+ 0x0111, /* #...#...# */
+ 0x0118, /* #...##... */
+ 0x0044, /* ..#...#.. */
+ 0x0188, /* ##...#... */
+ 0x0112, /* #...#..#. */
+},
+{
+ 0x0020, /* ...#..... */
+ 0x011a, /* #...##.#. */
+ 0x00d7, /* .##.#.### */
+ 0x0086, /* .#....##. */
+ 0x0028, /* ...#.#... */
+ 0x00c2, /* .##....#. */
+ 0x01d6, /* ###.#.##. */
+ 0x00b1, /* .#.##...# */
+ 0x0008, /* .....#... */
+},
+{
+ 0x000c, /* .....##.. */
+ 0x0034, /* ...##.#.. */
+ 0x01c4, /* ###...#.. */
+ 0x012a, /* #..#.#.#. */
+ 0x0082, /* .#.....#. */
+ 0x00a9, /* .#.#.#..# */
+ 0x0047, /* ..#...### */
+ 0x0058, /* ..#.##... */
+ 0x0060, /* ..##..... */
+},
+{
+ 0x0101, /* #.......# */
+ 0x0028, /* ...#.#... */
+ 0x00ee, /* .###.###. */
+ 0x0092, /* .#..#..#. */
+ 0x0101, /* #.......# */
+ 0x0092, /* .#..#..#. */
+ 0x00ee, /* .###.###. */
+ 0x0028, /* ...#.#... */
+ 0x0101, /* #.......# */
+},
+{
+ 0x0111, /* #...#...# */
+ 0x0155, /* #.#.#.#.# */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x0028, /* ...#.#... */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0155, /* #.#.#.#.# */
+ 0x0111, /* #...#...# */
+},
+{
+ 0x0188, /* ##...#... */
+ 0x0110, /* #...#.... */
+ 0x008c, /* .#...##.. */
+ 0x0091, /* .#..#...# */
+ 0x0155, /* #.#.#.#.# */
+ 0x0112, /* #...#..#. */
+ 0x0062, /* ..##...#. */
+ 0x0011, /* ....#...# */
+ 0x0023, /* ...#...## */
+},
+{
+ 0x00b5, /* .#.##.#.# */
+ 0x0100, /* #........ */
+ 0x0048, /* ..#..#... */
+ 0x0019, /* ....##..# */
+ 0x0183, /* ##.....## */
+ 0x0130, /* #..##.... */
+ 0x0024, /* ...#..#.. */
+ 0x0001, /* ........# */
+ 0x015a, /* #.#.##.#. */
+},
+{
+ 0x0195, /* ##..#.#.# */
+ 0x0041, /* ..#.....# */
+ 0x010a, /* #....#.#. */
+ 0x0068, /* ..##.#... */
+ 0x0111, /* #...#...# */
+ 0x002c, /* ...#.##.. */
+ 0x00a1, /* .#.#....# */
+ 0x0104, /* #.....#.. */
+ 0x0153, /* #.#.#..## */
+},
+{
+ 0x0000, /* ......... */
+ 0x0032, /* ...##..#. */
+ 0x007b, /* ..####.## */
+ 0x004e, /* ..#..###. */
+ 0x0000, /* ......... */
+ 0x00e4, /* .###..#.. */
+ 0x01bc, /* ##.####.. */
+ 0x0098, /* .#..##... */
+ 0x0000, /* ......... */
+},
+{
+ 0x0019, /* ....##..# */
+ 0x0060, /* ..##..... */
+ 0x0105, /* #.....#.# */
+ 0x0142, /* #.#....#. */
+ 0x0044, /* ..#...#.. */
+ 0x0085, /* .#....#.# */
+ 0x0141, /* #.#.....# */
+ 0x000c, /* .....##.. */
+ 0x0130, /* #..##.... */
+},
+{
+ 0x00f0, /* .####.... */
+ 0x008f, /* .#...#### */
+ 0x00a9, /* .#.#.#..# */
+ 0x00c5, /* .##...#.# */
+ 0x0111, /* #...#...# */
+ 0x0146, /* #.#...##. */
+ 0x012a, /* #..#.#.#. */
+ 0x01e2, /* ####...#. */
+ 0x001e, /* ....####. */
+},
+{
+ 0x0105, /* #.....#.# */
+ 0x0068, /* ..##.#... */
+ 0x0108, /* #....#... */
+ 0x0042, /* ..#....#. */
+ 0x00fe, /* .#######. */
+ 0x0084, /* .#....#.. */
+ 0x0021, /* ...#....# */
+ 0x002c, /* ...#.##.. */
+ 0x0141, /* #.#.....# */
+},
+{
+ 0x01b0, /* ##.##.... */
+ 0x0071, /* ..###...# */
+ 0x010e, /* #....###. */
+ 0x014a, /* #.#..#.#. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x00a5, /* .#.#..#.# */
+ 0x00e1, /* .###....# */
+ 0x011c, /* #...###.. */
+ 0x001b, /* ....##.## */
+},
+{
+ 0x0038, /* ...###... */
+ 0x0092, /* .#..#..#. */
+ 0x00c6, /* .##...##. */
+ 0x0044, /* ..#...#.. */
+ 0x0155, /* #.#.#.#.# */
+ 0x0044, /* ..#...#.. */
+ 0x00c6, /* .##...##. */
+ 0x0092, /* .#..#..#. */
+ 0x0038, /* ...###... */
+},
+{
+ 0x00a2, /* .#.#...#. */
+ 0x0051, /* ..#.#...# */
+ 0x0080, /* .#....... */
+ 0x0191, /* ##..#...# */
+ 0x0054, /* ..#.#.#.. */
+ 0x0113, /* #...#..## */
+ 0x0002, /* .......#. */
+ 0x0114, /* #...#.#.. */
+ 0x008a, /* .#...#.#. */
+},
+{
+ 0x0139, /* #..###..# */
+ 0x000c, /* .....##.. */
+ 0x00e4, /* .###..#.. */
+ 0x01ad, /* ##.#.##.# */
+ 0x0101, /* #.......# */
+ 0x016b, /* #.##.#.## */
+ 0x004e, /* ..#..###. */
+ 0x0060, /* ..##..... */
+ 0x0139, /* #..###..# */
+},
+{
+ 0x00c4, /* .##...#.. */
+ 0x0031, /* ...##...# */
+ 0x0109, /* #....#..# */
+ 0x006a, /* ..##.#.#. */
+ 0x0092, /* .#..#..#. */
+ 0x00ac, /* .#.#.##.. */
+ 0x0121, /* #..#....# */
+ 0x0118, /* #...##... */
+ 0x0046, /* ..#...##. */
+},
+{
+ 0x0122, /* #..#...#. */
+ 0x0024, /* ...#..#.. */
+ 0x008a, /* .#...#.#. */
+ 0x0112, /* #...#..#. */
+ 0x0054, /* ..#.#.#.. */
+ 0x0091, /* .#..#...# */
+ 0x00a2, /* .#.#...#. */
+ 0x0048, /* ..#..#... */
+ 0x0089, /* .#...#..# */
+},
+{
+ 0x0052, /* ..#.#..#. */
+ 0x0004, /* ......#.. */
+ 0x01f1, /* #####...# */
+ 0x0164, /* #.##..#.. */
+ 0x0010, /* ....#.... */
+ 0x004d, /* ..#..##.# */
+ 0x011f, /* #...##### */
+ 0x0040, /* ..#...... */
+ 0x0094, /* .#..#.#.. */
+},
+{
+ 0x00e4, /* .###..#.. */
+ 0x0015, /* ....#.#.# */
+ 0x0189, /* ##...#..# */
+ 0x0041, /* ..#.....# */
+ 0x0082, /* .#.....#. */
+ 0x0104, /* #.....#.. */
+ 0x0123, /* #..#...## */
+ 0x0150, /* #.#.#.... */
+ 0x004e, /* ..#..###. */
+},
+{
+ 0x0063, /* ..##...## */
+ 0x0120, /* #..#..... */
+ 0x0080, /* .#....... */
+ 0x0052, /* ..#.#..#. */
+ 0x00ee, /* .###.###. */
+ 0x0094, /* .#..#.#.. */
+ 0x0002, /* .......#. */
+ 0x0009, /* .....#..# */
+ 0x018c, /* ##...##.. */
+},
+{
+ 0x0082, /* .#.....#. */
+ 0x0044, /* ..#...#.. */
+ 0x01bb, /* ##.###.## */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0101, /* #.......# */
+ 0x00aa, /* .#.#.#.#. */
+ 0x01bb, /* ##.###.## */
+ 0x0044, /* ..#...#.. */
+ 0x0082, /* .#.....#. */
+},
+{
+ 0x0028, /* ...#.#... */
+ 0x0044, /* ..#...#.. */
+ 0x01ab, /* ##.#.#.## */
+ 0x0082, /* .#.....#. */
+ 0x0145, /* #.#...#.# */
+ 0x0082, /* .#.....#. */
+ 0x01ab, /* ##.#.#.## */
+ 0x0044, /* ..#...#.. */
+ 0x0028, /* ...#.#... */
+},
+{
+ 0x0121, /* #..#....# */
+ 0x0034, /* ...##.#.. */
+ 0x0088, /* .#...#... */
+ 0x0043, /* ..#....## */
+ 0x0092, /* .#..#..#. */
+ 0x0184, /* ##....#.. */
+ 0x0022, /* ...#...#. */
+ 0x0058, /* ..#.##... */
+ 0x0109, /* #....#..# */
+},
+{
+ 0x00ac, /* .#.#.##.. */
+ 0x0098, /* .#..##... */
+ 0x0042, /* ..#....#. */
+ 0x0049, /* ..#..#..# */
+ 0x0101, /* #.......# */
+ 0x0124, /* #..#..#.. */
+ 0x0084, /* .#....#.. */
+ 0x0032, /* ...##..#. */
+ 0x006a, /* ..##.#.#. */
+},
+{
+ 0x0092, /* .#..#..#. */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x0145, /* #.#...#.# */
+ 0x0028, /* ...#.#... */
+ 0x0145, /* #.#...#.# */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0092, /* .#..#..#. */
+},
+{
+ 0x000c, /* .....##.. */
+ 0x0091, /* .#..#...# */
+ 0x0089, /* .#...#..# */
+ 0x0048, /* ..#..#... */
+ 0x0183, /* ##.....## */
+ 0x0024, /* ...#..#.. */
+ 0x0122, /* #..#...#. */
+ 0x0112, /* #...#..#. */
+ 0x0060, /* ..##..... */
+},
+{
+ 0x006c, /* ..##.##.. */
+ 0x0146, /* #.#...##. */
+ 0x0018, /* ....##... */
+ 0x001d, /* ....###.# */
+ 0x0101, /* #.......# */
+ 0x0170, /* #.###.... */
+ 0x0030, /* ...##.... */
+ 0x00c5, /* .##...#.# */
+ 0x006c, /* ..##.##.. */
+},
+{
+ 0x0015, /* ....#.#.# */
+ 0x0088, /* .#...#... */
+ 0x0140, /* #.#...... */
+ 0x009a, /* .#..##.#. */
+ 0x0101, /* #.......# */
+ 0x00b2, /* .#.##..#. */
+ 0x0005, /* ......#.# */
+ 0x0022, /* ...#...#. */
+ 0x0150, /* #.#.#.... */
+},
+{
+ 0x0000, /* ......... */
+ 0x00aa, /* .#.#.#.#. */
+ 0x01c7, /* ###...### */
+ 0x007c, /* ..#####.. */
+ 0x0000, /* ......... */
+ 0x007c, /* ..#####.. */
+ 0x01c7, /* ###...### */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0000, /* ......... */
+},
+{
+ 0x0192, /* ##..#..#. */
+ 0x0093, /* .#..#..## */
+ 0x0088, /* .#...#... */
+ 0x0068, /* ..##.#... */
+ 0x0101, /* #.......# */
+ 0x002c, /* ...#.##.. */
+ 0x0022, /* ...#...#. */
+ 0x0192, /* ##..#..#. */
+ 0x0093, /* .#..#..## */
+},
+{
+ 0x0129, /* #..#.#..# */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0044, /* ..#...#.. */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0044, /* ..#...#.. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0129, /* #..#.#..# */
+},
+{
+ 0x0113, /* #...#..## */
+ 0x0130, /* #..##.... */
+ 0x01c0, /* ###...... */
+ 0x0025, /* ...#..#.# */
+ 0x0082, /* .#.....#. */
+ 0x0148, /* #.#..#... */
+ 0x0007, /* ......### */
+ 0x0019, /* ....##..# */
+ 0x0191, /* ##..#...# */
+},
+{
+ 0x0094, /* .#..#.#.. */
+ 0x0013, /* ....#..## */
+ 0x001d, /* ....###.# */
+ 0x018a, /* ##...#.#. */
+ 0x0010, /* ....#.... */
+ 0x00a3, /* .#.#...## */
+ 0x0170, /* #.###.... */
+ 0x0190, /* ##..#.... */
+ 0x0052, /* ..#.#..#. */
+},
+{
+ 0x0017, /* ....#.### */
+ 0x01b2, /* ##.##..#. */
+ 0x0004, /* ......#.. */
+ 0x0021, /* ...#....# */
+ 0x01ab, /* ##.#.#.## */
+ 0x0108, /* #....#... */
+ 0x0040, /* ..#...... */
+ 0x009b, /* .#..##.## */
+ 0x01d0, /* ###.#.... */
+},
+{
+ 0x0129, /* #..#.#..# */
+ 0x0000, /* ......... */
+ 0x01c7, /* ###...### */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x01c7, /* ###...### */
+ 0x0000, /* ......... */
+ 0x0129, /* #..#.#..# */
+},
+{
+ 0x00d8, /* .##.##... */
+ 0x0093, /* .#..#..## */
+ 0x008a, /* .#...#.#. */
+ 0x0110, /* #...#.... */
+ 0x0145, /* #.#...#.# */
+ 0x0011, /* ....#...# */
+ 0x00a2, /* .#.#...#. */
+ 0x0192, /* ##..#..#. */
+ 0x0036, /* ...##.##. */
+},
+{
+ 0x0056, /* ..#.#.##. */
+ 0x01a2, /* ##.#...#. */
+ 0x0048, /* ..#..#... */
+ 0x0050, /* ..#.#.... */
+ 0x0145, /* #.#...#.# */
+ 0x0014, /* ....#.#.. */
+ 0x0024, /* ...#..#.. */
+ 0x008b, /* .#...#.## */
+ 0x00d4, /* .##.#.#.. */
+},
+{
+ 0x0066, /* ..##..##. */
+ 0x0105, /* #.....#.# */
+ 0x0091, /* .#..#...# */
+ 0x008c, /* .#...##.. */
+ 0x0028, /* ...#.#... */
+ 0x0062, /* ..##...#. */
+ 0x0112, /* #...#..#. */
+ 0x0141, /* #.#.....# */
+ 0x00cc, /* .##..##.. */
+},
+{
+ 0x01a0, /* ##.#..... */
+ 0x00b9, /* .#.###..# */
+ 0x000b, /* .....#.## */
+ 0x0120, /* #..#..... */
+ 0x0101, /* #.......# */
+ 0x0009, /* .....#..# */
+ 0x01a0, /* ##.#..... */
+ 0x013a, /* #..###.#. */
+ 0x000b, /* .....#.## */
+},
+{
+ 0x0000, /* ......... */
+ 0x01ad, /* ##.#.##.# */
+ 0x0056, /* ..#.#.##. */
+ 0x0018, /* ....##... */
+ 0x0145, /* #.#...#.# */
+ 0x0030, /* ...##.... */
+ 0x00d4, /* .##.#.#.. */
+ 0x016b, /* #.##.#.## */
+ 0x0000, /* ......... */
+},
+{
+ 0x0028, /* ...#.#... */
+ 0x0082, /* .#.....#. */
+ 0x01c7, /* ###...### */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x01c7, /* ###...### */
+ 0x0082, /* .#.....#. */
+ 0x0028, /* ...#.#... */
+},
+{
+ 0x0024, /* ...#..#.. */
+ 0x0152, /* #.#.#..#. */
+ 0x0124, /* #..#..#.. */
+ 0x0059, /* ..#.##..# */
+ 0x0082, /* .#.....#. */
+ 0x0134, /* #..##.#.. */
+ 0x0049, /* ..#..#..# */
+ 0x0095, /* .#..#.#.# */
+ 0x0048, /* ..#..#... */
+},
+{
+ 0x016d, /* #.##.##.# */
+ 0x006c, /* ..##.##.. */
+ 0x0082, /* .#.....#. */
+ 0x0028, /* ...#.#... */
+ 0x0101, /* #.......# */
+ 0x0028, /* ...#.#... */
+ 0x0082, /* .#.....#. */
+ 0x006c, /* ..##.##.. */
+ 0x016d, /* #.##.##.# */
+},
+{
+ 0x0091, /* .#..#...# */
+ 0x0069, /* ..##.#..# */
+ 0x0038, /* ...###... */
+ 0x0084, /* .#....#.. */
+ 0x0183, /* ##.....## */
+ 0x0042, /* ..#....#. */
+ 0x0038, /* ...###... */
+ 0x012c, /* #..#.##.. */
+ 0x0112, /* #...#..#. */
+},
+{
+ 0x0101, /* #.......# */
+ 0x0021, /* ...#....# */
+ 0x01d4, /* ###.#.#.. */
+ 0x012a, /* #..#.#.#. */
+ 0x0082, /* .#.....#. */
+ 0x00a9, /* .#.#.#..# */
+ 0x0057, /* ..#.#.### */
+ 0x0108, /* #....#... */
+ 0x0101, /* #.......# */
+},
+{
+ 0x0156, /* #.#.#.##. */
+ 0x00c0, /* .##...... */
+ 0x0021, /* ...#....# */
+ 0x0160, /* #.##..... */
+ 0x0129, /* #..#.#..# */
+ 0x000d, /* .....##.# */
+ 0x0108, /* #....#... */
+ 0x0006, /* ......##. */
+ 0x00d5, /* .##.#.#.# */
+},
+{
+ 0x00c2, /* .##....#. */
+ 0x010a, /* #....#.#. */
+ 0x012c, /* #..#.##.. */
+ 0x0095, /* .#..#.#.# */
+ 0x0000, /* ......... */
+ 0x0152, /* #.#.#..#. */
+ 0x0069, /* ..##.#..# */
+ 0x00a1, /* .#.#....# */
+ 0x0086, /* .#....##. */
+},
+{
+ 0x0003, /* .......## */
+ 0x0048, /* ..#..#... */
+ 0x0168, /* #.##.#... */
+ 0x0195, /* ##..#.#.# */
+ 0x0028, /* ...#.#... */
+ 0x0153, /* #.#.#..## */
+ 0x002d, /* ...#.##.# */
+ 0x0024, /* ...#..#.. */
+ 0x0180, /* ##....... */
+},
+{
+ 0x00c2, /* .##....#. */
+ 0x01b0, /* ##.##.... */
+ 0x000d, /* .....##.# */
+ 0x0007, /* ......### */
+ 0x0082, /* .#.....#. */
+ 0x01c0, /* ###...... */
+ 0x0160, /* #.##..... */
+ 0x001b, /* ....##.## */
+ 0x0086, /* .#....##. */
+},
+{
+ 0x016d, /* #.##.##.# */
+ 0x0044, /* ..#...#.. */
+ 0x0082, /* .#.....#. */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0082, /* .#.....#. */
+ 0x0044, /* ..#...#.. */
+ 0x016d, /* #.##.##.# */
+},
+{
+ 0x0022, /* ...#...#. */
+ 0x0006, /* ......##. */
+ 0x0135, /* #..##.#.# */
+ 0x0112, /* #...#..#. */
+ 0x0183, /* ##.....## */
+ 0x0091, /* .#..#...# */
+ 0x0159, /* #.#.##..# */
+ 0x00c0, /* .##...... */
+ 0x0088, /* .#...#... */
+},
+{
+ 0x0044, /* ..#...#.. */
+ 0x006c, /* ..##.##.. */
+ 0x0111, /* #...#...# */
+ 0x00ee, /* .###.###. */
+ 0x0000, /* ......... */
+ 0x00ee, /* .###.###. */
+ 0x0111, /* #...#...# */
+ 0x006c, /* ..##.##.. */
+ 0x0044, /* ..#...#.. */
+},
+{
+ 0x0043, /* ..#....## */
+ 0x014c, /* #.#..##.. */
+ 0x0050, /* ..#.#.... */
+ 0x0034, /* ...##.#.. */
+ 0x0129, /* #..#.#..# */
+ 0x0058, /* ..#.##... */
+ 0x0014, /* ....#.#.. */
+ 0x0065, /* ..##..#.# */
+ 0x0184, /* ##....#.. */
+},
+{
+ 0x00a8, /* .#.#.#... */
+ 0x018c, /* ##...##.. */
+ 0x0010, /* ....#.... */
+ 0x0184, /* ##....#.. */
+ 0x0101, /* #.......# */
+ 0x0043, /* ..#....## */
+ 0x0010, /* ....#.... */
+ 0x0063, /* ..##...## */
+ 0x002a, /* ...#.#.#. */
+},
+{
+ 0x0145, /* #.#...#.# */
+ 0x00ee, /* .###.###. */
+ 0x0101, /* #.......# */
+ 0x0028, /* ...#.#... */
+ 0x0092, /* .#..#..#. */
+ 0x0028, /* ...#.#... */
+ 0x0101, /* #.......# */
+ 0x00ee, /* .###.###. */
+ 0x0145, /* #.#...#.# */
+},
+{
+ 0x01a0, /* ##.#..... */
+ 0x0054, /* ..#.#.#.. */
+ 0x0021, /* ...#....# */
+ 0x008a, /* .#...#.#. */
+ 0x0129, /* #..#.#..# */
+ 0x00a2, /* .#.#...#. */
+ 0x0108, /* #....#... */
+ 0x0054, /* ..#.#.#.. */
+ 0x000b, /* .....#.## */
+},
+{
+ 0x00aa, /* .#.#.#.#. */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x0054, /* ..#.#.#.. */
+ 0x0101, /* #.......# */
+ 0x0054, /* ..#.#.#.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x00aa, /* .#.#.#.#. */
+},
+{
+ 0x0074, /* ..###.#.. */
+ 0x0041, /* ..#.....# */
+ 0x0126, /* #..#..##. */
+ 0x00d8, /* .##.##... */
+ 0x0000, /* ......... */
+ 0x0036, /* ...##.##. */
+ 0x00c9, /* .##..#..# */
+ 0x0104, /* #.....#.. */
+ 0x005c, /* ..#.###.. */
+},
+{
+ 0x0111, /* #...#...# */
+ 0x0183, /* ##.....## */
+ 0x0028, /* ...#.#... */
+ 0x0093, /* .#..#..## */
+ 0x0044, /* ..#...#.. */
+ 0x0192, /* ##..#..#. */
+ 0x0028, /* ...#.#... */
+ 0x0183, /* ##.....## */
+ 0x0111, /* #...#...# */
+},
+{
+ 0x0044, /* ..#...#.. */
+ 0x0028, /* ...#.#... */
+ 0x0183, /* ##.....## */
+ 0x006c, /* ..##.##.. */
+ 0x0183, /* ##.....## */
+ 0x006c, /* ..##.##.. */
+ 0x0183, /* ##.....## */
+ 0x0028, /* ...#.#... */
+ 0x0044, /* ..#...#.. */
+},
+{
+ 0x0037, /* ...##.### */
+ 0x0013, /* ....#..## */
+ 0x0044, /* ..#...#.. */
+ 0x0122, /* #..#...#. */
+ 0x0044, /* ..#...#.. */
+ 0x0089, /* .#...#..# */
+ 0x0044, /* ..#...#.. */
+ 0x0190, /* ##..#.... */
+ 0x01d8, /* ###.##... */
+},
+{
+ 0x0007, /* ......### */
+ 0x014a, /* #.#..#.#. */
+ 0x0094, /* .#..#.#.. */
+ 0x0112, /* #...#..#. */
+ 0x0082, /* .#.....#. */
+ 0x0091, /* .#..#...# */
+ 0x0052, /* ..#.#..#. */
+ 0x00a5, /* .#.#..#.# */
+ 0x01c0, /* ###...... */
+},
+{
+ 0x00ee, /* .###.###. */
+ 0x0000, /* ......... */
+ 0x0183, /* ##.....## */
+ 0x006c, /* ..##.##.. */
+ 0x0092, /* .#..#..#. */
+ 0x006c, /* ..##.##.. */
+ 0x0183, /* ##.....## */
+ 0x0000, /* ......... */
+ 0x00ee, /* .###.###. */
+},
+{
+ 0x01ab, /* ##.#.#.## */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0101, /* #.......# */
+ 0x0028, /* ...#.#... */
+ 0x0082, /* .#.....#. */
+ 0x0028, /* ...#.#... */
+ 0x0101, /* #.......# */
+ 0x00aa, /* .#.#.#.#. */
+ 0x01ab, /* ##.#.#.## */
+},
+{
+ 0x01aa, /* ##.#.#.#. */
+ 0x0152, /* #.#.#..#. */
+ 0x0012, /* ....#..#. */
+ 0x002c, /* ...#.##.. */
+ 0x0000, /* ......... */
+ 0x0068, /* ..##.#... */
+ 0x0090, /* .#..#.... */
+ 0x0095, /* .#..#.#.# */
+ 0x00ab, /* .#.#.#.## */
+},
+{
+ 0x0046, /* ..#...##. */
+ 0x0182, /* ##.....#. */
+ 0x002c, /* ...#.##.. */
+ 0x004d, /* ..#..##.# */
+ 0x0028, /* ...#.#... */
+ 0x0164, /* #.##..#.. */
+ 0x0068, /* ..##.#... */
+ 0x0083, /* .#.....## */
+ 0x00c4, /* .##...#.. */
+},
+{
+ 0x00a9, /* .#.#.#..# */
+ 0x0015, /* ....#.#.# */
+ 0x0016, /* ....#.##. */
+ 0x0083, /* .#.....## */
+ 0x0028, /* ...#.#... */
+ 0x0182, /* ##.....#. */
+ 0x00d0, /* .##.#.... */
+ 0x0150, /* #.#.#.... */
+ 0x012a, /* #..#.#.#. */
+},
+{
+ 0x00a4, /* .#.#..#.. */
+ 0x0121, /* #..#....# */
+ 0x0059, /* ..#.##..# */
+ 0x0059, /* ..#.##..# */
+ 0x0000, /* ......... */
+ 0x0134, /* #..##.#.. */
+ 0x0134, /* #..##.#.. */
+ 0x0109, /* #....#..# */
+ 0x004a, /* ..#..#.#. */
+},
+{
+ 0x00e4, /* .###..#.. */
+ 0x0094, /* .#..#.#.. */
+ 0x00a8, /* .#.#.#... */
+ 0x0022, /* ...#...#. */
+ 0x0129, /* #..#.#..# */
+ 0x0088, /* .#...#... */
+ 0x002a, /* ...#.#.#. */
+ 0x0052, /* ..#.#..#. */
+ 0x004e, /* ..#..###. */
+},
+{
+ 0x0128, /* #..#.#... */
+ 0x0044, /* ..#...#.. */
+ 0x0025, /* ...#..#.# */
+ 0x004e, /* ..#..###. */
+ 0x0111, /* #...#...# */
+ 0x00e4, /* .###..#.. */
+ 0x0148, /* #.#..#... */
+ 0x0044, /* ..#...#.. */
+ 0x0029, /* ...#.#..# */
+},
+{
+ 0x002d, /* ...#.##.# */
+ 0x0062, /* ..##...#. */
+ 0x01c1, /* ###.....# */
+ 0x0010, /* ....#.... */
+ 0x0183, /* ##.....## */
+ 0x0010, /* ....#.... */
+ 0x0107, /* #.....### */
+ 0x008c, /* .#...##.. */
+ 0x0168, /* #.##.#... */
+},
+{
+ 0x0101, /* #.......# */
+ 0x00ba, /* .#.###.#. */
+ 0x0082, /* .#.....#. */
+ 0x006c, /* ..##.##.. */
+ 0x0082, /* .#.....#. */
+ 0x006c, /* ..##.##.. */
+ 0x0082, /* .#.....#. */
+ 0x00ba, /* .#.###.#. */
+ 0x0101, /* #.......# */
+},
+{
+ 0x016d, /* #.##.##.# */
+ 0x0044, /* ..#...#.. */
+ 0x0183, /* ##.....## */
+ 0x0028, /* ...#.#... */
+ 0x0082, /* .#.....#. */
+ 0x0028, /* ...#.#... */
+ 0x0183, /* ##.....## */
+ 0x0044, /* ..#...#.. */
+ 0x016d, /* #.##.##.# */
+},
+{
+ 0x00e1, /* .###....# */
+ 0x001b, /* ....##.## */
+ 0x00c0, /* .##...... */
+ 0x0051, /* ..#.#...# */
+ 0x0082, /* .#.....#. */
+ 0x0114, /* #...#.#.. */
+ 0x0006, /* ......##. */
+ 0x01b0, /* ##.##.... */
+ 0x010e, /* #....###. */
+},
+{
+ 0x0103, /* #......## */
+ 0x01a9, /* ##.#.#..# */
+ 0x0110, /* #...#.... */
+ 0x0088, /* .#...#... */
+ 0x0145, /* #.#...#.# */
+ 0x0022, /* ...#...#. */
+ 0x0011, /* ....#...# */
+ 0x012b, /* #..#.#.## */
+ 0x0181, /* ##......# */
+},
+{
+ 0x0082, /* .#.....#. */
+ 0x00ee, /* .###.###. */
+ 0x0145, /* #.#...#.# */
+ 0x0038, /* ...###... */
+ 0x0010, /* ....#.... */
+ 0x0038, /* ...###... */
+ 0x0145, /* #.#...#.# */
+ 0x00ee, /* .###.###. */
+ 0x0082, /* .#.....#. */
+},
+{
+ 0x0052, /* ..#.#..#. */
+ 0x00d0, /* .##.#.... */
+ 0x0148, /* #.#..#... */
+ 0x00c1, /* .##.....# */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0106, /* #.....##. */
+ 0x0025, /* ...#..#.# */
+ 0x0016, /* ....#.##. */
+ 0x0094, /* .#..#.#.. */
+},
+{
+ 0x0017, /* ....#.### */
+ 0x0041, /* ..#.....# */
+ 0x008a, /* .#...#.#. */
+ 0x0024, /* ...#..#.. */
+ 0x01ab, /* ##.#.#.## */
+ 0x0048, /* ..#..#... */
+ 0x00a2, /* .#.#...#. */
+ 0x0104, /* #.....#.. */
+ 0x01d0, /* ###.#.... */
+},
+{
+ 0x0162, /* #.##...#. */
+ 0x0010, /* ....#.... */
+ 0x0019, /* ....##..# */
+ 0x014c, /* #.#..##.. */
+ 0x0145, /* #.#...#.# */
+ 0x0065, /* ..##..#.# */
+ 0x0130, /* #..##.... */
+ 0x0010, /* ....#.... */
+ 0x008d, /* .#...##.# */
+},
+{
+ 0x00a6, /* .#.#..##. */
+ 0x0032, /* ...##..#. */
+ 0x0100, /* #........ */
+ 0x00e9, /* .###.#..# */
+ 0x0082, /* .#.....#. */
+ 0x012e, /* #..#.###. */
+ 0x0001, /* ........# */
+ 0x0098, /* .#..##... */
+ 0x00ca, /* .##..#.#. */
+},
+{
+ 0x0123, /* #..#...## */
+ 0x0090, /* .#..#.... */
+ 0x018a, /* ##...#.#. */
+ 0x0158, /* #.#.##... */
+ 0x0000, /* ......... */
+ 0x0035, /* ...##.#.# */
+ 0x00a3, /* .#.#...## */
+ 0x0012, /* ....#..#. */
+ 0x0189, /* ##...#..# */
+},
+{
+ 0x0145, /* #.#...#.# */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0082, /* .#.....#. */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0145, /* #.#...#.# */
+},
+{
+ 0x002d, /* ...#.##.# */
+ 0x01a1, /* ##.#....# */
+ 0x0008, /* .....#... */
+ 0x00e3, /* .###...## */
+ 0x0000, /* ......... */
+ 0x018e, /* ##...###. */
+ 0x0020, /* ...#..... */
+ 0x010b, /* #....#.## */
+ 0x0168, /* #.##.#... */
+},
+{
+ 0x019c, /* ##..###.. */
+ 0x00a5, /* .#.#..#.# */
+ 0x0180, /* ##....... */
+ 0x0021, /* ...#....# */
+ 0x0028, /* ...#.#... */
+ 0x0108, /* #....#... */
+ 0x0003, /* .......## */
+ 0x014a, /* #.#..#.#. */
+ 0x0073, /* ..###..## */
+},
+{
+ 0x0068, /* ..##.#... */
+ 0x0086, /* .#....##. */
+ 0x018c, /* ##...##.. */
+ 0x0162, /* #.##...#. */
+ 0x0010, /* ....#.... */
+ 0x008d, /* .#...##.# */
+ 0x0063, /* ..##...## */
+ 0x00c2, /* .##....#. */
+ 0x002c, /* ...#.##.. */
+},
+{
+ 0x0023, /* ...#...## */
+ 0x0188, /* ##...#... */
+ 0x0113, /* #...#..## */
+ 0x0094, /* .#..#.#.. */
+ 0x0101, /* #.......# */
+ 0x0052, /* ..#.#..#. */
+ 0x0191, /* ##..#...# */
+ 0x0023, /* ...#...## */
+ 0x0188, /* ##...#... */
+},
+{
+ 0x00f3, /* .####..## */
+ 0x0040, /* ..#...... */
+ 0x01a4, /* ##.#..#.. */
+ 0x0094, /* .#..#.#.. */
+ 0x0000, /* ......... */
+ 0x0052, /* ..#.#..#. */
+ 0x004b, /* ..#..#.## */
+ 0x0004, /* ......#.. */
+ 0x019e, /* ##..####. */
+},
+{
+ 0x00aa, /* .#.#.#.#. */
+ 0x00c6, /* .##...##. */
+ 0x0101, /* #.......# */
+ 0x007c, /* ..#####.. */
+ 0x0000, /* ......... */
+ 0x007c, /* ..#####.. */
+ 0x0101, /* #.......# */
+ 0x00c6, /* .##...##. */
+ 0x00aa, /* .#.#.#.#. */
+},
+{
+ 0x00ae, /* .#.#.###. */
+ 0x0009, /* .....#..# */
+ 0x0105, /* #.....#.# */
+ 0x00a6, /* .#.#..##. */
+ 0x0010, /* ....#.... */
+ 0x00ca, /* .##..#.#. */
+ 0x0141, /* #.#.....# */
+ 0x0120, /* #..#..... */
+ 0x00ea, /* .###.#.#. */
+},
+{
+ 0x0009, /* .....#..# */
+ 0x0194, /* ##..#.#.. */
+ 0x0029, /* ...#.#..# */
+ 0x0034, /* ...##.#.. */
+ 0x0145, /* #.#...#.# */
+ 0x0058, /* ..#.##... */
+ 0x0128, /* #..#.#... */
+ 0x0053, /* ..#.#..## */
+ 0x0120, /* #..#..... */
+},
+{
+ 0x0106, /* #.....##. */
+ 0x011a, /* #...##.#. */
+ 0x0080, /* .#....... */
+ 0x002c, /* ...#.##.. */
+ 0x00ee, /* .###.###. */
+ 0x0068, /* ..##.#... */
+ 0x0002, /* .......#. */
+ 0x00b1, /* .#.##...# */
+ 0x00c1, /* .##.....# */
+},
+{
+ 0x00aa, /* .#.#.#.#. */
+ 0x006c, /* ..##.##.. */
+ 0x00c6, /* .##...##. */
+ 0x0028, /* ...#.#... */
+ 0x0101, /* #.......# */
+ 0x0028, /* ...#.#... */
+ 0x00c6, /* .##...##. */
+ 0x006c, /* ..##.##.. */
+ 0x00aa, /* .#.#.#.#. */
+},
+{
+ 0x0024, /* ...#..#.. */
+ 0x0182, /* ##.....#. */
+ 0x004a, /* ..#..#.#. */
+ 0x00f2, /* .####..#. */
+ 0x0101, /* #.......# */
+ 0x009e, /* .#..####. */
+ 0x00a4, /* .#.#..#.. */
+ 0x0083, /* .#.....## */
+ 0x0048, /* ..#..#... */
+},
+{
+ 0x010b, /* #....#.## */
+ 0x0021, /* ...#....# */
+ 0x0122, /* #..#...#. */
+ 0x003a, /* ...###.#. */
+ 0x0082, /* .#.....#. */
+ 0x00b8, /* .#.###... */
+ 0x0089, /* .#...#..# */
+ 0x0108, /* #....#... */
+ 0x01a1, /* ##.#....# */
+},
+{
+ 0x0064, /* ..##..#.. */
+ 0x0198, /* ##..##... */
+ 0x0122, /* #..#...#. */
+ 0x0111, /* #...#...# */
+ 0x0044, /* ..#...#.. */
+ 0x0111, /* #...#...# */
+ 0x0089, /* .#...#..# */
+ 0x0033, /* ...##..## */
+ 0x004c, /* ..#..##.. */
+},
+{
+ 0x00a2, /* .#.#...#. */
+ 0x0023, /* ...#...## */
+ 0x006e, /* ..##.###. */
+ 0x00c0, /* .##...... */
+ 0x0101, /* #.......# */
+ 0x0006, /* ......##. */
+ 0x00ec, /* .###.##.. */
+ 0x0188, /* ##...#... */
+ 0x008a, /* .#...#.#. */
+},
+{
+ 0x0075, /* ..###.#.# */
+ 0x0161, /* #.##....# */
+ 0x0080, /* .#....... */
+ 0x0148, /* #.#..#... */
+ 0x0044, /* ..#...#.. */
+ 0x0025, /* ...#..#.# */
+ 0x0002, /* .......#. */
+ 0x010d, /* #....##.# */
+ 0x015c, /* #.#.###.. */
+},
+{
+ 0x0088, /* .#...#... */
+ 0x0136, /* #..##.##. */
+ 0x0142, /* #.#....#. */
+ 0x00d0, /* .##.#.... */
+ 0x0028, /* ...#.#... */
+ 0x0016, /* ....#.##. */
+ 0x0085, /* .#....#.# */
+ 0x00d9, /* .##.##..# */
+ 0x0022, /* ...#...#. */
+},
+{
+ 0x0023, /* ...#...## */
+ 0x00a2, /* .#.#...#. */
+ 0x004c, /* ..#..##.. */
+ 0x0118, /* #...##... */
+ 0x00c6, /* .##...##. */
+ 0x0031, /* ...##...# */
+ 0x0064, /* ..##..#.. */
+ 0x008a, /* .#...#.#. */
+ 0x0188, /* ##...#... */
+},
+{
+ 0x012c, /* #..#.##.. */
+ 0x006a, /* ..##.#.#. */
+ 0x0004, /* ......#.. */
+ 0x0098, /* .#..##... */
+ 0x006c, /* ..##.##.. */
+ 0x0032, /* ...##..#. */
+ 0x0040, /* ..#...... */
+ 0x00ac, /* .#.#.##.. */
+ 0x0069, /* ..##.#..# */
+},
+{
+ 0x00d4, /* .##.#.#.. */
+ 0x0101, /* #.......# */
+ 0x0150, /* #.#.#.... */
+ 0x0164, /* #.##..#.. */
+ 0x0082, /* .#.....#. */
+ 0x004d, /* ..#..##.# */
+ 0x0015, /* ....#.#.# */
+ 0x0101, /* #.......# */
+ 0x0056, /* ..#.#.##. */
+},
+{
+ 0x000e, /* .....###. */
+ 0x0164, /* #.##..#.. */
+ 0x0010, /* ....#.... */
+ 0x0103, /* #......## */
+ 0x01ab, /* ##.#.#.## */
+ 0x0181, /* ##......# */
+ 0x0010, /* ....#.... */
+ 0x004d, /* ..#..##.# */
+ 0x00e0, /* .###..... */
+},
+{
+ 0x010a, /* #....#.#. */
+ 0x0032, /* ...##..#. */
+ 0x00a1, /* .#.#....# */
+ 0x00d0, /* .##.#.... */
+ 0x0129, /* #..#.#..# */
+ 0x0016, /* ....#.##. */
+ 0x010a, /* #....#.#. */
+ 0x0098, /* .#..##... */
+ 0x00a1, /* .#.#....# */
+},
+{
+ 0x014a, /* #.#..#.#. */
+ 0x0019, /* ....##..# */
+ 0x0114, /* #...#.#.. */
+ 0x0042, /* ..#....#. */
+ 0x006c, /* ..##.##.. */
+ 0x0084, /* .#....#.. */
+ 0x0051, /* ..#.#...# */
+ 0x0130, /* #..##.... */
+ 0x00a5, /* .#.#..#.# */
+},
+{
+ 0x0120, /* #..#..... */
+ 0x0159, /* #.#.##..# */
+ 0x00e0, /* .###..... */
+ 0x0006, /* ......##. */
+ 0x0145, /* #.#...#.# */
+ 0x00c0, /* .##...... */
+ 0x000e, /* .....###. */
+ 0x0135, /* #..##.#.# */
+ 0x0009, /* .....#..# */
+},
+{
+ 0x0131, /* #..##...# */
+ 0x0086, /* .#....##. */
+ 0x0099, /* .#..##..# */
+ 0x0009, /* .....#..# */
+ 0x0044, /* ..#...#.. */
+ 0x0120, /* #..#..... */
+ 0x0132, /* #..##..#. */
+ 0x00c2, /* .##....#. */
+ 0x0119, /* #...##..# */
+},
+{
+ 0x0044, /* ..#...#.. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0183, /* ##.....## */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0183, /* ##.....## */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0044, /* ..#...#.. */
+},
+{
+ 0x0168, /* #.##.#... */
+ 0x010c, /* #....##.. */
+ 0x008a, /* .#...#.#. */
+ 0x0091, /* .#..#...# */
+ 0x0082, /* .#.....#. */
+ 0x0112, /* #...#..#. */
+ 0x00a2, /* .#.#...#. */
+ 0x0061, /* ..##....# */
+ 0x002d, /* ...#.##.# */
+},
+{
+ 0x0043, /* ..#....## */
+ 0x00d8, /* .##.##... */
+ 0x0120, /* #..#..... */
+ 0x0168, /* #.##.#... */
+ 0x0082, /* .#.....#. */
+ 0x002d, /* ...#.##.# */
+ 0x0009, /* .....#..# */
+ 0x0036, /* ...##.##. */
+ 0x0184, /* ##....#.. */
+},
+{
+ 0x01ab, /* ##.#.#.## */
+ 0x0010, /* ....#.... */
+ 0x0082, /* .#.....#. */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0082, /* .#.....#. */
+ 0x0010, /* ....#.... */
+ 0x01ab, /* ##.#.#.## */
+},
+{
+ 0x0120, /* #..#..... */
+ 0x0190, /* ##..#.... */
+ 0x0046, /* ..#...##. */
+ 0x00a9, /* .#.#.#..# */
+ 0x0129, /* #..#.#..# */
+ 0x012a, /* #..#.#.#. */
+ 0x00c4, /* .##...#.. */
+ 0x0013, /* ....#..## */
+ 0x0009, /* .....#..# */
+},
+{
+ 0x00a0, /* .#.#..... */
+ 0x0185, /* ##....#.# */
+ 0x0051, /* ..#.#...# */
+ 0x0158, /* #.#.##... */
+ 0x0082, /* .#.....#. */
+ 0x0035, /* ...##.#.# */
+ 0x0114, /* #...#.#.. */
+ 0x0143, /* #.#....## */
+ 0x000a, /* .....#.#. */
+},
+{
+ 0x0101, /* #.......# */
+ 0x00d6, /* .##.#.##. */
+ 0x0145, /* #.#...#.# */
+ 0x006c, /* ..##.##.. */
+ 0x0000, /* ......... */
+ 0x006c, /* ..##.##.. */
+ 0x0145, /* #.#...#.# */
+ 0x00d6, /* .##.#.##. */
+ 0x0101, /* #.......# */
+},
+{
+ 0x00e0, /* .###..... */
+ 0x0111, /* #...#...# */
+ 0x0011, /* ....#...# */
+ 0x014a, /* #.#..#.#. */
+ 0x0183, /* ##.....## */
+ 0x00a5, /* .#.#..#.# */
+ 0x0110, /* #...#.... */
+ 0x0111, /* #...#...# */
+ 0x000e, /* .....###. */
+},
+{
+ 0x0183, /* ##.....## */
+ 0x0028, /* ...#.#... */
+ 0x0145, /* #.#...#.# */
+ 0x006c, /* ..##.##.. */
+ 0x0082, /* .#.....#. */
+ 0x006c, /* ..##.##.. */
+ 0x0145, /* #.#...#.# */
+ 0x0028, /* ...#.#... */
+ 0x0183, /* ##.....## */
+},
+{
+ 0x018c, /* ##...##.. */
+ 0x0131, /* #..##...# */
+ 0x000c, /* .....##.. */
+ 0x0051, /* ..#.#...# */
+ 0x0082, /* .#.....#. */
+ 0x0114, /* #...#.#.. */
+ 0x0060, /* ..##..... */
+ 0x0119, /* #...##..# */
+ 0x0063, /* ..##...## */
+},
+{
+ 0x0163, /* #.##...## */
+ 0x0018, /* ....##... */
+ 0x000b, /* .....#.## */
+ 0x0043, /* ..#....## */
+ 0x0000, /* ......... */
+ 0x0184, /* ##....#.. */
+ 0x01a0, /* ##.#..... */
+ 0x0030, /* ...##.... */
+ 0x018d, /* ##...##.# */
+},
+{
+ 0x0155, /* #.#.#.#.# */
+ 0x0000, /* ......... */
+ 0x0027, /* ...#..### */
+ 0x0031, /* ...##...# */
+ 0x0129, /* #..#.#..# */
+ 0x0118, /* #...##... */
+ 0x01c8, /* ###..#... */
+ 0x0000, /* ......... */
+ 0x0155, /* #.#.#.#.# */
+},
+{
+ 0x0033, /* ...##..## */
+ 0x0199, /* ##..##..# */
+ 0x0000, /* ......... */
+ 0x008a, /* .#...#.#. */
+ 0x00c6, /* .##...##. */
+ 0x00a2, /* .#.#...#. */
+ 0x0000, /* ......... */
+ 0x0133, /* #..##..## */
+ 0x0198, /* ##..##... */
+},
+{
+ 0x0183, /* ##.....## */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0183, /* ##.....## */
+},
+{
+ 0x008e, /* .#...###. */
+ 0x0043, /* ..#....## */
+ 0x0015, /* ....#.#.# */
+ 0x0031, /* ...##...# */
+ 0x0082, /* .#.....#. */
+ 0x0118, /* #...##... */
+ 0x0150, /* #.#.#.... */
+ 0x0184, /* ##....#.. */
+ 0x00e2, /* .###...#. */
+},
+{
+ 0x00b8, /* .#.###... */
+ 0x0021, /* ...#....# */
+ 0x0081, /* .#......# */
+ 0x0103, /* #......## */
+ 0x00ee, /* .###.###. */
+ 0x0181, /* ##......# */
+ 0x0102, /* #......#. */
+ 0x0108, /* #....#... */
+ 0x003a, /* ...###.#. */
+},
+{
+ 0x0162, /* #.##...#. */
+ 0x0034, /* ...##.#.. */
+ 0x0108, /* #....#... */
+ 0x0103, /* #......## */
+ 0x0145, /* #.#...#.# */
+ 0x0181, /* ##......# */
+ 0x0021, /* ...#....# */
+ 0x0058, /* ..#.##... */
+ 0x008d, /* .#...##.# */
+},
+{
+ 0x0132, /* #..##..#. */
+ 0x00c8, /* .##..#... */
+ 0x0090, /* .#..#.... */
+ 0x005e, /* ..#.####. */
+ 0x0010, /* ....#.... */
+ 0x00f4, /* .####.#.. */
+ 0x0012, /* ....#..#. */
+ 0x0026, /* ...#..##. */
+ 0x0099, /* .#..##..# */
+},
+{
+ 0x0031, /* ...##...# */
+ 0x0107, /* #.....### */
+ 0x0042, /* ..#....#. */
+ 0x0031, /* ...##...# */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0118, /* #...##... */
+ 0x0084, /* .#....#.. */
+ 0x01c1, /* ###.....# */
+ 0x0118, /* #...##... */
+},
+{
+ 0x0042, /* ..#....#. */
+ 0x0183, /* ##.....## */
+ 0x0066, /* ..##..##. */
+ 0x011a, /* #...##.#. */
+ 0x0010, /* ....#.... */
+ 0x00b1, /* .#.##...# */
+ 0x00cc, /* .##..##.. */
+ 0x0183, /* ##.....## */
+ 0x0084, /* .#....#.. */
+},
+{
+ 0x00aa, /* .#.#.#.#. */
+ 0x0028, /* ...#.#... */
+ 0x0145, /* #.#...#.# */
+ 0x006c, /* ..##.##.. */
+ 0x0101, /* #.......# */
+ 0x006c, /* ..##.##.. */
+ 0x0145, /* #.#...#.# */
+ 0x0028, /* ...#.#... */
+ 0x00aa, /* .#.#.#.#. */
+},
+{
+ 0x0032, /* ...##..#. */
+ 0x003a, /* ...###.#. */
+ 0x010c, /* #....##.. */
+ 0x0105, /* #.....#.# */
+ 0x0028, /* ...#.#... */
+ 0x0141, /* #.#.....# */
+ 0x0061, /* ..##....# */
+ 0x00b8, /* .#.###... */
+ 0x0098, /* .#..##... */
+},
+{
+ 0x0106, /* #.....##. */
+ 0x00c8, /* .##..#... */
+ 0x004c, /* ..#..##.. */
+ 0x0112, /* #...#..#. */
+ 0x00c6, /* .##...##. */
+ 0x0091, /* .#..#...# */
+ 0x0064, /* ..##..#.. */
+ 0x0026, /* ...#..##. */
+ 0x00c1, /* .##.....# */
+},
+{
+ 0x0049, /* ..#..#..# */
+ 0x0110, /* #...#.... */
+ 0x0046, /* ..#...##. */
+ 0x0131, /* #..##...# */
+ 0x0129, /* #..#.#..# */
+ 0x0119, /* #...##..# */
+ 0x00c4, /* .##...#.. */
+ 0x0011, /* ....#...# */
+ 0x0124, /* #..#..#.. */
+},
+{
+ 0x0095, /* .#..#.#.# */
+ 0x0118, /* #...##... */
+ 0x0021, /* ...#....# */
+ 0x003e, /* ...#####. */
+ 0x0010, /* ....#.... */
+ 0x00f8, /* .#####... */
+ 0x0108, /* #....#... */
+ 0x0031, /* ...##...# */
+ 0x0152, /* #.#.#..#. */
+},
+{
+ 0x0009, /* .....#..# */
+ 0x014c, /* #.#..##.. */
+ 0x0083, /* .#.....## */
+ 0x0051, /* ..#.#...# */
+ 0x0028, /* ...#.#... */
+ 0x0114, /* #...#.#.. */
+ 0x0182, /* ##.....#. */
+ 0x0065, /* ..##..#.# */
+ 0x0120, /* #..#..... */
+},
+{
+ 0x0014, /* ....#.#.. */
+ 0x008b, /* .#...#.## */
+ 0x0110, /* #...#.... */
+ 0x004b, /* ..#..#.## */
+ 0x0101, /* #.......# */
+ 0x01a4, /* ##.#..#.. */
+ 0x0011, /* ....#...# */
+ 0x01a2, /* ##.#...#. */
+ 0x0050, /* ..#.#.... */
+},
+{
+ 0x0114, /* #...#.#.. */
+ 0x010d, /* #....##.# */
+ 0x0024, /* ...#..#.. */
+ 0x006d, /* ..##.##.# */
+ 0x0000, /* ......... */
+ 0x016c, /* #.##.##.. */
+ 0x0048, /* ..#..#... */
+ 0x0161, /* #.##....# */
+ 0x0051, /* ..#.#...# */
+},
+{
+ 0x0092, /* .#..#..#. */
+ 0x002a, /* ...#.#.#. */
+ 0x0013, /* ....#..## */
+ 0x010e, /* #....###. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x00e1, /* .###....# */
+ 0x0190, /* ##..#.... */
+ 0x00a8, /* .#.#.#... */
+ 0x0092, /* .#..#..#. */
+},
+{
+ 0x00d1, /* .##.#...# */
+ 0x0084, /* .#....#.. */
+ 0x0158, /* #.#.##... */
+ 0x0064, /* ..##..#.. */
+ 0x0028, /* ...#.#... */
+ 0x004c, /* ..#..##.. */
+ 0x0035, /* ...##.#.# */
+ 0x0042, /* ..#....#. */
+ 0x0116, /* #...#.##. */
+},
+{
+ 0x000b, /* .....#.## */
+ 0x0180, /* ##....... */
+ 0x000d, /* .....##.# */
+ 0x019a, /* ##..##.#. */
+ 0x0082, /* .#.....#. */
+ 0x00b3, /* .#.##..## */
+ 0x0160, /* #.##..... */
+ 0x0003, /* .......## */
+ 0x01a0, /* ##.#..... */
+},
+{
+ 0x00a6, /* .#.#..##. */
+ 0x0115, /* #...#.#.# */
+ 0x0110, /* #...#.... */
+ 0x00ca, /* .##..#.#. */
+ 0x0010, /* ....#.... */
+ 0x00a6, /* .#.#..##. */
+ 0x0011, /* ....#...# */
+ 0x0151, /* #.#.#...# */
+ 0x00ca, /* .##..#.#. */
+},
+{
+ 0x0058, /* ..#.##... */
+ 0x0064, /* ..##..#.. */
+ 0x0023, /* ...#...## */
+ 0x0065, /* ..##..#.# */
+ 0x0082, /* .#.....#. */
+ 0x014c, /* #.#..##.. */
+ 0x0188, /* ##...#... */
+ 0x004c, /* ..#..##.. */
+ 0x0034, /* ...##.#.. */
+},
+{
+ 0x0120, /* #..#..... */
+ 0x00b9, /* .#.###..# */
+ 0x005a, /* ..#.##.#. */
+ 0x0108, /* #....#... */
+ 0x0044, /* ..#...#.. */
+ 0x0021, /* ...#....# */
+ 0x00b4, /* .#.##.#.. */
+ 0x013a, /* #..###.#. */
+ 0x0009, /* .....#..# */
+},
+{
+ 0x0183, /* ##.....## */
+ 0x0064, /* ..##..#.. */
+ 0x0128, /* #..#.#... */
+ 0x0116, /* #...#.##. */
+ 0x0010, /* ....#.... */
+ 0x00d1, /* .##.#...# */
+ 0x0029, /* ...#.#..# */
+ 0x004c, /* ..#..##.. */
+ 0x0183, /* ##.....## */
+},
+{
+ 0x006c, /* ..##.##.. */
+ 0x00aa, /* .#.#.#.#. */
+ 0x0101, /* #.......# */
+ 0x007c, /* ..#####.. */
+ 0x0000, /* ......... */
+ 0x007c, /* ..#####.. */
+ 0x0101, /* #.......# */
+ 0x00aa, /* .#.#.#.#. */
+ 0x006c, /* ..##.##.. */
+},
+{
+ 0x009a, /* .#..##.#. */
+ 0x0100, /* #........ */
+ 0x001b, /* ....##.## */
+ 0x0154, /* #.#.#.#.. */
+ 0x0028, /* ...#.#... */
+ 0x0055, /* ..#.#.#.# */
+ 0x01b0, /* ##.##.... */
+ 0x0001, /* ........# */
+ 0x00b2, /* .#.##..#. */
+},
+{
+ 0x0188, /* ##...#... */
+ 0x0023, /* ...#...## */
+ 0x0171, /* #.###...# */
+ 0x00b0, /* .#.##.... */
+ 0x0000, /* ......... */
+ 0x001a, /* ....##.#. */
+ 0x011d, /* #...###.# */
+ 0x0188, /* ##...#... */
+ 0x0023, /* ...#...## */
+},
+{
+ 0x011d, /* #...###.# */
+ 0x0182, /* ##.....#. */
+ 0x001a, /* ....##.#. */
+ 0x0084, /* .#....#.. */
+ 0x0028, /* ...#.#... */
+ 0x0042, /* ..#....#. */
+ 0x00b0, /* .#.##.... */
+ 0x0083, /* .#.....## */
+ 0x0171, /* #.###...# */
+},
+{
+ 0x0082, /* .#.....#. */
+ 0x0054, /* ..#.#.#.. */
+ 0x0183, /* ##.....## */
+ 0x007c, /* ..#####.. */
+ 0x0000, /* ......... */
+ 0x007c, /* ..#####.. */
+ 0x0183, /* ##.....## */
+ 0x0054, /* ..#.#.#.. */
+ 0x0082, /* .#.....#. */
+},
+{
+ 0x0028, /* ...#.#... */
+ 0x0082, /* .#.....#. */
+ 0x0145, /* #.#...#.# */
+ 0x007c, /* ..#####.. */
+ 0x0101, /* #.......# */
+ 0x007c, /* ..#####.. */
+ 0x0145, /* #.#...#.# */
+ 0x0082, /* .#.....#. */
+ 0x0028, /* ...#.#... */
+},
+{
+ 0x0044, /* ..#...#.. */
+ 0x000b, /* .....#.## */
+ 0x01b0, /* ##.##.... */
+ 0x0003, /* .......## */
+ 0x01c7, /* ###...### */
+ 0x0180, /* ##....... */
+ 0x001b, /* ....##.## */
+ 0x01a0, /* ##.#..... */
+ 0x0044, /* ..#...#.. */
+},
+{
+ 0x0116, /* #...#.##. */
+ 0x00b4, /* .#.##.#.. */
+ 0x0008, /* .....#... */
+ 0x00c5, /* .##...#.# */
+ 0x0101, /* #.......# */
+ 0x0146, /* #.#...##. */
+ 0x0020, /* ...#..... */
+ 0x005a, /* ..#.##.#. */
+ 0x00d1, /* .##.#...# */
+},
+{
+ 0x0081, /* .#......# */
+ 0x0039, /* ...###..# */
+ 0x010e, /* #....###. */
+ 0x0088, /* .#...#... */
+ 0x0044, /* ..#...#.. */
+ 0x0022, /* ...#...#. */
+ 0x00e1, /* .###....# */
+ 0x0138, /* #..###... */
+ 0x0102, /* #......#. */
+},
+{
+ 0x0014, /* ....#.#.. */
+ 0x0182, /* ##.....#. */
+ 0x00e4, /* .###..#.. */
+ 0x0066, /* ..##..##. */
+ 0x0028, /* ...#.#... */
+ 0x00cc, /* .##..##.. */
+ 0x004e, /* ..#..###. */
+ 0x0083, /* .#.....## */
+ 0x0050, /* ..#.#.... */
+},
+{
+ 0x00a1, /* .#.#....# */
+ 0x0023, /* ...#...## */
+ 0x01a0, /* ##.#..... */
+ 0x00b5, /* .#.##.#.# */
+ 0x0000, /* ......... */
+ 0x015a, /* #.#.##.#. */
+ 0x000b, /* .....#.## */
+ 0x0188, /* ##...#... */
+ 0x010a, /* #....#.#. */
+},
+{
+ 0x0159, /* #.#.##..# */
+ 0x00a1, /* .#.#....# */
+ 0x00a2, /* .#.#...#. */
+ 0x0102, /* #......#. */
+ 0x006c, /* ..##.##.. */
+ 0x0081, /* .#......# */
+ 0x008a, /* .#...#.#. */
+ 0x010a, /* #....#.#. */
+ 0x0134, /* #..##.#.. */
+},
+{
+ 0x008b, /* .#...#.## */
+ 0x004c, /* ..#..##.. */
+ 0x0001, /* ........# */
+ 0x01a4, /* ##.#..#.. */
+ 0x0129, /* #..#.#..# */
+ 0x004b, /* ..#..#.## */
+ 0x0100, /* #........ */
+ 0x0064, /* ..##..#.. */
+ 0x01a2, /* ##.#...#. */
+},
+{
+ 0x0028, /* ...#.#... */
+ 0x00ee, /* .###.###. */
+ 0x00c6, /* .##...##. */
+ 0x0028, /* ...#.#... */
+ 0x0101, /* #.......# */
+ 0x0028, /* ...#.#... */
+ 0x00c6, /* .##...##. */
+ 0x00ee, /* .###.###. */
+ 0x0028, /* ...#.#... */
+},
+{
+ 0x0159, /* #.#.##..# */
+ 0x005c, /* ..#.###.. */
+ 0x0000, /* ......... */
+ 0x0052, /* ..#.#..#. */
+ 0x0145, /* #.#...#.# */
+ 0x0094, /* .#..#.#.. */
+ 0x0000, /* ......... */
+ 0x0074, /* ..###.#.. */
+ 0x0135, /* #..##.#.# */
+},
+{
+ 0x0130, /* #..##.... */
+ 0x0116, /* #...#.##. */
+ 0x0088, /* .#...#... */
+ 0x0107, /* #.....### */
+ 0x0028, /* ...#.#... */
+ 0x01c1, /* ###.....# */
+ 0x0022, /* ...#...#. */
+ 0x00d1, /* .##.#...# */
+ 0x0019, /* ....##..# */
+},
+{
+ 0x0102, /* #......#. */
+ 0x012c, /* #..#.##.. */
+ 0x000b, /* .....#.## */
+ 0x01c8, /* ###..#... */
+ 0x0044, /* ..#...#.. */
+ 0x0027, /* ...#..### */
+ 0x01a0, /* ##.#..... */
+ 0x0069, /* ..##.#..# */
+ 0x0081, /* .#......# */
+}
+};
diff --git a/apps/plugins/sudoku/templates.h b/apps/plugins/sudoku/templates.h
new file mode 100644
index 0000000..a8d639b
--- /dev/null
+++ b/apps/plugins/sudoku/templates.h
@@ -0,0 +1,8 @@
+
+#ifndef _TEMPLATES_H
+#define _TEMPLATES_H
+
+#define NUM_TEMPLATES 261
+extern const unsigned short templates[NUM_TEMPLATES][9];
+
+#endif