summaryrefslogtreecommitdiff
path: root/apps/plugins/sudoku/sudoku.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sudoku/sudoku.c')
-rw-r--r--apps/plugins/sudoku/sudoku.c231
1 files changed, 148 insertions, 83 deletions
diff --git a/apps/plugins/sudoku/sudoku.c b/apps/plugins/sudoku/sudoku.c
index 12924e8fe6..191f985e3b 100644
--- a/apps/plugins/sudoku/sudoku.c
+++ b/apps/plugins/sudoku/sudoku.c
@@ -64,6 +64,14 @@ Example ".ss" file, and one with a saved state:
64#include "sudoku.h" 64#include "sudoku.h"
65#include "generator.h" 65#include "generator.h"
66 66
67/* The bitmaps */
68#include "sudoku_normal.h"
69#include "sudoku_inverse.h"
70#include "sudoku_start.h"
71
72#define BITMAP_HEIGHT (BMPHEIGHT_sudoku_normal/10)
73#define BITMAP_STRIDE BMPWIDTH_sudoku_normal
74
67PLUGIN_HEADER 75PLUGIN_HEADER
68 76
69/* here is a global api struct pointer. while not strictly necessary, 77/* here is a global api struct pointer. while not strictly necessary,
@@ -72,11 +80,6 @@ PLUGIN_HEADER
72 80
73struct plugin_api* rb; 81struct plugin_api* rb;
74 82
75/* The bitmaps */
76extern const fb_data sudoku_normal[];
77extern const fb_data sudoku_start[];
78extern const fb_data sudoku_inverse[];
79
80/* Default game - used to initialise sudoku.ss if it doesn't exist. */ 83/* Default game - used to initialise sudoku.ss if it doesn't exist. */
81static const char default_game[9][9] = 84static const char default_game[9][9] =
82{ 85{
@@ -93,80 +96,103 @@ static const char default_game[9][9] =
93 { '0','0','0', '4','0','8', '0','5','0' }, 96 { '0','0','0', '4','0','8', '0','5','0' },
94}; 97};
95 98
96#if ((LCD_HEIGHT==128) && (LCD_WIDTH==160)) || \ 99#if LCD_HEIGHT <= LCD_WIDTH /* Horizontal layout, scratchpad at the left */
97 ((LCD_HEIGHT==132) && (LCD_WIDTH==176))
98/* For iriver H1x0 - 160x128, 9 cells @ 12x12 with 14 border lines*/
99 100
100/* Internal dimensions of a cell */ 101#if (LCD_HEIGHT==64) && (LCD_WIDTH==112)
101#define CELL_WIDTH 12 102/* Archos Recorders and Ondios - 112x64, 9 cells @ 8x6 with 10 border lines */
102#define CELL_HEIGHT 12
103 103
104#define BOARD_WIDTH (CELL_WIDTH*9+10+4) 104/* Internal dimensions of a cell */
105#define BOARD_HEIGHT (CELL_HEIGHT*9+10+4) 105#define CELL_WIDTH 8
106#define CELL_HEIGHT 6
107#define SMALL_BOARD
106 108
107#define XOFS (((LCD_WIDTH-BOARD_WIDTH)/2)+10) 109#elif (LCD_HEIGHT==110) && (LCD_WIDTH==138)
108#define YOFS ((LCD_HEIGHT-BOARD_HEIGHT)/2) 110/* iPod Mini - 138x110, 9 cells @ 10x10 with 14 border lines */
109 111
110#define XOFSSCRATCHPAD 3 112/* Internal dimensions of a cell */
113#define CELL_WIDTH 10
114#define CELL_HEIGHT 10
111 115
112/* Locations of each cell */ 116#elif ((LCD_HEIGHT==128) && (LCD_WIDTH==160)) || \
113static unsigned char cellxpos[9]={ 2, 15, 28, 42, 55, 68, 82, 95, 108 }; 117 ((LCD_HEIGHT==132) && (LCD_WIDTH==176))
114static unsigned char cellypos[9]={ 2, 15, 28, 42, 55, 68, 82, 95, 108 }; 118/* iAudio X5, Iriver H1x0, iPod G3, G4 - 160x128; */
119/* iPod Nano - 176x132, 9 cells @ 12x12 with 14 border lines */
115 120
116/* The height of one cell in the bitmap */ 121/* Internal dimensions of a cell */
117#define BITMAP_HEIGHT 12 122#define CELL_WIDTH 12
118#define BITMAP_STRIDE 12 123#define CELL_HEIGHT 12
119 124
120#elif (LCD_HEIGHT==64) && (LCD_WIDTH==112) 125#elif (LCD_HEIGHT==176) && (LCD_WIDTH==220)
121/* For Archos Recorder, FM and Ondio (112x64): 126/* Iriver h300, iPod Color/Photo - 220x176, 9 cells @ 16x16 with 14 border lines */
122 9 cells @ 8x6 with 10 border lines
123*/
124 127
125/* Internal dimensions of a cell */ 128/* Internal dimensions of a cell */
126#define CELL_WIDTH 8 129#define CELL_WIDTH 16
127#define CELL_HEIGHT 6 130#define CELL_HEIGHT 16
128
129#define BOARD_WIDTH (CELL_WIDTH*9+10)
130#define BOARD_HEIGHT (CELL_HEIGHT*9+10)
131 131
132#define XOFS (((LCD_WIDTH-BOARD_WIDTH)/2)+7) 132#elif (LCD_HEIGHT>=240) && (LCD_WIDTH>=320)
133#define YOFS ((LCD_HEIGHT-BOARD_HEIGHT)/2) 133/* iPod Video - 320x240, 9 cells @ 25x25 with 14 border lines */
134 134
135#define XOFSSCRATCHPAD 2 135/* Internal dimensions of a cell */
136#define CELL_WIDTH 25
137#define CELL_HEIGHT 25
136 138
137/* Locations of each cell */ 139#else
138static unsigned char cellxpos[9]={ 1, 10, 19, 28, 37, 46, 55, 64, 73 }; 140 #error SUDOKU: Unsupported LCD size
139static unsigned char cellypos[9]={ 1, 8, 15, 22, 29, 36, 43, 50, 57 }; 141#endif
140 142
141/* The height of one cell in the bitmap */ 143#else /* Vertical layout, scratchpad at the bottom */
142#define BITMAP_HEIGHT 8 144#define VERTICAL_LAYOUT
143#define BITMAP_STRIDE 8
144 145
145#elif (LCD_HEIGHT>=176) && (LCD_WIDTH>=220) 146#if (LCD_HEIGHT>=320) && (LCD_WIDTH>=240)
146/* iriver h300 */ 147/* Gigabeat - 240x320, 9 cells @ 16x16 with 14 border lines */
147 148
148/* Internal dimensions of a cell */ 149/* Internal dimensions of a cell */
149#define CELL_WIDTH 16 150#define CELL_WIDTH 25
150#define CELL_HEIGHT 16 151#define CELL_HEIGHT 25
151 152
152#define BOARD_WIDTH (CELL_WIDTH*9+10+4) 153#else
153#define BOARD_HEIGHT (CELL_HEIGHT*9+10+4) 154 #error SUDOKU: Unsupported LCD size
154 155#endif
155#define XOFS (((LCD_WIDTH-BOARD_WIDTH)/2)+15)
156#define YOFS ((LCD_HEIGHT-BOARD_HEIGHT)/2)
157
158#define XOFSSCRATCHPAD 10
159 156
160/* Locations of each cell */ 157#endif /* Layout */
161static unsigned char cellxpos[9]={ 2, 19, 36, 54, 71, 88, 106, 123, 140 };
162static unsigned char cellypos[9]={ 2, 19, 36, 54, 71, 88, 106, 123, 140 };
163 158
164/* The height of one cell in the bitmap */ 159/* Size dependent build-time calculations */
165#define BITMAP_HEIGHT 16 160#ifdef SMALL_BOARD
166#define BITMAP_STRIDE 16 161#define BOARD_WIDTH (CELL_WIDTH*9+10)
162#define BOARD_HEIGHT (CELL_HEIGHT*9+10)
163static unsigned char cellxpos[9]={
164 1, (CELL_WIDTH+2), (2*CELL_WIDTH+3),
165 (3*CELL_WIDTH+4), (4*CELL_WIDTH+5), (5*CELL_WIDTH+6),
166 (6*CELL_WIDTH+7), (7*CELL_WIDTH+8), (8*CELL_WIDTH+9)
167};
168static unsigned char cellypos[9]={
169 1, (CELL_HEIGHT+2), (2*CELL_HEIGHT+3),
170 (3*CELL_HEIGHT+4), (4*CELL_HEIGHT+5), (5*CELL_HEIGHT+6),
171 (6*CELL_HEIGHT+7), (7*CELL_HEIGHT+8), (8*CELL_HEIGHT+9)
172};
173#else /* !SMALL_BOARD */
174#define BOARD_WIDTH (CELL_WIDTH*9+10+4)
175#define BOARD_HEIGHT (CELL_HEIGHT*9+10+4)
176static unsigned char cellxpos[9]={
177 2, (CELL_WIDTH +3), (2*CELL_WIDTH +4),
178 (3*CELL_WIDTH +6), (4*CELL_WIDTH +7), (5*CELL_WIDTH +8),
179 (6*CELL_WIDTH+10), (7*CELL_WIDTH+11), (8*CELL_WIDTH+12)
180};
181static unsigned char cellypos[9]={
182 2, (CELL_HEIGHT +3), (2*CELL_HEIGHT +4),
183 (3*CELL_HEIGHT +6), (4*CELL_HEIGHT +7), (5*CELL_HEIGHT +8),
184 (6*CELL_HEIGHT+10), (7*CELL_HEIGHT+11), (8*CELL_HEIGHT+12)
185};
186#endif
167 187
188#ifdef VERTICAL_LAYOUT
189#define XOFS ((LCD_WIDTH-BOARD_WIDTH)/2)
190#define YOFS ((LCD_HEIGHT-(BOARD_HEIGHT+CELL_HEIGHT*2+2))/2)
191#define YOFSSCRATCHPAD (YOFS+BOARD_HEIGHT+CELL_WIDTH)
168#else 192#else
169 #error SUDOKU: Unsupported LCD size 193#define XOFSSCRATCHPAD ((LCD_WIDTH-(BOARD_WIDTH+CELL_WIDTH*2+2))/2)
194#define XOFS (XOFSSCRATCHPAD+CELL_WIDTH*2+2)
195#define YOFS ((LCD_HEIGHT-BOARD_HEIGHT)/2)
170#endif 196#endif
171 197
172/****** Solver routine by Tom Shackell <shackell@cs.york.ac.uk> 198/****** Solver routine by Tom Shackell <shackell@cs.york.ac.uk>
@@ -760,7 +786,26 @@ void display_board(struct sudoku_state_t* state)
760 786
761 /* Draw the gridlines - differently for different targets */ 787 /* Draw the gridlines - differently for different targets */
762 788
763#if LCD_HEIGHT > 64 789#ifdef SMALL_BOARD
790 /* Small targets - draw dotted/single lines */
791 for (r=0;r<9;r++) {
792 if ((r % 3)==0) {
793 /* Solid Line */
794 rb->lcd_hline(XOFS,XOFS+BOARD_WIDTH-1,YOFS+cellypos[r]-1);
795 rb->lcd_vline(XOFS+cellxpos[r]-1,YOFS,YOFS+BOARD_HEIGHT-1);
796 } else {
797 /* Dotted line */
798 for (c=XOFS;c<XOFS+BOARD_WIDTH;c+=2) {
799 rb->lcd_drawpixel(c,YOFS+cellypos[r]-1);
800 }
801 for (c=YOFS;c<YOFS+BOARD_HEIGHT;c+=2) {
802 rb->lcd_drawpixel(XOFS+cellxpos[r]-1,c);
803 }
804 }
805 }
806 rb->lcd_hline(XOFS,XOFS+BOARD_WIDTH-1,YOFS+cellypos[8]+CELL_HEIGHT);
807 rb->lcd_vline(XOFS+cellxpos[8]+CELL_WIDTH,YOFS,YOFS+BOARD_HEIGHT-1);
808#else
764 /* Large targets - draw single/double lines */ 809 /* Large targets - draw single/double lines */
765 for (r=0;r<9;r++) { 810 for (r=0;r<9;r++) {
766 rb->lcd_hline(XOFS,XOFS+BOARD_WIDTH-1,YOFS+cellypos[r]-1); 811 rb->lcd_hline(XOFS,XOFS+BOARD_WIDTH-1,YOFS+cellypos[r]-1);
@@ -774,41 +819,53 @@ void display_board(struct sudoku_state_t* state)
774 rb->lcd_hline(XOFS,XOFS+BOARD_WIDTH-1,YOFS+cellypos[8]+CELL_HEIGHT+1); 819 rb->lcd_hline(XOFS,XOFS+BOARD_WIDTH-1,YOFS+cellypos[8]+CELL_HEIGHT+1);
775 rb->lcd_vline(XOFS+cellxpos[8]+CELL_WIDTH,YOFS,YOFS+BOARD_HEIGHT-1); 820 rb->lcd_vline(XOFS+cellxpos[8]+CELL_WIDTH,YOFS,YOFS+BOARD_HEIGHT-1);
776 rb->lcd_vline(XOFS+cellxpos[8]+CELL_WIDTH+1,YOFS,YOFS+BOARD_HEIGHT-1); 821 rb->lcd_vline(XOFS+cellxpos[8]+CELL_WIDTH+1,YOFS,YOFS+BOARD_HEIGHT-1);
777#elif (LCD_HEIGHT==64) 822#endif
778 /* Small targets - draw dotted/single lines */ 823
824#ifdef SUDOKU_BUTTON_POSSIBLE
825#ifdef VERTICAL_LAYOUT
826 rb->lcd_hline(XOFS,XOFS+BOARD_WIDTH-1,YOFSSCRATCHPAD);
827 rb->lcd_hline(XOFS,XOFS+BOARD_WIDTH-1,YOFSSCRATCHPAD+CELL_HEIGHT+1);
779 for (r=0;r<9;r++) { 828 for (r=0;r<9;r++) {
829#ifdef SMALL_BOARD
830 /* Small targets - draw dotted/single lines */
780 if ((r % 3)==0) { 831 if ((r % 3)==0) {
781 /* Solid Line */ 832 /* Solid Line */
782 rb->lcd_hline(XOFS,XOFS+BOARD_WIDTH-1,YOFS+cellypos[r]-1); 833 rb->lcd_vline(XOFS+cellxpos[r]-1,YOFSSCRATCHPAD,
783 rb->lcd_vline(XOFS+cellxpos[r]-1,YOFS,YOFS+BOARD_HEIGHT-1); 834 YOFSSCRATCHPAD+CELL_HEIGHT+1);
784 } else { 835 } else {
785 /* Dotted line */ 836 /* Dotted line */
786 for (c=XOFS;c<XOFS+BOARD_WIDTH;c+=2) { 837 for (c=YOFSSCRATCHPAD;c<YOFSSCRATCHPAD+CELL_HEIGHT+1;c+=2) {
787 rb->lcd_drawpixel(c,YOFS+cellypos[r]-1);
788 }
789 for (c=YOFS;c<YOFS+BOARD_HEIGHT;c+=2) {
790 rb->lcd_drawpixel(XOFS+cellxpos[r]-1,c); 838 rb->lcd_drawpixel(XOFS+cellxpos[r]-1,c);
791 } 839 }
792 } 840 }
793 }
794 rb->lcd_hline(XOFS,XOFS+BOARD_WIDTH-1,YOFS+cellypos[8]+CELL_HEIGHT);
795 rb->lcd_vline(XOFS+cellxpos[8]+CELL_WIDTH,YOFS,YOFS+BOARD_HEIGHT-1);
796#else 841#else
797#error SUDOKU: Unsupported LCD height 842 /* Large targets - draw single/double lines */
843 rb->lcd_vline(XOFS+cellxpos[r]-1,YOFSSCRATCHPAD,
844 YOFSSCRATCHPAD+CELL_HEIGHT+1);
845 if ((r % 3)==0)
846 rb->lcd_vline(XOFS+cellxpos[r]-2,YOFSSCRATCHPAD,
847 YOFSSCRATCHPAD+CELL_HEIGHT+1);
798#endif 848#endif
799 849 if ((r>0) && state->possiblevals[state->y][state->x]&(1<<(r)))
800#ifdef SUDOKU_BUTTON_POSSIBLE 850 rb->lcd_bitmap_part(sudoku_normal,0,BITMAP_HEIGHT*r,BITMAP_STRIDE,
851 XOFS+cellxpos[r-1],YOFSSCRATCHPAD+1,
852 CELL_WIDTH,CELL_HEIGHT);
853 }
854 rb->lcd_vline(XOFS+cellxpos[8]+CELL_WIDTH,YOFSSCRATCHPAD,
855 YOFSSCRATCHPAD+CELL_HEIGHT+1);
856#ifndef SMALL_BOARD
857 rb->lcd_vline(XOFS+cellxpos[8]+CELL_WIDTH+1,YOFSSCRATCHPAD,
858 YOFSSCRATCHPAD+CELL_HEIGHT+1);
859#endif
860 if (state->possiblevals[state->y][state->x]&(1<<(r)))
861 rb->lcd_bitmap_part(sudoku_normal,0,BITMAP_HEIGHT*r,BITMAP_STRIDE,
862 XOFS+cellxpos[8],YOFSSCRATCHPAD+1,
863 CELL_WIDTH,CELL_HEIGHT);
864#else /* Horizontal layout */
801 rb->lcd_vline(XOFSSCRATCHPAD,YOFS,YOFS+BOARD_HEIGHT-1); 865 rb->lcd_vline(XOFSSCRATCHPAD,YOFS,YOFS+BOARD_HEIGHT-1);
802 rb->lcd_vline(XOFSSCRATCHPAD+CELL_WIDTH+1,YOFS,YOFS+BOARD_HEIGHT-1); 866 rb->lcd_vline(XOFSSCRATCHPAD+CELL_WIDTH+1,YOFS,YOFS+BOARD_HEIGHT-1);
803 for (r=0;r<9;r++) { 867 for (r=0;r<9;r++) {
804#if LCD_HEIGHT > 64 868#ifdef SMALL_BOARD
805 /* Large targets - draw single/double lines */
806 rb->lcd_hline(XOFSSCRATCHPAD,XOFSSCRATCHPAD+CELL_WIDTH+1,
807 YOFS+cellypos[r]-1);
808 if ((r % 3)==0)
809 rb->lcd_hline(XOFSSCRATCHPAD,XOFSSCRATCHPAD+CELL_WIDTH+1,
810 YOFS+cellypos[r]-2);
811#elif LCD_HEIGHT == 64
812 /* Small targets - draw dotted/single lines */ 869 /* Small targets - draw dotted/single lines */
813 if ((r % 3)==0) { 870 if ((r % 3)==0) {
814 /* Solid Line */ 871 /* Solid Line */
@@ -820,6 +877,13 @@ void display_board(struct sudoku_state_t* state)
820 rb->lcd_drawpixel(c,YOFS+cellypos[r]-1); 877 rb->lcd_drawpixel(c,YOFS+cellypos[r]-1);
821 } 878 }
822 } 879 }
880#else
881 /* Large targets - draw single/double lines */
882 rb->lcd_hline(XOFSSCRATCHPAD,XOFSSCRATCHPAD+CELL_WIDTH+1,
883 YOFS+cellypos[r]-1);
884 if ((r % 3)==0)
885 rb->lcd_hline(XOFSSCRATCHPAD,XOFSSCRATCHPAD+CELL_WIDTH+1,
886 YOFS+cellypos[r]-2);
823#endif 887#endif
824 if ((r>0) && state->possiblevals[state->y][state->x]&(1<<(r))) 888 if ((r>0) && state->possiblevals[state->y][state->x]&(1<<(r)))
825 rb->lcd_bitmap_part(sudoku_normal,0,BITMAP_HEIGHT*r,BITMAP_STRIDE, 889 rb->lcd_bitmap_part(sudoku_normal,0,BITMAP_HEIGHT*r,BITMAP_STRIDE,
@@ -828,7 +892,7 @@ void display_board(struct sudoku_state_t* state)
828 } 892 }
829 rb->lcd_hline(XOFSSCRATCHPAD,XOFSSCRATCHPAD+CELL_WIDTH+1, 893 rb->lcd_hline(XOFSSCRATCHPAD,XOFSSCRATCHPAD+CELL_WIDTH+1,
830 YOFS+cellypos[8]+CELL_HEIGHT); 894 YOFS+cellypos[8]+CELL_HEIGHT);
831#if LCD_HEIGHT > 64 895#ifndef SMALL_BOARD
832 rb->lcd_hline(XOFSSCRATCHPAD,XOFSSCRATCHPAD+CELL_WIDTH+1, 896 rb->lcd_hline(XOFSSCRATCHPAD,XOFSSCRATCHPAD+CELL_WIDTH+1,
833 YOFS+cellypos[8]+CELL_HEIGHT+1); 897 YOFS+cellypos[8]+CELL_HEIGHT+1);
834#endif 898#endif
@@ -836,7 +900,8 @@ void display_board(struct sudoku_state_t* state)
836 rb->lcd_bitmap_part(sudoku_normal,0,BITMAP_HEIGHT*r,BITMAP_STRIDE, 900 rb->lcd_bitmap_part(sudoku_normal,0,BITMAP_HEIGHT*r,BITMAP_STRIDE,
837 XOFSSCRATCHPAD+1,YOFS+cellypos[8], 901 XOFSSCRATCHPAD+1,YOFS+cellypos[8],
838 CELL_WIDTH,CELL_HEIGHT); 902 CELL_WIDTH,CELL_HEIGHT);
839#endif 903#endif /* Layout */
904#endif /* SUDOKU_BUTTON_POSSIBLE */
840 905
841 /* Draw the numbers */ 906 /* Draw the numbers */
842 for (r=0;r<9;r++) { 907 for (r=0;r<9;r++) {