puzzles: resync with upstream

There have been some improvements with regard to small screen sizes,
which will be nice to have.

Change-Id: I30c740514156258d2818fde325c1a751500f7611
This commit is contained in:
Franklin Wei 2017-10-23 17:19:29 -04:00
parent 7a8c9daf7e
commit ef1306764e
107 changed files with 4782 additions and 2368 deletions

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 5427 comp 3142 ratio 0.578957 level 11 saved 2285 */ /* orig 5427 comp 3142 ratio 0.578957 level 11 saved 2285 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 5211 comp 3117 ratio 0.598158 level 11 saved 2094 */ /* orig 5211 comp 3117 ratio 0.598158 level 11 saved 2094 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2051 comp 1450 ratio 0.706972 level 11 saved 601 */ /* orig 2051 comp 1450 ratio 0.706972 level 11 saved 601 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2276 comp 1548 ratio 0.680141 level 11 saved 728 */ /* orig 2276 comp 1548 ratio 0.680141 level 11 saved 728 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 1248 comp 937 ratio 0.750801 level 5 saved 311 */ /* orig 1248 comp 937 ratio 0.750801 level 5 saved 311 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 1796 comp 1242 ratio 0.691537 level 11 saved 554 */ /* orig 1796 comp 1242 ratio 0.691537 level 11 saved 554 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 1521 comp 1101 ratio 0.723866 level 11 saved 420 */ /* orig 1521 comp 1101 ratio 0.723866 level 11 saved 420 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2375 comp 1591 ratio 0.669895 level 11 saved 784 */ /* orig 2375 comp 1591 ratio 0.669895 level 11 saved 784 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2504 comp 1733 ratio 0.692093 level 11 saved 771 */ /* orig 2504 comp 1733 ratio 0.692093 level 11 saved 771 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 3030 comp 1882 ratio 0.621122 level 11 saved 1148 */ /* orig 3030 comp 1882 ratio 0.621122 level 11 saved 1148 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2265 comp 1577 ratio 0.696247 level 11 saved 688 */ /* orig 2265 comp 1577 ratio 0.696247 level 11 saved 688 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 3936 comp 2381 ratio 0.604929 level 11 saved 1555 */ /* orig 3936 comp 2381 ratio 0.604929 level 11 saved 1555 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2314 comp 1548 ratio 0.668971 level 11 saved 766 */ /* orig 2314 comp 1548 ratio 0.668971 level 11 saved 766 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2264 comp 1613 ratio 0.712456 level 11 saved 651 */ /* orig 2264 comp 1613 ratio 0.712456 level 11 saved 651 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2498 comp 1657 ratio 0.663331 level 11 saved 841 */ /* orig 2498 comp 1657 ratio 0.663331 level 11 saved 841 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 3464 comp 2297 ratio 0.663106 level 11 saved 1167 */ /* orig 3464 comp 2297 ratio 0.663106 level 11 saved 1167 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 3796 comp 2357 ratio 0.620917 level 11 saved 1439 */ /* orig 3796 comp 2357 ratio 0.620917 level 11 saved 1439 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 3445 comp 2367 ratio 0.687083 level 11 saved 1078 */ /* orig 3445 comp 2367 ratio 0.687083 level 11 saved 1078 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 524 comp 416 ratio 0.793893 level 3 saved 108 */ /* orig 524 comp 416 ratio 0.793893 level 3 saved 108 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 1110 comp 894 ratio 0.805405 level 3 saved 216 */ /* orig 1110 comp 894 ratio 0.805405 level 3 saved 216 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2123 comp 1468 ratio 0.691474 level 4 saved 655 */ /* orig 2123 comp 1468 ratio 0.691474 level 4 saved 655 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2565 comp 1606 ratio 0.626121 level 11 saved 959 */ /* orig 2565 comp 1606 ratio 0.626121 level 11 saved 959 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 1686 comp 1254 ratio 0.743772 level 3 saved 432 */ /* orig 1686 comp 1254 ratio 0.743772 level 3 saved 432 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2029 comp 1393 ratio 0.686545 level 4 saved 636 */ /* orig 2029 comp 1393 ratio 0.686545 level 4 saved 636 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,5 +1,5 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 3534 comp 2351 ratio 0.665252 level 11 saved 1183 */ /* orig 3533 comp 2352 ratio 0.665723 level 11 saved 1181 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */
const char help_text[] = { const char help_text[] = {
@ -33,212 +33,212 @@ const char help_text[] = {
0x2e, 0x20, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x20, 0x2e, 0x20, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x20,
0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x67, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x67,
0x61, 0x6d, 0x65, 0x20, 0x67, 0x6f, 0x65, 0x73, 0x49, 0x00, 0x61, 0x6d, 0x65, 0x20, 0x67, 0x6f, 0x65, 0x73, 0x49, 0x00,
0xf0, 0x19, 0x4a, 0x61, 0x70, 0x61, 0x6e, 0x65, 0x73, 0x65, 0xf0, 0x18, 0x4a, 0x61, 0x70, 0x61, 0x6e, 0x65, 0x73, 0x65,
0x20, 0x70, 0x75, 0x7a, 0x7a, 0x6c, 0x65, 0x20, 0x6d, 0x61, 0x20, 0x70, 0x75, 0x7a, 0x7a, 0x6c, 0x65, 0x20, 0x6d, 0x61,
0x67, 0x61, 0x7a, 0x69, 0x6e, 0x65, 0x20, 0x4e, 0x69, 0x6b, 0x67, 0x61, 0x7a, 0x69, 0x6e, 0x65, 0x20, 0x4e, 0x69, 0x6b,
0x6f, 0x6c, 0x69, 0x20, 0x5b, 0x33, 0x5d, 0x20, 0x3b, 0x20, 0x6f, 0x6c, 0x69, 0x20, 0x5b, 0x33, 0x5d, 0x3b, 0x20, 0x49,
0x49, 0x27, 0x7e, 0x01, 0xf1, 0x14, 0x6c, 0x73, 0x6f, 0x20, 0x27, 0x7d, 0x01, 0xf1, 0x14, 0x6c, 0x73, 0x6f, 0x20, 0x73,
0x73, 0x65, 0x65, 0x6e, 0x20, 0x61, 0x20, 0x50, 0x61, 0x6c, 0x65, 0x65, 0x6e, 0x20, 0x61, 0x20, 0x50, 0x61, 0x6c, 0x6d,
0x6d, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x74, 0x20, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x74, 0x20, 0x50,
0x50, 0x45, 0x00, 0x00, 0x1e, 0x00, 0xfa, 0x00, 0x61, 0x63, 0x44, 0x00, 0x00, 0x1e, 0x00, 0xfa, 0x00, 0x61, 0x63, 0x65,
0x65, 0x20, 0x5b, 0x34, 0x5d, 0x2e, 0x20, 0x55, 0x6e, 0x6c, 0x20, 0x5b, 0x34, 0x5d, 0x2e, 0x20, 0x55, 0x6e, 0x6c, 0x69,
0x69, 0x6b, 0x65, 0x1a, 0x00, 0x2b, 0x27, 0x73, 0x3c, 0x00, 0x6b, 0x65, 0x1a, 0x00, 0x2b, 0x27, 0x73, 0x3c, 0x00, 0x91,
0x91, 0x2c, 0x20, 0x6d, 0x79, 0x20, 0x76, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x6d, 0x79, 0x20, 0x76, 0x65, 0x72, 0x73, 0x48,
0x48, 0x00, 0xf1, 0x0e, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x00, 0xf1, 0x0e, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69,
0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x67, 0x65, 0x6e, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x67, 0x65, 0x6e, 0x65,
0x65, 0x72, 0x61, 0x74, 0x65, 0x73, 0x20, 0x72, 0x61, 0x6e, 0x72, 0x61, 0x74, 0x65, 0x73, 0x20, 0x72, 0x61, 0x6e, 0x64,
0x64, 0x6f, 0x6d, 0x99, 0x01, 0x01, 0x8a, 0x01, 0x31, 0x61, 0x6f, 0x6d, 0x98, 0x01, 0x01, 0x89, 0x01, 0x31, 0x61, 0x6e,
0x6e, 0x79, 0x86, 0x01, 0x50, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x79, 0x85, 0x01, 0x50, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x65,
0x65, 0x00, 0x60, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x27, 0x00, 0x60, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x26, 0x01,
0x01, 0x64, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0xd4, 0x00, 0x64, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0xd3, 0x00, 0x61,
0x61, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0xe6, 0x01, 0x81, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0xe5, 0x01, 0x81, 0x68,
0x68, 0x65, 0x72, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x16, 0x02, 0x65, 0x72, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x15, 0x02, 0xd0,
0xd0, 0x71, 0x75, 0x69, 0x74, 0x65, 0x20, 0x61, 0x73, 0x20, 0x71, 0x75, 0x69, 0x74, 0x65, 0x20, 0x61, 0x73, 0x20, 0x67,
0x67, 0x6f, 0x6f, 0x64, 0x08, 0x00, 0xc3, 0x68, 0x61, 0x6e, 0x6f, 0x6f, 0x64, 0x08, 0x00, 0xc3, 0x68, 0x61, 0x6e, 0x64,
0x64, 0x2d, 0x63, 0x72, 0x61, 0x66, 0x74, 0x65, 0x64, 0x3d, 0x2d, 0x63, 0x72, 0x61, 0x66, 0x74, 0x65, 0x64, 0x3d, 0x00,
0x00, 0xc0, 0x73, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0xc0, 0x73, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62,
0x62, 0x65, 0x2c, 0x20, 0x4e, 0x02, 0x21, 0x6f, 0x6e, 0x37, 0x65, 0x2c, 0x20, 0x4d, 0x02, 0x21, 0x6f, 0x6e, 0x36, 0x01,
0x01, 0x21, 0x70, 0x6c, 0x03, 0x02, 0x12, 0x64, 0x7d, 0x00, 0x21, 0x70, 0x6c, 0x02, 0x02, 0x12, 0x64, 0x7d, 0x00, 0x50,
0x50, 0x67, 0x65, 0x74, 0x20, 0x61, 0x86, 0x01, 0xf6, 0x02, 0x67, 0x65, 0x74, 0x20, 0x61, 0x85, 0x01, 0xf6, 0x02, 0x65,
0x65, 0x78, 0x68, 0x61, 0x75, 0x73, 0x74, 0x69, 0x62, 0x6c, 0x78, 0x68, 0x61, 0x75, 0x73, 0x74, 0x69, 0x62, 0x6c, 0x65,
0x65, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x87, 0x00, 0x00, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x87, 0x00, 0x00, 0x72,
0x73, 0x01, 0x70, 0x61, 0x69, 0x6c, 0x6f, 0x72, 0x65, 0x64, 0x01, 0x70, 0x61, 0x69, 0x6c, 0x6f, 0x72, 0x65, 0x64, 0x7b,
0x7c, 0x01, 0x10, 0x79, 0x7d, 0x02, 0xc1, 0x6f, 0x77, 0x6e, 0x01, 0x10, 0x79, 0x7c, 0x02, 0xc1, 0x6f, 0x77, 0x6e, 0x20,
0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x08, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x08, 0x01,
0x01, 0x30, 0x2e, 0x20, 0x0a, 0x71, 0x01, 0xc1, 0x68, 0x74, 0xf1, 0x04, 0x2e, 0x20, 0x0a, 0x5b, 0x33, 0x5d, 0x20, 0x68,
0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6e, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
0x87, 0x01, 0xa3, 0x2e, 0x63, 0x6f, 0x2e, 0x6a, 0x70, 0x2f, 0x6e, 0x86, 0x01, 0xa3, 0x2e, 0x63, 0x6f, 0x2e, 0x6a, 0x70,
0x65, 0x6e, 0x2f, 0x4c, 0x00, 0xf0, 0x06, 0x2f, 0x73, 0x68, 0x2f, 0x65, 0x6e, 0x2f, 0x4c, 0x00, 0xf0, 0x06, 0x2f, 0x73,
0x69, 0x6b, 0x61, 0x6b, 0x75, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x68, 0x69, 0x6b, 0x61, 0x6b, 0x75, 0x2e, 0x68, 0x74, 0x6d,
0x20, 0x28, 0x62, 0x65, 0x77, 0x61, 0x72, 0x65, 0x6c, 0x00, 0x6c, 0x20, 0x28, 0x62, 0x65, 0x77, 0x61, 0x72, 0x65, 0x6c,
0xa2, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x29, 0x20, 0x0a, 0x5b, 0x00, 0xa2, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x29, 0x20, 0x0a,
0x34, 0x47, 0x00, 0x10, 0x73, 0x48, 0x00, 0xe0, 0x65, 0x62, 0x5b, 0x34, 0x47, 0x00, 0x10, 0x73, 0x48, 0x00, 0xe0, 0x65,
0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x6f, 0x62, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e,
0x72, 0x67, 0x10, 0x00, 0xf7, 0x01, 0x2f, 0x32, 0x30, 0x30, 0x6f, 0x72, 0x67, 0x10, 0x00, 0xf7, 0x01, 0x2f, 0x32, 0x30,
0x34, 0x31, 0x30, 0x32, 0x34, 0x30, 0x30, 0x31, 0x34, 0x35, 0x30, 0x34, 0x31, 0x30, 0x32, 0x34, 0x30, 0x30, 0x31, 0x34,
0x39, 0x2f, 0x72, 0x00, 0x02, 0x62, 0x00, 0x63, 0x2e, 0x67, 0x35, 0x39, 0x2f, 0x72, 0x00, 0x02, 0x62, 0x00, 0x63, 0x2e,
0x72, 0x2e, 0x6a, 0x70, 0x6f, 0x00, 0x21, 0x2f, 0x73, 0x6d, 0x67, 0x72, 0x2e, 0x6a, 0x70, 0x6f, 0x00, 0x21, 0x2f, 0x73,
0x00, 0xb1, 0x2f, 0x70, 0x61, 0x6c, 0x6d, 0x2f, 0x69, 0x6e, 0x6d, 0x00, 0xb1, 0x2f, 0x70, 0x61, 0x6c, 0x6d, 0x2f, 0x69,
0x64, 0x65, 0x78, 0x78, 0x00, 0xa7, 0x2e, 0x65, 0x6e, 0x20, 0x6e, 0x64, 0x65, 0x78, 0x78, 0x00, 0xa7, 0x2e, 0x65, 0x6e,
0x0a, 0x0a, 0x23, 0x38, 0x2e, 0x31, 0xaf, 0x03, 0x01, 0xf4, 0x20, 0x0a, 0x0a, 0x23, 0x38, 0x2e, 0x31, 0xae, 0x03, 0x01,
0x02, 0x73, 0x72, 0x6f, 0x6c, 0x73, 0x20, 0x0a, 0x54, 0x72, 0xf3, 0x02, 0x73, 0x72, 0x6f, 0x6c, 0x73, 0x20, 0x0a, 0x54,
0x02, 0x01, 0xbf, 0x02, 0x61, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x71, 0x02, 0x01, 0xbe, 0x02, 0x61, 0x70, 0x6c, 0x61, 0x79,
0x64, 0xb0, 0x03, 0x01, 0x42, 0x01, 0xf1, 0x12, 0x6d, 0x6f, 0x65, 0x64, 0xaf, 0x03, 0x01, 0x42, 0x01, 0xf1, 0x12, 0x6d,
0x75, 0x73, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x75, 0x72, 0x6f, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x75,
0x73, 0x6f, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x20, 0x72, 0x73, 0x6f, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x2e,
0x0a, 0x4c, 0x65, 0x66, 0x74, 0x2d, 0x63, 0x6c, 0x69, 0x63, 0x20, 0x0a, 0x4c, 0x65, 0x66, 0x74, 0x2d, 0x63, 0x6c, 0x69,
0x6b, 0xe0, 0x01, 0x41, 0x65, 0x64, 0x67, 0x65, 0xab, 0x02, 0x63, 0x6b, 0xe0, 0x01, 0x41, 0x65, 0x64, 0x67, 0x65, 0xaa,
0x21, 0x6f, 0x67, 0x07, 0x03, 0x00, 0x81, 0x01, 0x00, 0x35, 0x02, 0x21, 0x6f, 0x67, 0x06, 0x03, 0x00, 0x81, 0x01, 0x00,
0x00, 0x40, 0x6f, 0x66, 0x66, 0x2c, 0x08, 0x00, 0x18, 0x6c, 0x35, 0x00, 0x40, 0x6f, 0x66, 0x66, 0x2c, 0x08, 0x00, 0x18,
0x2f, 0x00, 0x90, 0x64, 0x20, 0x64, 0x72, 0x61, 0x67, 0x20, 0x6c, 0x2f, 0x00, 0x90, 0x64, 0x20, 0x64, 0x72, 0x61, 0x67,
0x74, 0x6f, 0x08, 0x00, 0x10, 0x77, 0x92, 0x01, 0x67, 0x65, 0x20, 0x74, 0x6f, 0x08, 0x00, 0x10, 0x77, 0x92, 0x01, 0x67,
0x6e, 0x74, 0x69, 0x72, 0x65, 0x48, 0x03, 0x10, 0x28, 0x34, 0x65, 0x6e, 0x74, 0x69, 0x72, 0x65, 0x47, 0x03, 0x10, 0x28,
0x00, 0x78, 0x69, 0x6e, 0x65, 0x29, 0x20, 0x6f, 0x6e, 0xe7, 0x34, 0x00, 0x78, 0x69, 0x6e, 0x65, 0x29, 0x20, 0x6f, 0x6e,
0x03, 0x01, 0x99, 0x03, 0xc2, 0x67, 0x6f, 0x20, 0x28, 0x72, 0xe6, 0x03, 0x01, 0x98, 0x03, 0xc2, 0x67, 0x6f, 0x20, 0x28,
0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x7e, 0x00, 0x71, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x7e, 0x00,
0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x87, 0x00, 0x11, 0x71, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x87, 0x00,
0x73, 0xbc, 0x00, 0x21, 0x69, 0x6e, 0xee, 0x03, 0x06, 0x53, 0x11, 0x73, 0xbc, 0x00, 0x21, 0x69, 0x6e, 0xed, 0x03, 0x06,
0x00, 0x73, 0x29, 0x2e, 0x20, 0x52, 0x69, 0x67, 0x68, 0x86, 0x53, 0x00, 0x73, 0x29, 0x2e, 0x20, 0x52, 0x69, 0x67, 0x68,
0x00, 0x35, 0x69, 0x6e, 0x67, 0x89, 0x00, 0x10, 0x67, 0x0d, 0x86, 0x00, 0x35, 0x69, 0x6e, 0x67, 0x89, 0x00, 0x10, 0x67,
0x00, 0x40, 0x77, 0x69, 0x6c, 0x6c, 0x7f, 0x04, 0x20, 0x6f, 0x0d, 0x00, 0x40, 0x77, 0x69, 0x6c, 0x6c, 0x7e, 0x04, 0x20,
0x77, 0xf3, 0x01, 0x00, 0x9c, 0x00, 0x40, 0x65, 0x72, 0x61, 0x6f, 0x77, 0xf3, 0x01, 0x00, 0x9c, 0x00, 0x40, 0x65, 0x72,
0x73, 0x63, 0x04, 0x02, 0x1e, 0x04, 0x32, 0x65, 0x6e, 0x74, 0x61, 0x73, 0x62, 0x04, 0x02, 0x1d, 0x04, 0x32, 0x65, 0x6e,
0xcd, 0x02, 0x06, 0x52, 0x00, 0x01, 0x68, 0x00, 0x90, 0x6f, 0x74, 0xcd, 0x02, 0x06, 0x52, 0x00, 0x01, 0x68, 0x00, 0x90,
0x75, 0x74, 0x20, 0x61, 0x66, 0x66, 0x65, 0x63, 0x80, 0x00, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x66, 0x66, 0x65, 0x63, 0x80,
0x00, 0xdd, 0x03, 0x01, 0x84, 0x00, 0x00, 0x22, 0x01, 0xf2, 0x00, 0x00, 0xdc, 0x03, 0x01, 0x84, 0x00, 0x00, 0x22, 0x01,
0x01, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0xf2, 0x01, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74,
0x76, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x75, 0x4d, 0x00, 0x07, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x75, 0x4d, 0x00,
0x47, 0x01, 0x01, 0xdc, 0x03, 0x42, 0x6d, 0x6f, 0x76, 0x65, 0x07, 0x47, 0x01, 0x01, 0xdb, 0x03, 0x42, 0x6d, 0x6f, 0x76,
0xaa, 0x02, 0x31, 0x6f, 0x73, 0x69, 0x9f, 0x03, 0x30, 0x69, 0x65, 0xaa, 0x02, 0x31, 0x6f, 0x73, 0x69, 0x9f, 0x03, 0x30,
0x6e, 0x64, 0x66, 0x02, 0x91, 0x6f, 0x72, 0x20, 0x61, 0x72, 0x69, 0x6e, 0x64, 0x66, 0x02, 0x91, 0x6f, 0x72, 0x20, 0x61,
0x6f, 0x75, 0x6e, 0x64, 0x1e, 0x00, 0xc0, 0x62, 0x6f, 0x61, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x1e, 0x00, 0xc0, 0x62, 0x6f,
0x72, 0x64, 0x2e, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x69, 0x61, 0x72, 0x64, 0x2e, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73,
0x00, 0x20, 0x74, 0x68, 0x2e, 0x01, 0x40, 0x74, 0x75, 0x72, 0x69, 0x00, 0x20, 0x74, 0x68, 0x2e, 0x01, 0x40, 0x74, 0x75,
0x6e, 0x4a, 0x00, 0x00, 0x0f, 0x00, 0x12, 0x6e, 0xbe, 0x00, 0x72, 0x6e, 0x4a, 0x00, 0x00, 0x0f, 0x00, 0x12, 0x6e, 0xbe,
0x13, 0x73, 0xbf, 0x00, 0x0f, 0x70, 0x00, 0x04, 0x01, 0xf1, 0x00, 0x13, 0x73, 0xbf, 0x00, 0x0f, 0x70, 0x00, 0x04, 0x01,
0x00, 0x09, 0xc5, 0x00, 0x00, 0xc1, 0x00, 0x41, 0x66, 0x72, 0xf1, 0x00, 0x09, 0xc5, 0x00, 0x00, 0xc1, 0x00, 0x41, 0x66,
0x6f, 0x6d, 0x2f, 0x01, 0x05, 0x86, 0x00, 0x02, 0xed, 0x04, 0x72, 0x6f, 0x6d, 0x2f, 0x01, 0x05, 0x86, 0x00, 0x02, 0xec,
0x1f, 0x70, 0x6f, 0x00, 0x04, 0x80, 0x61, 0x67, 0x61, 0x69, 0x04, 0x1f, 0x70, 0x6f, 0x00, 0x04, 0x80, 0x61, 0x67, 0x61,
0x6e, 0x20, 0x63, 0x6f, 0x1c, 0x04, 0x20, 0x74, 0x65, 0xaf, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x1c, 0x04, 0x20, 0x74, 0x65,
0x03, 0x07, 0xbc, 0x01, 0x35, 0x2e, 0x20, 0x55, 0x34, 0x00, 0xaf, 0x03, 0x07, 0xbc, 0x01, 0x35, 0x2e, 0x20, 0x55, 0x34,
0x20, 0x73, 0x70, 0x60, 0x04, 0xa0, 0x62, 0x61, 0x72, 0x20, 0x00, 0x20, 0x73, 0x70, 0x60, 0x04, 0xa0, 0x62, 0x61, 0x72,
0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x14, 0x06, 0x0b, 0x4d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x13, 0x06, 0x0b,
0x00, 0x03, 0xb7, 0x00, 0x0f, 0x76, 0x01, 0x32, 0x10, 0x2c, 0x4d, 0x00, 0x03, 0xb7, 0x00, 0x0f, 0x76, 0x01, 0x32, 0x10,
0x1d, 0x04, 0x57, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x2b, 0x01, 0x2c, 0x1d, 0x04, 0x57, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x2b,
0xf1, 0x01, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x20, 0x63, 0x01, 0xf1, 0x01, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x20,
0x61, 0x6e, 0x63, 0x65, 0x6c, 0x73, 0x20, 0x61, 0x03, 0x01, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x73, 0x20, 0x61, 0x03,
0x7a, 0x2e, 0x20, 0x0a, 0x57, 0x68, 0x65, 0x6e, 0x0a, 0x01, 0x01, 0x7a, 0x2e, 0x20, 0x0a, 0x57, 0x68, 0x65, 0x6e, 0x0a,
0x13, 0x66, 0x78, 0x00, 0x10, 0x72, 0x14, 0x00, 0x02, 0xb3, 0x01, 0x13, 0x66, 0x78, 0x00, 0x10, 0x72, 0x14, 0x00, 0x02,
0x04, 0x25, 0x69, 0x73, 0xe7, 0x00, 0x52, 0x64, 0x2c, 0x20, 0xb3, 0x04, 0x25, 0x69, 0x73, 0xe7, 0x00, 0x52, 0x64, 0x2c,
0x69, 0x74, 0x28, 0x02, 0xf2, 0x01, 0x62, 0x65, 0x20, 0x73, 0x20, 0x69, 0x74, 0x28, 0x02, 0xf2, 0x01, 0x62, 0x65, 0x20,
0x68, 0x61, 0x64, 0x65, 0x64, 0x2e, 0x20, 0x0a, 0x28, 0x41, 0x73, 0x68, 0x61, 0x64, 0x65, 0x64, 0x2e, 0x20, 0x0a, 0x28,
0x6c, 0x6c, 0x12, 0x06, 0x10, 0x63, 0x39, 0x01, 0x10, 0x73, 0x41, 0x6c, 0x6c, 0x11, 0x06, 0x10, 0x63, 0x39, 0x01, 0x10,
0xc6, 0x04, 0x61, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0xdf, 0x73, 0xc6, 0x04, 0x61, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64,
0x06, 0x21, 0x65, 0x63, 0xd5, 0x01, 0x63, 0x32, 0x2e, 0x31, 0xde, 0x06, 0x21, 0x65, 0x63, 0xd5, 0x01, 0x63, 0x32, 0x2e,
0x20, 0x61, 0x72, 0x9c, 0x05, 0xb2, 0x61, 0x76, 0x61, 0x69, 0x31, 0x20, 0x61, 0x72, 0x9c, 0x05, 0xb2, 0x61, 0x76, 0x61,
0x6c, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x29, 0x98, 0x03, 0x18, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x29, 0x98, 0x03,
0x32, 0x98, 0x03, 0x91, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x32, 0x98, 0x03, 0x91, 0x70, 0x61, 0x72, 0x61, 0x6d,
0x74, 0x65, 0x72, 0x9a, 0x03, 0x37, 0x65, 0x73, 0x65, 0x12, 0x65, 0x74, 0x65, 0x72, 0x9a, 0x03, 0x37, 0x65, 0x73, 0x65,
0x00, 0x00, 0x44, 0x00, 0x06, 0x3f, 0x00, 0x04, 0xb8, 0x01, 0x12, 0x00, 0x00, 0x44, 0x00, 0x06, 0x3f, 0x00, 0x04, 0xb8,
0xf0, 0x01, 0x65, 0x20, 0x60, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x01, 0xf0, 0x01, 0x65, 0x20, 0x60, 0x43, 0x75, 0x73, 0x74,
0x6d, 0x2e, 0x2e, 0x2e, 0x27, 0x20, 0x6f, 0x70, 0x72, 0x00, 0x6f, 0x6d, 0x2e, 0x2e, 0x2e, 0x27, 0x20, 0x6f, 0x70, 0x72,
0x04, 0x38, 0x03, 0xf0, 0x0b, 0x60, 0x54, 0x79, 0x70, 0x65, 0x00, 0x04, 0x38, 0x03, 0xf0, 0x0b, 0x60, 0x54, 0x79, 0x70,
0x27, 0x20, 0x6d, 0x65, 0x6e, 0x75, 0x2e, 0x20, 0x0a, 0x5f, 0x65, 0x27, 0x20, 0x6d, 0x65, 0x6e, 0x75, 0x2e, 0x20, 0x0a,
0x57, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x2c, 0x20, 0x5f, 0x48, 0x5f, 0x57, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x2c, 0x20, 0x5f,
0x65, 0x0d, 0x03, 0x60, 0x5f, 0x20, 0x0a, 0x53, 0x69, 0x7a, 0x48, 0x65, 0x0d, 0x03, 0x60, 0x5f, 0x20, 0x0a, 0x53, 0x69,
0xfb, 0x00, 0x00, 0x61, 0x03, 0x00, 0xe2, 0x00, 0x16, 0x6e, 0x7a, 0xfb, 0x00, 0x00, 0x61, 0x03, 0x00, 0xe2, 0x00, 0x16,
0x78, 0x07, 0x71, 0x0a, 0x5f, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x6e, 0x77, 0x07, 0x71, 0x0a, 0x5f, 0x45, 0x78, 0x70, 0x61,
0xec, 0x05, 0x73, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x6e, 0xec, 0x05, 0x73, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72,
0x2c, 0x04, 0x10, 0x69, 0x47, 0x01, 0x91, 0x6d, 0x65, 0x63, 0x5f, 0x2c, 0x04, 0x10, 0x69, 0x47, 0x01, 0x91, 0x6d, 0x65,
0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0xb6, 0x06, 0x00, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0xb5, 0x06, 0x00,
0x00, 0x14, 0x67, 0xf7, 0x01, 0x35, 0x74, 0x79, 0x70, 0x54, 0x0c, 0x00, 0x14, 0x67, 0xf7, 0x01, 0x35, 0x74, 0x79, 0x70,
0x00, 0x15, 0x73, 0x1a, 0x06, 0x42, 0x64, 0x20, 0x62, 0x79, 0x54, 0x00, 0x15, 0x73, 0x1a, 0x06, 0x42, 0x64, 0x20, 0x62,
0xeb, 0x02, 0x90, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x2e, 0x79, 0xeb, 0x02, 0x90, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d,
0x20, 0x53, 0xfd, 0x07, 0x60, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x2e, 0x20, 0x53, 0xfc, 0x07, 0x60, 0x70, 0x65, 0x6f, 0x70,
0x65, 0x6c, 0x02, 0x33, 0x66, 0x65, 0x72, 0x3b, 0x08, 0x04, 0x6c, 0x65, 0x6c, 0x02, 0x33, 0x66, 0x65, 0x72, 0x3a, 0x08,
0x91, 0x07, 0x01, 0xa7, 0x03, 0x96, 0x20, 0x66, 0x65, 0x77, 0x04, 0x90, 0x07, 0x01, 0xa7, 0x03, 0x96, 0x20, 0x66, 0x65,
0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x02, 0x01, 0x18, 0x07, 0x77, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x02, 0x01, 0x17,
0x00, 0x0c, 0x04, 0x08, 0x29, 0x00, 0x11, 0x6d, 0x69, 0x06, 0x07, 0x00, 0x0c, 0x04, 0x08, 0x29, 0x00, 0x11, 0x6d, 0x69,
0x70, 0x6d, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x6e, 0xc1, 0x00, 0x06, 0x70, 0x6d, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x6e, 0xc1,
0x11, 0x53, 0xbf, 0x05, 0x00, 0xfa, 0x01, 0x10, 0x20, 0x3e, 0x00, 0x11, 0x53, 0xbf, 0x05, 0x00, 0xfa, 0x01, 0x10, 0x20,
0x08, 0x19, 0x52, 0x3d, 0x00, 0x30, 0x65, 0x73, 0x73, 0x76, 0x3d, 0x08, 0x19, 0x52, 0x3d, 0x00, 0x30, 0x65, 0x73, 0x73,
0x04, 0x08, 0xbc, 0x06, 0x00, 0xb9, 0x08, 0x11, 0x5f, 0x41, 0x76, 0x04, 0x08, 0xbc, 0x06, 0x00, 0xb8, 0x08, 0x11, 0x5f,
0x00, 0x31, 0x65, 0x72, 0x5f, 0x88, 0x00, 0x00, 0x15, 0x03, 0x41, 0x00, 0x31, 0x65, 0x72, 0x5f, 0x88, 0x00, 0x00, 0x15,
0x01, 0x48, 0x01, 0x05, 0xc1, 0x06, 0x04, 0x08, 0x06, 0x21, 0x03, 0x01, 0x48, 0x01, 0x05, 0xc1, 0x06, 0x04, 0x08, 0x06,
0x65, 0x64, 0x23, 0x03, 0x01, 0x7a, 0x03, 0x01, 0x4f, 0x00, 0x21, 0x65, 0x64, 0x23, 0x03, 0x01, 0x7a, 0x03, 0x01, 0x4f,
0x20, 0x78, 0x70, 0x0f, 0x00, 0x20, 0x69, 0x74, 0xe5, 0x00, 0x00, 0x20, 0x78, 0x70, 0x0f, 0x00, 0x20, 0x69, 0x74, 0xe5,
0x30, 0x61, 0x64, 0x64, 0x91, 0x00, 0x10, 0x72, 0xd8, 0x02, 0x00, 0x30, 0x61, 0x64, 0x64, 0x91, 0x00, 0x10, 0x72, 0xd8,
0x20, 0x61, 0x6e, 0xce, 0x00, 0x60, 0x6c, 0x75, 0x6d, 0x6e, 0x02, 0x20, 0x61, 0x6e, 0xce, 0x00, 0x60, 0x6c, 0x75, 0x6d,
0x73, 0x2e, 0x3f, 0x01, 0x00, 0xe7, 0x06, 0x7b, 0x66, 0x61, 0x6e, 0x73, 0x2e, 0x3f, 0x01, 0x00, 0xe7, 0x06, 0x7b, 0x66,
0x75, 0x6c, 0x74, 0x20, 0x65, 0x5e, 0x01, 0x00, 0x32, 0x01, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x65, 0x5e, 0x01, 0x00, 0x32,
0xa1, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x01, 0xa1, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x6d, 0x65, 0x61,
0x73, 0x90, 0x03, 0x07, 0xb4, 0x00, 0x02, 0x7a, 0x02, 0x46, 0x6e, 0x73, 0x90, 0x03, 0x07, 0xb4, 0x00, 0x02, 0x7a, 0x02,
0x73, 0x69, 0x6d, 0x70, 0xb1, 0x00, 0x07, 0x6a, 0x09, 0x09, 0x46, 0x73, 0x69, 0x6d, 0x70, 0xb1, 0x00, 0x07, 0x69, 0x09,
0xa5, 0x00, 0x00, 0xef, 0x00, 0x00, 0x96, 0x01, 0x12, 0x2c, 0x09, 0xa5, 0x00, 0x00, 0xef, 0x00, 0x00, 0x96, 0x01, 0x12,
0xe4, 0x04, 0x10, 0x6f, 0x46, 0x07, 0x10, 0x68, 0x92, 0x00, 0x2c, 0xe4, 0x04, 0x10, 0x6f, 0x46, 0x07, 0x10, 0x68, 0x92,
0x30, 0x66, 0x75, 0x72, 0x5b, 0x07, 0x42, 0x2e, 0x20, 0x49, 0x00, 0x30, 0x66, 0x75, 0x72, 0x5b, 0x07, 0x42, 0x2e, 0x20,
0x66, 0xcd, 0x00, 0x01, 0x11, 0x07, 0x0f, 0x8a, 0x00, 0x02, 0x49, 0x66, 0xcd, 0x00, 0x01, 0x11, 0x07, 0x0f, 0x8a, 0x00,
0x90, 0x28, 0x73, 0x61, 0x79, 0x29, 0x20, 0x30, 0x2e, 0x35, 0x02, 0x90, 0x28, 0x73, 0x61, 0x79, 0x29, 0x20, 0x30, 0x2e,
0xf7, 0x02, 0x07, 0x93, 0x00, 0x02, 0xf2, 0x08, 0x42, 0x64, 0x35, 0xf7, 0x02, 0x07, 0x93, 0x00, 0x02, 0xf1, 0x08, 0x42,
0x69, 0x6d, 0x65, 0x32, 0x00, 0x25, 0x6f, 0x66, 0xa0, 0x05, 0x64, 0x69, 0x6d, 0x65, 0x32, 0x00, 0x25, 0x6f, 0x66, 0xa0,
0x04, 0x1d, 0x03, 0x03, 0x0d, 0x01, 0x02, 0x41, 0x07, 0x42, 0x05, 0x04, 0x1d, 0x03, 0x03, 0x0d, 0x01, 0x02, 0x41, 0x07,
0x68, 0x61, 0x6c, 0x66, 0x31, 0x04, 0x00, 0x9d, 0x03, 0x40, 0x42, 0x68, 0x61, 0x6c, 0x66, 0x31, 0x04, 0x00, 0x9d, 0x03,
0x62, 0x69, 0x67, 0x20, 0xb7, 0x07, 0x12, 0x72, 0xc3, 0x00, 0x40, 0x62, 0x69, 0x67, 0x20, 0xb7, 0x07, 0x12, 0x72, 0xc3,
0x03, 0x4d, 0x07, 0x60, 0x49, 0x6e, 0x20, 0x6f, 0x74, 0x68, 0x00, 0x03, 0x4d, 0x07, 0x60, 0x49, 0x6e, 0x20, 0x6f, 0x74,
0x28, 0x09, 0x51, 0x6f, 0x72, 0x64, 0x73, 0x2c, 0x51, 0x00, 0x68, 0x27, 0x09, 0x51, 0x6f, 0x72, 0x64, 0x73, 0x2c, 0x51,
0x30, 0x69, 0x6e, 0x69, 0x9e, 0x01, 0x0a, 0x59, 0x00, 0x36, 0x00, 0x30, 0x69, 0x6e, 0x69, 0x9e, 0x01, 0x0a, 0x59, 0x00,
0x32, 0x2f, 0x33, 0xe9, 0x00, 0x28, 0x69, 0x6e, 0x8c, 0x00, 0x36, 0x32, 0x2f, 0x33, 0xe9, 0x00, 0x28, 0x69, 0x6e, 0x8c,
0x03, 0xb5, 0x04, 0x0f, 0x85, 0x00, 0x02, 0x01, 0x22, 0x04, 0x00, 0x03, 0xb5, 0x04, 0x0f, 0x85, 0x00, 0x02, 0x01, 0x22,
0x21, 0x66, 0x75, 0x40, 0x01, 0x17, 0x7a, 0x42, 0x04, 0x24, 0x04, 0x21, 0x66, 0x75, 0x40, 0x01, 0x17, 0x7a, 0x42, 0x04,
0x64, 0x64, 0x42, 0x06, 0x27, 0x6d, 0x6f, 0x7f, 0x06, 0x01, 0x24, 0x64, 0x64, 0x42, 0x06, 0x27, 0x6d, 0x6f, 0x7f, 0x06,
0xfd, 0x02, 0x30, 0x53, 0x65, 0x74, 0x5d, 0x04, 0x0f, 0x1f, 0x01, 0xfd, 0x02, 0x30, 0x53, 0x65, 0x74, 0x5d, 0x04, 0x0f,
0x01, 0x04, 0x03, 0x9c, 0x05, 0x00, 0x20, 0x01, 0x52, 0x20, 0x1f, 0x01, 0x04, 0x03, 0x9c, 0x05, 0x00, 0x20, 0x01, 0x52,
0x74, 0x65, 0x6e, 0x64, 0xcc, 0x05, 0x21, 0x61, 0x6b, 0xbb, 0x20, 0x74, 0x65, 0x6e, 0x64, 0xcc, 0x05, 0x21, 0x61, 0x6b,
0x04, 0x01, 0x4c, 0x07, 0x02, 0x53, 0x00, 0x91, 0x64, 0x69, 0xbb, 0x04, 0x01, 0x4c, 0x07, 0x02, 0x53, 0x00, 0x91, 0x64,
0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x9c, 0x00, 0x02, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x9c, 0x00,
0xff, 0x03, 0x60, 0x28, 0x69, 0x6e, 0x20, 0x6d, 0x79, 0x56, 0x02, 0xff, 0x03, 0x60, 0x28, 0x69, 0x6e, 0x20, 0x6d, 0x79,
0x00, 0xa0, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x29, 0x56, 0x00, 0xa0, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65,
0x20, 0x72, 0x18, 0x08, 0x10, 0x64, 0x56, 0x03, 0x30, 0x6c, 0x29, 0x20, 0x72, 0x18, 0x08, 0x10, 0x64, 0x56, 0x03, 0x30,
0x65, 0x73, 0x43, 0x04, 0x30, 0x64, 0x75, 0x63, 0x39, 0x06, 0x6c, 0x65, 0x73, 0x43, 0x04, 0x30, 0x64, 0x75, 0x63, 0x39,
0x00, 0x35, 0x00, 0x01, 0x49, 0x00, 0x00, 0xe2, 0x0a, 0x20, 0x06, 0x00, 0x35, 0x00, 0x01, 0x49, 0x00, 0x00, 0xe1, 0x0a,
0x75, 0x69, 0x13, 0x00, 0x01, 0xa1, 0x07, 0x00, 0x99, 0x00, 0x20, 0x75, 0x69, 0x13, 0x00, 0x01, 0xa1, 0x07, 0x00, 0x99,
0x58, 0x73, 0x74, 0x79, 0x6c, 0x65, 0xca, 0x01, 0x00, 0xa8, 0x00, 0x58, 0x73, 0x74, 0x79, 0x6c, 0x65, 0xca, 0x01, 0x00,
0x01, 0xc0, 0x5f, 0x74, 0x6f, 0x6f, 0x5f, 0x20, 0x68, 0x69, 0xa8, 0x01, 0xc0, 0x5f, 0x74, 0x6f, 0x6f, 0x5f, 0x20, 0x68,
0x67, 0x68, 0x2c, 0x20, 0xe5, 0x00, 0x35, 0x67, 0x68, 0x2c, 0x69, 0x67, 0x68, 0x2c, 0x20, 0xe5, 0x00, 0x35, 0x67, 0x68,
0x92, 0x00, 0x03, 0x3d, 0x02, 0x00, 0x10, 0x03, 0x34, 0x6e, 0x2c, 0x92, 0x00, 0x03, 0x3d, 0x02, 0x00, 0x10, 0x03, 0x34,
0x6f, 0x74, 0x81, 0x01, 0x02, 0xa9, 0x00, 0x01, 0xe9, 0x02, 0x6e, 0x6f, 0x74, 0x81, 0x01, 0x02, 0xa9, 0x00, 0x01, 0xe9,
0x02, 0x6b, 0x03, 0x0b, 0x65, 0x03, 0x50, 0x63, 0x6f, 0x76, 0x02, 0x02, 0x6b, 0x03, 0x0b, 0x65, 0x03, 0x50, 0x63, 0x6f,
0x65, 0x72, 0x44, 0x00, 0x02, 0xa5, 0x07, 0x01, 0xea, 0x01, 0x76, 0x65, 0x72, 0x44, 0x00, 0x02, 0xa5, 0x07, 0x01, 0xea,
0x02, 0xfc, 0x02, 0x06, 0x59, 0x00, 0x50, 0x62, 0x65, 0x63, 0x01, 0x02, 0xfc, 0x02, 0x06, 0x59, 0x00, 0x50, 0x62, 0x65,
0x6f, 0x6d, 0x2f, 0x00, 0x61, 0x72, 0x69, 0x76, 0x69, 0x61, 0x63, 0x6f, 0x6d, 0x2f, 0x00, 0x61, 0x72, 0x69, 0x76, 0x69,
0x6c, 0x3b, 0x04, 0xf0, 0x02, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x61, 0x6c, 0x3b, 0x04, 0xf0, 0x02, 0x6e, 0x73, 0x75, 0x72,
0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x73, 0x6f, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x73,
0x6c, 0x75, 0xeb, 0x01, 0x70, 0x5f, 0x20, 0x0a, 0x4e, 0x6f, 0x6f, 0x6c, 0x75, 0xeb, 0x01, 0x70, 0x5f, 0x20, 0x0a, 0x4e,
0x72, 0x6d, 0x75, 0x03, 0x1c, 0x2c, 0xdc, 0x02, 0x02, 0x3f, 0x6f, 0x72, 0x6d, 0x75, 0x03, 0x1c, 0x2c, 0xdc, 0x02, 0x02,
0x01, 0x00, 0x36, 0x00, 0x01, 0x68, 0x02, 0x00, 0x5e, 0x00, 0x3f, 0x01, 0x00, 0x36, 0x00, 0x01, 0x68, 0x02, 0x00, 0x5e,
0x05, 0x92, 0x09, 0x21, 0x69, 0x74, 0x8c, 0x06, 0x00, 0x0f, 0x00, 0x05, 0x92, 0x09, 0x21, 0x69, 0x74, 0x8c, 0x06, 0x00,
0x06, 0x02, 0x62, 0x0c, 0x21, 0x6f, 0x6e, 0xa5, 0x0b, 0x06, 0x0f, 0x06, 0x02, 0x61, 0x0c, 0x21, 0x6f, 0x6e, 0xa4, 0x0b,
0x5a, 0x00, 0x13, 0x2e, 0xba, 0x0a, 0x12, 0x73, 0xba, 0x08, 0x06, 0x5a, 0x00, 0x13, 0x2e, 0xba, 0x0a, 0x12, 0x73, 0xba,
0x61, 0x61, 0x6d, 0x62, 0x69, 0x67, 0x75, 0x00, 0x0c, 0x12, 0x08, 0x61, 0x61, 0x6d, 0x62, 0x69, 0x67, 0x75, 0xff, 0x0b,
0x65, 0x98, 0x05, 0x01, 0x07, 0x04, 0x1c, 0x62, 0x97, 0x01, 0x12, 0x65, 0x98, 0x05, 0x01, 0x07, 0x04, 0x1c, 0x62, 0x97,
0x05, 0x61, 0x01, 0x00, 0x56, 0x0c, 0xa5, 0x74, 0x6c, 0x65, 0x01, 0x05, 0x61, 0x01, 0x00, 0x55, 0x0c, 0xa5, 0x74, 0x6c,
0x2c, 0x20, 0x73, 0x6f, 0x20, 0x69, 0x66, 0xab, 0x0a, 0x05, 0x65, 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x69, 0x66, 0xab, 0x0a,
0x41, 0x04, 0x00, 0xaf, 0x06, 0x00, 0xce, 0x08, 0x02, 0x9f, 0x05, 0x41, 0x04, 0x00, 0xaf, 0x06, 0x00, 0xce, 0x08, 0x02,
0x0b, 0x62, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x9f, 0x01, 0x9e, 0x0b, 0x62, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x9f,
0x70, 0x72, 0x69, 0x73, 0x6b, 0x20, 0x68, 0x61, 0x8d, 0x08, 0x01, 0x70, 0x72, 0x69, 0x73, 0x6b, 0x20, 0x68, 0x61, 0x8d,
0x06, 0x77, 0x00, 0x04, 0xba, 0x00, 0xb1, 0x2e, 0x20, 0x41, 0x08, 0x06, 0x77, 0x00, 0x04, 0xba, 0x00, 0xb1, 0x2e, 0x20,
0x6c, 0x73, 0x6f, 0x2c, 0x20, 0x66, 0x69, 0x6e, 0x6c, 0x02, 0x41, 0x6c, 0x73, 0x6f, 0x2c, 0x20, 0x66, 0x69, 0x6e, 0x6c,
0x54, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0xf0, 0x07, 0x42, 0x73, 0x02, 0x54, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0xf0, 0x07, 0x42,
0x69, 0x62, 0x6c, 0xc2, 0x00, 0x09, 0xa2, 0x00, 0x20, 0x61, 0x73, 0x69, 0x62, 0x6c, 0xc2, 0x00, 0x09, 0xa2, 0x00, 0x20,
0x6e, 0x9a, 0x02, 0x01, 0x87, 0x07, 0x50, 0x61, 0x6c, 0x20, 0x61, 0x6e, 0x9a, 0x02, 0x01, 0x87, 0x07, 0x50, 0x61, 0x6c,
0x63, 0x68, 0x90, 0x04, 0x30, 0x6e, 0x67, 0x65, 0xd1, 0x03, 0x20, 0x63, 0x68, 0x90, 0x04, 0x30, 0x6e, 0x67, 0x65, 0xd1,
0x02, 0x1c, 0x00, 0x10, 0x76, 0xcb, 0x06, 0x11, 0x64, 0x09, 0x03, 0x02, 0x1c, 0x00, 0x10, 0x76, 0xcb, 0x06, 0x11, 0x64,
0x02, 0x00, 0xcc, 0x03, 0x30, 0x54, 0x75, 0x72, 0x00, 0x05, 0x09, 0x02, 0x00, 0xcc, 0x03, 0x30, 0x54, 0x75, 0x72, 0x00,
0x05, 0x9e, 0x00, 0x03, 0x02, 0x06, 0x00, 0x4f, 0x00, 0x03, 0x05, 0x05, 0x9e, 0x00, 0x03, 0x02, 0x06, 0x00, 0x4f, 0x00,
0x0c, 0x0c, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x75, 0x70, 0x03, 0x0c, 0x0c, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x75,
0x95, 0x00, 0x06, 0x7b, 0x03, 0x50, 0x6e, 0x2e, 0x20, 0x0a, 0x70, 0x95, 0x00, 0x06, 0x7b, 0x03, 0x50, 0x6e, 0x2e, 0x20,
0x00, 0x0a, 0x00,
}; };
const unsigned short help_text_len = 3534; const unsigned short help_text_len = 3533;
const char quick_help_text[] = "Divide the grid into rectangles with areas equal to the numbers."; const char quick_help_text[] = "Divide the grid into rectangles with areas equal to the numbers.";

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2464 comp 1626 ratio 0.659903 level 11 saved 838 */ /* orig 2464 comp 1626 ratio 0.659903 level 11 saved 838 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 3045 comp 1899 ratio 0.623645 level 11 saved 1146 */ /* orig 3045 comp 1899 ratio 0.623645 level 11 saved 1146 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 1385 comp 1059 ratio 0.764621 level 11 saved 326 */ /* orig 1385 comp 1059 ratio 0.764621 level 11 saved 326 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2533 comp 1760 ratio 0.694828 level 11 saved 773 */ /* orig 2533 comp 1760 ratio 0.694828 level 11 saved 773 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2374 comp 1659 ratio 0.698821 level 11 saved 715 */ /* orig 2374 comp 1659 ratio 0.698821 level 11 saved 715 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 6245 comp 3641 ratio 0.583026 level 11 saved 2604 */ /* orig 6245 comp 3641 ratio 0.583026 level 11 saved 2604 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2139 comp 1397 ratio 0.653109 level 11 saved 742 */ /* orig 2139 comp 1397 ratio 0.653109 level 11 saved 742 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 3527 comp 2209 ratio 0.626311 level 11 saved 1318 */ /* orig 3527 comp 2209 ratio 0.626311 level 11 saved 1318 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 1858 comp 1275 ratio 0.686222 level 11 saved 583 */ /* orig 1858 comp 1275 ratio 0.686222 level 11 saved 583 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 2914 comp 1863 ratio 0.639327 level 11 saved 1051 */ /* orig 2914 comp 1863 ratio 0.639327 level 11 saved 1051 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 3275 comp 2117 ratio 0.646412 level 11 saved 1158 */ /* orig 3275 comp 2117 ratio 0.646412 level 11 saved 1158 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 3917 comp 2359 ratio 0.602247 level 11 saved 1558 */ /* orig 3917 comp 2359 ratio 0.602247 level 11 saved 1558 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 1684 comp 1231 ratio 0.730998 level 11 saved 453 */ /* orig 1684 comp 1231 ratio 0.730998 level 11 saved 453 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -1,4 +1,4 @@
/* auto-generated on Aug 16 2017 by genhelp.sh */ /* auto-generated on Oct 23 2017 by genhelp.sh */
/* orig 747 comp 620 ratio 0.829987 level 4 saved 127 */ /* orig 747 comp 620 ratio 0.829987 level 4 saved 127 */
/* DO NOT EDIT! */ /* DO NOT EDIT! */

View file

@ -25,7 +25,7 @@ in puzzles do echo '$#define VER "Version $(Version)"' >> version.h
in puzzles do perl -i -pe 's/Unidentified build/$(Version)/' osx-info.plist in puzzles do perl -i -pe 's/Unidentified build/$(Version)/' osx-info.plist
# First build some local binaries, to run the icon build. # First build some local binaries, to run the icon build.
in puzzles do perl mkfiles.pl -U in puzzles do perl mkfiles.pl -U CFLAGS='-Wwrite-strings -Werror'
in puzzles do make in puzzles do make
# Now build the screenshots and icons. # Now build the screenshots and icons.
@ -45,7 +45,7 @@ in puzzles do ./mkauto.sh
# Build the OS X .dmg archive. # Build the OS X .dmg archive.
delegate osx delegate osx
in puzzles do make -f Makefile.osx clean in puzzles do make -f Makefile.osx clean
in puzzles do make -f Makefile.osx release VER=-DVER=$(Version) in puzzles do make -f Makefile.osx release VER=-DVER=$(Version) XFLAGS='-Wwrite-strings -Werror'
return puzzles/Puzzles.dmg return puzzles/Puzzles.dmg
enddelegate enddelegate
@ -56,7 +56,7 @@ in puzzles do mason.pl --args '{"version":"$(Version)","descfile":"gamedesc.txt"
in puzzles do perl winiss.pl $(Version) gamedesc.txt > puzzles.iss in puzzles do perl winiss.pl $(Version) gamedesc.txt > puzzles.iss
ifneq "$(VISUAL_STUDIO)" "yes" then ifneq "$(VISUAL_STUDIO)" "yes" then
in puzzles with clangcl64 do Platform=x64 make -f Makefile.clangcl clean in puzzles with clangcl64 do Platform=x64 make -f Makefile.clangcl clean
in puzzles with clangcl64 do Platform=x64 make -f Makefile.clangcl VER=-DVER=$(Version) in puzzles with clangcl64 do Platform=x64 make -f Makefile.clangcl VER=-DVER=$(Version) XFLAGS='-Wwrite-strings -Werror'
# Code-sign the binaries, if the local bob config provides a script # Code-sign the binaries, if the local bob config provides a script
# to do so. We assume here that the script accepts an -i option to # to do so. We assume here that the script accepts an -i option to
# provide a 'more info' URL, and an optional -n option to provide a # provide a 'more info' URL, and an optional -n option to provide a
@ -144,7 +144,7 @@ ifneq "$(JAVA_UNFINISHED)" "" in puzzles do perl mkfiles.pl
# Build the Java applets. # Build the Java applets.
delegate nestedvm delegate nestedvm
in puzzles do make -f Makefile.nestedvm NESTEDVM="$$NESTEDVM" VER=-DVER=$(Version) in puzzles do make -f Makefile.nestedvm NESTEDVM="$$NESTEDVM" VER=-DVER=$(Version) XFLAGS="-Wwrite-strings -Werror"
return puzzles/*.jar return puzzles/*.jar
enddelegate enddelegate
@ -154,7 +154,7 @@ enddelegate
in puzzles do mkdir js # so we can tell output .js files from emcc*.js in puzzles do mkdir js # so we can tell output .js files from emcc*.js
delegate emscripten delegate emscripten
in puzzles do make -f Makefile.emcc OUTPREFIX=js/ clean in puzzles do make -f Makefile.emcc OUTPREFIX=js/ clean
in puzzles do make -f Makefile.emcc OUTPREFIX=js/ in puzzles do make -f Makefile.emcc OUTPREFIX=js/ XFLAGS="-Wwrite-strings -Werror"
return puzzles/js/*.js return puzzles/js/*.js
enddelegate enddelegate

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15 from Makefile.am. # Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@ # @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc. # Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,

View file

@ -1,6 +1,6 @@
# generated automatically by aclocal 1.15 -*- Autoconf -*- # generated automatically by aclocal 1.15.1 -*- Autoconf -*-
# Copyright (C) 1996-2014 Free Software Foundation, Inc. # Copyright (C) 1996-2017 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -424,9 +424,9 @@ AC_DEFUN([GTK_CHECK_BACKEND],
fi fi
]) ])
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
dnl serial 11 (pkg-config-0.29.1) # serial 12 (pkg-config-0.29.2)
dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl dnl
@ -467,7 +467,7 @@ dnl
dnl See the "Since" comment for each macro you use to see what version dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require. dnl of the macros you require.
m4_defun([PKG_PREREQ], m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.1]) [m4_define([PKG_MACROS_VERSION], [0.29.2])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ ])dnl PKG_PREREQ
@ -568,7 +568,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no pkg_failed=no
AC_MSG_CHECKING([for $1]) AC_MSG_CHECKING([for $2])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2])
@ -578,11 +578,11 @@ and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.]) See the pkg-config man page for more details.])
if test $pkg_failed = yes; then if test $pkg_failed = yes; then
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED _PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi fi
# Put the nasty error message in config.log where it belongs # Put the nasty error message in config.log where it belongs
@ -599,7 +599,7 @@ installed software in a non-standard prefix.
_PKG_TEXT])[]dnl _PKG_TEXT])[]dnl
]) ])
elif test $pkg_failed = untried; then elif test $pkg_failed = untried; then
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE( m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it [The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full is in your PATH or set the PKG_CONFIG environment variable to the full
@ -700,7 +700,7 @@ AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR ])dnl PKG_CHECK_VAR
# Copyright (C) 2002-2014 Free Software Foundation, Inc. # Copyright (C) 2002-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -715,7 +715,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.15' [am__api_version='1.15'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro. dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.15], [], m4_if([$1], [1.15.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
]) ])
@ -731,14 +731,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.15])dnl [AM_AUTOMAKE_VERSION([1.15.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION], m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*- # AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001-2014 Free Software Foundation, Inc. # Copyright (C) 2001-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -790,7 +790,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
# AM_CONDITIONAL -*- Autoconf -*- # AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2014 Free Software Foundation, Inc. # Copyright (C) 1997-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -821,7 +821,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]]) Usually this means the macro was only invoked conditionally.]])
fi])]) fi])])
# Copyright (C) 1999-2014 Free Software Foundation, Inc. # Copyright (C) 1999-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1012,7 +1012,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*- # Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999-2014 Free Software Foundation, Inc. # Copyright (C) 1999-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1088,7 +1088,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*- # Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996-2014 Free Software Foundation, Inc. # Copyright (C) 1996-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1285,7 +1285,7 @@ for _am_header in $config_headers :; do
done done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001-2014 Free Software Foundation, Inc. # Copyright (C) 2001-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1306,7 +1306,7 @@ if test x"${install_sh+set}" != xset; then
fi fi
AC_SUBST([install_sh])]) AC_SUBST([install_sh])])
# Copyright (C) 2003-2014 Free Software Foundation, Inc. # Copyright (C) 2003-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1327,7 +1327,7 @@ AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*- # Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001-2014 Free Software Foundation, Inc. # Copyright (C) 2001-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1377,7 +1377,7 @@ rm -f confinc confmf
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997-2014 Free Software Foundation, Inc. # Copyright (C) 1997-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1416,7 +1416,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*- # Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001-2014 Free Software Foundation, Inc. # Copyright (C) 2001-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1445,7 +1445,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION], AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Copyright (C) 1999-2014 Free Software Foundation, Inc. # Copyright (C) 1999-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1492,7 +1492,7 @@ AC_LANG_POP([C])])
# For backward compatibility. # For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
# Copyright (C) 2001-2014 Free Software Foundation, Inc. # Copyright (C) 2001-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1511,7 +1511,7 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*- # Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996-2014 Free Software Foundation, Inc. # Copyright (C) 1996-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1592,7 +1592,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file rm -f conftest.file
]) ])
# Copyright (C) 2009-2014 Free Software Foundation, Inc. # Copyright (C) 2009-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1652,7 +1652,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
]) ])
# Copyright (C) 2001-2014 Free Software Foundation, Inc. # Copyright (C) 2001-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1680,7 +1680,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])]) AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006-2014 Free Software Foundation, Inc. # Copyright (C) 2006-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1699,7 +1699,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*- # Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004-2014 Free Software Foundation, Inc. # Copyright (C) 2004-2017 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,

View file

@ -148,14 +148,12 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "No. of balls"; ret[2].name = "No. of balls";
ret[2].type = C_STRING; ret[2].type = C_STRING;
@ -163,13 +161,10 @@ static config_item *game_configure(const game_params *params)
sprintf(buf, "%d", params->minballs); sprintf(buf, "%d", params->minballs);
else else
sprintf(buf, "%d-%d", params->minballs, params->maxballs); sprintf(buf, "%d-%d", params->minballs, params->maxballs);
ret[2].sval = dupstr(buf); ret[2].u.string.sval = dupstr(buf);
ret[2].ival = 0;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -178,17 +173,18 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
/* Allow 'a-b' for a range, otherwise assume a single number. */ /* Allow 'a-b' for a range, otherwise assume a single number. */
if (sscanf(cfg[2].sval, "%d-%d", &ret->minballs, &ret->maxballs) < 2) if (sscanf(cfg[2].u.string.sval, "%d-%d",
ret->minballs = ret->maxballs = atoi(cfg[2].sval); &ret->minballs, &ret->maxballs) < 2)
ret->minballs = ret->maxballs = atoi(cfg[2].u.string.sval);
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 2 || params->h < 2) if (params->w < 2 || params->h < 2)
return "Width and height must both be at least two"; return "Width and height must both be at least two";
@ -253,11 +249,11 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int nballs, dlen = strlen(desc), i; int nballs, dlen = strlen(desc), i;
unsigned char *bmp; unsigned char *bmp;
char *ret; const char *ret;
/* the bitmap is 2+(nballs*2) long; the hex version is double that. */ /* the bitmap is 2+(nballs*2) long; the hex version is double that. */
nballs = ((dlen/2)-2)/2; nballs = ((dlen/2)-2)/2;
@ -464,7 +460,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
return dupstr("S"); return dupstr("S");
} }
@ -904,7 +900,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->cur_x = cx; ui->cur_x = cx;
ui->cur_y = cy; ui->cur_y = cy;
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
if (button == LEFT_BUTTON || button == RIGHT_BUTTON) { if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
@ -914,7 +910,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
wouldflash = 1; wouldflash = 1;
} else if (button == LEFT_RELEASE) { } else if (button == LEFT_RELEASE) {
ui->flash_laser = 0; ui->flash_laser = 0;
return ""; return UI_UPDATE;
} else if (IS_CURSOR_SELECT(button)) { } else if (IS_CURSOR_SELECT(button)) {
if (ui->cur_visible) { if (ui->cur_visible) {
gx = ui->cur_x; gx = ui->cur_x;
@ -923,7 +919,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
wouldflash = 2; wouldflash = 2;
} else { } else {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
/* Fix up 'button' for the below logic. */ /* Fix up 'button' for the below logic. */
if (button == CURSOR_SELECT2) button = RIGHT_BUTTON; if (button == CURSOR_SELECT2) button = RIGHT_BUTTON;
@ -972,9 +968,9 @@ static char *interpret_move(const game_state *state, game_ui *ui,
return nullret; return nullret;
ui->flash_laserno = rangeno; ui->flash_laserno = rangeno;
ui->flash_laser = wouldflash; ui->flash_laser = wouldflash;
nullret = ""; nullret = UI_UPDATE;
if (state->exits[rangeno] != LASER_EMPTY) if (state->exits[rangeno] != LASER_EMPTY)
return ""; return UI_UPDATE;
sprintf(buf, "F%d", rangeno); sprintf(buf, "F%d", rangeno);
break; break;

View file

@ -742,44 +742,40 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Difficulty"; ret[2].name = "Difficulty";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = ":Easy:Medium:Hard"; ret[2].u.choices.choicenames = ":Easy:Medium:Hard";
ret[2].ival = params->difficulty; ret[2].u.choices.selected = params->difficulty;
ret[3].name = "Allow loops"; ret[3].name = "Allow loops";
ret[3].type = C_BOOLEAN; ret[3].type = C_BOOLEAN;
ret[3].sval = NULL; ret[3].u.boolean.bval = params->allowloops;
ret[3].ival = params->allowloops;
ret[4].name = "Max. bridges per direction"; ret[4].name = "Max. bridges per direction";
ret[4].type = C_CHOICES; ret[4].type = C_CHOICES;
ret[4].sval = ":1:2:3:4"; /* keep up-to-date with MAX_BRIDGES */ ret[4].u.choices.choicenames = ":1:2:3:4"; /* keep up-to-date with
ret[4].ival = params->maxb - 1; * MAX_BRIDGES */
ret[4].u.choices.selected = params->maxb - 1;
ret[5].name = "%age of island squares"; ret[5].name = "%age of island squares";
ret[5].type = C_CHOICES; ret[5].type = C_CHOICES;
ret[5].sval = ":5%:10%:15%:20%:25%:30%"; ret[5].u.choices.choicenames = ":5%:10%:15%:20%:25%:30%";
ret[5].ival = (params->islands / 5)-1; ret[5].u.choices.selected = (params->islands / 5)-1;
ret[6].name = "Expansion factor (%age)"; ret[6].name = "Expansion factor (%age)";
ret[6].type = C_CHOICES; ret[6].type = C_CHOICES;
ret[6].sval = ":0%:10%:20%:30%:40%:50%:60%:70%:80%:90%:100%"; ret[6].u.choices.choicenames = ":0%:10%:20%:30%:40%:50%:60%:70%:80%:90%:100%";
ret[6].ival = params->expansion / 10; ret[6].u.choices.selected = params->expansion / 10;
ret[7].name = NULL; ret[7].name = NULL;
ret[7].type = C_END; ret[7].type = C_END;
ret[7].sval = NULL;
ret[7].ival = 0;
return ret; return ret;
} }
@ -788,18 +784,18 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->difficulty = cfg[2].ival; ret->difficulty = cfg[2].u.choices.selected;
ret->allowloops = cfg[3].ival; ret->allowloops = cfg[3].u.boolean.bval;
ret->maxb = cfg[4].ival + 1; ret->maxb = cfg[4].u.choices.selected + 1;
ret->islands = (cfg[5].ival + 1) * 5; ret->islands = (cfg[5].u.choices.selected + 1) * 5;
ret->expansion = cfg[6].ival * 10; ret->expansion = cfg[6].u.choices.selected * 10;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 3 || params->h < 3) if (params->w < 3 || params->h < 3)
return "Width and height must be at least 3"; return "Width and height must be at least 3";
@ -1993,7 +1989,7 @@ generated:
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int i, wh = params->w * params->h; int i, wh = params->w * params->h;
@ -2094,7 +2090,7 @@ static char *ui_cancel_drag(game_ui *ui)
ui->dragx_src = ui->dragy_src = -1; ui->dragx_src = ui->dragy_src = -1;
ui->dragx_dst = ui->dragy_dst = -1; ui->dragx_dst = ui->dragy_dst = -1;
ui->dragging = 0; ui->dragging = 0;
return ""; return UI_UPDATE;
} }
static game_ui *new_ui(const game_state *state) static game_ui *new_ui(const game_state *state)
@ -2282,7 +2278,7 @@ static char *update_drag_dst(const game_state *state, game_ui *ui,
/*debug(("update_drag src (%d,%d) d(%d,%d) dst (%d,%d)\n", /*debug(("update_drag src (%d,%d) d(%d,%d) dst (%d,%d)\n",
ui->dragx_src, ui->dragy_src, dx, dy, ui->dragx_src, ui->dragy_src, dx, dy,
ui->dragx_dst, ui->dragy_dst));*/ ui->dragx_dst, ui->dragy_dst));*/
return ""; return UI_UPDATE;
} }
static char *finish_drag(const game_state *state, game_ui *ui) static char *finish_drag(const game_state *state, game_ui *ui)
@ -2325,7 +2321,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (ggrid & G_ISLAND) { if (ggrid & G_ISLAND) {
ui->dragx_src = gx; ui->dragx_src = gx;
ui->dragy_src = gy; ui->dragy_src = gy;
return ""; return UI_UPDATE;
} else } else
return ui_cancel_drag(ui); return ui_cancel_drag(ui);
} else if (button == LEFT_DRAG || button == RIGHT_DRAG) { } else if (button == LEFT_DRAG || button == RIGHT_DRAG) {
@ -2339,7 +2335,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
/* cancel a drag when we go back to the starting point */ /* cancel a drag when we go back to the starting point */
ui->dragx_dst = -1; ui->dragx_dst = -1;
ui->dragy_dst = -1; ui->dragy_dst = -1;
return ""; return UI_UPDATE;
} }
} else if (button == LEFT_RELEASE || button == RIGHT_RELEASE) { } else if (button == LEFT_RELEASE || button == RIGHT_RELEASE) {
if (ui->dragging) { if (ui->dragging) {
@ -2424,19 +2420,19 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (!dingrid) break; if (!dingrid) break;
} }
if (!oingrid) return ""; if (!oingrid) return UI_UPDATE;
} }
/* not reached */ /* not reached */
found: found:
ui->cur_x = nx; ui->cur_x = nx;
ui->cur_y = ny; ui->cur_y = ny;
return ""; return UI_UPDATE;
} }
} else if (IS_CURSOR_SELECT(button)) { } else if (IS_CURSOR_SELECT(button)) {
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
if (ui->dragging || button == CURSOR_SELECT2) { if (ui->dragging || button == CURSOR_SELECT2) {
ui_cancel_drag(ui); ui_cancel_drag(ui);
@ -2444,7 +2440,7 @@ found:
sprintf(buf, "M%d,%d", ui->cur_x, ui->cur_y); sprintf(buf, "M%d,%d", ui->cur_x, ui->cur_y);
return dupstr(buf); return dupstr(buf);
} else } else
return ""; return UI_UPDATE;
} else { } else {
grid_type v = GRID(state, ui->cur_x, ui->cur_y); grid_type v = GRID(state, ui->cur_x, ui->cur_y);
if (v & G_ISLAND) { if (v & G_ISLAND) {
@ -2453,7 +2449,7 @@ found:
ui->dragy_src = ui->cur_y; ui->dragy_src = ui->cur_y;
ui->dragx_dst = ui->dragy_dst = -1; ui->dragx_dst = ui->dragy_dst = -1;
ui->drag_is_noline = (button == CURSOR_SELECT2) ? 1 : 0; ui->drag_is_noline = (button == CURSOR_SELECT2) ? 1 : 0;
return ""; return UI_UPDATE;
} }
} }
} else if ((button >= '0' && button <= '9') || } else if ((button >= '0' && button <= '9') ||
@ -2471,7 +2467,7 @@ found:
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
for (i = 0; i < state->n_islands; ++i) { for (i = 0; i < state->n_islands; ++i) {
@ -2498,12 +2494,12 @@ found:
if (best_x != -1 && best_y != -1) { if (best_x != -1 && best_y != -1) {
ui->cur_x = best_x; ui->cur_x = best_x;
ui->cur_y = best_y; ui->cur_y = best_y;
return ""; return UI_UPDATE;
} else } else
return NULL; return NULL;
} else if (button == 'g' || button == 'G') { } else if (button == 'g' || button == 'G') {
ui->show_hints = 1 - ui->show_hints; ui->show_hints = 1 - ui->show_hints;
return ""; return UI_UPDATE;
} }
return NULL; return NULL;
@ -2577,7 +2573,7 @@ badmove:
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
char *ret; char *ret;
game_state *solved; game_state *solved;

View file

@ -79,7 +79,7 @@ void free_combi(combi_ctx *combi)
#include <stdio.h> #include <stdio.h>
void fatal(char *fmt, ...) void fatal(const char *fmt, ...)
{ {
abort(); abort();
} }

View file

@ -4,7 +4,7 @@ running configure, to aid debugging if configure makes a mistake.
It was created by puzzles configure 6.66, which was It was created by puzzles configure 6.66, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ ./configure $ ./configure --no-create --no-recursion
## --------- ## ## --------- ##
## Platform. ## ## Platform. ##
@ -12,9 +12,9 @@ generated by GNU Autoconf 2.69. Invocation command line was
hostname = alpha hostname = alpha
uname -m = x86_64 uname -m = x86_64
uname -r = 4.8.4-1-ARCH uname -r = 4.11.9-1-ARCH
uname -s = Linux uname -s = Linux
uname -v = #1 SMP PREEMPT Sat Oct 22 18:26:57 CEST 2016 uname -v = #1 SMP PREEMPT Wed Jul 5 18:23:08 CEST 2017
/usr/bin/uname -p = unknown /usr/bin/uname -p = unknown
/bin/uname -X = unknown /bin/uname -X = unknown
@ -42,11 +42,241 @@ PATH: /usr/bin/core_perl
## Core tests. ## ## Core tests. ##
## ----------- ## ## ----------- ##
configure:1943: checking for a BSD-compatible install
configure:2011: result: /usr/bin/install -c
configure:2022: checking whether build environment is sane
configure:2077: result: yes
configure:2228: checking for a thread-safe mkdir -p
configure:2267: result: /usr/bin/mkdir -p
configure:2274: checking for gawk
configure:2290: found /usr/bin/gawk
configure:2301: result: gawk
configure:2312: checking whether make sets $(MAKE)
configure:2334: result: yes
configure:2363: checking whether make supports nested variables
configure:2380: result: yes
configure:2554: checking for gcc
configure:2570: found /usr/bin/gcc
configure:2581: result: gcc
configure:2810: checking for C compiler version
configure:2819: gcc --version >&5
gcc (GCC) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
configure:2830: $? = 0
configure:2819: gcc -v >&5
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc-multilib/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release --enable-default-pie --enable-default-ssp
Thread model: posix
gcc version 7.2.0 (GCC)
configure:2830: $? = 0
configure:2819: gcc -V >&5
gcc: error: unrecognized command line option '-V'
gcc: fatal error: no input files
compilation terminated.
configure:2830: $? = 1
configure:2819: gcc -qversion >&5
gcc: error: unrecognized command line option '-qversion'; did you mean '--version'?
gcc: fatal error: no input files
compilation terminated.
configure:2830: $? = 1
configure:2850: checking whether the C compiler works
configure:2872: gcc conftest.c >&5
configure:2876: $? = 0
configure:2924: result: yes
configure:2927: checking for C compiler default output file name
configure:2929: result: a.out
configure:2935: checking for suffix of executables
configure:2942: gcc -o conftest conftest.c >&5
configure:2946: $? = 0
configure:2968: result:
configure:2990: checking whether we are cross compiling
configure:2998: gcc -o conftest conftest.c >&5
configure:3002: $? = 0
configure:3009: ./conftest
configure:3013: $? = 0
configure:3028: result: no
configure:3033: checking for suffix of object files
configure:3055: gcc -c conftest.c >&5
configure:3059: $? = 0
configure:3080: result: o
configure:3084: checking whether we are using the GNU C compiler
configure:3103: gcc -c conftest.c >&5
configure:3103: $? = 0
configure:3112: result: yes
configure:3121: checking whether gcc accepts -g
configure:3141: gcc -c -g conftest.c >&5
configure:3141: $? = 0
configure:3182: result: yes
configure:3199: checking for gcc option to accept ISO C89
configure:3262: gcc -c -g -O2 conftest.c >&5
configure:3262: $? = 0
configure:3275: result: none needed
configure:3300: checking whether gcc understands -c and -o together
configure:3322: gcc -c conftest.c -o conftest2.o
configure:3325: $? = 0
configure:3322: gcc -c conftest.c -o conftest2.o
configure:3325: $? = 0
configure:3337: result: yes
configure:3365: checking for style of include used by make
configure:3393: result: GNU
configure:3419: checking dependency style of gcc
configure:3530: result: gcc3
configure:3591: checking for pkg-config
configure:3609: found /usr/bin/pkg-config
configure:3622: result: /usr/bin/pkg-config
configure:3643: checking for GTK+ - version >= 3.0.0
configure:3750: gcc -o conftest -g -O2 -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/harfbuzz -I/usr/include/libdrm -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include conftest.c -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 >&5
configure:3750: $? = 0
configure:3750: ./conftest
configure:3750: $? = 0
configure:3764: result: yes (version 3.22.16)
configure:4287: checking for usable gcc warning flags
configure:4330: gcc -c -g -O2 -Wall -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/harfbuzz -I/usr/include/libdrm -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include conftest.c >&5
configure:4330: $? = 0
configure:4330: gcc -c -g -O2 -Wall -Werror -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/harfbuzz -I/usr/include/libdrm -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include conftest.c >&5
configure:4330: $? = 0
configure:4330: gcc -c -g -O2 -Wall -Werror -std=c89 -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/harfbuzz -I/usr/include/libdrm -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include conftest.c >&5
configure:4330: $? = 0
configure:4330: gcc -c -g -O2 -Wall -Werror -std=c89 -pedantic -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/harfbuzz -I/usr/include/libdrm -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include conftest.c >&5
In file included from /usr/lib/glib-2.0/include/glibconfig.h:9:0,
from /usr/include/glib-2.0/glib/gtypes.h:32,
from /usr/include/glib-2.0/glib/galloca.h:32,
from /usr/include/glib-2.0/glib.h:30,
from /usr/include/gtk-3.0/gdk/gdkconfig.h:13,
from /usr/include/gtk-3.0/gdk/gdk.h:30,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from conftest.c:24:
/usr/include/glib-2.0/glib/gtypes.h: In function '_GLIB_CHECKED_ADD_U64':
/usr/include/glib-2.0/glib/gtypes.h:423:41: error: ISO C90 does not support 'long long' [-Werror=long-long]
G_STATIC_ASSERT(sizeof (unsigned long long) == sizeof (guint64));
^
/usr/include/glib-2.0/glib/gmacros.h:232:104: note: in definition of macro 'G_STATIC_ASSERT'
#define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] G_GNUC_UNUSED
^~~~
In file included from /usr/include/glib-2.0/glib/galloca.h:32:0,
from /usr/include/glib-2.0/glib.h:30,
from /usr/include/gtk-3.0/gdk/gdkconfig.h:13,
from /usr/include/gtk-3.0/gdk/gdk.h:30,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from conftest.c:24:
/usr/include/glib-2.0/glib/gtypes.h:424:58: error: ISO C90 does not support 'long long' [-Werror=long-long]
return !__builtin_uaddll_overflow(a, b, (unsigned long long *) dest); }
^~~~
/usr/include/glib-2.0/glib/gtypes.h: In function '_GLIB_CHECKED_MUL_U64':
/usr/include/glib-2.0/glib/gtypes.h:426:58: error: ISO C90 does not support 'long long' [-Werror=long-long]
return !__builtin_umulll_overflow(a, b, (unsigned long long *) dest); }
^~~~
In file included from /usr/include/glib-2.0/glib.h:62:0,
from /usr/include/gtk-3.0/gdk/gdkconfig.h:13,
from /usr/include/gtk-3.0/gdk/gdk.h:30,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from conftest.c:24:
/usr/include/glib-2.0/glib/gmessages.h: At top level:
/usr/include/glib-2.0/glib/gmessages.h:136:29: error: comma at end of enumerator list [-Werror=pedantic]
G_LOG_WRITER_UNHANDLED = 0,
^
/usr/include/glib-2.0/glib/gmessages.h:322:17: error: anonymous variadic macros were introduced in C99 [-Werror=variadic-macros]
#define g_error(...) G_STMT_START { \
^~~
/usr/include/glib-2.0/glib/gmessages.h:328:19: error: anonymous variadic macros were introduced in C99 [-Werror=variadic-macros]
#define g_message(...) g_log (G_LOG_DOMAIN, \
^~~
/usr/include/glib-2.0/glib/gmessages.h:331:20: error: anonymous variadic macros were introduced in C99 [-Werror=variadic-macros]
#define g_critical(...) g_log (G_LOG_DOMAIN, \
^~~
/usr/include/glib-2.0/glib/gmessages.h:334:19: error: anonymous variadic macros were introduced in C99 [-Werror=variadic-macros]
#define g_warning(...) g_log (G_LOG_DOMAIN, \
^~~
/usr/include/glib-2.0/glib/gmessages.h:337:16: error: anonymous variadic macros were introduced in C99 [-Werror=variadic-macros]
#define g_info(...) g_log (G_LOG_DOMAIN, \
^~~
/usr/include/glib-2.0/glib/gmessages.h:340:17: error: anonymous variadic macros were introduced in C99 [-Werror=variadic-macros]
#define g_debug(...) g_log (G_LOG_DOMAIN, \
^~~
In file included from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:30:0,
from /usr/include/gtk-3.0/gdk/gdk.h:32,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from conftest.c:24:
/usr/include/gtk-3.0/gdk/gdktypes.h:319:39: error: comma at end of enumerator list [-Werror=pedantic]
GDK_MODIFIER_INTENT_DEFAULT_MOD_MASK,
^
/usr/include/gtk-3.0/gdk/gdktypes.h:597:48: error: comma at end of enumerator list [-Werror=pedantic]
GDK_AXIS_FLAG_SLIDER = 1 << GDK_AXIS_SLIDER,
^
In file included from /usr/include/gtk-3.0/gdk/gdkevents.h:36:0,
from /usr/include/gtk-3.0/gdk/gdkdisplay.h:31,
from /usr/include/gtk-3.0/gdk/gdkscreen.h:32,
from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:31,
from /usr/include/gtk-3.0/gdk/gdk.h:32,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from conftest.c:24:
/usr/include/gtk-3.0/gdk/gdkdevicetool.h:61:28: error: comma at end of enumerator list [-Werror=pedantic]
GDK_DEVICE_TOOL_TYPE_LENS,
^
cc1: all warnings being treated as errors
configure:4330: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "puzzles"
| #define PACKAGE_TARNAME "puzzles"
| #define PACKAGE_VERSION "6.66"
| #define PACKAGE_STRING "puzzles 6.66"
| #define PACKAGE_BUGREPORT "anakin@pobox.com"
| #define PACKAGE_URL ""
| #define PACKAGE "puzzles"
| #define VERSION "6.66"
| /* end confdefs.h. */
|
| #include <stdio.h>
| #include <assert.h>
| #include <stdlib.h>
| #include <time.h>
| #include <stdarg.h>
| #include <string.h>
| #include <errno.h>
| #include <math.h>
|
| #include <sys/time.h>
| #include <sys/resource.h>
|
| #include <gtk/gtk.h>
| #include <gdk/gdkkeysyms.h>
|
| #include <gdk-pixbuf/gdk-pixbuf.h>
|
| #include <gdk/gdkx.h>
| #include <X11/Xlib.h>
| #include <X11/Xutil.h>
| #include <X11/Xatom.h>
|
| int
| main ()
| {
|
| return 0;
|
| ;
| return 0;
| }
configure:4337: result: -Wall -Werror -std=c89
configure:4385: checking for ranlib
configure:4401: found /usr/bin/ranlib
configure:4412: result: ranlib
configure:4582: checking that generated files are newer than configure
configure:4588: result: done
configure:4611: creating ./config.status
## ---------------- ## ## ---------------- ##
## Cache variables. ## ## Cache variables. ##
## ---------------- ## ## ---------------- ##
ac_cv_c_compiler_gnu=yes
ac_cv_env_CC_set= ac_cv_env_CC_set=
ac_cv_env_CC_value= ac_cv_env_CC_value=
ac_cv_env_CFLAGS_set= ac_cv_env_CFLAGS_set=
@ -57,33 +287,74 @@ ac_cv_env_LDFLAGS_set=
ac_cv_env_LDFLAGS_value= ac_cv_env_LDFLAGS_value=
ac_cv_env_LIBS_set= ac_cv_env_LIBS_set=
ac_cv_env_LIBS_value= ac_cv_env_LIBS_value=
ac_cv_env_PKG_CONFIG_LIBDIR_set=
ac_cv_env_PKG_CONFIG_LIBDIR_value=
ac_cv_env_PKG_CONFIG_PATH_set=
ac_cv_env_PKG_CONFIG_PATH_value=
ac_cv_env_PKG_CONFIG_set=
ac_cv_env_PKG_CONFIG_value=
ac_cv_env_build_alias_set= ac_cv_env_build_alias_set=
ac_cv_env_build_alias_value= ac_cv_env_build_alias_value=
ac_cv_env_host_alias_set= ac_cv_env_host_alias_set=
ac_cv_env_host_alias_value= ac_cv_env_host_alias_value=
ac_cv_env_target_alias_set= ac_cv_env_target_alias_set=
ac_cv_env_target_alias_value= ac_cv_env_target_alias_value=
ac_cv_objext=o
ac_cv_path_PKG_CONFIG=/usr/bin/pkg-config
ac_cv_path_install='/usr/bin/install -c'
ac_cv_path_mkdir=/usr/bin/mkdir
ac_cv_prog_AWK=gawk
ac_cv_prog_ac_ct_CC=gcc
ac_cv_prog_ac_ct_RANLIB=ranlib
ac_cv_prog_cc_c89=
ac_cv_prog_cc_g=yes
ac_cv_prog_make_make_set=yes
am_cv_CC_dependencies_compiler_type=gcc3
am_cv_make_support_nested_variables=yes
am_cv_prog_cc_c_o=yes
## ----------------- ## ## ----------------- ##
## Output variables. ## ## Output variables. ##
## ----------------- ## ## ----------------- ##
CC='' ACLOCAL='${SHELL} /home/franklin/puzzles/missing aclocal-1.15'
CFLAGS='' AMDEPBACKSLASH='\'
AMDEP_FALSE='#'
AMDEP_TRUE=''
AMTAR='$${TAR-tar}'
AM_BACKSLASH='\'
AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
AM_DEFAULT_VERBOSITY='1'
AM_V='$(V)'
AUTOCONF='${SHELL} /home/franklin/puzzles/missing autoconf'
AUTOHEADER='${SHELL} /home/franklin/puzzles/missing autoheader'
AUTOMAKE='${SHELL} /home/franklin/puzzles/missing automake-1.15'
AWK='gawk'
CC='gcc'
CCDEPMODE='depmode=gcc3'
CFLAGS='-g -O2 -Wall -Werror -std=c89'
CPPFLAGS='' CPPFLAGS=''
DEFS='' CYGPATH_W='echo'
DEFS='-DPACKAGE_NAME=\"puzzles\" -DPACKAGE_TARNAME=\"puzzles\" -DPACKAGE_VERSION=\"6.66\" -DPACKAGE_STRING=\"puzzles\ 6.66\" -DPACKAGE_BUGREPORT=\"anakin@pobox.com\" -DPACKAGE_URL=\"\" -DPACKAGE=\"puzzles\" -DVERSION=\"6.66\"'
DEPDIR='.deps'
ECHO_C='' ECHO_C=''
ECHO_N='-n' ECHO_N='-n'
ECHO_T='' ECHO_T=''
EXEEXT='' EXEEXT=''
INSTALL_DATA='' GTK_CFLAGS='-pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/harfbuzz -I/usr/include/libdrm -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include'
INSTALL_PROGRAM='' GTK_LIBS='-lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0'
INSTALL_SCRIPT='' INSTALL_DATA='${INSTALL} -m 644'
INSTALL_PROGRAM='${INSTALL}'
INSTALL_SCRIPT='${INSTALL}'
INSTALL_STRIP_PROGRAM='$(install_sh) -c -s'
LDFLAGS='' LDFLAGS=''
LIBOBJS='' LIBOBJS=''
LIBS='' LIBS=''
LTLIBOBJS='' LTLIBOBJS=''
OBJEXT='' MAKEINFO='${SHELL} /home/franklin/puzzles/missing makeinfo'
MKDIR_P='/usr/bin/mkdir -p'
OBJEXT='o'
PACKAGE='puzzles'
PACKAGE_BUGREPORT='anakin@pobox.com' PACKAGE_BUGREPORT='anakin@pobox.com'
PACKAGE_NAME='puzzles' PACKAGE_NAME='puzzles'
PACKAGE_STRING='puzzles 6.66' PACKAGE_STRING='puzzles 6.66'
@ -91,28 +362,47 @@ PACKAGE_TARNAME='puzzles'
PACKAGE_URL='' PACKAGE_URL=''
PACKAGE_VERSION='6.66' PACKAGE_VERSION='6.66'
PATH_SEPARATOR=':' PATH_SEPARATOR=':'
RANLIB='' PKG_CONFIG='/usr/bin/pkg-config'
PKG_CONFIG_LIBDIR=''
PKG_CONFIG_PATH=''
RANLIB='ranlib'
SET_MAKE=''
SHELL='/bin/sh' SHELL='/bin/sh'
ac_ct_CC='' STRIP=''
VERSION='6.66'
ac_ct_CC='gcc'
am__EXEEXT_FALSE=''
am__EXEEXT_TRUE='#'
am__fastdepCC_FALSE='#'
am__fastdepCC_TRUE=''
am__include='include'
am__isrc=''
am__leading_dot='.'
am__nodep='_no'
am__quote=''
am__tar='$${TAR-tar} chof - "$$tardir"'
am__untar='$${TAR-tar} xf -'
bindir='${exec_prefix}/bin' bindir='${exec_prefix}/bin'
build_alias='' build_alias=''
datadir='${datarootdir}' datadir='${datarootdir}'
datarootdir='${prefix}/share' datarootdir='${prefix}/share'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
dvidir='${docdir}' dvidir='${docdir}'
exec_prefix='NONE' exec_prefix='${prefix}'
host_alias='' host_alias=''
htmldir='${docdir}' htmldir='${docdir}'
includedir='${prefix}/include' includedir='${prefix}/include'
infodir='${datarootdir}/info' infodir='${datarootdir}/info'
install_sh='${SHELL} /home/franklin/puzzles/install-sh'
libdir='${exec_prefix}/lib' libdir='${exec_prefix}/lib'
libexecdir='${exec_prefix}/libexec' libexecdir='${exec_prefix}/libexec'
localedir='${datarootdir}/locale' localedir='${datarootdir}/locale'
localstatedir='${prefix}/var' localstatedir='${prefix}/var'
mandir='${datarootdir}/man' mandir='${datarootdir}/man'
mkdir_p='$(MKDIR_P)'
oldincludedir='/usr/include' oldincludedir='/usr/include'
pdfdir='${docdir}' pdfdir='${docdir}'
prefix='NONE' prefix='/usr/local'
program_transform_name='s,x,x,' program_transform_name='s,x,x,'
psdir='${docdir}' psdir='${docdir}'
sbindir='${exec_prefix}/sbin' sbindir='${exec_prefix}/sbin'
@ -131,5 +421,25 @@ target_alias=''
#define PACKAGE_STRING "puzzles 6.66" #define PACKAGE_STRING "puzzles 6.66"
#define PACKAGE_BUGREPORT "anakin@pobox.com" #define PACKAGE_BUGREPORT "anakin@pobox.com"
#define PACKAGE_URL "" #define PACKAGE_URL ""
#define PACKAGE "puzzles"
#define VERSION "6.66"
configure: exit 2 configure: exit 0
## ---------------------- ##
## Running config.status. ##
## ---------------------- ##
This file was extended by puzzles config.status 6.66, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES =
CONFIG_HEADERS =
CONFIG_LINKS =
CONFIG_COMMANDS =
$ ./config.status
on alpha
config.status:782: creating Makefile
config.status:954: executing depfiles commands

View file

@ -238,7 +238,7 @@ static game_params *default_params(void)
static int game_fetch_preset(int i, char **name, game_params **params) static int game_fetch_preset(int i, char **name, game_params **params)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
char *str; const char *str;
switch (i) { switch (i) {
case 0: case 0:
@ -489,25 +489,21 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Type of solid"; ret[0].name = "Type of solid";
ret[0].type = C_CHOICES; ret[0].type = C_CHOICES;
ret[0].sval = ":Tetrahedron:Cube:Octahedron:Icosahedron"; ret[0].u.choices.choicenames = ":Tetrahedron:Cube:Octahedron:Icosahedron";
ret[0].ival = params->solid; ret[0].u.choices.selected = params->solid;
ret[1].name = "Width / top"; ret[1].name = "Width / top";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->d1); sprintf(buf, "%d", params->d1);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Height / bottom"; ret[2].name = "Height / bottom";
ret[2].type = C_STRING; ret[2].type = C_STRING;
sprintf(buf, "%d", params->d2); sprintf(buf, "%d", params->d2);
ret[2].sval = dupstr(buf); ret[2].u.string.sval = dupstr(buf);
ret[2].ival = 0;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -516,9 +512,9 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->solid = cfg[0].ival; ret->solid = cfg[0].u.choices.selected;
ret->d1 = atoi(cfg[1].sval); ret->d1 = atoi(cfg[1].u.string.sval);
ret->d2 = atoi(cfg[2].sval); ret->d2 = atoi(cfg[2].u.string.sval);
return ret; return ret;
} }
@ -538,7 +534,7 @@ static void count_grid_square_callback(void *ctx, struct grid_square *sq)
classes[thisclass]++; classes[thisclass]++;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
int classes[5]; int classes[5];
int i; int i;
@ -846,7 +842,7 @@ static struct solid *transform_poly(const struct solid *solid, int flip,
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int area = grid_area(params->d1, params->d2, solids[params->solid]->order); int area = grid_area(params->d1, params->d2, solids[params->solid]->order);
int i, j; int i, j;
@ -1004,7 +1000,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
return NULL; return NULL;
} }

View file

@ -555,16 +555,15 @@ The \cw{config_item} structure contains the following elements:
\c char *name; \c char *name;
\c int type; \c int type;
\c char *sval; \c union { /* type-specific fields */ } u;
\c int ival; \e iiiiiiiiiiiiiiiiiiiiiiiiii
\c{name} is an ASCII string giving the textual label for a GUI \c{name} is an ASCII string giving the textual label for a GUI
control. It is \e{not} expected to be dynamically allocated. control. It is \e{not} expected to be dynamically allocated.
\c{type} contains one of a small number of \c{enum} values defining \c{type} contains one of a small number of \c{enum} values defining
what type of control is being described. The meaning of the \c{sval} what type of control is being described. The usable member of the
and \c{ival} fields depends on the value in \c{type}. The valid union field \c{u} depends on \c{type}. The valid type values are:
values are:
\dt \c{C_STRING} \dt \c{C_STRING}
@ -572,38 +571,64 @@ values are:
input. The back end does not bother informing the front end that the input. The back end does not bother informing the front end that the
box is numeric rather than textual; some front ends do have the box is numeric rather than textual; some front ends do have the
capacity to take this into account, but I decided it wasn't worth capacity to take this into account, but I decided it wasn't worth
the extra complexity in the interface.) For this type, \c{ival} is the extra complexity in the interface.)
unused, and \c{sval} contains a dynamically allocated string
representing the contents of the input box. \lcont{
For controls of this type, \c{u.string} contains a single field
\c char *sval;
which stores a dynamically allocated string representing the contents
of the input box.
}
\dt \c{C_BOOLEAN} \dt \c{C_BOOLEAN}
\dd Describes a simple checkbox. For this type, \c{sval} is unused, \dd Describes a simple checkbox.
and \c{ival} is \cw{TRUE} or \cw{FALSE}.
\lcont{
For controls of this type, \c{u.boolean} contains a single field
\c int bval;
which is either \cw{TRUE} or \cw{FALSE}.
}
\dt \c{C_CHOICES} \dt \c{C_CHOICES}
\dd Describes a drop-down list presenting one of a small number of \dd Describes a drop-down list presenting one of a small number of
fixed choices. For this type, \c{sval} contains a list of strings fixed choices.
describing the choices; the very first character of \c{sval} is used
as a delimiter when processing the rest (so that the strings
\cq{:zero:one:two}, \cq{!zero!one!two} and \cq{xzeroxonextwo} all
define a three-element list containing \cq{zero}, \cq{one} and
\cq{two}). \c{ival} contains the index of the currently selected
element, numbering from zero (so that in the above example, 0 would
mean \cq{zero} and 2 would mean \cq{two}).
\lcont{ \lcont{
Note that for this control type, \c{sval} is \e{not} dynamically For controls of this type, \c{u.choices} contains two fields:
allocated, whereas it was for \c{C_STRING}.
\c const char *choicenames;
\c int selected;
\c{choicenames} contains a list of strings describing the choices. The
very first character of \c{sval} is used as a delimiter when
processing the rest (so that the strings \cq{:zero:one:two},
\cq{!zero!one!two} and \cq{xzeroxonextwo} all define a three-element
list containing \cq{zero}, \cq{one} and \cq{two}).
\c{selected} contains the index of the currently selected element,
numbering from zero (so that in the above example, 0 would mean
\cq{zero} and 2 would mean \cq{two}).
Note that \c{u.choices.choicenames} is \e{not} dynamically allocated,
unlike \c{u.string.sval}.
} }
\dt \c{C_END} \dt \c{C_END}
\dd Marks the end of the array of \c{config_item}s. All other fields \dd Marks the end of the array of \c{config_item}s. There is no
are unused. associated member of the union field \c{u} for this type.
The array returned from this function is expected to have filled in The array returned from this function is expected to have filled in
the initial values of all the controls according to the input the initial values of all the controls according to the input
@ -639,7 +664,8 @@ function is never called and need not do anything at all.
\S{backend-validate-params} \cw{validate_params()} \S{backend-validate-params} \cw{validate_params()}
\c char *(*validate_params)(const game_params *params, int full); \c const char *(*validate_params)(const game_params *params,
\c int full);
This function takes a \c{game_params} structure as input, and checks This function takes a \c{game_params} structure as input, and checks
that the parameters described in it fall within sensible limits. (At that the parameters described in it fall within sensible limits. (At
@ -724,7 +750,8 @@ again in the game description.
\S{backend-validate-desc} \cw{validate_desc()} \S{backend-validate-desc} \cw{validate_desc()}
\c char *(*validate_desc)(const game_params *params, const char *desc); \c const char *(*validate_desc)(const game_params *params,
\c const char *desc);
This function is given a game description, and its job is to This function is given a game description, and its job is to
validate that it describes a puzzle which makes sense. validate that it describes a puzzle which makes sense.
@ -907,10 +934,10 @@ divide mouse coordinates by it.)
in response to the input event; the puzzle was not interested in it in response to the input event; the puzzle was not interested in it
at all. at all.
\b Returning the empty string (\cw{""}) indicates that the input \b Returning the special value \cw{UI_UPDATE} indicates that the input
event has resulted in a change being made to the \c{game_ui} which event has resulted in a change being made to the \c{game_ui} which
will require a redraw of the game window, but that no actual will require a redraw of the game window, but that no actual \e{move}
\e{move} was made (i.e. no new \c{game_state} needs to be created). was made (i.e. no new \c{game_state} needs to be created).
\b Returning anything else indicates that a move was made and that a \b Returning anything else indicates that a move was made and that a
new \c{game_state} must be created. However, instead of actually new \c{game_state} must be created. However, instead of actually
@ -925,7 +952,7 @@ strings can be written to disk when saving the game and fed to
The return value from \cw{interpret_move()} is expected to be The return value from \cw{interpret_move()} is expected to be
dynamically allocated if and only if it is not either \cw{NULL} dynamically allocated if and only if it is not either \cw{NULL}
\e{or} the empty string. \e{or} the special string constant \c{UI_UPDATE}.
After this function is called, the back end is permitted to rely on After this function is called, the back end is permitted to rely on
some subsequent operations happening in sequence: some subsequent operations happening in sequence:
@ -1028,7 +1055,7 @@ not even offer the \q{Solve} menu option.
\S{backend-solve} \cw{solve()} \S{backend-solve} \cw{solve()}
\c char *(*solve)(const game_state *orig, const game_state *curr, \c char *(*solve)(const game_state *orig, const game_state *curr,
\c const char *aux, char **error); \c const char *aux, const char **error);
This function is called when the user selects the \q{Solve} option This function is called when the user selects the \q{Solve} option
from the menu. from the menu.
@ -1934,7 +1961,8 @@ This ensures that thin lines are visible even at small scales.
\S{drawing-draw-text} \cw{draw_text()} \S{drawing-draw-text} \cw{draw_text()}
\c void draw_text(drawing *dr, int x, int y, int fonttype, \c void draw_text(drawing *dr, int x, int y, int fonttype,
\c int fontsize, int align, int colour, char *text); \c int fontsize, int align, int colour,
\c const char *text);
Draws text in the puzzle window. Draws text in the puzzle window.
@ -2095,7 +2123,7 @@ printing routines, that code may safely call \cw{draw_update()}.)
\S{drawing-status-bar} \cw{status_bar()} \S{drawing-status-bar} \cw{status_bar()}
\c void status_bar(drawing *dr, char *text); \c void status_bar(drawing *dr, const char *text);
Sets the text in the game's status bar to \c{text}. The text is copied Sets the text in the game's status bar to \c{text}. The text is copied
from the supplied buffer, so the caller is free to deallocate or from the supplied buffer, so the caller is free to deallocate or
@ -2366,7 +2394,8 @@ function \cw{drawing_new()} (see \k{drawing-new}).
\S{drawingapi-draw-text} \cw{draw_text()} \S{drawingapi-draw-text} \cw{draw_text()}
\c void (*draw_text)(void *handle, int x, int y, int fonttype, \c void (*draw_text)(void *handle, int x, int y, int fonttype,
\c int fontsize, int align, int colour, char *text); \c int fontsize, int align, int colour,
\c const char *text);
This function behaves exactly like the back end \cw{draw_text()} This function behaves exactly like the back end \cw{draw_text()}
function; see \k{drawing-draw-text}. function; see \k{drawing-draw-text}.
@ -2469,7 +2498,7 @@ called unless drawing is attempted.
\S{drawingapi-status-bar} \cw{status_bar()} \S{drawingapi-status-bar} \cw{status_bar()}
\c void (*status_bar)(void *handle, char *text); \c void (*status_bar)(void *handle, const char *text);
This function behaves exactly like the back end \cw{status_bar()} This function behaves exactly like the back end \cw{status_bar()}
function; see \k{drawing-status-bar}. function; see \k{drawing-status-bar}.
@ -3129,8 +3158,8 @@ will probably need to pass it to \cw{midend_set_config}.)
\H{midend-set-config} \cw{midend_set_config()} \H{midend-set-config} \cw{midend_set_config()}
\c char *midend_set_config(midend *me, int which, \c const char *midend_set_config(midend *me, int which,
\c config_item *cfg); \c config_item *cfg);
Passes the mid-end the results of a configuration dialog box. Passes the mid-end the results of a configuration dialog box.
\c{which} should have the same value which it had when \c{which} should have the same value which it had when
@ -3151,7 +3180,7 @@ using \cw{midend_size()} and eventually perform a refresh using
\H{midend-game-id} \cw{midend_game_id()} \H{midend-game-id} \cw{midend_game_id()}
\c char *midend_game_id(midend *me, char *id); \c const char *midend_game_id(midend *me, const char *id);
Passes the mid-end a string game ID (of any of the valid forms Passes the mid-end a string game ID (of any of the valid forms
\cq{params}, \cq{params:description} or \cq{params#seed}) which the \cq{params}, \cq{params:description} or \cq{params#seed}) which the
@ -3219,7 +3248,7 @@ conversion.
\H{midend-solve} \cw{midend_solve()} \H{midend-solve} \cw{midend_solve()}
\c char *midend_solve(midend *me); \c const char *midend_solve(midend *me);
Requests the mid-end to perform a Solve operation. Requests the mid-end to perform a Solve operation.
@ -3267,8 +3296,7 @@ visually activate and deactivate a redo button.
\H{midend-serialise} \cw{midend_serialise()} \H{midend-serialise} \cw{midend_serialise()}
\c void midend_serialise(midend *me, \c void midend_serialise(midend *me,
\c void (*write)(void *ctx, void *buf, int len), \c void (*write)(void *ctx, const void *buf, int len), void *wctx);
\c void *wctx);
Calling this function causes the mid-end to convert its entire Calling this function causes the mid-end to convert its entire
internal state into a long ASCII text string, and to pass that internal state into a long ASCII text string, and to pass that
@ -3291,9 +3319,8 @@ output string.
\H{midend-deserialise} \cw{midend_deserialise()} \H{midend-deserialise} \cw{midend_deserialise()}
\c char *midend_deserialise(midend *me, \c const char *midend_deserialise(midend *me,
\c int (*read)(void *ctx, void *buf, int len), \c int (*read)(void *ctx, void *buf, int len), void *rctx);
\c void *rctx);
This function is the counterpart to \cw{midend_serialise()}. It This function is the counterpart to \cw{midend_serialise()}. It
calls the supplied \cw{read} function repeatedly to read a quantity calls the supplied \cw{read} function repeatedly to read a quantity
@ -3330,9 +3357,8 @@ place.
\H{identify-game} \cw{identify_game()} \H{identify-game} \cw{identify_game()}
\c char *identify_game(char **name, \c const char *identify_game(char **name,
\c int (*read)(void *ctx, void *buf, int len), \c int (*read)(void *ctx, void *buf, int len), void *rctx);
\c void *rctx);
This function examines a serialised midend stream, of the same kind This function examines a serialised midend stream, of the same kind
used by \cw{midend_serialise()} and \cw{midend_deserialise()}, and used by \cw{midend_serialise()} and \cw{midend_deserialise()}, and
@ -3482,7 +3508,7 @@ calling \cw{midend_timer()}.
\H{frontend-fatal} \cw{fatal()} \H{frontend-fatal} \cw{fatal()}
\c void fatal(char *fmt, ...); \c void fatal(const char *fmt, ...);
This is called by some utility functions if they encounter a This is called by some utility functions if they encounter a
genuinely fatal error such as running out of memory. It is a genuinely fatal error such as running out of memory. It is a
@ -3737,10 +3763,10 @@ quite everywhere.)
\c void free_cfg(config_item *cfg); \c void free_cfg(config_item *cfg);
This function correctly frees an array of \c{config_item}s, This function correctly frees an array of \c{config_item}s, including
including walking the array until it gets to the end and freeing walking the array until it gets to the end and freeing any subsidiary
precisely those \c{sval} fields which are expected to be dynamically data items in each \c{u} sub-union which are expected to be
allocated. dynamically allocated.
(See \k{backend-configure} for details of the \c{config_item} (See \k{backend-configure} for details of the \c{config_item}
structure.) structure.)

View file

@ -169,18 +169,14 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Maximum number on dominoes"; ret[0].name = "Maximum number on dominoes";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->n); sprintf(buf, "%d", params->n);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Ensure unique solution"; ret[1].name = "Ensure unique solution";
ret[1].type = C_BOOLEAN; ret[1].type = C_BOOLEAN;
ret[1].sval = NULL; ret[1].u.boolean.bval = params->unique;
ret[1].ival = params->unique;
ret[2].name = NULL; ret[2].name = NULL;
ret[2].type = C_END; ret[2].type = C_END;
ret[2].sval = NULL;
ret[2].ival = 0;
return ret; return ret;
} }
@ -189,13 +185,13 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->n = atoi(cfg[0].sval); ret->n = atoi(cfg[0].u.string.sval);
ret->unique = cfg[1].ival; ret->unique = cfg[1].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->n < 1) if (params->n < 1)
return "Maximum face number must be at least one"; return "Maximum face number must be at least one";
@ -748,12 +744,12 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int n = params->n, w = n+2, h = n+1, wh = w*h; int n = params->n, w = n+2, h = n+1, wh = w*h;
int *occurrences; int *occurrences;
int i, j; int i, j;
char *ret; const char *ret;
ret = NULL; ret = NULL;
occurrences = snewn(n+1, int); occurrences = snewn(n+1, int);
@ -875,7 +871,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
int n = state->params.n, w = n+2, h = n+1, wh = w*h; int n = state->params.n, w = n+2, h = n+1, wh = w*h;
int *placements; int *placements;
@ -1119,7 +1115,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
move_cursor(button, &ui->cur_x, &ui->cur_y, 2*w-1, 2*h-1, 0); move_cursor(button, &ui->cur_x, &ui->cur_y, 2*w-1, 2*h-1, 0);
return ""; return UI_UPDATE;
} else if (IS_CURSOR_SELECT(button)) { } else if (IS_CURSOR_SELECT(button)) {
int d1, d2; int d1, d2;
@ -1152,7 +1148,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} else { } else {
return NULL; return NULL;
} }
return ""; return UI_UPDATE;
} }
return NULL; return NULL;

View file

@ -71,7 +71,7 @@ void drawing_free(drawing *dr)
} }
void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize, void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize,
int align, int colour, char *text) int align, int colour, const char *text)
{ {
dr->api->draw_text(dr->handle, x, y, fonttype, fontsize, align, dr->api->draw_text(dr->handle, x, y, fonttype, fontsize, align,
colour, text); colour, text);
@ -190,7 +190,7 @@ char *text_fallback(drawing *dr, const char *const *strings, int nstrings)
return NULL; /* placate optimiser */ return NULL; /* placate optimiser */
} }
void status_bar(drawing *dr, char *text) void status_bar(drawing *dr, const char *text)
{ {
char *rewritten; char *rewritten;

View file

@ -122,7 +122,7 @@ void get_random_seed(void **randseed, int *randseedsize)
* Fatal error, called in cases of complete despair such as when * Fatal error, called in cases of complete despair such as when
* malloc() has returned NULL. * malloc() has returned NULL.
*/ */
void fatal(char *fmt, ...) void fatal(const char *fmt, ...)
{ {
char buf[512]; char buf[512];
va_list ap; va_list ap;
@ -136,7 +136,7 @@ void fatal(char *fmt, ...)
js_error_box(buf); js_error_box(buf);
} }
void debug_printf(char *fmt, ...) void debug_printf(const char *fmt, ...)
{ {
char buf[512]; char buf[512];
va_list ap; va_list ap;
@ -384,7 +384,8 @@ static void js_unclip(void *handle)
} }
static void js_draw_text(void *handle, int x, int y, int fonttype, static void js_draw_text(void *handle, int x, int y, int fonttype,
int fontsize, int align, int colour, char *text) int fontsize, int align, int colour,
const char *text)
{ {
char fontstyle[80]; char fontstyle[80];
int halign; int halign;
@ -515,7 +516,7 @@ static void js_end_draw(void *handle)
js_canvas_end_draw(); js_canvas_end_draw();
} }
static void js_status_bar(void *handle, char *text) static void js_status_bar(void *handle, const char *text)
{ {
js_canvas_set_statusbar(text); js_canvas_set_statusbar(text);
} }
@ -599,13 +600,14 @@ static void cfg_start(int which)
for (i = 0; cfg[i].type != C_END; i++) { for (i = 0; cfg[i].type != C_END; i++) {
switch (cfg[i].type) { switch (cfg[i].type) {
case C_STRING: case C_STRING:
js_dialog_string(i, cfg[i].name, cfg[i].sval); js_dialog_string(i, cfg[i].name, cfg[i].u.string.sval);
break; break;
case C_BOOLEAN: case C_BOOLEAN:
js_dialog_boolean(i, cfg[i].name, cfg[i].ival); js_dialog_boolean(i, cfg[i].name, cfg[i].u.boolean.bval);
break; break;
case C_CHOICES: case C_CHOICES:
js_dialog_choices(i, cfg[i].name, cfg[i].sval, cfg[i].ival); js_dialog_choices(i, cfg[i].name, cfg[i].u.choices.choicenames,
cfg[i].u.choices.selected);
break; break;
} }
} }
@ -619,12 +621,29 @@ static void cfg_start(int which)
*/ */
void dlg_return_sval(int index, const char *val) void dlg_return_sval(int index, const char *val)
{ {
sfree(cfg[index].sval); config_item *i = cfg + index;
cfg[index].sval = dupstr(val); switch (i->type) {
case C_STRING:
sfree(i->u.string.sval);
i->u.string.sval = dupstr(val);
break;
default:
assert(0 && "Bad type for return_sval");
}
} }
void dlg_return_ival(int index, int val) void dlg_return_ival(int index, int val)
{ {
cfg[index].ival = val; config_item *i = cfg + index;
switch (i->type) {
case C_BOOLEAN:
i->u.boolean.bval = val;
break;
case C_CHOICES:
i->u.choices.selected = val;
break;
default:
assert(0 && "Bad type for return_ival");
}
} }
/* /*
@ -638,7 +657,7 @@ static void cfg_end(int use_results)
/* /*
* User hit OK. * User hit OK.
*/ */
char *err = midend_set_config(me, cfg_which, cfg); const char *err = midend_set_config(me, cfg_which, cfg);
if (err) { if (err) {
/* /*
@ -748,7 +767,7 @@ void command(int n)
break; break;
case 9: /* Solve */ case 9: /* Solve */
if (thegame.can_solve) { if (thegame.can_solve) {
char *msg = midend_solve(me); const char *msg = midend_solve(me);
if (msg) if (msg)
js_error_box(msg); js_error_box(msg);
} }
@ -768,7 +787,7 @@ struct savefile_write_ctx {
size_t pos; size_t pos;
}; };
static void savefile_write(void *vctx, void *buf, int len) static void savefile_write(void *vctx, const void *buf, int len)
{ {
struct savefile_write_ctx *ctx = (struct savefile_write_ctx *)vctx; struct savefile_write_ctx *ctx = (struct savefile_write_ctx *)vctx;
if (ctx->buffer) if (ctx->buffer)
@ -845,7 +864,7 @@ void load_game(const char *buffer, int len)
*/ */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char *param_err; const char *param_err;
float *colours; float *colours;
int i; int i;

View file

@ -111,19 +111,15 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = NULL; ret[2].name = NULL;
ret[2].type = C_END; ret[2].type = C_END;
ret[2].sval = NULL;
ret[2].ival = 0;
return ret; return ret;
} }
@ -132,13 +128,13 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 2 || params->h < 2) if (params->w < 2 || params->h < 2)
return "Width and height must both be at least two"; return "Width and height must both be at least two";
@ -274,10 +270,10 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
const char *p; const char *p;
char *err; const char *err;
int i, area; int i, area;
int *used; int *used;
@ -383,7 +379,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
return dupstr("S"); return dupstr("S");
} }
@ -1130,7 +1126,8 @@ int main(int argc, char **argv)
{ {
game_params *params; game_params *params;
game_state *state; game_state *state;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
int grade = FALSE; int grade = FALSE;
char *progname = argv[0]; char *progname = argv[0];

View file

@ -68,7 +68,7 @@
static unsigned char verbose; static unsigned char verbose;
static void printv(char *fmt, ...) { static void printv(const char *fmt, ...) {
#ifndef PALM #ifndef PALM
if (verbose) { if (verbose) {
va_list va; va_list va;
@ -161,19 +161,15 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = NULL; ret[2].name = NULL;
ret[2].type = C_END; ret[2].type = C_END;
ret[2].sval = NULL;
ret[2].ival = 0;
return ret; return ret;
} }
@ -182,13 +178,13 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 1) return "Width must be at least one"; if (params->w < 1) return "Width must be at least one";
if (params->h < 1) return "Height must be at least one"; if (params->h < 1) return "Height must be at least one";
@ -1270,7 +1266,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return sresize(description, j, char); return sresize(description, j, char);
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
const int sz = params->w * params->h; const int sz = params->w * params->h;
const char m = '0' + max(max(params->w, params->h), 3); const char m = '0' + max(max(params->w, params->h), 3);
@ -1342,7 +1338,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
if (aux == NULL) { if (aux == NULL) {
const int w = state->shared->params.w; const int w = state->shared->params.w;
@ -1449,22 +1445,22 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->sel[w*ty+tx] = 1; ui->sel[w*ty+tx] = 1;
} }
ui->cur_visible = 0; ui->cur_visible = 0;
return ""; /* redraw */ return UI_UPDATE;
} }
if (IS_CURSOR_MOVE(button)) { if (IS_CURSOR_MOVE(button)) {
ui->cur_visible = 1; ui->cur_visible = 1;
move_cursor(button, &ui->cur_x, &ui->cur_y, w, h, 0); move_cursor(button, &ui->cur_x, &ui->cur_y, w, h, 0);
if (ui->keydragging) goto select_square; if (ui->keydragging) goto select_square;
return ""; return UI_UPDATE;
} }
if (button == CURSOR_SELECT) { if (button == CURSOR_SELECT) {
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
ui->keydragging = !ui->keydragging; ui->keydragging = !ui->keydragging;
if (!ui->keydragging) return ""; if (!ui->keydragging) return UI_UPDATE;
select_square: select_square:
if (!ui->sel) { if (!ui->sel) {
@ -1473,12 +1469,12 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} }
if (!state->shared->clues[w*ui->cur_y + ui->cur_x]) if (!state->shared->clues[w*ui->cur_y + ui->cur_x])
ui->sel[w*ui->cur_y + ui->cur_x] = 1; ui->sel[w*ui->cur_y + ui->cur_x] = 1;
return ""; return UI_UPDATE;
} }
if (button == CURSOR_SELECT2) { if (button == CURSOR_SELECT2) {
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
if (!ui->sel) { if (!ui->sel) {
ui->sel = snewn(w*h, int); ui->sel = snewn(w*h, int);
@ -1492,14 +1488,14 @@ static char *interpret_move(const game_state *state, game_ui *ui,
sfree(ui->sel); sfree(ui->sel);
ui->sel = NULL; ui->sel = NULL;
} }
return ""; return UI_UPDATE;
} }
if (button == '\b' || button == 27) { if (button == '\b' || button == 27) {
sfree(ui->sel); sfree(ui->sel);
ui->sel = NULL; ui->sel = NULL;
ui->keydragging = FALSE; ui->keydragging = FALSE;
return ""; return UI_UPDATE;
} }
if (button < '0' || button > '9') return NULL; if (button < '0' || button > '9') return NULL;
@ -1534,7 +1530,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
sfree(ui->sel); sfree(ui->sel);
ui->sel = NULL; ui->sel = NULL;
/* Need to update UI at least, as we cleared the selection */ /* Need to update UI at least, as we cleared the selection */
return move ? move : ""; return move ? move : UI_UPDATE;
} }
static game_state *execute_move(const game_state *state, const char *move) static game_state *execute_move(const game_state *state, const char *move)

View file

@ -149,24 +149,20 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Shape type"; ret[2].name = "Shape type";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = ":Crosses:Random"; ret[2].u.choices.choicenames = ":Crosses:Random";
ret[2].ival = params->matrix_type; ret[2].u.choices.selected = params->matrix_type;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -175,14 +171,14 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->matrix_type = cfg[2].ival; ret->matrix_type = cfg[2].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w <= 0 || params->h <= 0) if (params->w <= 0 || params->h <= 0)
return "Width and height must both be greater than zero"; return "Width and height must both be greater than zero";
@ -596,7 +592,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->w, h = params->h, wh = w * h; int w = params->w, h = params->h, wh = w * h;
int mlen = (wh*wh+3)/4, glen = (wh+3)/4; int mlen = (wh*wh+3)/4, glen = (wh+3)/4;
@ -673,7 +669,7 @@ static void rowxor(unsigned char *row1, unsigned char *row2, int len)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
int w = state->w, h = state->h, wh = w * h; int w = state->w, h = state->h, wh = w * h;
unsigned char *equations, *solution, *shortest; unsigned char *equations, *solution, *shortest;
@ -951,7 +947,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
tx = ui->cx; ty = ui->cy; tx = ui->cx; ty = ui->cy;
ui->cdraw = 1; ui->cdraw = 1;
} }
nullret = ""; nullret = UI_UPDATE;
if (tx >= 0 && tx < w && ty >= 0 && ty < h) { if (tx >= 0 && tx < w && ty >= 0 && ty < h) {
/* /*
@ -985,7 +981,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->cx = min(max(ui->cx, 0), state->w - 1); ui->cx = min(max(ui->cx, 0), state->w - 1);
ui->cy = min(max(ui->cy, 0), state->h - 1); ui->cy = min(max(ui->cy, 0), state->h - 1);
ui->cdraw = 1; ui->cdraw = 1;
nullret = ""; nullret = UI_UPDATE;
} }
return nullret; return nullret;

View file

@ -170,31 +170,25 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Colours"; ret[2].name = "Colours";
ret[2].type = C_STRING; ret[2].type = C_STRING;
sprintf(buf, "%d", params->colours); sprintf(buf, "%d", params->colours);
ret[2].sval = dupstr(buf); ret[2].u.string.sval = dupstr(buf);
ret[2].ival = 0;
ret[3].name = "Extra moves permitted"; ret[3].name = "Extra moves permitted";
ret[3].type = C_STRING; ret[3].type = C_STRING;
sprintf(buf, "%d", params->leniency); sprintf(buf, "%d", params->leniency);
ret[3].sval = dupstr(buf); ret[3].u.string.sval = dupstr(buf);
ret[3].ival = 0;
ret[4].name = NULL; ret[4].name = NULL;
ret[4].type = C_END; ret[4].type = C_END;
ret[4].sval = NULL;
ret[4].ival = 0;
return ret; return ret;
} }
@ -203,15 +197,15 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->colours = atoi(cfg[2].sval); ret->colours = atoi(cfg[2].u.string.sval);
ret->leniency = atoi(cfg[3].sval); ret->leniency = atoi(cfg[3].u.string.sval);
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w * params->h < 2) if (params->w * params->h < 2)
return "Grid must contain at least two squares"; return "Grid must contain at least two squares";
@ -597,7 +591,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return desc; return desc;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->w, h = params->h, wh = w*h; int w = params->w, h = params->h, wh = w*h;
int i; int i;
@ -691,7 +685,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
int w = state->w, h = state->h, wh = w*h; int w = state->w, h = state->h, wh = w*h;
char *moves, *ret, *p; char *moves, *ret, *p;
@ -832,19 +826,19 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} else if (button == CURSOR_LEFT && ui->cx > 0) { } else if (button == CURSOR_LEFT && ui->cx > 0) {
ui->cx--; ui->cx--;
ui->cursor_visible = TRUE; ui->cursor_visible = TRUE;
return ""; return UI_UPDATE;
} else if (button == CURSOR_RIGHT && ui->cx+1 < w) { } else if (button == CURSOR_RIGHT && ui->cx+1 < w) {
ui->cx++; ui->cx++;
ui->cursor_visible = TRUE; ui->cursor_visible = TRUE;
return ""; return UI_UPDATE;
} else if (button == CURSOR_UP && ui->cy > 0) { } else if (button == CURSOR_UP && ui->cy > 0) {
ui->cy--; ui->cy--;
ui->cursor_visible = TRUE; ui->cursor_visible = TRUE;
return ""; return UI_UPDATE;
} else if (button == CURSOR_DOWN && ui->cy+1 < h) { } else if (button == CURSOR_DOWN && ui->cy+1 < h) {
ui->cy++; ui->cy++;
ui->cursor_visible = TRUE; ui->cursor_visible = TRUE;
return ""; return UI_UPDATE;
} else if (button == CURSOR_SELECT) { } else if (button == CURSOR_SELECT) {
tx = ui->cx; tx = ui->cx;
ty = ui->cy; ty = ui->cy;

View file

@ -248,24 +248,20 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Difficulty"; ret[2].name = "Difficulty";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = DIFFCONFIG; ret[2].u.choices.choicenames = DIFFCONFIG;
ret[2].ival = params->diff; ret[2].u.choices.selected = params->diff;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -274,14 +270,14 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->diff = cfg[2].ival; ret->diff = cfg[2].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 3 || params->h < 3) if (params->w < 3 || params->h < 3)
return "Width and height must both be at least 3"; return "Width and height must both be at least 3";
@ -671,7 +667,8 @@ static char *diff_game(const game_state *src, const game_state *dest,
int issolve) int issolve)
{ {
int movelen = 0, movesize = 256, x, y, len; int movelen = 0, movesize = 256, x, y, len;
char *move = snewn(movesize, char), buf[80], *sep = ""; char *move = snewn(movesize, char), buf[80];
const char *sep = "";
char achar = issolve ? 'a' : 'A'; char achar = issolve ? 'a' : 'A';
space *sps, *spd; space *sps, *spd;
@ -1527,10 +1524,10 @@ static int dots_too_close(game_state *state)
} }
static game_state *load_game(const game_params *params, const char *desc, static game_state *load_game(const game_params *params, const char *desc,
char **why_r) const char **why_r)
{ {
game_state *state = blank_game(params->w, params->h); game_state *state = blank_game(params->w, params->h);
char *why = NULL; const char *why = NULL;
int i, x, y, n; int i, x, y, n;
unsigned int df; unsigned int df;
@ -1574,9 +1571,9 @@ fail:
return NULL; return NULL;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
char *why = NULL; const char *why = NULL;
game_state *dummy = load_game(params, desc, &why); game_state *dummy = load_game(params, desc, &why);
if (dummy) { if (dummy) {
free_game(dummy); free_game(dummy);
@ -2258,7 +2255,7 @@ got_result:
#ifndef EDITOR #ifndef EDITOR
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
game_state *tosolve; game_state *tosolve;
char *ret; char *ret;
@ -2553,13 +2550,13 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->dy = y; ui->dy = y;
ui->dotx = dot->x; ui->dotx = dot->x;
ui->doty = dot->y; ui->doty = dot->y;
return ""; return UI_UPDATE;
} }
} else if (button == RIGHT_DRAG && ui->dragging) { } else if (button == RIGHT_DRAG && ui->dragging) {
/* just move the drag coords. */ /* just move the drag coords. */
ui->dx = x; ui->dx = x;
ui->dy = y; ui->dy = y;
return ""; return UI_UPDATE;
} else if (button == RIGHT_RELEASE && ui->dragging) { } else if (button == RIGHT_RELEASE && ui->dragging) {
ui->dragging = FALSE; ui->dragging = FALSE;
@ -2574,7 +2571,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
* is a null move; just update the ui and finish. * is a null move; just update the ui and finish.
*/ */
if (px == ui->srcx && py == ui->srcy) if (px == ui->srcx && py == ui->srcy)
return ""; return UI_UPDATE;
/* /*
* Otherwise, we remove the arrow from its starting * Otherwise, we remove the arrow from its starting
@ -2601,7 +2598,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (buf[0]) if (buf[0])
return dupstr(buf); return dupstr(buf);
else else
return ""; return UI_UPDATE;
} else if (IS_CURSOR_MOVE(button)) { } else if (IS_CURSOR_MOVE(button)) {
move_cursor(button, &ui->cur_x, &ui->cur_y, state->sx-1, state->sy-1, 0); move_cursor(button, &ui->cur_x, &ui->cur_y, state->sx-1, state->sy-1, 0);
if (ui->cur_x < 1) ui->cur_x = 1; if (ui->cur_x < 1) ui->cur_x = 1;
@ -2611,11 +2608,11 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->dx = SCOORD(ui->cur_x); ui->dx = SCOORD(ui->cur_x);
ui->dy = SCOORD(ui->cur_y); ui->dy = SCOORD(ui->cur_y);
} }
return ""; return UI_UPDATE;
} else if (IS_CURSOR_SELECT(button)) { } else if (IS_CURSOR_SELECT(button)) {
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
sp = &SPACE(state, ui->cur_x, ui->cur_y); sp = &SPACE(state, ui->cur_x, ui->cur_y);
if (ui->dragging) { if (ui->dragging) {
@ -2637,7 +2634,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->dy = SCOORD(ui->cur_y); ui->dy = SCOORD(ui->cur_y);
ui->dotx = ui->srcx = ui->cur_x; ui->dotx = ui->srcx = ui->cur_x;
ui->doty = ui->srcy = ui->cur_y; ui->doty = ui->srcy = ui->cur_y;
return ""; return UI_UPDATE;
} else if (sp->flags & F_TILE_ASSOC) { } else if (sp->flags & F_TILE_ASSOC) {
assert(sp->type == s_tile); assert(sp->type == s_tile);
ui->dragging = TRUE; ui->dragging = TRUE;
@ -2647,7 +2644,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->doty = sp->doty; ui->doty = sp->doty;
ui->srcx = ui->cur_x; ui->srcx = ui->cur_x;
ui->srcy = ui->cur_y; ui->srcy = ui->cur_y;
return ""; return UI_UPDATE;
} else if (sp->type == s_edge) { } else if (sp->type == s_edge) {
sprintf(buf, "E%d,%d", ui->cur_x, ui->cur_y); sprintf(buf, "E%d,%d", ui->cur_x, ui->cur_y);
return dupstr(buf); return dupstr(buf);
@ -3775,7 +3772,8 @@ static void soak(game_params *p, random_state *rs)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
game_state *s; game_state *s;
int diff, do_soak = 0, verbose = 0; int diff, do_soak = 0, verbose = 0;
random_state *rs; random_state *rs;

View file

@ -1529,8 +1529,8 @@ static void grid_size_triangular(int width, int height,
*yextent = height * vec_y; *yextent = height * vec_y;
} }
static char *grid_validate_desc_triangular(grid_type type, int width, static const char *grid_validate_desc_triangular(grid_type type, int width,
int height, const char *desc) int height, const char *desc)
{ {
/* /*
* Triangular grids: an absent description is valid (indicating * Triangular grids: an absent description is valid (indicating
@ -2855,8 +2855,9 @@ static char *grid_new_desc_penrose(grid_type type, int width, int height, random
return dupstr(gd); return dupstr(gd);
} }
static char *grid_validate_desc_penrose(grid_type type, int width, int height, static const char *grid_validate_desc_penrose(grid_type type,
const char *desc) int width, int height,
const char *desc)
{ {
int tilesize = PENROSE_TILESIZE, startsz, depth, xoff, yoff, aoff, inner_radius; int tilesize = PENROSE_TILESIZE, startsz, depth, xoff, yoff, aoff, inner_radius;
double outer_radius; double outer_radius;
@ -3032,8 +3033,8 @@ char *grid_new_desc(grid_type type, int width, int height, random_state *rs)
} }
} }
char *grid_validate_desc(grid_type type, int width, int height, const char *grid_validate_desc(grid_type type, int width, int height,
const char *desc) const char *desc)
{ {
if (type == GRID_PENROSE_P2 || type == GRID_PENROSE_P3) { if (type == GRID_PENROSE_P2 || type == GRID_PENROSE_P3) {
return grid_validate_desc_penrose(type, width, height, desc); return grid_validate_desc_penrose(type, width, height, desc);
@ -3048,7 +3049,7 @@ char *grid_validate_desc(grid_type type, int width, int height,
grid *grid_new(grid_type type, int width, int height, const char *desc) grid *grid_new(grid_type type, int width, int height, const char *desc)
{ {
char *err = grid_validate_desc(type, width, height, desc); const char *err = grid_validate_desc(type, width, height, desc);
if (err) assert(!"Invalid grid description."); if (err) assert(!"Invalid grid description.");
return grid_news[type](width, height, desc); return grid_news[type](width, height, desc);

View file

@ -116,8 +116,8 @@ typedef enum grid_type { GRIDGEN_LIST(ENUM) GRID_TYPE_MAX } grid_type;
/* Free directly after use if non-NULL. Will never contain an underscore /* Free directly after use if non-NULL. Will never contain an underscore
* (so clients can safely use that as a separator). */ * (so clients can safely use that as a separator). */
char *grid_new_desc(grid_type type, int width, int height, random_state *rs); char *grid_new_desc(grid_type type, int width, int height, random_state *rs);
char *grid_validate_desc(grid_type type, int width, int height, const char *grid_validate_desc(grid_type type, int width, int height,
const char *desc); const char *desc);
grid *grid_new(grid_type type, int width, int height, const char *desc); grid *grid_new(grid_type type, int width, int height, const char *desc);

View file

@ -71,7 +71,7 @@
#ifdef DEBUGGING #ifdef DEBUGGING
static FILE *debug_fp = NULL; static FILE *debug_fp = NULL;
void dputs(char *buf) void dputs(const char *buf)
{ {
if (!debug_fp) { if (!debug_fp) {
debug_fp = fopen("debug.log", "w"); debug_fp = fopen("debug.log", "w");
@ -85,7 +85,7 @@ void dputs(char *buf)
} }
} }
void debug_printf(char *fmt, ...) void debug_printf(const char *fmt, ...)
{ {
char buf[4096]; char buf[4096];
va_list ap; va_list ap;
@ -101,7 +101,7 @@ void debug_printf(char *fmt, ...)
* Error reporting functions used elsewhere. * Error reporting functions used elsewhere.
*/ */
void fatal(char *fmt, ...) void fatal(const char *fmt, ...)
{ {
va_list ap; va_list ap;
@ -189,6 +189,38 @@ struct frontend {
int drawing_area_shrink_pending; int drawing_area_shrink_pending;
int menubar_is_local; int menubar_is_local;
#endif #endif
#if GTK_CHECK_VERSION(3,0,0)
/*
* This is used to get round an annoying lack of GTK notification
* message. If we request a window resize with
* gtk_window_resize(), we normally get back a "configure" event
* on the window and on its drawing area, and we respond to the
* latter by doing an appropriate resize of the puzzle. If the
* window is maximised, so that gtk_window_resize() _doesn't_
* change its size, then that configure event never shows up. But
* if we requested the resize in response to a change of puzzle
* parameters (say, the user selected a differently-sized preset
* from the menu), then we would still like to be _notified_ that
* the window size was staying the same, so that we can respond by
* choosing an appropriate tile size for the new puzzle preset in
* the existing window size.
*
* Fortunately, in GTK 3, we may not get a "configure" event on
* the drawing area in this situation, but we still get a
* "size_allocate" event on the whole window (which, in other
* situations when we _do_ get a "configure" on the area, turns up
* second). So we treat _that_ event as indicating that if the
* "configure" event hasn't already shown up then it's not going
* to arrive.
*
* This flag is where we bookkeep this system. On
* gtk_window_resize we set this flag to true; the area's
* configure handler sets it back to false; then if that doesn't
* happen, the window's size_allocate handler does a fallback
* puzzle resize when it sees this flag still set to true.
*/
int awaiting_resize_ack;
#endif
}; };
struct blitter { struct blitter {
@ -232,7 +264,7 @@ void frontend_default_colour(frontend *fe, float *output)
#endif #endif
} }
void gtk_status_bar(void *handle, char *text) void gtk_status_bar(void *handle, const char *text)
{ {
frontend *fe = (frontend *)handle; frontend *fe = (frontend *)handle;
@ -968,7 +1000,7 @@ void gtk_unclip(void *handle)
} }
void gtk_draw_text(void *handle, int x, int y, int fonttype, int fontsize, void gtk_draw_text(void *handle, int x, int y, int fonttype, int fontsize,
int align, int colour, char *text) int align, int colour, const char *text)
{ {
frontend *fe = (frontend *)handle; frontend *fe = (frontend *)handle;
int i; int i;
@ -1338,15 +1370,10 @@ static gint map_window(GtkWidget *widget, GdkEvent *event,
return TRUE; return TRUE;
} }
static gint configure_area(GtkWidget *widget, static void resize_puzzle_to_area(frontend *fe, int x, int y)
GdkEventConfigure *event, gpointer data)
{ {
frontend *fe = (frontend *)data;
int x, y;
int oldw = fe->w, oldpw = fe->pw, oldh = fe->h, oldph = fe->ph; int oldw = fe->w, oldpw = fe->pw, oldh = fe->h, oldph = fe->ph;
x = event->width;
y = event->height;
fe->w = x; fe->w = x;
fe->h = y; fe->h = y;
midend_size(fe->me, &x, &y, TRUE); midend_size(fe->me, &x, &y, TRUE);
@ -1363,10 +1390,31 @@ static gint configure_area(GtkWidget *widget,
} }
midend_force_redraw(fe->me); midend_force_redraw(fe->me);
}
static gint configure_area(GtkWidget *widget,
GdkEventConfigure *event, gpointer data)
{
frontend *fe = (frontend *)data;
resize_puzzle_to_area(fe, event->width, event->height);
fe->awaiting_resize_ack = FALSE;
return TRUE; return TRUE;
} }
#if GTK_CHECK_VERSION(3,0,0)
static void window_size_alloc(GtkWidget *widget, GtkAllocation *allocation,
gpointer data)
{
frontend *fe = (frontend *)data;
if (fe->awaiting_resize_ack) {
GtkAllocation a;
gtk_widget_get_allocation(fe->area, &a);
resize_puzzle_to_area(fe, a.width, a.height);
fe->awaiting_resize_ack = FALSE;
}
}
#endif
static gint timer_func(gpointer data) static gint timer_func(gpointer data)
{ {
frontend *fe = (frontend *)data; frontend *fe = (frontend *)data;
@ -1444,8 +1492,8 @@ static void align_label(GtkLabel *label, double x, double y)
} }
#if GTK_CHECK_VERSION(3,0,0) #if GTK_CHECK_VERSION(3,0,0)
int message_box(GtkWidget *parent, char *title, char *msg, int centre, int message_box(GtkWidget *parent, const char *title, const char *msg,
int type) int centre, int type)
{ {
GtkWidget *window; GtkWidget *window;
gint ret; gint ret;
@ -1539,7 +1587,7 @@ int message_box(GtkWidget *parent, char *title, char *msg, int centre,
} }
#endif /* GTK_CHECK_VERSION(3,0,0) */ #endif /* GTK_CHECK_VERSION(3,0,0) */
void error_box(GtkWidget *parent, char *msg) void error_box(GtkWidget *parent, const char *msg)
{ {
message_box(parent, "Error", msg, FALSE, MB_OK); message_box(parent, "Error", msg, FALSE, MB_OK);
} }
@ -1547,7 +1595,7 @@ void error_box(GtkWidget *parent, char *msg)
static void config_ok_button_clicked(GtkButton *button, gpointer data) static void config_ok_button_clicked(GtkButton *button, gpointer data)
{ {
frontend *fe = (frontend *)data; frontend *fe = (frontend *)data;
char *err; const char *err;
err = midend_set_config(fe->me, fe->cfg_which, fe->cfg); err = midend_set_config(fe->me, fe->cfg_which, fe->cfg);
@ -1593,22 +1641,25 @@ static void editbox_changed(GtkEditable *ed, gpointer data)
{ {
config_item *i = (config_item *)data; config_item *i = (config_item *)data;
sfree(i->sval); assert(i->type == C_STRING);
i->sval = dupstr(gtk_entry_get_text(GTK_ENTRY(ed))); sfree(i->u.string.sval);
i->u.string.sval = dupstr(gtk_entry_get_text(GTK_ENTRY(ed)));
} }
static void button_toggled(GtkToggleButton *tb, gpointer data) static void button_toggled(GtkToggleButton *tb, gpointer data)
{ {
config_item *i = (config_item *)data; config_item *i = (config_item *)data;
i->ival = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tb)); assert(i->type == C_BOOLEAN);
i->u.boolean.bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tb));
} }
static void droplist_sel(GtkComboBox *combo, gpointer data) static void droplist_sel(GtkComboBox *combo, gpointer data)
{ {
config_item *i = (config_item *)data; config_item *i = (config_item *)data;
i->ival = gtk_combo_box_get_active(combo); assert(i->type == C_CHOICES);
i->u.choices.selected = gtk_combo_box_get_active(combo);
} }
static int get_config(frontend *fe, int which) static int get_config(frontend *fe, int which)
@ -1703,7 +1754,7 @@ static int get_config(frontend *fe, int which)
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
3, 3); 3, 3);
#endif #endif
gtk_entry_set_text(GTK_ENTRY(w), i->sval); gtk_entry_set_text(GTK_ENTRY(w), i->u.string.sval);
g_signal_connect(G_OBJECT(w), "changed", g_signal_connect(G_OBJECT(w), "changed",
G_CALLBACK(editbox_changed), i); G_CALLBACK(editbox_changed), i);
g_signal_connect(G_OBJECT(w), "key_press_event", g_signal_connect(G_OBJECT(w), "key_press_event",
@ -1728,7 +1779,8 @@ static int get_config(frontend *fe, int which)
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
3, 3); 3, 3);
#endif #endif
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), i->ival); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
i->u.boolean.bval);
gtk_widget_show(w); gtk_widget_show(w);
break; break;
@ -1751,15 +1803,16 @@ static int get_config(frontend *fe, int which)
{ {
int c; int c;
char *p, *q, *name; const char *p, *q;
char *name;
GtkListStore *model; GtkListStore *model;
GtkCellRenderer *cr; GtkCellRenderer *cr;
GtkTreeIter iter; GtkTreeIter iter;
model = gtk_list_store_new(1, G_TYPE_STRING); model = gtk_list_store_new(1, G_TYPE_STRING);
c = *i->sval; c = *i->u.choices.choicenames;
p = i->sval+1; p = i->u.choices.choicenames+1;
while (*p) { while (*p) {
q = p; q = p;
@ -1780,7 +1833,8 @@ static int get_config(frontend *fe, int which)
w = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model)); w = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
gtk_combo_box_set_active(GTK_COMBO_BOX(w), i->ival); gtk_combo_box_set_active(GTK_COMBO_BOX(w),
i->u.choices.selected);
cr = gtk_cell_renderer_text_new(); cr = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(w), cr, TRUE); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(w), cr, TRUE);
@ -1881,8 +1935,7 @@ static void changed_preset(frontend *fe)
struct preset_menu_entry *entry = struct preset_menu_entry *entry =
(struct preset_menu_entry *)g_object_get_data( (struct preset_menu_entry *)g_object_get_data(
G_OBJECT(gs->data), "user-data"); G_OBJECT(gs->data), "user-data");
if (!entry || entry->id != n)
if (entry && entry->id != n)
gtk_check_menu_item_set_active( gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(gs->data), FALSE); GTK_CHECK_MENU_ITEM(gs->data), FALSE);
else else
@ -1890,7 +1943,7 @@ static void changed_preset(frontend *fe)
} }
if (found) if (found)
gtk_check_menu_item_set_active( gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(found->data), FALSE); GTK_CHECK_MENU_ITEM(found->data), TRUE);
} }
fe->preset_threaded = FALSE; fe->preset_threaded = FALSE;
@ -1996,6 +2049,7 @@ static void resize_fe(frontend *fe)
#if GTK_CHECK_VERSION(3,0,0) #if GTK_CHECK_VERSION(3,0,0)
gtk_window_resize(GTK_WINDOW(fe->window), x, y + window_extra_height(fe)); gtk_window_resize(GTK_WINDOW(fe->window), x, y + window_extra_height(fe));
fe->awaiting_resize_ack = TRUE;
#else #else
fe->drawing_area_shrink_pending = FALSE; fe->drawing_area_shrink_pending = FALSE;
gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y); gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y);
@ -2114,7 +2168,7 @@ static void filesel_ok(GtkButton *button, gpointer data)
fe->filesel_name = dupstr(name); fe->filesel_name = dupstr(name);
} }
static char *file_selector(frontend *fe, char *title, int save) static char *file_selector(frontend *fe, const char *title, int save)
{ {
GtkWidget *filesel = GtkWidget *filesel =
gtk_file_selection_new(title); gtk_file_selection_new(title);
@ -2145,7 +2199,7 @@ static char *file_selector(frontend *fe, char *title, int save)
#else #else
static char *file_selector(frontend *fe, char *title, int save) static char *file_selector(frontend *fe, const char *title, int save)
{ {
char *filesel_name = NULL; char *filesel_name = NULL;
@ -2177,7 +2231,7 @@ struct savefile_write_ctx {
int error; int error;
}; };
static void savefile_write(void *wctx, void *buf, int len) static void savefile_write(void *wctx, const void *buf, int len)
{ {
struct savefile_write_ctx *ctx = (struct savefile_write_ctx *)wctx; struct savefile_write_ctx *ctx = (struct savefile_write_ctx *)wctx;
if (fwrite(buf, 1, len, ctx->fp) < len) if (fwrite(buf, 1, len, ctx->fp) < len)
@ -2244,7 +2298,8 @@ static void menu_save_event(GtkMenuItem *menuitem, gpointer data)
static void menu_load_event(GtkMenuItem *menuitem, gpointer data) static void menu_load_event(GtkMenuItem *menuitem, gpointer data)
{ {
frontend *fe = (frontend *)data; frontend *fe = (frontend *)data;
char *name, *err; char *name;
const char *err;
name = file_selector(fe, "Enter name of saved game file to load", FALSE); name = file_selector(fe, "Enter name of saved game file to load", FALSE);
@ -2275,7 +2330,7 @@ static void menu_load_event(GtkMenuItem *menuitem, gpointer data)
static void menu_solve_event(GtkMenuItem *menuitem, gpointer data) static void menu_solve_event(GtkMenuItem *menuitem, gpointer data)
{ {
frontend *fe = (frontend *)data; frontend *fe = (frontend *)data;
char *msg; const char *msg;
msg = midend_solve(fe->me); msg = midend_solve(fe->me);
@ -2341,7 +2396,7 @@ static void menu_about_event(GtkMenuItem *menuitem, gpointer data)
} }
static GtkWidget *add_menu_ui_item( static GtkWidget *add_menu_ui_item(
frontend *fe, GtkContainer *cont, char *text, int action, frontend *fe, GtkContainer *cont, const char *text, int action,
int accel_key, int accel_keyqual) int accel_key, int accel_keyqual)
{ {
GtkWidget *menuitem = gtk_menu_item_new_with_label(text); GtkWidget *menuitem = gtk_menu_item_new_with_label(text);
@ -2434,7 +2489,7 @@ static frontend *new_window(char *arg, int argtype, char **error)
fe->me = midend_new(fe, &thegame, &gtk_drawing, fe); fe->me = midend_new(fe, &thegame, &gtk_drawing, fe);
if (arg) { if (arg) {
char *err; const char *err;
FILE *fp; FILE *fp;
errbuf[0] = '\0'; errbuf[0] = '\0';
@ -2522,6 +2577,10 @@ static frontend *new_window(char *arg, int argtype, char **error)
} }
#endif #endif
#if GTK_CHECK_VERSION(3,0,0)
fe->awaiting_resize_ack = FALSE;
#endif
fe->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); fe->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(fe->window), thegame.name); gtk_window_set_title(GTK_WINDOW(fe->window), thegame.name);
@ -2786,6 +2845,10 @@ static frontend *new_window(char *arg, int argtype, char **error)
G_CALLBACK(configure_area), fe); G_CALLBACK(configure_area), fe);
g_signal_connect(G_OBJECT(fe->window), "configure_event", g_signal_connect(G_OBJECT(fe->window), "configure_event",
G_CALLBACK(configure_window), fe); G_CALLBACK(configure_window), fe);
#if GTK_CHECK_VERSION(3,0,0)
g_signal_connect(G_OBJECT(fe->window), "size_allocate",
G_CALLBACK(window_size_alloc), fe);
#endif
gtk_widget_add_events(GTK_WIDGET(fe->area), gtk_widget_add_events(GTK_WIDGET(fe->area),
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_PRESS_MASK |
@ -2865,7 +2928,7 @@ int main(int argc, char **argv)
int soln = FALSE, colour = FALSE; int soln = FALSE, colour = FALSE;
float scale = 1.0F; float scale = 1.0F;
float redo_proportion = 0.0F; float redo_proportion = 0.0F;
char *savefile = NULL, *savesuffix = NULL; const char *savefile = NULL, *savesuffix = NULL;
char *arg = NULL; char *arg = NULL;
int argtype = ARG_EITHER; int argtype = ARG_EITHER;
char *screenshot_file = NULL; char *screenshot_file = NULL;
@ -3108,7 +3171,8 @@ int main(int argc, char **argv)
* generated descriptive game IDs.) * generated descriptive game IDs.)
*/ */
while (ngenerate == 0 || i < n) { while (ngenerate == 0 || i < n) {
char *pstr, *err, *seed; char *pstr, *seed;
const char *err;
struct rusage before, after; struct rusage before, after;
if (ngenerate == 0) { if (ngenerate == 0) {
@ -3162,7 +3226,7 @@ int main(int argc, char **argv)
* re-entering the same game id, and then try to solve * re-entering the same game id, and then try to solve
* it. * it.
*/ */
char *game_id, *err; char *game_id;
game_id = midend_get_game_id(me); game_id = midend_get_game_id(me);
err = midend_game_id(me, game_id); err = midend_game_id(me, game_id);
@ -3207,7 +3271,7 @@ int main(int argc, char **argv)
sprintf(realname, "%s%d%s", savefile, i, savesuffix); sprintf(realname, "%s%d%s", savefile, i, savesuffix);
if (soln) { if (soln) {
char *err = midend_solve(me); const char *err = midend_solve(me);
if (err) { if (err) {
fprintf(stderr, "%s: unable to show solution: %s\n", fprintf(stderr, "%s: unable to show solution: %s\n",
realname, err); realname, err);

View file

@ -74,7 +74,7 @@ static game_params *dup_params(const game_params *params)
} }
static const struct { static const struct {
char *name; const char *name;
game_params params; game_params params;
} guess_presets[] = { } guess_presets[] = {
{"Standard", {6, 4, 10, FALSE, TRUE}}, {"Standard", {6, 4, 10, FALSE, TRUE}},
@ -166,35 +166,28 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Colours"; ret[0].name = "Colours";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->ncolours); sprintf(buf, "%d", params->ncolours);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Pegs per guess"; ret[1].name = "Pegs per guess";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->npegs); sprintf(buf, "%d", params->npegs);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Guesses"; ret[2].name = "Guesses";
ret[2].type = C_STRING; ret[2].type = C_STRING;
sprintf(buf, "%d", params->nguesses); sprintf(buf, "%d", params->nguesses);
ret[2].sval = dupstr(buf); ret[2].u.string.sval = dupstr(buf);
ret[2].ival = 0;
ret[3].name = "Allow blanks"; ret[3].name = "Allow blanks";
ret[3].type = C_BOOLEAN; ret[3].type = C_BOOLEAN;
ret[3].sval = NULL; ret[3].u.boolean.bval = params->allow_blank;
ret[3].ival = params->allow_blank;
ret[4].name = "Allow duplicates"; ret[4].name = "Allow duplicates";
ret[4].type = C_BOOLEAN; ret[4].type = C_BOOLEAN;
ret[4].sval = NULL; ret[4].u.boolean.bval = params->allow_multiple;
ret[4].ival = params->allow_multiple;
ret[5].name = NULL; ret[5].name = NULL;
ret[5].type = C_END; ret[5].type = C_END;
ret[5].sval = NULL;
ret[5].ival = 0;
return ret; return ret;
} }
@ -203,17 +196,17 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->ncolours = atoi(cfg[0].sval); ret->ncolours = atoi(cfg[0].u.string.sval);
ret->npegs = atoi(cfg[1].sval); ret->npegs = atoi(cfg[1].u.string.sval);
ret->nguesses = atoi(cfg[2].sval); ret->nguesses = atoi(cfg[2].u.string.sval);
ret->allow_blank = cfg[3].ival; ret->allow_blank = cfg[3].u.boolean.bval;
ret->allow_multiple = cfg[4].ival; ret->allow_multiple = cfg[4].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->ncolours < 2 || params->npegs < 2) if (params->ncolours < 2 || params->npegs < 2)
return "Trivial solutions are uninteresting"; return "Trivial solutions are uninteresting";
@ -287,7 +280,7 @@ newcol:
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
unsigned char *bmp; unsigned char *bmp;
int i; int i;
@ -367,7 +360,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
return dupstr("S"); return dupstr("S");
} }
@ -447,7 +440,8 @@ static void free_ui(game_ui *ui)
static char *encode_ui(const game_ui *ui) static char *encode_ui(const game_ui *ui)
{ {
char *ret, *p, *sep; char *ret, *p;
const char *sep;
int i; int i;
/* /*
@ -621,7 +615,8 @@ static int mark_pegs(pegrow guess, const pegrow solution, int ncols)
static char *encode_move(const game_state *from, game_ui *ui) static char *encode_move(const game_state *from, game_ui *ui)
{ {
char *buf, *p, *sep; char *buf, *p;
const char *sep;
int len, i; int len, i;
len = ui->curr_pegs->npegs * 20 + 2; len = ui->curr_pegs->npegs * 20 + 2;
@ -779,7 +774,7 @@ static char *interpret_move(const game_state *from, game_ui *ui,
*/ */
if (button == 'l' || button == 'L') { if (button == 'l' || button == 'L') {
ui->show_labels = !ui->show_labels; ui->show_labels = !ui->show_labels;
return ""; return UI_UPDATE;
} }
if (from->solved) return NULL; if (from->solved) return NULL;
@ -836,13 +831,13 @@ static char *interpret_move(const game_state *from, game_ui *ui,
ui->drag_y = y; ui->drag_y = y;
debug(("Start dragging, col = %d, (%d,%d)", debug(("Start dragging, col = %d, (%d,%d)",
ui->drag_col, ui->drag_x, ui->drag_y)); ui->drag_col, ui->drag_x, ui->drag_y));
ret = ""; ret = UI_UPDATE;
} }
} else if (button == LEFT_DRAG && ui->drag_col) { } else if (button == LEFT_DRAG && ui->drag_col) {
ui->drag_x = x; ui->drag_x = x;
ui->drag_y = y; ui->drag_y = y;
debug(("Keep dragging, (%d,%d)", ui->drag_x, ui->drag_y)); debug(("Keep dragging, (%d,%d)", ui->drag_x, ui->drag_y));
ret = ""; ret = UI_UPDATE;
} else if (button == LEFT_RELEASE && ui->drag_col) { } else if (button == LEFT_RELEASE && ui->drag_col) {
if (over_guess > -1) { if (over_guess > -1) {
debug(("Dropping colour %d onto guess peg %d", debug(("Dropping colour %d onto guess peg %d",
@ -859,13 +854,13 @@ static char *interpret_move(const game_state *from, game_ui *ui,
ui->drag_opeg = -1; ui->drag_opeg = -1;
ui->display_cur = 0; ui->display_cur = 0;
debug(("Stop dragging.")); debug(("Stop dragging."));
ret = ""; ret = UI_UPDATE;
} else if (button == RIGHT_BUTTON) { } else if (button == RIGHT_BUTTON) {
if (over_guess > -1) { if (over_guess > -1) {
/* we use ths feedback in the game_ui to signify /* we use ths feedback in the game_ui to signify
* 'carry this peg to the next guess as well'. */ * 'carry this peg to the next guess as well'. */
ui->holds[over_guess] = 1 - ui->holds[over_guess]; ui->holds[over_guess] = 1 - ui->holds[over_guess];
ret = ""; ret = UI_UPDATE;
} }
} else if (button == LEFT_RELEASE && over_hint && ui->markable) { } else if (button == LEFT_RELEASE && over_hint && ui->markable) {
/* NB this won't trigger if on the end of a drag; that's on /* NB this won't trigger if on the end of a drag; that's on
@ -880,10 +875,10 @@ static char *interpret_move(const game_state *from, game_ui *ui,
ui->colour_cur++; ui->colour_cur++;
if (button == CURSOR_UP && ui->colour_cur > 0) if (button == CURSOR_UP && ui->colour_cur > 0)
ui->colour_cur--; ui->colour_cur--;
ret = ""; ret = UI_UPDATE;
} else if (button == 'h' || button == 'H' || button == '?') { } else if (button == 'h' || button == 'H' || button == '?') {
compute_hint(from, ui); compute_hint(from, ui);
ret = ""; ret = UI_UPDATE;
} else if (button == CURSOR_LEFT || button == CURSOR_RIGHT) { } else if (button == CURSOR_LEFT || button == CURSOR_RIGHT) {
int maxcur = from->params.npegs; int maxcur = from->params.npegs;
if (ui->markable) maxcur++; if (ui->markable) maxcur++;
@ -893,25 +888,25 @@ static char *interpret_move(const game_state *from, game_ui *ui,
ui->peg_cur++; ui->peg_cur++;
if (button == CURSOR_LEFT && ui->peg_cur > 0) if (button == CURSOR_LEFT && ui->peg_cur > 0)
ui->peg_cur--; ui->peg_cur--;
ret = ""; ret = UI_UPDATE;
} else if (IS_CURSOR_SELECT(button)) { } else if (IS_CURSOR_SELECT(button)) {
ui->display_cur = 1; ui->display_cur = 1;
if (ui->peg_cur == from->params.npegs) { if (ui->peg_cur == from->params.npegs) {
ret = encode_move(from, ui); ret = encode_move(from, ui);
} else { } else {
set_peg(&from->params, ui, ui->peg_cur, ui->colour_cur+1); set_peg(&from->params, ui, ui->peg_cur, ui->colour_cur+1);
ret = ""; ret = UI_UPDATE;
} }
} else if (button == 'D' || button == 'd' || button == '\b') { } else if (button == 'D' || button == 'd' || button == '\b') {
ui->display_cur = 1; ui->display_cur = 1;
set_peg(&from->params, ui, ui->peg_cur, 0); set_peg(&from->params, ui, ui->peg_cur, 0);
ret = ""; ret = UI_UPDATE;
} else if (button == CURSOR_SELECT2) { } else if (button == CURSOR_SELECT2) {
if (ui->peg_cur == from->params.npegs) if (ui->peg_cur == from->params.npegs)
return NULL; return NULL;
ui->display_cur = 1; ui->display_cur = 1;
ui->holds[ui->peg_cur] = 1 - ui->holds[ui->peg_cur]; ui->holds[ui->peg_cur] = 1 - ui->holds[ui->peg_cur];
ret = ""; ret = UI_UPDATE;
} }
return ret; return ret;
} }

View file

@ -168,19 +168,15 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = NULL; ret[2].name = NULL;
ret[2].type = C_END; ret[2].type = C_END;
ret[2].sval = NULL;
ret[2].ival = 0;
return ret; return ret;
} }
@ -189,13 +185,13 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
/* /*
* Avoid completely degenerate cases which only have one * Avoid completely degenerate cases which only have one
@ -589,7 +585,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return gengrid(params->w, params->h, rs); return gengrid(params->w, params->h, rs);
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->w, h = params->h, wh = w*h; int w = params->w, h = params->h, wh = w*h;
int starts = 0, gems = 0, i; int starts = 0, gems = 0, i;
@ -733,7 +729,7 @@ static int compare_integers(const void *av, const void *bv)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
int w = currstate->p.w, h = currstate->p.h, wh = w*h; int w = currstate->p.w, h = currstate->p.h, wh = w*h;
int *nodes, *nodeindex, *edges, *backedges, *edgei, *backedgei, *circuit; int *nodes, *nodeindex, *edges, *backedges, *edgei, *backedgei, *circuit;
@ -742,7 +738,8 @@ static char *solve_game(const game_state *state, const game_state *currstate,
int *unvisited; int *unvisited;
int circuitlen, circuitsize; int circuitlen, circuitsize;
int head, tail, pass, i, j, n, x, y, d, dd; int head, tail, pass, i, j, n, x, y, d, dd;
char *err, *soln, *p; const char *err;
char *soln, *p;
/* /*
* Before anything else, deal with the special case in which * Before anything else, deal with the special case in which
@ -1737,7 +1734,8 @@ static game_state *execute_move(const game_state *state, const char *move)
assert(ret->solnpos < ret->soln->len); /* or gems == 0 */ assert(ret->solnpos < ret->soln->len); /* or gems == 0 */
assert(!ret->dead); /* or not a solution */ assert(!ret->dead); /* or not a solution */
} else { } else {
char *error = NULL, *soln = solve_game(NULL, ret, NULL, &error); const char *error = NULL;
char *soln = solve_game(NULL, ret, NULL, &error);
if (!error) { if (!error) {
install_new_solution(ret, soln); install_new_solution(ret, soln);
sfree(soln); sfree(soln);

View file

@ -183,23 +183,19 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Grid size"; ret[0].name = "Grid size";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Difficulty"; ret[1].name = "Difficulty";
ret[1].type = C_CHOICES; ret[1].type = C_CHOICES;
ret[1].sval = DIFFCONFIG; ret[1].u.choices.choicenames = DIFFCONFIG;
ret[1].ival = params->diff; ret[1].u.choices.selected = params->diff;
ret[2].name = "Multiplication only"; ret[2].name = "Multiplication only";
ret[2].type = C_BOOLEAN; ret[2].type = C_BOOLEAN;
ret[2].sval = NULL; ret[2].u.boolean.bval = params->multiplication_only;
ret[2].ival = params->multiplication_only;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -208,14 +204,14 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->diff = cfg[1].ival; ret->diff = cfg[1].u.choices.selected;
ret->multiplication_only = cfg[2].ival; ret->multiplication_only = cfg[2].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 3 || params->w > 9) if (params->w < 3 || params->w > 9)
return "Grid size must be between 3 and 9"; return "Grid size must be between 3 and 9";
@ -731,7 +727,7 @@ static char *encode_block_structure(char *p, int w, int *dsf)
return q; return q;
} }
static char *parse_block_structure(const char **p, int w, int *dsf) static const char *parse_block_structure(const char **p, int w, int *dsf)
{ {
int a = w*w; int a = w*w;
int pos = 0; int pos = 0;
@ -1207,11 +1203,11 @@ done
* Gameplay. * Gameplay.
*/ */
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->w, a = w*w; int w = params->w, a = w*w;
int *dsf; int *dsf;
char *ret; const char *ret;
const char *p = desc; const char *p = desc;
int i; int i;
@ -1349,7 +1345,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
int w = state->par.w, a = w*w; int w = state->par.w, a = w*w;
int i, ret; int i, ret;
@ -1616,7 +1612,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->hpencil = 0; ui->hpencil = 0;
} }
ui->hcursor = 0; ui->hcursor = 0;
return ""; /* UI activity occurred */ return UI_UPDATE;
} }
if (button == RIGHT_BUTTON) { if (button == RIGHT_BUTTON) {
/* /*
@ -1636,19 +1632,19 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->hshow = 0; ui->hshow = 0;
} }
ui->hcursor = 0; ui->hcursor = 0;
return ""; /* UI activity occurred */ return UI_UPDATE;
} }
} }
if (IS_CURSOR_MOVE(button)) { if (IS_CURSOR_MOVE(button)) {
move_cursor(button, &ui->hx, &ui->hy, w, w, 0); move_cursor(button, &ui->hx, &ui->hy, w, w, 0);
ui->hshow = ui->hcursor = 1; ui->hshow = ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
if (ui->hshow && if (ui->hshow &&
(button == CURSOR_SELECT)) { (button == CURSOR_SELECT)) {
ui->hpencil = 1 - ui->hpencil; ui->hpencil = 1 - ui->hpencil;
ui->hcursor = 1; ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
if (ui->hshow && if (ui->hshow &&
@ -2383,7 +2379,8 @@ int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
game_state *s; game_state *s;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
int grade = FALSE; int grade = FALSE;
int ret, diff, really_show_working = FALSE; int ret, diff, really_show_working = FALSE;

View file

@ -73,7 +73,7 @@ void latin_solver_place(struct latin_solver *solver, int x, int y, int n)
int latin_solver_elim(struct latin_solver *solver, int start, int step int latin_solver_elim(struct latin_solver *solver, int start, int step
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
, char *fmt, ... , const char *fmt, ...
#endif #endif
) )
{ {
@ -150,7 +150,7 @@ int latin_solver_set(struct latin_solver *solver,
struct latin_solver_scratch *scratch, struct latin_solver_scratch *scratch,
int start, int step1, int step2 int start, int step1, int step2
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
, char *fmt, ... , const char *fmt, ...
#endif #endif
) )
{ {
@ -499,7 +499,7 @@ int latin_solver_forcing(struct latin_solver *solver,
(xt == x || yt == y)) { (xt == x || yt == y)) {
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
if (solver_show_working) { if (solver_show_working) {
char *sep = ""; const char *sep = "";
int xl, yl; int xl, yl;
printf("%*sforcing chain, %s at ends of ", printf("%*sforcing chain, %s at ends of ",
solver_recurse_depth*4, "", solver_recurse_depth*4, "",
@ -775,7 +775,7 @@ static int latin_solver_recurse
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
if (solver_show_working) { if (solver_show_working) {
char *sep = ""; const char *sep = "";
printf("%*srecursing on (%d,%d) [", printf("%*srecursing on (%d,%d) [",
solver_recurse_depth*4, "", x+1, y+1); solver_recurse_depth*4, "", x+1, y+1);
for (i = 0; i < j; i++) { for (i = 0; i < j; i++) {

View file

@ -39,7 +39,7 @@ void latin_solver_place(struct latin_solver *solver, int x, int y, int n);
/* Positional elimination. */ /* Positional elimination. */
int latin_solver_elim(struct latin_solver *solver, int start, int step int latin_solver_elim(struct latin_solver *solver, int start, int step
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
, char *fmt, ... , const char *fmt, ...
#endif #endif
); );
@ -49,7 +49,7 @@ int latin_solver_set(struct latin_solver *solver,
struct latin_solver_scratch *scratch, struct latin_solver_scratch *scratch,
int start, int step1, int step2 int start, int step1, int step2
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
, char *fmt, ... , const char *fmt, ...
#endif #endif
); );

View file

@ -299,37 +299,32 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "%age of black squares"; ret[2].name = "%age of black squares";
ret[2].type = C_STRING; ret[2].type = C_STRING;
sprintf(buf, "%d", params->blackpc); sprintf(buf, "%d", params->blackpc);
ret[2].sval = dupstr(buf); ret[2].u.string.sval = dupstr(buf);
ret[2].ival = 0;
ret[3].name = "Symmetry"; ret[3].name = "Symmetry";
ret[3].type = C_CHOICES; ret[3].type = C_CHOICES;
ret[3].sval = ":None" ret[3].u.choices.choicenames = ":None"
":2-way mirror:2-way rotational" ":2-way mirror:2-way rotational"
":4-way mirror:4-way rotational"; ":4-way mirror:4-way rotational";
ret[3].ival = params->symm; ret[3].u.choices.selected = params->symm;
ret[4].name = "Difficulty"; ret[4].name = "Difficulty";
ret[4].type = C_CHOICES; ret[4].type = C_CHOICES;
ret[4].sval = ":Easy:Tricky:Hard"; ret[4].u.choices.choicenames = ":Easy:Tricky:Hard";
ret[4].ival = params->difficulty; ret[4].u.choices.selected = params->difficulty;
ret[5].name = NULL; ret[5].name = NULL;
ret[5].type = C_END; ret[5].type = C_END;
ret[5].sval = NULL;
ret[5].ival = 0;
return ret; return ret;
} }
@ -338,16 +333,16 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->blackpc = atoi(cfg[2].sval); ret->blackpc = atoi(cfg[2].u.string.sval);
ret->symm = cfg[3].ival; ret->symm = cfg[3].u.choices.selected;
ret->difficulty = cfg[4].ival; ret->difficulty = cfg[4].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 2 || params->h < 2) if (params->w < 2 || params->h < 2)
return "Width and height must be at least 2"; return "Width and height must be at least 2";
@ -1629,7 +1624,7 @@ goodpuzzle:
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int i; int i;
for (i = 0; i < params->w*params->h; i++) { for (i = 0; i < params->w*params->h; i++) {
@ -1700,7 +1695,7 @@ static game_state *new_game(midend *me, const game_params *params,
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
game_state *solved; game_state *solved;
char *move = NULL, buf[80]; char *move = NULL, buf[80];
@ -1882,7 +1877,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
enum { NONE, FLIP_LIGHT, FLIP_IMPOSSIBLE } action = NONE; enum { NONE, FLIP_LIGHT, FLIP_IMPOSSIBLE } action = NONE;
int cx = -1, cy = -1; int cx = -1, cy = -1;
unsigned int flags; unsigned int flags;
char buf[80], *nullret = NULL, *empty = "", c; char buf[80], *nullret = UI_UPDATE, *empty = UI_UPDATE, c;
if (button == LEFT_BUTTON || button == RIGHT_BUTTON) { if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
if (ui->cur_visible) if (ui->cur_visible)
@ -2331,7 +2326,8 @@ int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
game_state *s; game_state *s;
char *id = NULL, *desc, *err, *result; char *id = NULL, *desc, *result;
const char *err;
int nsol, diff, really_verbose = 0; int nsol, diff, really_verbose = 0;
unsigned int sflags; unsigned int sflags;

View file

@ -232,7 +232,7 @@ struct game_drawstate {
char *clue_satisfied; char *clue_satisfied;
}; };
static char *validate_desc(const game_params *params, const char *desc); static const char *validate_desc(const game_params *params, const char *desc);
static int dot_order(const game_state* state, int i, char line_type); static int dot_order(const game_state* state, int i, char line_type);
static int face_order(const game_state* state, int i, char line_type); static int face_order(const game_state* state, int i, char line_type);
static solver_state *solve_game_rec(const solver_state *sstate); static solver_state *solve_game_rec(const solver_state *sstate);
@ -295,7 +295,7 @@ static grid_type grid_types[] = { GRIDLIST(GRID_GRIDTYPE) };
#define NUM_GRID_TYPES (sizeof(grid_types) / sizeof(grid_types[0])) #define NUM_GRID_TYPES (sizeof(grid_types) / sizeof(grid_types[0]))
static const struct { static const struct {
int amin, omin; int amin, omin;
char *aerr, *oerr; const char *aerr, *oerr;
} grid_size_limits[] = { GRIDLIST(GRID_SIZES) }; } grid_size_limits[] = { GRIDLIST(GRID_SIZES) };
/* Generates a (dynamically allocated) new grid, according to the /* Generates a (dynamically allocated) new grid, according to the
@ -640,29 +640,25 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Grid type"; ret[2].name = "Grid type";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = GRID_CONFIGS; ret[2].u.choices.choicenames = GRID_CONFIGS;
ret[2].ival = params->type; ret[2].u.choices.selected = params->type;
ret[3].name = "Difficulty"; ret[3].name = "Difficulty";
ret[3].type = C_CHOICES; ret[3].type = C_CHOICES;
ret[3].sval = DIFFCONFIG; ret[3].u.choices.choicenames = DIFFCONFIG;
ret[3].ival = params->diff; ret[3].u.choices.selected = params->diff;
ret[4].name = NULL; ret[4].name = NULL;
ret[4].type = C_END; ret[4].type = C_END;
ret[4].sval = NULL;
ret[4].ival = 0;
return ret; return ret;
} }
@ -671,15 +667,15 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->type = cfg[2].ival; ret->type = cfg[2].u.choices.selected;
ret->diff = cfg[3].ival; ret->diff = cfg[3].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->type < 0 || params->type >= NUM_GRID_TYPES) if (params->type < 0 || params->type >= NUM_GRID_TYPES)
return "Illegal grid type"; return "Illegal grid type";
@ -760,11 +756,12 @@ static char *extract_grid_desc(const char **desc)
/* We require that the params pass the test in validate_params and that the /* We require that the params pass the test in validate_params and that the
* description fills the entire game area */ * description fills the entire game area */
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int count = 0; int count = 0;
grid *g; grid *g;
char *grid_desc, *ret; char *grid_desc;
const char *ret;
/* It's pretty inefficient to do this just for validation. All we need to /* It's pretty inefficient to do this just for validation. All we need to
* know is the precise number of faces. */ * know is the precise number of faces. */
@ -2912,7 +2909,7 @@ static solver_state *solve_game_rec(const solver_state *sstate_start)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
char *soln = NULL; char *soln = NULL;
solver_state *sstate, *new_sstate; solver_state *sstate, *new_sstate;
@ -3691,7 +3688,8 @@ int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
game_state *s; game_state *s;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
int grade = FALSE; int grade = FALSE;
int ret, diff; int ret, diff;
#if 0 /* verbose solver not supported here (yet) */ #if 0 /* verbose solver not supported here (yet) */

View file

@ -193,29 +193,24 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Difficulty"; ret[2].name = "Difficulty";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = DIFFCONFIG; ret[2].u.choices.choicenames = DIFFCONFIG;
ret[2].ival = params->diff; ret[2].u.choices.selected = params->diff;
ret[3].name = "Strip clues"; ret[3].name = "Strip clues";
ret[3].type = C_BOOLEAN; ret[3].type = C_BOOLEAN;
ret[3].sval = NULL; ret[3].u.boolean.bval = params->stripclues;
ret[3].ival = params->stripclues;
ret[4].name = NULL; ret[4].name = NULL;
ret[4].type = C_END; ret[4].type = C_END;
ret[4].sval = NULL;
ret[4].ival = 0;
return ret; return ret;
} }
@ -224,15 +219,15 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->diff = cfg[2].ival; ret->diff = cfg[2].u.choices.selected;
ret->stripclues = cfg[3].ival; ret->stripclues = cfg[3].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 2) return "Width must be at least one"; if (params->w < 2) return "Width must be at least one";
if (params->h < 2) return "Height must be at least one"; if (params->h < 2) return "Height must be at least one";
@ -539,7 +534,7 @@ done:
return state; return state;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
const char *prob; const char *prob;
game_state *st = new_game_int(params, desc, &prob); game_state *st = new_game_int(params, desc, &prob);
@ -1455,7 +1450,7 @@ static void solve_from_aux(const game_state *state, const char *aux)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
game_state *solved = dup_game(currstate); game_state *solved = dup_game(currstate);
char *move = NULL; char *move = NULL;
@ -1804,11 +1799,11 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (IS_CURSOR_MOVE(button)) { if (IS_CURSOR_MOVE(button)) {
move_cursor(button, &ui->cur_x, &ui->cur_y, state->w, state->h, 0); move_cursor(button, &ui->cur_x, &ui->cur_y, state->w, state->h, 0);
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} else if (IS_CURSOR_SELECT(button)) { } else if (IS_CURSOR_SELECT(button)) {
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
action = (button == CURSOR_SELECT) ? CYCLE_MAGNET : CYCLE_NEUTRAL; action = (button == CURSOR_SELECT) ? CYCLE_MAGNET : CYCLE_NEUTRAL;
gx = ui->cur_x; gx = ui->cur_x;
@ -1817,7 +1812,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
(button == LEFT_BUTTON || button == RIGHT_BUTTON)) { (button == LEFT_BUTTON || button == RIGHT_BUTTON)) {
if (ui->cur_visible) { if (ui->cur_visible) {
ui->cur_visible = 0; ui->cur_visible = 0;
nullret = ""; nullret = UI_UPDATE;
} }
action = (button == LEFT_BUTTON) ? CYCLE_MAGNET : CYCLE_NEUTRAL; action = (button == LEFT_BUTTON) ? CYCLE_MAGNET : CYCLE_NEUTRAL;
} else if (button == LEFT_BUTTON && is_clue(state, gx, gy)) { } else if (button == LEFT_BUTTON && is_clue(state, gx, gy)) {
@ -2540,7 +2535,8 @@ static void start_soak(game_params *p, random_state *rs)
int main(int argc, const char *argv[]) int main(int argc, const char *argv[])
{ {
int print = 0, soak = 0, solved = 0, ret; int print = 0, soak = 0, solved = 0, ret;
char *id = NULL, *desc, *desc_gen = NULL, *err, *aux = NULL; char *id = NULL, *desc, *desc_gen = NULL, *aux = NULL;
const char *err;
game_state *s = NULL; game_state *s = NULL;
game_params *p = NULL; game_params *p = NULL;
random_state *rs = NULL; random_state *rs = NULL;

View file

@ -213,30 +213,25 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Regions"; ret[2].name = "Regions";
ret[2].type = C_STRING; ret[2].type = C_STRING;
sprintf(buf, "%d", params->n); sprintf(buf, "%d", params->n);
ret[2].sval = dupstr(buf); ret[2].u.string.sval = dupstr(buf);
ret[2].ival = 0;
ret[3].name = "Difficulty"; ret[3].name = "Difficulty";
ret[3].type = C_CHOICES; ret[3].type = C_CHOICES;
ret[3].sval = DIFFCONFIG; ret[3].u.choices.choicenames = DIFFCONFIG;
ret[3].ival = params->diff; ret[3].u.choices.selected = params->diff;
ret[4].name = NULL; ret[4].name = NULL;
ret[4].type = C_END; ret[4].type = C_END;
ret[4].sval = NULL;
ret[4].ival = 0;
return ret; return ret;
} }
@ -245,15 +240,15 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->n = atoi(cfg[2].sval); ret->n = atoi(cfg[2].u.string.sval);
ret->diff = cfg[3].ival; ret->diff = cfg[3].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 2 || params->h < 2) if (params->w < 2 || params->h < 2)
return "Width and height must be at least two"; return "Width and height must be at least two";
@ -878,7 +873,7 @@ static const char colnames[FOUR] = { 'R', 'Y', 'G', 'B' };
static int place_colour(struct solver_scratch *sc, static int place_colour(struct solver_scratch *sc,
int *colouring, int index, int colour int *colouring, int index, int colour
#ifdef SOLVER_DIAGNOSTICS #ifdef SOLVER_DIAGNOSTICS
, char *verb , const char *verb
#endif #endif
) )
{ {
@ -925,7 +920,7 @@ static char *colourset(char *buf, int set)
{ {
int i; int i;
char *p = buf; char *p = buf;
char *sep = ""; const char *sep = "";
for (i = 0; i < FOUR; i++) for (i = 0; i < FOUR; i++)
if (set & (1 << i)) { if (set & (1 << i)) {
@ -1219,7 +1214,8 @@ static int map_solver(struct solver_scratch *sc,
(sc->possible[k] & currc)) { (sc->possible[k] & currc)) {
#ifdef SOLVER_DIAGNOSTICS #ifdef SOLVER_DIAGNOSTICS
if (verbose) { if (verbose) {
char buf[80], *sep = ""; char buf[80];
const char *sep = "";
int r; int r;
printf("%*sforcing chain, colour %s, ", printf("%*sforcing chain, colour %s, ",
@ -1704,8 +1700,8 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return ret; return ret;
} }
static char *parse_edge_list(const game_params *params, const char **desc, static const char *parse_edge_list(const game_params *params,
int *map) const char **desc, int *map)
{ {
int w = params->w, h = params->h, wh = w*h, n = params->n; int w = params->w, h = params->h, wh = w*h, n = params->n;
int i, k, pos, state; int i, k, pos, state;
@ -1781,12 +1777,12 @@ static char *parse_edge_list(const game_params *params, const char **desc,
return NULL; return NULL;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->w, h = params->h, wh = w*h, n = params->n; int w = params->w, h = params->h, wh = w*h, n = params->n;
int area; int area;
int *map; int *map;
char *ret; const char *ret;
map = snewn(2*wh, int); map = snewn(2*wh, int);
ret = parse_edge_list(params, &desc, map); ret = parse_edge_list(params, &desc, map);
@ -1846,7 +1842,7 @@ static game_state *new_game(midend *me, const game_params *params,
p = desc; p = desc;
{ {
char *ret; const char *ret;
ret = parse_edge_list(params, &p, state->map->map); ret = parse_edge_list(params, &p, state->map->map);
assert(!ret); assert(!ret);
} }
@ -2191,7 +2187,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
if (!aux) { if (!aux) {
/* /*
@ -2375,7 +2371,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
*/ */
if (button == 'l' || button == 'L') { if (button == 'l' || button == 'L') {
ui->show_numbers = !ui->show_numbers; ui->show_numbers = !ui->show_numbers;
return ""; return UI_UPDATE;
} }
if (IS_CURSOR_MOVE(button)) { if (IS_CURSOR_MOVE(button)) {
@ -2385,14 +2381,14 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->cur_lastmove = button; ui->cur_lastmove = button;
ui->dragx = COORD(ui->cur_x) + TILESIZE/2 + EPSILON_X(button); ui->dragx = COORD(ui->cur_x) + TILESIZE/2 + EPSILON_X(button);
ui->dragy = COORD(ui->cur_y) + TILESIZE/2 + EPSILON_Y(button); ui->dragy = COORD(ui->cur_y) + TILESIZE/2 + EPSILON_Y(button);
return ""; return UI_UPDATE;
} }
if (IS_CURSOR_SELECT(button)) { if (IS_CURSOR_SELECT(button)) {
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->dragx = COORD(ui->cur_x) + TILESIZE/2 + EPSILON_X(ui->cur_lastmove); ui->dragx = COORD(ui->cur_x) + TILESIZE/2 + EPSILON_X(ui->cur_lastmove);
ui->dragy = COORD(ui->cur_y) + TILESIZE/2 + EPSILON_Y(ui->cur_lastmove); ui->dragy = COORD(ui->cur_y) + TILESIZE/2 + EPSILON_Y(ui->cur_lastmove);
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
if (ui->drag_colour == -2) { /* not currently cursor-dragging, start. */ if (ui->drag_colour == -2) { /* not currently cursor-dragging, start. */
int r = region_from_coords(state, ds, ui->dragx, ui->dragy); int r = region_from_coords(state, ds, ui->dragx, ui->dragy);
@ -2404,7 +2400,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->drag_pencil = 0; ui->drag_pencil = 0;
} }
ui->cur_moved = 0; ui->cur_moved = 0;
return ""; return UI_UPDATE;
} else { /* currently cursor-dragging; drop the colour in the new region. */ } else { /* currently cursor-dragging; drop the colour in the new region. */
x = COORD(ui->cur_x) + TILESIZE/2 + EPSILON_X(ui->cur_lastmove); x = COORD(ui->cur_x) + TILESIZE/2 + EPSILON_X(ui->cur_lastmove);
y = COORD(ui->cur_y) + TILESIZE/2 + EPSILON_Y(ui->cur_lastmove); y = COORD(ui->cur_y) + TILESIZE/2 + EPSILON_Y(ui->cur_lastmove);
@ -2430,14 +2426,14 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->dragx = x; ui->dragx = x;
ui->dragy = y; ui->dragy = y;
ui->cur_visible = 0; ui->cur_visible = 0;
return ""; return UI_UPDATE;
} }
if ((button == LEFT_DRAG || button == RIGHT_DRAG) && if ((button == LEFT_DRAG || button == RIGHT_DRAG) &&
ui->drag_colour > -2) { ui->drag_colour > -2) {
ui->dragx = x; ui->dragx = x;
ui->dragy = y; ui->dragy = y;
return ""; return UI_UPDATE;
} }
if ((button == LEFT_RELEASE || button == RIGHT_RELEASE) && if ((button == LEFT_RELEASE || button == RIGHT_RELEASE) &&
@ -2461,18 +2457,18 @@ drag_dropped:
ui->drag_colour = -2; ui->drag_colour = -2;
if (r < 0) if (r < 0)
return ""; /* drag into border; do nothing else */ return UI_UPDATE; /* drag into border; do nothing else */
if (state->map->immutable[r]) if (state->map->immutable[r])
return ""; /* can't change this region */ return UI_UPDATE; /* can't change this region */
if (state->colouring[r] == c && state->pencil[r] == p) if (state->colouring[r] == c && state->pencil[r] == p)
return ""; /* don't _need_ to change this region */ return UI_UPDATE; /* don't _need_ to change this region */
if (alt_button) { if (alt_button) {
if (state->colouring[r] >= 0) { if (state->colouring[r] >= 0) {
/* Can't pencil on a coloured region */ /* Can't pencil on a coloured region */
return ""; return UI_UPDATE;
} else if (c >= 0) { } else if (c >= 0) {
/* Right-dragging from colour to blank toggles one pencil */ /* Right-dragging from colour to blank toggles one pencil */
p = state->pencil[r] ^ (1 << c); p = state->pencil[r] ^ (1 << c);
@ -3240,7 +3236,8 @@ int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
game_state *s; game_state *s;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
int grade = FALSE; int grade = FALSE;
int ret, diff, really_verbose = FALSE; int ret, diff, really_verbose = FALSE;
struct solver_scratch *sc; struct solver_scratch *sc;

View file

@ -80,7 +80,7 @@ int maxflow_with_scratch(void *scratch, int nv, int source, int sink,
/* /*
* Now do the BFS loop. * Now do the BFS loop.
*/ */
while (head < tail && prev[sink] <= 0) { while (head < tail && prev[sink] < 0) {
from = todo[head++]; from = todo[head++];
/* /*

View file

@ -63,6 +63,9 @@ struct midend {
int nstates, statesize, statepos; int nstates, statesize, statepos;
struct midend_state_entry *states; struct midend_state_entry *states;
char *newgame_undo_buf;
int newgame_undo_len, newgame_undo_size;
game_params *params, *curparams; game_params *params, *curparams;
game_drawstate *drawstate; game_drawstate *drawstate;
game_ui *ui; game_ui *ui;
@ -94,6 +97,30 @@ struct midend {
} \ } \
} while (0) } while (0)
/*
* Structure storing all the decoded data from reading a serialised
* game. We keep it in one of these while we check its sanity, and
* only once we're completely satisfied do we install it all in the
* midend structure proper.
*/
struct deserialise_data {
char *seed, *parstr, *desc, *privdesc;
char *auxinfo, *uistr, *cparstr;
float elapsed;
game_params *params, *cparams;
game_ui *ui;
struct midend_state_entry *states;
int nstates, statepos;
};
/*
* Forward reference.
*/
static const char *midend_deserialise_internal(
midend *me, int (*read)(void *ctx, void *buf, int len), void *rctx,
const char *(*check)(void *ctx, midend *, const struct deserialise_data *),
void *cctx);
void midend_reset_tilesize(midend *me) void midend_reset_tilesize(midend *me)
{ {
me->preferred_tilesize = me->ourgame->preferred_tilesize; me->preferred_tilesize = me->ourgame->preferred_tilesize;
@ -131,6 +158,8 @@ midend *midend_new(frontend *fe, const game *ourgame,
me->random = random_new(randseed, randseedsize); me->random = random_new(randseed, randseedsize);
me->nstates = me->statesize = me->statepos = 0; me->nstates = me->statesize = me->statepos = 0;
me->states = NULL; me->states = NULL;
me->newgame_undo_buf = NULL;
me->newgame_undo_size = me->newgame_undo_len = 0;
me->params = ourgame->default_params(); me->params = ourgame->default_params();
me->game_id_change_notify_function = NULL; me->game_id_change_notify_function = NULL;
me->game_id_change_notify_ctx = NULL; me->game_id_change_notify_ctx = NULL;
@ -228,6 +257,7 @@ void midend_free(midend *me)
if (me->drawing) if (me->drawing)
drawing_free(me->drawing); drawing_free(me->drawing);
random_free(me->random); random_free(me->random);
sfree(me->newgame_undo_buf);
sfree(me->states); sfree(me->states);
sfree(me->desc); sfree(me->desc);
sfree(me->privdesc); sfree(me->privdesc);
@ -354,8 +384,40 @@ void midend_force_redraw(midend *me)
midend_redraw(me); midend_redraw(me);
} }
static void newgame_serialise_write(void *ctx, const void *buf, int len)
{
midend *const me = ctx;
int new_len;
assert(len < INT_MAX - me->newgame_undo_len);
new_len = me->newgame_undo_len + len;
if (new_len > me->newgame_undo_size) {
me->newgame_undo_size = new_len + new_len / 4 + 1024;
me->newgame_undo_buf = sresize(me->newgame_undo_buf,
me->newgame_undo_size, char);
}
memcpy(me->newgame_undo_buf + me->newgame_undo_len, buf, len);
me->newgame_undo_len = new_len;
}
void midend_new_game(midend *me) void midend_new_game(midend *me)
{ {
me->newgame_undo_len = 0;
if (me->nstates != 0) {
/*
* Serialise the whole of the game that we're about to
* supersede, so that the 'New Game' action can be undone
* later. But if nstates == 0, that means there _isn't_ a
* current game (not even a starting position), because this
* is the initial call to midend_new_game when the midend is
* first set up; in that situation, we want to avoid writing
* out any serialisation, because it would be useless anyway
* and just confuse us into thinking we had something to undo
* to.
*/
midend_serialise(me, newgame_serialise_write, me);
}
midend_stop_anim(me); midend_stop_anim(me);
midend_free_game(me); midend_free_game(me);
@ -434,7 +496,8 @@ void midend_new_game(midend *me)
*/ */
if (me->ourgame->can_solve && me->aux_info) { if (me->ourgame->can_solve && me->aux_info) {
game_state *s; game_state *s;
char *msg, *movestr; const char *msg;
char *movestr;
msg = NULL; msg = NULL;
movestr = me->ourgame->solve(me->states[0].state, movestr = me->ourgame->solve(me->states[0].state,
@ -469,7 +532,7 @@ void midend_new_game(midend *me)
int midend_can_undo(midend *me) int midend_can_undo(midend *me)
{ {
return (me->statepos > 1); return (me->statepos > 1 || me->newgame_undo_len);
} }
int midend_can_redo(midend *me) int midend_can_redo(midend *me)
@ -477,8 +540,82 @@ int midend_can_redo(midend *me)
return (me->statepos < me->nstates); return (me->statepos < me->nstates);
} }
struct newgame_undo_deserialise_read_ctx {
midend *me;
int len, pos;
};
static int newgame_undo_deserialise_read(void *ctx, void *buf, int len)
{
struct newgame_undo_deserialise_read_ctx *const rctx = ctx;
midend *const me = rctx->me;
int use = min(len, rctx->len - rctx->pos);
memcpy(buf, me->newgame_undo_buf + rctx->pos, use);
rctx->pos += use;
return use;
}
struct newgame_undo_deserialise_check_ctx {
int refused;
};
static const char *newgame_undo_deserialise_check(
void *vctx, midend *me, const struct deserialise_data *data)
{
struct newgame_undo_deserialise_check_ctx *ctx =
(struct newgame_undo_deserialise_check_ctx *)vctx;
char *old, *new;
/*
* Undoing a New Game operation is only permitted if it doesn't
* change the game parameters. The point of having the ability at
* all is to recover from the momentary finger error of having hit
* the 'n' key (perhaps in place of some other nearby key), or hit
* the New Game menu item by mistake when aiming for the adjacent
* Restart; in both those situations, the game params are the same
* before and after the new-game operation.
*
* In principle, we could generalise this so that _any_ call to
* midend_new_game could be undone, but that would need all front
* ends to be alert to the possibility that any keystroke passed
* to midend_process_key might (if it turns out to have been one
* of the synonyms for undo, which the frontend doesn't
* necessarily check for) have various knock-on effects like
* needing to select a different preset in the game type menu, or
* even resizing the window. At least for the moment, it's easier
* not to do that, and to simply disallow any newgame-undo that is
* disruptive in either of those ways.
*
* We check both params and cparams, to be as safe as possible.
*/
old = me->ourgame->encode_params(me->params, TRUE);
new = me->ourgame->encode_params(data->params, TRUE);
if (strcmp(old, new)) {
/* Set a flag to distinguish this deserialise failure
* from one due to faulty decoding */
ctx->refused = TRUE;
return "Undoing this new-game operation would change params";
}
old = me->ourgame->encode_params(me->curparams, TRUE);
new = me->ourgame->encode_params(data->cparams, TRUE);
if (strcmp(old, new)) {
ctx->refused = TRUE;
return "Undoing this new-game operation would change params";
}
/*
* Otherwise, fine, go ahead.
*/
return NULL;
}
static int midend_undo(midend *me) static int midend_undo(midend *me)
{ {
const char *deserialise_error;
if (me->statepos > 1) { if (me->statepos > 1) {
if (me->ui) if (me->ui)
me->ourgame->changed_state(me->ui, me->ourgame->changed_state(me->ui,
@ -487,6 +624,36 @@ static int midend_undo(midend *me)
me->statepos--; me->statepos--;
me->dir = -1; me->dir = -1;
return 1; return 1;
} else if (me->newgame_undo_len) {
/* This undo cannot be undone with redo */
struct newgame_undo_deserialise_read_ctx rctx;
struct newgame_undo_deserialise_check_ctx cctx;
rctx.me = me;
rctx.len = me->newgame_undo_len; /* copy for reentrancy safety */
rctx.pos = 0;
cctx.refused = FALSE;
deserialise_error = midend_deserialise_internal(
me, newgame_undo_deserialise_read, &rctx,
newgame_undo_deserialise_check, &cctx);
if (cctx.refused) {
/*
* Our post-deserialisation check shows that we can't use
* this saved game after all. (deserialise_error will
* contain the dummy error message generated by our check
* function, which we ignore.)
*/
return 0;
} else {
/*
* There should never be any _other_ deserialisation
* error, because this serialised data has been held in
* our memory since it was created, and hasn't had any
* opportunity to be corrupted on disk, accidentally
* replaced by the wrong file, etc., by user error.
*/
assert(!deserialise_error);
return 1;
}
} else } else
return 0; return 0;
} }
@ -629,7 +796,7 @@ static int midend_really_process_key(midend *me, int x, int y, int button)
} else } else
goto done; goto done;
} else { } else {
if (!*movestr) if (movestr == UI_UPDATE)
s = me->states[me->statepos-1].state; s = me->states[me->statepos-1].state;
else { else {
s = me->ourgame->execute_move(me->states[me->statepos-1].state, s = me->ourgame->execute_move(me->states[me->statepos-1].state,
@ -1166,7 +1333,8 @@ void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx)
me->game_id_change_notify_ctx = ctx; me->game_id_change_notify_ctx = ctx;
} }
void midend_supersede_game_desc(midend *me, char *desc, char *privdesc) void midend_supersede_game_desc(midend *me, const char *desc,
const char *privdesc)
{ {
sfree(me->desc); sfree(me->desc);
sfree(me->privdesc); sfree(me->privdesc);
@ -1178,7 +1346,8 @@ void midend_supersede_game_desc(midend *me, char *desc, char *privdesc)
config_item *midend_get_config(midend *me, int which, char **wintitle) config_item *midend_get_config(midend *me, int which, char **wintitle)
{ {
char *titlebuf, *parstr, *rest; char *titlebuf, *parstr;
const char *rest;
config_item *ret; config_item *ret;
char sep; char sep;
@ -1207,7 +1376,6 @@ config_item *midend_get_config(midend *me, int which, char **wintitle)
ret[0].name = "Game random seed"; ret[0].name = "Game random seed";
else else
ret[0].name = "Game ID"; ret[0].name = "Game ID";
ret[0].ival = 0;
/* /*
* For CFG_DESC the text going in here will be a string * For CFG_DESC the text going in here will be a string
* encoding of the restricted parameters, plus a colon, * encoding of the restricted parameters, plus a colon,
@ -1226,13 +1394,12 @@ config_item *midend_get_config(midend *me, int which, char **wintitle)
rest = me->seedstr ? me->seedstr : ""; rest = me->seedstr ? me->seedstr : "";
sep = '#'; sep = '#';
} }
ret[0].sval = snewn(strlen(parstr) + strlen(rest) + 2, char); ret[0].u.string.sval = snewn(strlen(parstr) + strlen(rest) + 2, char);
sprintf(ret[0].sval, "%s%c%s", parstr, sep, rest); sprintf(ret[0].u.string.sval, "%s%c%s", parstr, sep, rest);
sfree(parstr); sfree(parstr);
ret[1].type = C_END; ret[1].type = C_END;
ret[1].name = ret[1].sval = NULL; ret[1].name = NULL;
ret[1].ival = 0;
return ret; return ret;
} }
@ -1241,9 +1408,11 @@ config_item *midend_get_config(midend *me, int which, char **wintitle)
return NULL; return NULL;
} }
static char *midend_game_id_int(midend *me, char *id, int defmode) static const char *midend_game_id_int(midend *me, const char *id, int defmode)
{ {
char *error, *par, *desc, *seed; const char *error;
char *par = NULL;
const char *desc, *seed;
game_params *newcurparams, *newparams, *oldparams1, *oldparams2; game_params *newcurparams, *newparams, *oldparams1, *oldparams2;
int free_params; int free_params;
@ -1256,8 +1425,10 @@ static char *midend_game_id_int(midend *me, char *id, int defmode)
* description. So `par' now points to the parameters * description. So `par' now points to the parameters
* string, and `desc' to the description string. * string, and `desc' to the description string.
*/ */
*desc++ = '\0'; par = snewn(desc-id + 1, char);
par = id; strncpy(par, id, desc-id);
par[desc-id] = '\0';
desc++;
seed = NULL; seed = NULL;
} else if (seed && (!desc || seed < desc)) { } else if (seed && (!desc || seed < desc)) {
/* /*
@ -1265,8 +1436,10 @@ static char *midend_game_id_int(midend *me, char *id, int defmode)
* So `par' now points to the parameters string, and `seed' * So `par' now points to the parameters string, and `seed'
* to the seed string. * to the seed string.
*/ */
*seed++ = '\0'; par = snewn(seed-id + 1, char);
par = id; strncpy(par, id, seed-id);
par[seed-id] = '\0';
seed++;
desc = NULL; desc = NULL;
} else { } else {
/* /*
@ -1275,12 +1448,14 @@ static char *midend_game_id_int(midend *me, char *id, int defmode)
*/ */
if (defmode == DEF_SEED) { if (defmode == DEF_SEED) {
seed = id; seed = id;
par = desc = NULL; par = NULL;
desc = NULL;
} else if (defmode == DEF_DESC) { } else if (defmode == DEF_DESC) {
desc = id; desc = id;
par = seed = NULL; par = NULL;
seed = NULL;
} else { } else {
par = id; par = dupstr(id);
seed = desc = NULL; seed = desc = NULL;
} }
} }
@ -1410,10 +1585,12 @@ static char *midend_game_id_int(midend *me, char *id, int defmode)
me->genmode = GOT_SEED; me->genmode = GOT_SEED;
} }
sfree(par);
return NULL; return NULL;
} }
char *midend_game_id(midend *me, char *id) const char *midend_game_id(midend *me, const char *id)
{ {
return midend_game_id_int(me, id, DEF_PARAMS); return midend_game_id_int(me, id, DEF_PARAMS);
} }
@ -1446,9 +1623,9 @@ char *midend_get_random_seed(midend *me)
return ret; return ret;
} }
char *midend_set_config(midend *me, int which, config_item *cfg) const char *midend_set_config(midend *me, int which, config_item *cfg)
{ {
char *error; const char *error;
game_params *params; game_params *params;
switch (which) { switch (which) {
@ -1467,7 +1644,7 @@ char *midend_set_config(midend *me, int which, config_item *cfg)
case CFG_SEED: case CFG_SEED:
case CFG_DESC: case CFG_DESC:
error = midend_game_id_int(me, cfg[0].sval, error = midend_game_id_int(me, cfg[0].u.string.sval,
(which == CFG_SEED ? DEF_SEED : DEF_DESC)); (which == CFG_SEED ? DEF_SEED : DEF_DESC));
if (error) if (error)
return error; return error;
@ -1494,10 +1671,11 @@ char *midend_text_format(midend *me)
return NULL; return NULL;
} }
char *midend_solve(midend *me) const char *midend_solve(midend *me)
{ {
game_state *s; game_state *s;
char *msg, *movestr; const char *msg;
char *movestr;
if (!me->ourgame->can_solve) if (!me->ourgame->can_solve)
return "This game does not support the Solve operation"; return "This game does not support the Solve operation";
@ -1509,6 +1687,7 @@ char *midend_solve(midend *me)
movestr = me->ourgame->solve(me->states[0].state, movestr = me->ourgame->solve(me->states[0].state,
me->states[me->statepos-1].state, me->states[me->statepos-1].state,
me->aux_info, &msg); me->aux_info, &msg);
assert(movestr != UI_UPDATE);
if (!movestr) { if (!movestr) {
if (!msg) if (!msg)
msg = "Solve operation failed"; /* _shouldn't_ happen, but can */ msg = "Solve operation failed"; /* _shouldn't_ happen, but can */
@ -1566,7 +1745,7 @@ int midend_status(midend *me)
return me->ourgame->status(me->states[me->statepos-1].state); return me->ourgame->status(me->states[me->statepos-1].state);
} }
char *midend_rewrite_statusbar(midend *me, char *text) char *midend_rewrite_statusbar(midend *me, const char *text)
{ {
/* /*
* An important special case is that we are occasionally called * An important special case is that we are occasionally called
@ -1600,7 +1779,7 @@ char *midend_rewrite_statusbar(midend *me, char *text)
#define SERIALISE_VERSION "1" #define SERIALISE_VERSION "1"
void midend_serialise(midend *me, void midend_serialise(midend *me,
void (*write)(void *ctx, void *buf, int len), void (*write)(void *ctx, const void *buf, int len),
void *wctx) void *wctx)
{ {
int i; int i;
@ -1616,7 +1795,7 @@ void midend_serialise(midend *me,
*/ */
#define wr(h,s) do { \ #define wr(h,s) do { \
char hbuf[80]; \ char hbuf[80]; \
char *str = (s); \ const char *str = (s); \
char lbuf[9]; \ char lbuf[9]; \
copy_left_justified(lbuf, sizeof(lbuf), h); \ copy_left_justified(lbuf, sizeof(lbuf), h); \
sprintf(hbuf, "%s:%d:", lbuf, (int)strlen(str)); \ sprintf(hbuf, "%s:%d:", lbuf, (int)strlen(str)); \
@ -1748,39 +1927,43 @@ void midend_serialise(midend *me,
} }
/* /*
* This function returns NULL on success, or an error message. * Internal version of midend_deserialise, taking an extra check
* function to be called just before beginning to install things in
* the midend.
*
* Like midend_deserialise proper, this function returns NULL on
* success, or an error message.
*/ */
char *midend_deserialise(midend *me, static const char *midend_deserialise_internal(
int (*read)(void *ctx, void *buf, int len), midend *me, int (*read)(void *ctx, void *buf, int len), void *rctx,
void *rctx) const char *(*check)(void *ctx, midend *, const struct deserialise_data *),
void *cctx)
{ {
int nstates = 0, statepos = -1, gotstates = 0; struct deserialise_data data;
int gotstates = 0;
int started = FALSE; int started = FALSE;
int i; int i;
char *val = NULL; char *val = NULL;
/* Initially all errors give the same report */ /* Initially all errors give the same report */
char *ret = "Data does not appear to be a saved game file"; const char *ret = "Data does not appear to be a saved game file";
/* data.seed = data.parstr = data.desc = data.privdesc = NULL;
* We construct all the new state in local variables while we data.auxinfo = data.uistr = data.cparstr = NULL;
* check its sanity. Only once we have finished reading the data.elapsed = 0.0F;
* serialised data and detected no errors at all do we start data.params = data.cparams = NULL;
* modifying stuff in the midend passed in. data.ui = NULL;
*/ data.states = NULL;
char *seed = NULL, *parstr = NULL, *desc = NULL, *privdesc = NULL; data.nstates = 0;
char *auxinfo = NULL, *uistr = NULL, *cparstr = NULL; data.statepos = -1;
float elapsed = 0.0F;
game_params *params = NULL, *cparams = NULL;
game_ui *ui = NULL;
struct midend_state_entry *states = NULL;
/* /*
* Loop round and round reading one key/value pair at a time * Loop round and round reading one key/value pair at a time
* from the serialised stream, until we have enough game states * from the serialised stream, until we have enough game states
* to finish. * to finish.
*/ */
while (nstates <= 0 || statepos < 0 || gotstates < nstates-1) { while (data.nstates <= 0 || data.statepos < 0 ||
gotstates < data.nstates-1) {
char key[9], c; char key[9], c;
int len; int len;
@ -1852,24 +2035,24 @@ char *midend_deserialise(midend *me,
goto cleanup; goto cleanup;
} }
} else if (!strcmp(key, "PARAMS")) { } else if (!strcmp(key, "PARAMS")) {
sfree(parstr); sfree(data.parstr);
parstr = val; data.parstr = val;
val = NULL; val = NULL;
} else if (!strcmp(key, "CPARAMS")) { } else if (!strcmp(key, "CPARAMS")) {
sfree(cparstr); sfree(data.cparstr);
cparstr = val; data.cparstr = val;
val = NULL; val = NULL;
} else if (!strcmp(key, "SEED")) { } else if (!strcmp(key, "SEED")) {
sfree(seed); sfree(data.seed);
seed = val; data.seed = val;
val = NULL; val = NULL;
} else if (!strcmp(key, "DESC")) { } else if (!strcmp(key, "DESC")) {
sfree(desc); sfree(data.desc);
desc = val; data.desc = val;
val = NULL; val = NULL;
} else if (!strcmp(key, "PRIVDESC")) { } else if (!strcmp(key, "PRIVDESC")) {
sfree(privdesc); sfree(data.privdesc);
privdesc = val; data.privdesc = val;
val = NULL; val = NULL;
} else if (!strcmp(key, "AUXINFO")) { } else if (!strcmp(key, "AUXINFO")) {
unsigned char *tmp; unsigned char *tmp;
@ -1877,49 +2060,49 @@ char *midend_deserialise(midend *me,
tmp = hex2bin(val, len); tmp = hex2bin(val, len);
obfuscate_bitmap(tmp, len*8, TRUE); obfuscate_bitmap(tmp, len*8, TRUE);
sfree(auxinfo); sfree(data.auxinfo);
auxinfo = snewn(len + 1, char); data.auxinfo = snewn(len + 1, char);
memcpy(auxinfo, tmp, len); memcpy(data.auxinfo, tmp, len);
auxinfo[len] = '\0'; data.auxinfo[len] = '\0';
sfree(tmp); sfree(tmp);
} else if (!strcmp(key, "UI")) { } else if (!strcmp(key, "UI")) {
sfree(uistr); sfree(data.uistr);
uistr = val; data.uistr = val;
val = NULL; val = NULL;
} else if (!strcmp(key, "TIME")) { } else if (!strcmp(key, "TIME")) {
elapsed = (float)atof(val); data.elapsed = (float)atof(val);
} else if (!strcmp(key, "NSTATES")) { } else if (!strcmp(key, "NSTATES")) {
nstates = atoi(val); data.nstates = atoi(val);
if (nstates <= 0) { if (data.nstates <= 0) {
ret = "Number of states in save file was negative"; ret = "Number of states in save file was negative";
goto cleanup; goto cleanup;
} }
if (states) { if (data.states) {
ret = "Two state counts provided in save file"; ret = "Two state counts provided in save file";
goto cleanup; goto cleanup;
} }
states = snewn(nstates, struct midend_state_entry); data.states = snewn(data.nstates, struct midend_state_entry);
for (i = 0; i < nstates; i++) { for (i = 0; i < data.nstates; i++) {
states[i].state = NULL; data.states[i].state = NULL;
states[i].movestr = NULL; data.states[i].movestr = NULL;
states[i].movetype = NEWGAME; data.states[i].movetype = NEWGAME;
} }
} else if (!strcmp(key, "STATEPOS")) { } else if (!strcmp(key, "STATEPOS")) {
statepos = atoi(val); data.statepos = atoi(val);
} else if (!strcmp(key, "MOVE")) { } else if (!strcmp(key, "MOVE")) {
gotstates++; gotstates++;
states[gotstates].movetype = MOVE; data.states[gotstates].movetype = MOVE;
states[gotstates].movestr = val; data.states[gotstates].movestr = val;
val = NULL; val = NULL;
} else if (!strcmp(key, "SOLVE")) { } else if (!strcmp(key, "SOLVE")) {
gotstates++; gotstates++;
states[gotstates].movetype = SOLVE; data.states[gotstates].movetype = SOLVE;
states[gotstates].movestr = val; data.states[gotstates].movestr = val;
val = NULL; val = NULL;
} else if (!strcmp(key, "RESTART")) { } else if (!strcmp(key, "RESTART")) {
gotstates++; gotstates++;
states[gotstates].movetype = RESTART; data.states[gotstates].movetype = RESTART;
states[gotstates].movestr = val; data.states[gotstates].movestr = val;
val = NULL; val = NULL;
} }
} }
@ -1928,68 +2111,77 @@ char *midend_deserialise(midend *me,
val = NULL; val = NULL;
} }
params = me->ourgame->default_params(); data.params = me->ourgame->default_params();
me->ourgame->decode_params(params, parstr); me->ourgame->decode_params(data.params, data.parstr);
if (me->ourgame->validate_params(params, TRUE)) { if (me->ourgame->validate_params(data.params, TRUE)) {
ret = "Long-term parameters in save file are invalid"; ret = "Long-term parameters in save file are invalid";
goto cleanup; goto cleanup;
} }
cparams = me->ourgame->default_params(); data.cparams = me->ourgame->default_params();
me->ourgame->decode_params(cparams, cparstr); me->ourgame->decode_params(data.cparams, data.cparstr);
if (me->ourgame->validate_params(cparams, FALSE)) { if (me->ourgame->validate_params(data.cparams, FALSE)) {
ret = "Short-term parameters in save file are invalid"; ret = "Short-term parameters in save file are invalid";
goto cleanup; goto cleanup;
} }
if (seed && me->ourgame->validate_params(cparams, TRUE)) { if (data.seed && me->ourgame->validate_params(data.cparams, TRUE)) {
/* /*
* The seed's no use with this version, but we can perfectly * The seed's no use with this version, but we can perfectly
* well use the rest of the data. * well use the rest of the data.
*/ */
sfree(seed); sfree(data.seed);
seed = NULL; data.seed = NULL;
} }
if (!desc) { if (!data.desc) {
ret = "Game description in save file is missing"; ret = "Game description in save file is missing";
goto cleanup; goto cleanup;
} else if (me->ourgame->validate_desc(params, desc)) { } else if (me->ourgame->validate_desc(data.cparams, data.desc)) {
ret = "Game description in save file is invalid"; ret = "Game description in save file is invalid";
goto cleanup; goto cleanup;
} }
if (privdesc && me->ourgame->validate_desc(params, privdesc)) { if (data.privdesc &&
me->ourgame->validate_desc(data.cparams, data.privdesc)) {
ret = "Game private description in save file is invalid"; ret = "Game private description in save file is invalid";
goto cleanup; goto cleanup;
} }
if (statepos < 0 || statepos >= nstates) { if (data.statepos < 0 || data.statepos >= data.nstates) {
ret = "Game position in save file is out of range"; ret = "Game position in save file is out of range";
} }
states[0].state = me->ourgame->new_game(me, params, data.states[0].state = me->ourgame->new_game(
privdesc ? privdesc : desc); me, data.cparams, data.privdesc ? data.privdesc : data.desc);
for (i = 1; i < nstates; i++) { for (i = 1; i < data.nstates; i++) {
assert(states[i].movetype != NEWGAME); assert(data.states[i].movetype != NEWGAME);
switch (states[i].movetype) { switch (data.states[i].movetype) {
case MOVE: case MOVE:
case SOLVE: case SOLVE:
states[i].state = me->ourgame->execute_move(states[i-1].state, data.states[i].state = me->ourgame->execute_move(
states[i].movestr); data.states[i-1].state, data.states[i].movestr);
if (states[i].state == NULL) { if (data.states[i].state == NULL) {
ret = "Save file contained an invalid move"; ret = "Save file contained an invalid move";
goto cleanup; goto cleanup;
} }
break; break;
case RESTART: case RESTART:
if (me->ourgame->validate_desc(params, states[i].movestr)) { if (me->ourgame->validate_desc(
data.cparams, data.states[i].movestr)) {
ret = "Save file contained an invalid restart move"; ret = "Save file contained an invalid restart move";
goto cleanup; goto cleanup;
} }
states[i].state = me->ourgame->new_game(me, params, data.states[i].state = me->ourgame->new_game(
states[i].movestr); me, data.cparams, data.states[i].movestr);
break; break;
} }
} }
ui = me->ourgame->new_ui(states[0].state); data.ui = me->ourgame->new_ui(data.states[0].state);
me->ourgame->decode_ui(ui, uistr); me->ourgame->decode_ui(data.ui, data.uistr);
/*
* Run the externally provided check function, and abort if it
* returns an error message.
*/
if (check && (ret = check(cctx, me, &data)) != NULL)
goto cleanup; /* error message is already in ret */
/* /*
* Now we've run out of possible error conditions, so we're * Now we've run out of possible error conditions, so we're
@ -2002,45 +2194,54 @@ char *midend_deserialise(midend *me,
char *tmp; char *tmp;
tmp = me->desc; tmp = me->desc;
me->desc = desc; me->desc = data.desc;
desc = tmp; data.desc = tmp;
tmp = me->privdesc; tmp = me->privdesc;
me->privdesc = privdesc; me->privdesc = data.privdesc;
privdesc = tmp; data.privdesc = tmp;
tmp = me->seedstr; tmp = me->seedstr;
me->seedstr = seed; me->seedstr = data.seed;
seed = tmp; data.seed = tmp;
tmp = me->aux_info; tmp = me->aux_info;
me->aux_info = auxinfo; me->aux_info = data.auxinfo;
auxinfo = tmp; data.auxinfo = tmp;
} }
me->genmode = GOT_NOTHING; me->genmode = GOT_NOTHING;
me->statesize = nstates; me->statesize = data.nstates;
nstates = me->nstates; data.nstates = me->nstates;
me->nstates = me->statesize; me->nstates = me->statesize;
{ {
struct midend_state_entry *tmp; struct midend_state_entry *tmp;
tmp = me->states; tmp = me->states;
me->states = states; me->states = data.states;
states = tmp; data.states = tmp;
} }
me->statepos = statepos; me->statepos = data.statepos;
/*
* Don't save the "new game undo" state. So "new game" twice or
* (in some environments) switching away and back, will make a
* "new game" irreversible. Maybe in the future we will have a
* more sophisticated way to decide when to discard the previous
* game state.
*/
me->newgame_undo_len = 0;
{ {
game_params *tmp; game_params *tmp;
tmp = me->params; tmp = me->params;
me->params = params; me->params = data.params;
params = tmp; data.params = tmp;
tmp = me->curparams; tmp = me->curparams;
me->curparams = cparams; me->curparams = data.cparams;
cparams = tmp; data.cparams = tmp;
} }
me->oldstate = NULL; me->oldstate = NULL;
@ -2051,11 +2252,11 @@ char *midend_deserialise(midend *me,
game_ui *tmp; game_ui *tmp;
tmp = me->ui; tmp = me->ui;
me->ui = ui; me->ui = data.ui;
ui = tmp; data.ui = tmp;
} }
me->elapsed = elapsed; me->elapsed = data.elapsed;
me->pressed_mouse_button = 0; me->pressed_mouse_button = 0;
midend_set_timer(me); midend_set_timer(me);
@ -2073,33 +2274,39 @@ char *midend_deserialise(midend *me,
cleanup: cleanup:
sfree(val); sfree(val);
sfree(seed); sfree(data.seed);
sfree(parstr); sfree(data.parstr);
sfree(cparstr); sfree(data.cparstr);
sfree(desc); sfree(data.desc);
sfree(privdesc); sfree(data.privdesc);
sfree(auxinfo); sfree(data.auxinfo);
sfree(uistr); sfree(data.uistr);
if (params) if (data.params)
me->ourgame->free_params(params); me->ourgame->free_params(data.params);
if (cparams) if (data.cparams)
me->ourgame->free_params(cparams); me->ourgame->free_params(data.cparams);
if (ui) if (data.ui)
me->ourgame->free_ui(ui); me->ourgame->free_ui(data.ui);
if (states) { if (data.states) {
int i; int i;
for (i = 0; i < nstates; i++) { for (i = 0; i < data.nstates; i++) {
if (states[i].state) if (data.states[i].state)
me->ourgame->free_game(states[i].state); me->ourgame->free_game(data.states[i].state);
sfree(states[i].movestr); sfree(data.states[i].movestr);
} }
sfree(states); sfree(data.states);
} }
return ret; return ret;
} }
const char *midend_deserialise(
midend *me, int (*read)(void *ctx, void *buf, int len), void *rctx)
{
return midend_deserialise_internal(me, read, rctx, NULL, NULL);
}
/* /*
* This function examines a saved game file just far enough to * This function examines a saved game file just far enough to
* determine which game type it contains. It returns NULL on success * determine which game type it contains. It returns NULL on success
@ -2107,15 +2314,16 @@ char *midend_deserialise(midend *me,
* allocated and should be caller-freed), or an error message on * allocated and should be caller-freed), or an error message on
* failure. * failure.
*/ */
char *identify_game(char **name, int (*read)(void *ctx, void *buf, int len), const char *identify_game(char **name,
void *rctx) int (*read)(void *ctx, void *buf, int len),
void *rctx)
{ {
int nstates = 0, statepos = -1, gotstates = 0; int nstates = 0, statepos = -1, gotstates = 0;
int started = FALSE; int started = FALSE;
char *val = NULL; char *val = NULL;
/* Initially all errors give the same report */ /* Initially all errors give the same report */
char *ret = "Data does not appear to be a saved game file"; const char *ret = "Data does not appear to be a saved game file";
*name = NULL; *name = NULL;
@ -2205,7 +2413,7 @@ char *identify_game(char **name, int (*read)(void *ctx, void *buf, int len),
return ret; return ret;
} }
char *midend_print_puzzle(midend *me, document *doc, int with_soln) const char *midend_print_puzzle(midend *me, document *doc, int with_soln)
{ {
game_state *soln = NULL; game_state *soln = NULL;
@ -2213,7 +2421,8 @@ char *midend_print_puzzle(midend *me, document *doc, int with_soln)
return "No game set up to print";/* _shouldn't_ happen! */ return "No game set up to print";/* _shouldn't_ happen! */
if (with_soln) { if (with_soln) {
char *msg, *movestr; const char *msg;
char *movestr;
if (!me->ourgame->can_solve) if (!me->ourgame->can_solve)
return "This game does not support the Solve operation"; return "This game does not support the Solve operation";

View file

@ -203,30 +203,24 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Mines"; ret[2].name = "Mines";
ret[2].type = C_STRING; ret[2].type = C_STRING;
sprintf(buf, "%d", params->n); sprintf(buf, "%d", params->n);
ret[2].sval = dupstr(buf); ret[2].u.string.sval = dupstr(buf);
ret[2].ival = 0;
ret[3].name = "Ensure solubility"; ret[3].name = "Ensure solubility";
ret[3].type = C_BOOLEAN; ret[3].type = C_BOOLEAN;
ret[3].sval = NULL; ret[3].u.boolean.bval = params->unique;
ret[3].ival = params->unique;
ret[4].name = NULL; ret[4].name = NULL;
ret[4].type = C_END; ret[4].type = C_END;
ret[4].sval = NULL;
ret[4].ival = 0;
return ret; return ret;
} }
@ -235,17 +229,17 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->n = atoi(cfg[2].sval); ret->n = atoi(cfg[2].u.string.sval);
if (strchr(cfg[2].sval, '%')) if (strchr(cfg[2].u.string.sval, '%'))
ret->n = ret->n * (ret->w * ret->h) / 100; ret->n = ret->n * (ret->w * ret->h) / 100;
ret->unique = cfg[3].ival; ret->unique = cfg[3].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
/* /*
* Lower limit on grid size: each dimension must be at least 3. * Lower limit on grid size: each dimension must be at least 3.
@ -1996,7 +1990,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
} }
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int wh = params->w * params->h; int wh = params->w * params->h;
int x, y; int x, y;
@ -2306,7 +2300,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
if (!state->layout->mines) { if (!state->layout->mines) {
*error = "Game has not been started yet"; *error = "Game has not been started yet";
@ -2434,14 +2428,14 @@ static char *interpret_move(const game_state *from, game_ui *ui,
if (IS_CURSOR_MOVE(button)) { if (IS_CURSOR_MOVE(button)) {
move_cursor(button, &ui->cur_x, &ui->cur_y, from->w, from->h, 0); move_cursor(button, &ui->cur_x, &ui->cur_y, from->w, from->h, 0);
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
if (IS_CURSOR_SELECT(button)) { if (IS_CURSOR_SELECT(button)) {
int v = from->grid[ui->cur_y * from->w + ui->cur_x]; int v = from->grid[ui->cur_y * from->w + ui->cur_x];
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
if (button == CURSOR_SELECT2) { if (button == CURSOR_SELECT2) {
/* As for RIGHT_BUTTON; only works on covered square. */ /* As for RIGHT_BUTTON; only works on covered square. */
@ -2481,7 +2475,7 @@ static char *interpret_move(const game_state *from, game_ui *ui,
else if (button == MIDDLE_BUTTON) else if (button == MIDDLE_BUTTON)
ui->validradius = 1; ui->validradius = 1;
ui->cur_visible = 0; ui->cur_visible = 0;
return ""; return UI_UPDATE;
} }
if (button == RIGHT_BUTTON) { if (button == RIGHT_BUTTON) {
@ -2509,10 +2503,10 @@ static char *interpret_move(const game_state *from, game_ui *ui,
/* /*
* At this stage we must never return NULL: we have adjusted * At this stage we must never return NULL: we have adjusted
* the ui, so at worst we return "". * the ui, so at worst we return UI_UPDATE.
*/ */
if (cx < 0 || cx >= from->w || cy < 0 || cy >= from->h) if (cx < 0 || cx >= from->w || cy < 0 || cy >= from->h)
return ""; return UI_UPDATE;
/* /*
* Left-clicking on a covered square opens a tile. Not * Left-clicking on a covered square opens a tile. Not
@ -2566,7 +2560,7 @@ uncover:
* can. * can.
*/ */
char *p = buf; char *p = buf;
char *sep = ""; const char *sep = "";
for (dy = -1; dy <= +1; dy++) for (dy = -1; dy <= +1; dy++)
for (dx = -1; dx <= +1; dx++) for (dx = -1; dx <= +1; dx++)
@ -2590,7 +2584,7 @@ uncover:
} }
} }
return ""; return UI_UPDATE;
} }
} }
@ -3235,7 +3229,8 @@ int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
game_state *s; game_state *s;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
int y, x; int y, x;
while (--argc > 0) { while (--argc > 0) {

View file

@ -9,13 +9,15 @@
#include "puzzles.h" #include "puzzles.h"
char UI_UPDATE[] = "";
void free_cfg(config_item *cfg) void free_cfg(config_item *cfg)
{ {
config_item *i; config_item *i;
for (i = cfg; i->type != C_END; i++) for (i = cfg; i->type != C_END; i++)
if (i->type == C_STRING) if (i->type == C_STRING)
sfree(i->sval); sfree(i->u.string.sval);
sfree(cfg); sfree(cfg);
} }
@ -349,7 +351,7 @@ void pos2c(int w, int h, int pos, int *cx, int *cy)
void draw_text_outline(drawing *dr, int x, int y, int fonttype, void draw_text_outline(drawing *dr, int x, int y, int fonttype,
int fontsize, int align, int fontsize, int align,
int text_colour, int outline_colour, char *text) int text_colour, int outline_colour, const char *text)
{ {
if (outline_colour > -1) { if (outline_colour > -1) {
draw_text(dr, x-1, y, fonttype, fontsize, align, outline_colour, text); draw_text(dr, x-1, y, fonttype, fontsize, align, outline_colour, text);

View file

@ -17,7 +17,7 @@
extern void _pause(); extern void _pause();
extern int _call_java(int cmd, int arg1, int arg2, int arg3); extern int _call_java(int cmd, int arg1, int arg2, int arg3);
void fatal(char *fmt, ...) void fatal(const char *fmt, ...)
{ {
va_list ap; va_list ap;
fprintf(stderr, "fatal error: "); fprintf(stderr, "fatal error: ");
@ -53,7 +53,7 @@ void frontend_default_colour(frontend *fe, float *output)
output[0] = output[1]= output[2] = 0.8f; output[0] = output[1]= output[2] = 0.8f;
} }
void nestedvm_status_bar(void *handle, char *text) void nestedvm_status_bar(void *handle, const char *text)
{ {
_call_java(4,0,(int)text,0); _call_java(4,0,(int)text,0);
} }
@ -79,7 +79,7 @@ void nestedvm_unclip(void *handle)
} }
void nestedvm_draw_text(void *handle, int x, int y, int fonttype, int fontsize, void nestedvm_draw_text(void *handle, int x, int y, int fonttype, int fontsize,
int align, int colour, char *text) int align, int colour, const char *text)
{ {
frontend *fe = (frontend *)handle; frontend *fe = (frontend *)handle;
_call_java(5, x + fe->ox, y + fe->oy, _call_java(5, x + fe->ox, y + fe->oy,
@ -259,7 +259,7 @@ void activate_timer(frontend *fe)
void jcallback_config_ok() void jcallback_config_ok()
{ {
frontend *fe = (frontend *)_fe; frontend *fe = (frontend *)_fe;
char *err; const char *err;
err = midend_set_config(fe->me, fe->cfg_which, fe->cfg); err = midend_set_config(fe->me, fe->cfg_which, fe->cfg);
@ -273,19 +273,22 @@ void jcallback_config_ok()
void jcallback_config_set_string(int item_ptr, int char_ptr) { void jcallback_config_set_string(int item_ptr, int char_ptr) {
config_item *i = (config_item *)item_ptr; config_item *i = (config_item *)item_ptr;
char* newval = (char*) char_ptr; char* newval = (char*) char_ptr;
sfree(i->sval); assert(i->type == C_STRING);
i->sval = dupstr(newval); sfree(i->u.string.sval);
i->u.string.sval = dupstr(newval);
free(newval); free(newval);
} }
void jcallback_config_set_boolean(int item_ptr, int selected) { void jcallback_config_set_boolean(int item_ptr, int selected) {
config_item *i = (config_item *)item_ptr; config_item *i = (config_item *)item_ptr;
i->ival = selected != 0 ? TRUE : FALSE; assert(i->type == C_BOOLEAN);
i->u.boolean.bval = selected != 0 ? TRUE : FALSE;
} }
void jcallback_config_set_choice(int item_ptr, int selected) { void jcallback_config_set_choice(int item_ptr, int selected) {
config_item *i = (config_item *)item_ptr; config_item *i = (config_item *)item_ptr;
i->ival = selected; assert(i->type == C_CHOICES);
i->u.choices.selected = selected;
} }
static int get_config(frontend *fe, int which) static int get_config(frontend *fe, int which)
@ -298,7 +301,18 @@ static int get_config(frontend *fe, int which)
_call_java(10, (int)title, 0, 0); _call_java(10, (int)title, 0, 0);
for (i = fe->cfg; i->type != C_END; i++) { for (i = fe->cfg; i->type != C_END; i++) {
_call_java(5, (int)i, i->type, (int)i->name); _call_java(5, (int)i, i->type, (int)i->name);
_call_java(11, (int)i->sval, i->ival, 0); switch (i->type) {
case C_STRING:
_call_java(11, (int)i->u.string.sval, 0, 0);
break;
case C_BOOLEAN:
_call_java(11, 0, i->u.boolean.bval, 0);
break;
case C_CHOICES:
_call_java(11, (int)i->u.choices.choicenames,
i->u.choices.selected, 0);
break;
}
} }
_call_java(12,0,0,0); _call_java(12,0,0,0);
free_cfg(fe->cfg); free_cfg(fe->cfg);
@ -363,7 +377,7 @@ int jcallback_preset_event(int ptr_game_params)
int jcallback_solve_event() int jcallback_solve_event()
{ {
frontend *fe = (frontend *)_fe; frontend *fe = (frontend *)_fe;
char *msg; const char *msg;
msg = midend_solve(fe->me); msg = midend_solve(fe->me);

View file

@ -270,35 +270,28 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->width); sprintf(buf, "%d", params->width);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->height); sprintf(buf, "%d", params->height);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Walls wrap around"; ret[2].name = "Walls wrap around";
ret[2].type = C_BOOLEAN; ret[2].type = C_BOOLEAN;
ret[2].sval = NULL; ret[2].u.boolean.bval = params->wrapping;
ret[2].ival = params->wrapping;
ret[3].name = "Barrier probability"; ret[3].name = "Barrier probability";
ret[3].type = C_STRING; ret[3].type = C_STRING;
ftoa(buf, params->barrier_probability); ftoa(buf, params->barrier_probability);
ret[3].sval = dupstr(buf); ret[3].u.string.sval = dupstr(buf);
ret[3].ival = 0;
ret[4].name = "Ensure unique solution"; ret[4].name = "Ensure unique solution";
ret[4].type = C_BOOLEAN; ret[4].type = C_BOOLEAN;
ret[4].sval = NULL; ret[4].u.boolean.bval = params->unique;
ret[4].ival = params->unique;
ret[5].name = NULL; ret[5].name = NULL;
ret[5].type = C_END; ret[5].type = C_END;
ret[5].sval = NULL;
ret[5].ival = 0;
return ret; return ret;
} }
@ -307,16 +300,16 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->width = atoi(cfg[0].sval); ret->width = atoi(cfg[0].u.string.sval);
ret->height = atoi(cfg[1].sval); ret->height = atoi(cfg[1].u.string.sval);
ret->wrapping = cfg[2].ival; ret->wrapping = cfg[2].u.boolean.bval;
ret->barrier_probability = (float)atof(cfg[3].sval); ret->barrier_probability = (float)atof(cfg[3].u.string.sval);
ret->unique = cfg[4].ival; ret->unique = cfg[4].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->width <= 0 || params->height <= 0) if (params->width <= 0 || params->height <= 0)
return "Width and height must both be greater than zero"; return "Width and height must both be greater than zero";
@ -1601,7 +1594,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return desc; return desc;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->width, h = params->height; int w = params->width, h = params->height;
int i; int i;
@ -1752,7 +1745,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
unsigned char *tiles; unsigned char *tiles;
char *ret; char *ret;
@ -2099,7 +2092,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (ui->cur_visible) { if (ui->cur_visible) {
ui->cur_visible = FALSE; ui->cur_visible = FALSE;
nullret = ""; nullret = UI_UPDATE;
} }
/* /*
@ -2339,7 +2332,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
OFFSET(ui->cur_x, ui->cur_y, ui->cur_x, ui->cur_y, dir, state); OFFSET(ui->cur_x, ui->cur_y, ui->cur_x, ui->cur_y, dir, state);
ui->cur_visible = TRUE; ui->cur_visible = TRUE;
} }
return ""; return UI_UPDATE;
} else { } else {
return NULL; return NULL;
} }

View file

@ -265,36 +265,29 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->width); sprintf(buf, "%d", params->width);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->height); sprintf(buf, "%d", params->height);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Walls wrap around"; ret[2].name = "Walls wrap around";
ret[2].type = C_BOOLEAN; ret[2].type = C_BOOLEAN;
ret[2].sval = NULL; ret[2].u.boolean.bval = params->wrapping;
ret[2].ival = params->wrapping;
ret[3].name = "Barrier probability"; ret[3].name = "Barrier probability";
ret[3].type = C_STRING; ret[3].type = C_STRING;
ftoa(buf, params->barrier_probability); ftoa(buf, params->barrier_probability);
ret[3].sval = dupstr(buf); ret[3].u.string.sval = dupstr(buf);
ret[3].ival = 0;
ret[4].name = "Number of shuffling moves"; ret[4].name = "Number of shuffling moves";
ret[4].type = C_STRING; ret[4].type = C_STRING;
sprintf(buf, "%d", params->movetarget); sprintf(buf, "%d", params->movetarget);
ret[4].sval = dupstr(buf); ret[4].u.string.sval = dupstr(buf);
ret[4].ival = 0;
ret[5].name = NULL; ret[5].name = NULL;
ret[5].type = C_END; ret[5].type = C_END;
ret[5].sval = NULL;
ret[5].ival = 0;
return ret; return ret;
} }
@ -303,16 +296,16 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->width = atoi(cfg[0].sval); ret->width = atoi(cfg[0].u.string.sval);
ret->height = atoi(cfg[1].sval); ret->height = atoi(cfg[1].u.string.sval);
ret->wrapping = cfg[2].ival; ret->wrapping = cfg[2].u.boolean.bval;
ret->barrier_probability = (float)atof(cfg[3].sval); ret->barrier_probability = (float)atof(cfg[3].u.string.sval);
ret->movetarget = atoi(cfg[4].sval); ret->movetarget = atoi(cfg[4].u.string.sval);
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->width <= 1 || params->height <= 1) if (params->width <= 1 || params->height <= 1)
return "Width and height must both be greater than one"; return "Width and height must both be greater than one";
@ -701,7 +694,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return desc; return desc;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->width, h = params->height; int w = params->width, h = params->height;
int i; int i;
@ -891,7 +884,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
if (!aux) { if (!aux) {
*error = "Solution not known for this puzzle"; *error = "Solution not known for this puzzle";
@ -1084,7 +1077,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} }
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
if (button == LEFT_BUTTON || button == RIGHT_BUTTON) { if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
@ -1098,7 +1091,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} else { } else {
/* 'click' when cursor is invisible just makes cursor visible. */ /* 'click' when cursor is invisible just makes cursor visible. */
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
} else } else
return NULL; return NULL;

View file

@ -10,7 +10,7 @@
void frontend_default_colour(frontend *fe, float *output) {} void frontend_default_colour(frontend *fe, float *output) {}
void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize, void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize,
int align, int colour, char *text) {} int align, int colour, const char *text) {}
void draw_rect(drawing *dr, int x, int y, int w, int h, int colour) {} void draw_rect(drawing *dr, int x, int y, int w, int h, int colour) {}
void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour) {} void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour) {}
void draw_thick_line(drawing *dr, float thickness, void draw_thick_line(drawing *dr, float thickness,
@ -41,15 +41,16 @@ int print_rgb_hatched_colour(drawing *dr, float r, float g, float b, int hatch)
{ return 0; } { return 0; }
void print_line_width(drawing *dr, int width) {} void print_line_width(drawing *dr, int width) {}
void print_line_dotted(drawing *dr, int dotted) {} void print_line_dotted(drawing *dr, int dotted) {}
void midend_supersede_game_desc(midend *me, char *desc, char *privdesc) {} void midend_supersede_game_desc(midend *me, const char *desc,
void status_bar(drawing *dr, char *text) {} const char *privdesc) {}
void status_bar(drawing *dr, const char *text) {}
struct preset_menu *preset_menu_new(void) {return NULL;} struct preset_menu *preset_menu_new(void) {return NULL;}
struct preset_menu *preset_menu_add_submenu(struct preset_menu *parent, struct preset_menu *preset_menu_add_submenu(struct preset_menu *parent,
char *title) {return NULL;} char *title) {return NULL;}
void preset_menu_add_preset(struct preset_menu *parent, void preset_menu_add_preset(struct preset_menu *parent,
char *title, game_params *params) {} char *title, game_params *params) {}
void fatal(char *fmt, ...) void fatal(const char *fmt, ...)
{ {
va_list ap; va_list ap;
@ -64,7 +65,7 @@ void fatal(char *fmt, ...)
} }
#ifdef DEBUGGING #ifdef DEBUGGING
void debug_printf(char *fmt, ...) void debug_printf(const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);

View file

@ -78,7 +78,7 @@ static game_params *custom_params(const config_item *cfg)
return NULL; return NULL;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
return NULL; return NULL;
} }
@ -89,7 +89,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return dupstr("FIXME"); return dupstr("FIXME");
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
return NULL; return NULL;
} }
@ -119,7 +119,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
return NULL; return NULL;
} }

View file

@ -111,7 +111,7 @@ NSApplication *app;
* clearly defined subsystem. * clearly defined subsystem.
*/ */
void fatal(char *fmt, ...) void fatal(const char *fmt, ...)
{ {
va_list ap; va_list ap;
char errorbuf[2048]; char errorbuf[2048];
@ -152,7 +152,7 @@ void get_random_seed(void **randseed, int *randseedsize)
*randseedsize = sizeof(time_t); *randseedsize = sizeof(time_t);
} }
static void savefile_write(void *wctx, void *buf, int len) static void savefile_write(void *wctx, const void *buf, int len)
{ {
FILE *fp = (FILE *)wctx; FILE *fp = (FILE *)wctx;
fwrite(buf, 1, len, fp); fwrite(buf, 1, len, fp);
@ -275,7 +275,7 @@ id initnewitem(NSMenuItem *item, NSMenu *parent, const char *title,
return item; return item;
} }
NSMenuItem *newitem(NSMenu *parent, char *title, char *key, NSMenuItem *newitem(NSMenu *parent, const char *title, const char *key,
id target, SEL action) id target, SEL action)
{ {
return initnewitem([NSMenuItem allocWithZone:[NSMenu menuZone]], return initnewitem([NSMenuItem allocWithZone:[NSMenu menuZone]],
@ -437,7 +437,7 @@ struct frontend {
- (void)keyDown:(NSEvent *)ev; - (void)keyDown:(NSEvent *)ev;
- (void)activateTimer; - (void)activateTimer;
- (void)deactivateTimer; - (void)deactivateTimer;
- (void)setStatusLine:(char *)text; - (void)setStatusLine:(const char *)text;
- (void)resizeForNewGameParams; - (void)resizeForNewGameParams;
- (void)updateTypeMenuTick; - (void)updateTypeMenuTick;
@end @end
@ -726,7 +726,7 @@ struct frontend {
last_time = now; last_time = now;
} }
- (void)showError:(char *)message - (void)showError:(const char *)message
{ {
NSAlert *alert; NSAlert *alert;
@ -789,7 +789,7 @@ struct frontend {
const char *name = [[[op filenames] objectAtIndex:0] const char *name = [[[op filenames] objectAtIndex:0]
cStringUsingEncoding: cStringUsingEncoding:
[NSString defaultCStringEncoding]]; [NSString defaultCStringEncoding]];
char *err; const char *err;
FILE *fp = fopen(name, "r"); FILE *fp = fopen(name, "r");
@ -836,7 +836,7 @@ struct frontend {
- (void)solveGame:(id)sender - (void)solveGame:(id)sender
{ {
char *msg; const char *msg;
msg = midend_solve(me); msg = midend_solve(me);
@ -1103,7 +1103,8 @@ struct frontend {
[tf setEditable:YES]; [tf setEditable:YES];
[tf setSelectable:YES]; [tf setSelectable:YES];
[tf setBordered:YES]; [tf setBordered:YES];
[[tf cell] setTitle:[NSString stringWithUTF8String:i->sval]]; [[tf cell] setTitle:[NSString
stringWithUTF8String:i->u.string.sval]];
[tf sizeToFit]; [tf sizeToFit];
rect = [tf frame]; rect = [tf frame];
/* /*
@ -1132,7 +1133,7 @@ struct frontend {
[b setButtonType:NSSwitchButton]; [b setButtonType:NSSwitchButton];
[b setTitle:[NSString stringWithUTF8String:i->name]]; [b setTitle:[NSString stringWithUTF8String:i->name]];
[b sizeToFit]; [b sizeToFit];
[b setState:(i->ival ? NSOnState : NSOffState)]; [b setState:(i->u.boolean.bval ? NSOnState : NSOffState)];
rect = [b frame]; rect = [b frame];
if (totalw < rect.size.width + 1) totalw = rect.size.width + 1; if (totalw < rect.size.width + 1) totalw = rect.size.width + 1;
if (thish < rect.size.height + 1) thish = rect.size.height + 1; if (thish < rect.size.height + 1) thish = rect.size.height + 1;
@ -1161,12 +1162,14 @@ struct frontend {
pb = [[NSPopUpButton alloc] initWithFrame:tmprect pullsDown:NO]; pb = [[NSPopUpButton alloc] initWithFrame:tmprect pullsDown:NO];
[pb setBezelStyle:NSRoundedBezelStyle]; [pb setBezelStyle:NSRoundedBezelStyle];
{ {
char c, *p; char c;
const char *p;
p = i->sval; p = i->u.choices.choicenames;
c = *p++; c = *p++;
while (*p) { while (*p) {
char *q, *copy; const char *q;
char *copy;
q = p; q = p;
while (*p && *p != c) p++; while (*p && *p != c) p++;
@ -1180,7 +1183,7 @@ struct frontend {
if (*p) p++; if (*p) p++;
} }
} }
[pb selectItemAtIndex:i->ival]; [pb selectItemAtIndex:i->u.choices.selected];
[pb sizeToFit]; [pb sizeToFit];
rect = [pb frame]; rect = [pb frame];
@ -1297,23 +1300,24 @@ struct frontend {
if (update) { if (update) {
int k; int k;
config_item *i; config_item *i;
char *error; const char *error;
k = 0; k = 0;
for (i = cfg; i->type != C_END; i++) { for (i = cfg; i->type != C_END; i++) {
switch (i->type) { switch (i->type) {
case C_STRING: case C_STRING:
sfree(i->sval); sfree(i->u.string.sval);
i->sval = dupstr([[[(id)cfg_controls[k+1] cell] i->u.string.sval = dupstr([[[(id)cfg_controls[k+1] cell]
title] UTF8String]); title] UTF8String]);
k += 2; k += 2;
break; break;
case C_BOOLEAN: case C_BOOLEAN:
i->ival = [(id)cfg_controls[k] state] == NSOnState; i->u.boolean.bval = [(id)cfg_controls[k] state] == NSOnState;
k++; k++;
break; break;
case C_CHOICES: case C_CHOICES:
i->ival = [(id)cfg_controls[k+1] indexOfSelectedItem]; i->u.choices.selected =
[(id)cfg_controls[k+1] indexOfSelectedItem];
k += 2; k += 2;
break; break;
} }
@ -1344,7 +1348,7 @@ struct frontend {
[self sheetEndWithStatus:NO]; [self sheetEndWithStatus:NO];
} }
- (void)setStatusLine:(char *)text - (void)setStatusLine:(const char *)text
{ {
[[status cell] setTitle:[NSString stringWithUTF8String:text]]; [[status cell] setTitle:[NSString stringWithUTF8String:text]];
} }
@ -1457,7 +1461,8 @@ static void osx_draw_rect(void *handle, int x, int y, int w, int h, int colour)
NSRectFill(r); NSRectFill(r);
} }
static void osx_draw_text(void *handle, int x, int y, int fonttype, static void osx_draw_text(void *handle, int x, int y, int fonttype,
int fontsize, int align, int colour, char *text) int fontsize, int align, int colour,
const char *text)
{ {
frontend *fe = (frontend *)handle; frontend *fe = (frontend *)handle;
NSString *string = [NSString stringWithUTF8String:text]; NSString *string = [NSString stringWithUTF8String:text];
@ -1608,7 +1613,7 @@ static void osx_end_draw(void *handle)
frontend *fe = (frontend *)handle; frontend *fe = (frontend *)handle;
[fe->image unlockFocus]; [fe->image unlockFocus];
} }
static void osx_status_bar(void *handle, char *text) static void osx_status_bar(void *handle, const char *text)
{ {
frontend *fe = (frontend *)handle; frontend *fe = (frontend *)handle;
[fe->window setStatusLine:text]; [fe->window setStatusLine:text];

View file

@ -119,10 +119,20 @@ static config_item *game_configure(const game_params *params)
{ {
config_item *ret = snewn(4, config_item); config_item *ret = snewn(4, config_item);
CONFIG(0, "Width", C_STRING, 0, string(20, "%d", params->w)); ret[0].name = "Width";
CONFIG(1, "Height", C_STRING, 0, string(20, "%d", params->h)); ret[0].type = C_STRING;
CONFIG(2, "Region size", C_STRING, 0, string(20, "%d", params->k)); ret[0].u.string.sval = string(20, "%d", params->w);
CONFIG(3, NULL, C_END, 0, NULL);
ret[1].name = "Height";
ret[1].type = C_STRING;
ret[1].u.string.sval = string(20, "%d", params->h);
ret[2].name = "Region size";
ret[2].type = C_STRING;
ret[2].u.string.sval = string(20, "%d", params->k);
ret[3].name = NULL;
ret[3].type = C_END;
return ret; return ret;
} }
@ -131,9 +141,9 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *params = snew(game_params); game_params *params = snew(game_params);
params->w = atoi(cfg[0].sval); params->w = atoi(cfg[0].u.string.sval);
params->h = atoi(cfg[1].sval); params->h = atoi(cfg[1].u.string.sval);
params->k = atoi(cfg[2].sval); params->k = atoi(cfg[2].u.string.sval);
return params; return params;
} }
@ -145,7 +155,7 @@ static game_params *custom_params(const config_item *cfg)
* +---+ the dominos is horizontal or vertical. +---+---+ * +---+ the dominos is horizontal or vertical. +---+---+
*/ */
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
int w = params->w, h = params->h, k = params->k, wh = w * h; int w = params->w, h = params->h, k = params->k, wh = w * h;
@ -691,7 +701,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return sresize(numbers, p - numbers, clue); return sresize(numbers, p - numbers, clue);
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->w, h = params->h, wh = w*h, squares = 0; int w = params->w, h = params->h, wh = w*h, squares = 0;
@ -772,7 +782,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
int w = state->shared->params.w, h = state->shared->params.h, wh = w*h; int w = state->shared->params.w, h = state->shared->params.h, wh = w*h;
borderflag *move; borderflag *move;
@ -986,7 +996,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->x, ui->y, flag, x, y, newflag); ui->x, ui->y, flag, x, y, newflag);
} else { } else {
move_cursor(button, &ui->x, &ui->y, w, h, FALSE); move_cursor(button, &ui->x, &ui->y, w, h, FALSE);
return ""; return UI_UPDATE;
} }
} }

View file

@ -148,19 +148,15 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = NULL; ret[2].name = NULL;
ret[2].type = C_END; ret[2].type = C_END;
ret[2].sval = NULL;
ret[2].ival = 0;
return ret; return ret;
} }
@ -169,13 +165,13 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w <= 0 || params->h <= 0) if (params->w <= 0 || params->h <= 0)
return "Width and height must both be greater than zero"; return "Width and height must both be greater than zero";
@ -891,7 +887,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return desc; return desc;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int i, n, rowspace; int i, n, rowspace;
const char *p; const char *p;
@ -1051,7 +1047,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *ai, char **error) const char *ai, const char **error)
{ {
unsigned char *matrix; unsigned char *matrix;
int w = state->common->w, h = state->common->h; int w = state->common->w, h = state->common->h;
@ -1287,7 +1283,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->drag_start_y = ui->drag_end_y = y; ui->drag_start_y = ui->drag_end_y = y;
ui->cur_visible = 0; ui->cur_visible = 0;
return ""; /* UI activity occurred */ return UI_UPDATE;
} }
if (ui->dragging && button == ui->drag) { if (ui->dragging && button == ui->drag) {
@ -1316,7 +1312,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->drag_end_x = x; ui->drag_end_x = x;
ui->drag_end_y = y; ui->drag_end_y = y;
return ""; /* UI activity occurred */ return UI_UPDATE;
} }
if (ui->dragging && button == ui->release) { if (ui->dragging && button == ui->release) {
@ -1344,7 +1340,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
x1, y1, x2-x1+1, y2-y1+1); x1, y1, x2-x1+1, y2-y1+1);
return dupstr(buf); return dupstr(buf);
} else } else
return ""; /* UI activity occurred */ return UI_UPDATE;
} }
if (IS_CURSOR_MOVE(button)) { if (IS_CURSOR_MOVE(button)) {
@ -1352,12 +1348,12 @@ static char *interpret_move(const game_state *state, game_ui *ui,
char buf[80]; char buf[80];
move_cursor(button, &ui->cur_x, &ui->cur_y, state->common->w, state->common->h, 0); move_cursor(button, &ui->cur_x, &ui->cur_y, state->common->w, state->common->h, 0);
ui->cur_visible = 1; ui->cur_visible = 1;
if (!control && !shift) return ""; if (!control && !shift) return UI_UPDATE;
newstate = control ? shift ? GRID_UNKNOWN : GRID_FULL : GRID_EMPTY; newstate = control ? shift ? GRID_UNKNOWN : GRID_FULL : GRID_EMPTY;
if (state->grid[y * state->common->w + x] == newstate && if (state->grid[y * state->common->w + x] == newstate &&
state->grid[ui->cur_y * state->common->w + ui->cur_x] == newstate) state->grid[ui->cur_y * state->common->w + ui->cur_x] == newstate)
return ""; return UI_UPDATE;
sprintf(buf, "%c%d,%d,%d,%d", control ? shift ? 'U' : 'F' : 'E', sprintf(buf, "%c%d,%d,%d,%d", control ? shift ? 'U' : 'F' : 'E',
min(x, ui->cur_x), min(y, ui->cur_y), min(x, ui->cur_x), min(y, ui->cur_y),
@ -1372,7 +1368,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
if (button == CURSOR_SELECT2) if (button == CURSOR_SELECT2)
@ -2027,7 +2023,8 @@ int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
game_state *s; game_state *s;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
while (--argc > 0) { while (--argc > 0) {
char *p = *++argv; char *p = *++argv;

View file

@ -234,29 +234,24 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Difficulty"; ret[2].name = "Difficulty";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = DIFFCONFIG; ret[2].u.choices.choicenames = DIFFCONFIG;
ret[2].ival = params->difficulty; ret[2].u.choices.selected = params->difficulty;
ret[3].name = "Allow unsoluble"; ret[3].name = "Allow unsoluble";
ret[3].type = C_BOOLEAN; ret[3].type = C_BOOLEAN;
ret[3].sval = NULL; ret[3].u.boolean.bval = params->nosolve;
ret[3].ival = params->nosolve;
ret[4].name = NULL; ret[4].name = NULL;
ret[4].type = C_END; ret[4].type = C_END;
ret[4].sval = NULL;
ret[4].ival = 0;
return ret; return ret;
} }
@ -265,15 +260,15 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->difficulty = cfg[2].ival; ret->difficulty = cfg[2].u.choices.selected;
ret->nosolve = cfg[3].ival; ret->nosolve = cfg[3].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 5) return "Width must be at least five"; if (params->w < 5) return "Width must be at least five";
if (params->h < 5) return "Height must be at least five"; if (params->h < 5) return "Height must be at least five";
@ -1392,7 +1387,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return desc; return desc;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int i, sizesofar; int i, sizesofar;
const int totalsize = params->w * params->h; const int totalsize = params->w * params->h;
@ -1726,7 +1721,7 @@ static char *solve_for_diff(game_state *state, char *old_lines, char *new_lines)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
game_state *solved = dup_game(state); game_state *solved = dup_game(state);
int i, ret, sz = state->shared->sz; int i, ret, sz = state->shared->sz;
@ -2022,11 +2017,11 @@ static char *mark_in_direction(const game_state *state, int x, int y, int dir,
char ch = primary ? 'F' : 'M', *other; char ch = primary ? 'F' : 'M', *other;
if (!INGRID(state, x, y) || !INGRID(state, x2, y2)) return ""; if (!INGRID(state, x, y) || !INGRID(state, x2, y2)) return UI_UPDATE;
/* disallow laying a mark over a line, or vice versa. */ /* disallow laying a mark over a line, or vice versa. */
other = primary ? state->marks : state->lines; other = primary ? state->marks : state->lines;
if (other[y*w+x] & dir || other[y2*w+x2] & dir2) return ""; if (other[y*w+x] & dir || other[y2*w+x2] & dir2) return UI_UPDATE;
sprintf(buf, "%c%d,%d,%d;%c%d,%d,%d", ch, dir, x, y, ch, dir2, x2, y2); sprintf(buf, "%c%d,%d,%d;%c%d,%d,%d", ch, dir, x, y, ch, dir2, x2, y2);
return dupstr(buf); return dupstr(buf);
@ -2060,12 +2055,12 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->dragcoords[0] = gy * w + gx; ui->dragcoords[0] = gy * w + gx;
ui->ndragcoords = 0; /* will be 1 once drag is confirmed */ ui->ndragcoords = 0; /* will be 1 once drag is confirmed */
return ""; return UI_UPDATE;
} }
if (button == LEFT_DRAG && ui->ndragcoords >= 0) { if (button == LEFT_DRAG && ui->ndragcoords >= 0) {
update_ui_drag(state, ui, gx, gy); update_ui_drag(state, ui, gx, gy);
return ""; return UI_UPDATE;
} }
if (IS_MOUSE_RELEASE(button)) release = TRUE; if (IS_MOUSE_RELEASE(button)) release = TRUE;
@ -2087,30 +2082,30 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (ui->ndragcoords >= 0) if (ui->ndragcoords >= 0)
update_ui_drag(state, ui, ui->curx, ui->cury); update_ui_drag(state, ui, ui->curx, ui->cury);
} }
return ""; return UI_UPDATE;
} }
if (IS_CURSOR_SELECT(button)) { if (IS_CURSOR_SELECT(button)) {
if (!ui->cursor_active) { if (!ui->cursor_active) {
ui->cursor_active = TRUE; ui->cursor_active = TRUE;
return ""; return UI_UPDATE;
} else if (button == CURSOR_SELECT) { } else if (button == CURSOR_SELECT) {
if (ui->ndragcoords == -1) { if (ui->ndragcoords == -1) {
ui->ndragcoords = 0; ui->ndragcoords = 0;
ui->dragcoords[0] = ui->cury * w + ui->curx; ui->dragcoords[0] = ui->cury * w + ui->curx;
ui->clickx = CENTERED_COORD(ui->curx); ui->clickx = CENTERED_COORD(ui->curx);
ui->clicky = CENTERED_COORD(ui->cury); ui->clicky = CENTERED_COORD(ui->cury);
return ""; return UI_UPDATE;
} else release = TRUE; } else release = TRUE;
} else if (button == CURSOR_SELECT2 && ui->ndragcoords >= 0) { } else if (button == CURSOR_SELECT2 && ui->ndragcoords >= 0) {
ui->ndragcoords = -1; ui->ndragcoords = -1;
return ""; return UI_UPDATE;
} }
} }
if (button == 27 || button == '\b') { if (button == 27 || button == '\b') {
ui->ndragcoords = -1; ui->ndragcoords = -1;
return ""; return UI_UPDATE;
} }
if (release) { if (release) {
@ -2142,7 +2137,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->ndragcoords = -1; ui->ndragcoords = -1;
return buf ? buf : ""; return buf ? buf : UI_UPDATE;
} else if (ui->ndragcoords == 0) { } else if (ui->ndragcoords == 0) {
/* Click (or tiny drag). Work out which edge we were /* Click (or tiny drag). Work out which edge we were
* closest to. */ * closest to. */
@ -2163,12 +2158,12 @@ static char *interpret_move(const game_state *state, game_ui *ui,
cx = CENTERED_COORD(gx); cx = CENTERED_COORD(gx);
cy = CENTERED_COORD(gy); cy = CENTERED_COORD(gy);
if (!INGRID(state, gx, gy)) return ""; if (!INGRID(state, gx, gy)) return UI_UPDATE;
if (max(abs(x-cx),abs(y-cy)) < TILE_SIZE/4) { if (max(abs(x-cx),abs(y-cy)) < TILE_SIZE/4) {
/* TODO closer to centre of grid: process as a cell click not an edge click. */ /* TODO closer to centre of grid: process as a cell click not an edge click. */
return ""; return UI_UPDATE;
} else { } else {
int direction; int direction;
if (abs(x-cx) < abs(y-cy)) { if (abs(x-cx) < abs(y-cy)) {
@ -2712,7 +2707,8 @@ int main(int argc, const char *argv[])
game_params *p = NULL; game_params *p = NULL;
random_state *rs = NULL; random_state *rs = NULL;
time_t seed = time(NULL); time_t seed = time(NULL);
char *id = NULL, *err; char *id = NULL;
const char *err;
setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0);

View file

@ -149,24 +149,20 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Board type"; ret[2].name = "Board type";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = TYPECONFIG; ret[2].u.choices.choicenames = TYPECONFIG;
ret[2].ival = params->type; ret[2].u.choices.selected = params->type;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -175,14 +171,14 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->type = cfg[2].ival; ret->type = cfg[2].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (full && (params->w <= 3 || params->h <= 3)) if (full && (params->w <= 3 || params->h <= 3))
return "Width and height must both be greater than three"; return "Width and height must both be greater than three";
@ -660,7 +656,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int len = params->w * params->h; int len = params->w * params->h;
@ -711,7 +707,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
return NULL; return NULL;
} }
@ -848,7 +844,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->dx = x; ui->dx = x;
ui->dy = y; ui->dy = y;
ui->cur_visible = ui->cur_jumping = 0; ui->cur_visible = ui->cur_jumping = 0;
return ""; /* ui modified */ return UI_UPDATE;
} }
} else if (button == LEFT_DRAG && ui->dragging) { } else if (button == LEFT_DRAG && ui->dragging) {
/* /*
@ -856,7 +852,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
*/ */
ui->dx = x; ui->dx = x;
ui->dy = y; ui->dy = y;
return ""; /* ui modified */ return UI_UPDATE;
} else if (button == LEFT_RELEASE && ui->dragging) { } else if (button == LEFT_RELEASE && ui->dragging) {
int tx, ty, dx, dy; int tx, ty, dx, dy;
@ -868,18 +864,18 @@ static char *interpret_move(const game_state *state, game_ui *ui,
tx = FROMCOORD(x); tx = FROMCOORD(x);
ty = FROMCOORD(y); ty = FROMCOORD(y);
if (tx < 0 || tx >= w || ty < 0 || ty >= h) if (tx < 0 || tx >= w || ty < 0 || ty >= h)
return ""; /* target out of range */ return UI_UPDATE; /* target out of range */
dx = tx - ui->sx; dx = tx - ui->sx;
dy = ty - ui->sy; dy = ty - ui->sy;
if (max(abs(dx),abs(dy)) != 2 || min(abs(dx),abs(dy)) != 0) if (max(abs(dx),abs(dy)) != 2 || min(abs(dx),abs(dy)) != 0)
return ""; /* move length was wrong */ return UI_UPDATE; /* move length was wrong */
dx /= 2; dx /= 2;
dy /= 2; dy /= 2;
if (state->grid[ty*w+tx] != GRID_HOLE || if (state->grid[ty*w+tx] != GRID_HOLE ||
state->grid[(ty-dy)*w+(tx-dx)] != GRID_PEG || state->grid[(ty-dy)*w+(tx-dx)] != GRID_PEG ||
state->grid[ui->sy*w+ui->sx] != GRID_PEG) state->grid[ui->sy*w+ui->sx] != GRID_PEG)
return ""; /* grid contents were invalid */ return UI_UPDATE; /* grid contents were invalid */
/* /*
* We have a valid move. Encode it simply as source and * We have a valid move. Encode it simply as source and
@ -899,7 +895,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->cur_x = cx; ui->cur_x = cx;
ui->cur_y = cy; ui->cur_y = cy;
} }
return ""; return UI_UPDATE;
} else { } else {
int dx, dy, mx, my, jx, jy; int dx, dy, mx, my, jx, jy;
@ -922,21 +918,21 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->cur_x = jx; ui->cur_y = jy; ui->cur_x = jx; ui->cur_y = jy;
return dupstr(buf); return dupstr(buf);
} }
return ""; return UI_UPDATE;
} }
} else if (IS_CURSOR_SELECT(button)) { } else if (IS_CURSOR_SELECT(button)) {
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
if (ui->cur_jumping) { if (ui->cur_jumping) {
ui->cur_jumping = 0; ui->cur_jumping = 0;
return ""; return UI_UPDATE;
} }
if (state->grid[ui->cur_y*w+ui->cur_x] == GRID_PEG) { if (state->grid[ui->cur_y*w+ui->cur_x] == GRID_PEG) {
/* cursor is on peg: next arrow-move wil jump. */ /* cursor is on peg: next arrow-move wil jump. */
ui->cur_jumping = 1; ui->cur_jumping = 1;
return ""; return UI_UPDATE;
} }
return NULL; return NULL;
} }

View file

@ -21,7 +21,7 @@ struct psdata {
drawing *drawing; drawing *drawing;
}; };
static void ps_printf(psdata *ps, char *fmt, ...) static void ps_printf(psdata *ps, const char *fmt, ...)
{ {
va_list ap; va_list ap;
@ -73,7 +73,7 @@ static void ps_fill(psdata *ps, int colour)
} }
} }
static void ps_setcolour_internal(psdata *ps, int colour, char *suffix) static void ps_setcolour_internal(psdata *ps, int colour, const char *suffix)
{ {
int hatch; int hatch;
float r, g, b; float r, g, b;
@ -102,7 +102,8 @@ static void ps_stroke(psdata *ps, int colour)
} }
static void ps_draw_text(void *handle, int x, int y, int fonttype, static void ps_draw_text(void *handle, int x, int y, int fonttype,
int fontsize, int align, int colour, char *text) int fontsize, int align, int colour,
const char *text)
{ {
psdata *ps = (psdata *)handle; psdata *ps = (psdata *)handle;

View file

@ -137,30 +137,36 @@ typedef struct psdata psdata;
*/ */
enum { C_STRING, C_CHOICES, C_BOOLEAN, C_END }; enum { C_STRING, C_CHOICES, C_BOOLEAN, C_END };
struct config_item { struct config_item {
/* /* Not dynamically allocated */
* `name' is never dynamically allocated. const char *name;
*/ /* Value from the above C_* enum */
char *name;
/*
* `type' contains one of the above values.
*/
int type; int type;
/* union {
* For C_STRING, `sval' is always dynamically allocated and struct { /* if type == C_STRING */
* non-NULL. For C_BOOLEAN and C_END, `sval' is always NULL. /* Always dynamically allocated and non-NULL */
* For C_CHOICES, `sval' is non-NULL, _not_ dynamically char *sval;
* allocated, and contains a set of option strings separated by } string;
* a delimiter. The delimeter is also the first character in struct { /* if type == C_CHOICES */
* the string, so for example ":Foo:Bar:Baz" gives three /*
* options `Foo', `Bar' and `Baz'. * choicenames is non-NULL, not dynamically allocated, and
*/ * contains a set of option strings separated by a
char *sval; * delimiter. The delimiter is also the first character in
/* * the string, so for example ":Foo:Bar:Baz" gives three
* For C_BOOLEAN, this is TRUE or FALSE. For C_CHOICES, it * options `Foo', `Bar' and `Baz'.
* indicates the chosen index from the `sval' list. In the */
* above example, 0==Foo, 1==Bar and 2==Baz. const char *choicenames;
*/ /*
int ival; * Indicates the chosen index from the options in
* choicenames. In the above example, 0==Foo, 1==Bar and
* 2==Baz.
*/
int selected;
} choices;
struct {
/* just TRUE or FALSE */
int bval;
} boolean;
} u;
}; };
/* /*
@ -218,12 +224,12 @@ game_params *preset_menu_lookup_by_id(struct preset_menu *menu, int id);
/* We can't use #ifdef DEBUG, because Cygwin defines it by default. */ /* We can't use #ifdef DEBUG, because Cygwin defines it by default. */
#ifdef DEBUGGING #ifdef DEBUGGING
#define debug(x) (debug_printf x) #define debug(x) (debug_printf x)
void debug_printf(char *fmt, ...); void debug_printf(const char *fmt, ...);
#else #else
#define debug(x) #define debug(x)
#endif #endif
void fatal(char *fmt, ...); void fatal(const char *fmt, ...);
void frontend_default_colour(frontend *fe, float *output); void frontend_default_colour(frontend *fe, float *output);
void deactivate_timer(frontend *fe); void deactivate_timer(frontend *fe);
void activate_timer(frontend *fe); void activate_timer(frontend *fe);
@ -235,7 +241,7 @@ void get_random_seed(void **randseed, int *randseedsize);
drawing *drawing_new(const drawing_api *api, midend *me, void *handle); drawing *drawing_new(const drawing_api *api, midend *me, void *handle);
void drawing_free(drawing *dr); void drawing_free(drawing *dr);
void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize, void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize,
int align, int colour, char *text); int align, int colour, const char *text);
void draw_rect(drawing *dr, int x, int y, int w, int h, int colour); void draw_rect(drawing *dr, int x, int y, int w, int h, int colour);
void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour); void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour);
void draw_polygon(drawing *dr, int *coords, int npoints, void draw_polygon(drawing *dr, int *coords, int npoints,
@ -250,7 +256,7 @@ void start_draw(drawing *dr);
void draw_update(drawing *dr, int x, int y, int w, int h); void draw_update(drawing *dr, int x, int y, int w, int h);
void end_draw(drawing *dr); void end_draw(drawing *dr);
char *text_fallback(drawing *dr, const char *const *strings, int nstrings); char *text_fallback(drawing *dr, const char *const *strings, int nstrings);
void status_bar(drawing *dr, char *text); void status_bar(drawing *dr, const char *text);
blitter *blitter_new(drawing *dr, int w, int h); blitter *blitter_new(drawing *dr, int w, int h);
void blitter_free(drawing *dr, blitter *bl); void blitter_free(drawing *dr, blitter *bl);
/* save puts the portion of the current display with top-left corner /* save puts the portion of the current display with top-left corner
@ -305,29 +311,31 @@ int midend_which_preset(midend *me);
int midend_wants_statusbar(midend *me); int midend_wants_statusbar(midend *me);
enum { CFG_SETTINGS, CFG_SEED, CFG_DESC, CFG_FRONTEND_SPECIFIC }; enum { CFG_SETTINGS, CFG_SEED, CFG_DESC, CFG_FRONTEND_SPECIFIC };
config_item *midend_get_config(midend *me, int which, char **wintitle); config_item *midend_get_config(midend *me, int which, char **wintitle);
char *midend_set_config(midend *me, int which, config_item *cfg); const char *midend_set_config(midend *me, int which, config_item *cfg);
char *midend_game_id(midend *me, char *id); const char *midend_game_id(midend *me, const char *id);
char *midend_get_game_id(midend *me); char *midend_get_game_id(midend *me);
char *midend_get_random_seed(midend *me); char *midend_get_random_seed(midend *me);
int midend_can_format_as_text_now(midend *me); int midend_can_format_as_text_now(midend *me);
char *midend_text_format(midend *me); char *midend_text_format(midend *me);
char *midend_solve(midend *me); const char *midend_solve(midend *me);
int midend_status(midend *me); int midend_status(midend *me);
int midend_can_undo(midend *me); int midend_can_undo(midend *me);
int midend_can_redo(midend *me); int midend_can_redo(midend *me);
void midend_supersede_game_desc(midend *me, char *desc, char *privdesc); void midend_supersede_game_desc(midend *me, const char *desc,
char *midend_rewrite_statusbar(midend *me, char *text); const char *privdesc);
char *midend_rewrite_statusbar(midend *me, const char *text);
void midend_serialise(midend *me, void midend_serialise(midend *me,
void (*write)(void *ctx, void *buf, int len), void (*write)(void *ctx, const void *buf, int len),
void *wctx); void *wctx);
char *midend_deserialise(midend *me, const char *midend_deserialise(midend *me,
int (*read)(void *ctx, void *buf, int len), int (*read)(void *ctx, void *buf, int len),
void *rctx); void *rctx);
char *identify_game(char **name, int (*read)(void *ctx, void *buf, int len), const char *identify_game(char **name,
void *rctx); int (*read)(void *ctx, void *buf, int len),
void *rctx);
void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx); void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx);
/* Printing functions supplied by the mid-end */ /* Printing functions supplied by the mid-end */
char *midend_print_puzzle(midend *me, document *doc, int with_soln); const char *midend_print_puzzle(midend *me, document *doc, int with_soln);
int midend_tilesize(midend *me); int midend_tilesize(midend *me);
/* /*
@ -385,7 +393,7 @@ void pos2c(int w, int h, int pos, int *cx, int *cy);
* by one pixel; useful for highlighting. Outline is omitted if -1. */ * by one pixel; useful for highlighting. Outline is omitted if -1. */
void draw_text_outline(drawing *dr, int x, int y, int fonttype, void draw_text_outline(drawing *dr, int x, int y, int fonttype,
int fontsize, int align, int fontsize, int align,
int text_colour, int outline_colour, char *text); int text_colour, int outline_colour, const char *text);
/* Copies text left-justified with spaces. Length of string must be /* Copies text left-justified with spaces. Length of string must be
* less than buffer size. */ * less than buffer size. */
@ -587,17 +595,17 @@ struct game {
int can_configure; int can_configure;
config_item *(*configure)(const game_params *params); config_item *(*configure)(const game_params *params);
game_params *(*custom_params)(const config_item *cfg); game_params *(*custom_params)(const config_item *cfg);
char *(*validate_params)(const game_params *params, int full); const char *(*validate_params)(const game_params *params, int full);
char *(*new_desc)(const game_params *params, random_state *rs, char *(*new_desc)(const game_params *params, random_state *rs,
char **aux, int interactive); char **aux, int interactive);
char *(*validate_desc)(const game_params *params, const char *desc); const char *(*validate_desc)(const game_params *params, const char *desc);
game_state *(*new_game)(midend *me, const game_params *params, game_state *(*new_game)(midend *me, const game_params *params,
const char *desc); const char *desc);
game_state *(*dup_game)(const game_state *state); game_state *(*dup_game)(const game_state *state);
void (*free_game)(game_state *state); void (*free_game)(game_state *state);
int can_solve; int can_solve;
char *(*solve)(const game_state *orig, const game_state *curr, char *(*solve)(const game_state *orig, const game_state *curr,
const char *aux, char **error); const char *aux, const char **error);
int can_format_as_text_ever; int can_format_as_text_ever;
int (*can_format_as_text_now)(const game_params *params); int (*can_format_as_text_now)(const game_params *params);
char *(*text_format)(const game_state *state); char *(*text_format)(const game_state *state);
@ -642,7 +650,7 @@ struct game {
*/ */
struct drawing_api { struct drawing_api {
void (*draw_text)(void *handle, int x, int y, int fonttype, int fontsize, void (*draw_text)(void *handle, int x, int y, int fonttype, int fontsize,
int align, int colour, char *text); int align, int colour, const char *text);
void (*draw_rect)(void *handle, int x, int y, int w, int h, int colour); void (*draw_rect)(void *handle, int x, int y, int w, int h, int colour);
void (*draw_line)(void *handle, int x1, int y1, int x2, int y2, void (*draw_line)(void *handle, int x1, int y1, int x2, int y2,
int colour); int colour);
@ -655,7 +663,7 @@ struct drawing_api {
void (*unclip)(void *handle); void (*unclip)(void *handle);
void (*start_draw)(void *handle); void (*start_draw)(void *handle);
void (*end_draw)(void *handle); void (*end_draw)(void *handle);
void (*status_bar)(void *handle, char *text); void (*status_bar)(void *handle, const char *text);
blitter *(*blitter_new)(void *handle, int w, int h); blitter *(*blitter_new)(void *handle, int w, int h);
void (*blitter_free)(void *handle, blitter *bl); void (*blitter_free)(void *handle, blitter *bl);
void (*blitter_save)(void *handle, blitter *bl, int x, int y); void (*blitter_save)(void *handle, blitter *bl, int x, int y);
@ -688,6 +696,14 @@ extern const int gamecount;
extern const game thegame; extern const game thegame;
#endif #endif
/*
* Special string value to return from interpret_move in the case
* where the game UI has been updated but no actual move is being
* appended to the undo chain. Must be declared as a non-const char,
* but should never actually be modified by anyone.
*/
extern char UI_UPDATE[];
/* A little bit of help to lazy developers */ /* A little bit of help to lazy developers */
#define DEFAULT_STATUSBAR_TEXT "Use status_bar() to fill this in." #define DEFAULT_STATUSBAR_TEXT "Use status_bar() to fill this in."

View file

@ -66,7 +66,7 @@
#define setmember(obj, field) ( (obj) . field = field ) #define setmember(obj, field) ( (obj) . field = field )
static char *nfmtstr(int n, char *fmt, ...) { static char *nfmtstr(int n, const char *fmt, ...) {
va_list va; va_list va;
char *ret = snewn(n+1, char); char *ret = snewn(n+1, char);
va_start(va, fmt); va_start(va, fmt);
@ -170,18 +170,14 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
ret[0].sval = nfmtstr(10, "%d", params->w); ret[0].u.string.sval = nfmtstr(10, "%d", params->w);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
ret[1].sval = nfmtstr(10, "%d", params->h); ret[1].u.string.sval = nfmtstr(10, "%d", params->h);
ret[1].ival = 0;
ret[2].name = NULL; ret[2].name = NULL;
ret[2].type = C_END; ret[2].type = C_END;
ret[2].sval = NULL;
ret[2].ival = 0;
return ret; return ret;
} }
@ -189,8 +185,8 @@ static config_item *game_configure(const game_params *params)
static game_params *custom_params(const config_item *configuration) static game_params *custom_params(const config_item *configuration)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(configuration[0].sval); ret->w = atoi(configuration[0].u.string.sval);
ret->h = atoi(configuration[1].sval); ret->h = atoi(configuration[1].u.string.sval);
return ret; return ret;
} }
@ -312,7 +308,7 @@ enum {
static move *solve_internal(const game_state *state, move *base, int diff); static move *solve_internal(const game_state *state, move *base, int diff);
static char *solve_game(const game_state *orig, const game_state *curpos, static char *solve_game(const game_state *orig, const game_state *curpos,
const char *aux, char **error) const char *aux, const char **error)
{ {
int const n = orig->params.w * orig->params.h; int const n = orig->params.w * orig->params.h;
move *const base = snewn(n, move); move *const base = snewn(n, move);
@ -910,7 +906,7 @@ static int dfs_count_white(game_state *state, int cell)
return k; return k;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
int const w = params->w, h = params->h; int const w = params->w, h = params->h;
if (w < 1) return "Error: width is less than 1"; if (w < 1) return "Error: width is less than 1";
@ -1077,7 +1073,7 @@ static char *newdesc_encode_game_description(int area, puzzle_size *grid)
return desc; return desc;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int const n = params->w * params->h; int const n = params->w * params->h;
int squares = 0; int squares = 0;
@ -1360,14 +1356,14 @@ static char *interpret_move(const game_state *state, game_ui *ui,
else if (do_post) else if (do_post)
return nfmtstr(40, "W,%d,%d", ui->r, ui->c); return nfmtstr(40, "W,%d,%d", ui->r, ui->c);
else else
return ""; return UI_UPDATE;
} else if (!out_of_bounds(ui->r + dr[i], ui->c + dc[i], w, h)) { } else if (!out_of_bounds(ui->r + dr[i], ui->c + dc[i], w, h)) {
ui->r += dr[i]; ui->r += dr[i];
ui->c += dc[i]; ui->c += dc[i];
} }
} else ui->cursor_show = TRUE; } else ui->cursor_show = TRUE;
return ""; return UI_UPDATE;
} }
if (action == hint) { if (action == hint) {

View file

@ -183,30 +183,24 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Expansion factor"; ret[2].name = "Expansion factor";
ret[2].type = C_STRING; ret[2].type = C_STRING;
ftoa(buf, params->expandfactor); ftoa(buf, params->expandfactor);
ret[2].sval = dupstr(buf); ret[2].u.string.sval = dupstr(buf);
ret[2].ival = 0;
ret[3].name = "Ensure unique solution"; ret[3].name = "Ensure unique solution";
ret[3].type = C_BOOLEAN; ret[3].type = C_BOOLEAN;
ret[3].sval = NULL; ret[3].u.boolean.bval = params->unique;
ret[3].ival = params->unique;
ret[4].name = NULL; ret[4].name = NULL;
ret[4].type = C_END; ret[4].type = C_END;
ret[4].sval = NULL;
ret[4].ival = 0;
return ret; return ret;
} }
@ -215,15 +209,15 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->expandfactor = (float)atof(cfg[2].sval); ret->expandfactor = (float)atof(cfg[2].u.string.sval);
ret->unique = cfg[3].ival; ret->unique = cfg[3].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w <= 0 || params->h <= 0) if (params->w <= 0 || params->h <= 0)
return "Width and height must both be greater than zero"; return "Width and height must both be greater than zero";
@ -1782,7 +1776,7 @@ static char *new_game_desc(const game_params *params_in, random_state *rs,
return desc; return desc;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int area = params->w * params->h; int area = params->w * params->h;
int squares = 0; int squares = 0;
@ -1983,7 +1977,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *ai, char **error) const char *ai, const char **error)
{ {
unsigned char *vedge, *hedge; unsigned char *vedge, *hedge;
int x, y, len; int x, y, len;
@ -2410,7 +2404,7 @@ static char *interpret_move(const game_state *from, game_ui *ui,
move_cursor(button, &ui->cur_x, &ui->cur_y, from->w, from->h, 0); move_cursor(button, &ui->cur_x, &ui->cur_y, from->w, from->h, 0);
ui->cur_visible = TRUE; ui->cur_visible = TRUE;
active = TRUE; active = TRUE;
if (!ui->cur_dragging) return ""; if (!ui->cur_dragging) return UI_UPDATE;
coord_round((float)ui->cur_x + 0.5F, (float)ui->cur_y + 0.5F, &xc, &yc); coord_round((float)ui->cur_x + 0.5F, (float)ui->cur_y + 0.5F, &xc, &yc);
} else if (IS_CURSOR_SELECT(button)) { } else if (IS_CURSOR_SELECT(button)) {
if (ui->drag_start_x >= 0 && !ui->cur_dragging) { if (ui->drag_start_x >= 0 && !ui->cur_dragging) {
@ -2423,7 +2417,7 @@ static char *interpret_move(const game_state *from, game_ui *ui,
if (!ui->cur_visible) { if (!ui->cur_visible) {
assert(!ui->cur_dragging); assert(!ui->cur_dragging);
ui->cur_visible = TRUE; ui->cur_visible = TRUE;
return ""; return UI_UPDATE;
} }
coord_round((float)ui->cur_x + 0.5F, (float)ui->cur_y + 0.5F, &xc, &yc); coord_round((float)ui->cur_x + 0.5F, (float)ui->cur_y + 0.5F, &xc, &yc);
erasing = (button == CURSOR_SELECT2); erasing = (button == CURSOR_SELECT2);
@ -2444,7 +2438,7 @@ static char *interpret_move(const game_state *from, game_ui *ui,
reset_ui(ui); /* cancel keyboard dragging */ reset_ui(ui); /* cancel keyboard dragging */
ui->cur_dragging = FALSE; ui->cur_dragging = FALSE;
} }
return ""; return UI_UPDATE;
} else if (button != LEFT_DRAG && button != RIGHT_DRAG) { } else if (button != LEFT_DRAG && button != RIGHT_DRAG) {
return NULL; return NULL;
} }
@ -2528,7 +2522,7 @@ static char *interpret_move(const game_state *from, game_ui *ui,
if (ret) if (ret)
return ret; /* a move has been made */ return ret; /* a move has been made */
else if (active) else if (active)
return ""; /* UI activity has occurred */ return UI_UPDATE;
else else
return NULL; return NULL;
} }

View file

@ -241,35 +241,29 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "No. of colours"; ret[2].name = "No. of colours";
ret[2].type = C_STRING; ret[2].type = C_STRING;
sprintf(buf, "%d", params->ncols); sprintf(buf, "%d", params->ncols);
ret[2].sval = dupstr(buf); ret[2].u.string.sval = dupstr(buf);
ret[2].ival = 0;
ret[3].name = "Scoring system"; ret[3].name = "Scoring system";
ret[3].type = C_CHOICES; ret[3].type = C_CHOICES;
ret[3].sval = ":(n-1)^2:(n-2)^2"; ret[3].u.choices.choicenames = ":(n-1)^2:(n-2)^2";
ret[3].ival = params->scoresub-1; ret[3].u.choices.selected = params->scoresub-1;
ret[4].name = "Ensure solubility"; ret[4].name = "Ensure solubility";
ret[4].type = C_BOOLEAN; ret[4].type = C_BOOLEAN;
ret[4].sval = NULL; ret[4].u.boolean.bval = params->soluble;
ret[4].ival = params->soluble;
ret[5].name = NULL; ret[5].name = NULL;
ret[5].type = C_END; ret[5].type = C_END;
ret[5].sval = NULL;
ret[5].ival = 0;
return ret; return ret;
} }
@ -278,16 +272,16 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->ncols = atoi(cfg[2].sval); ret->ncols = atoi(cfg[2].u.string.sval);
ret->scoresub = cfg[3].ival + 1; ret->scoresub = cfg[3].u.choices.selected + 1;
ret->soluble = cfg[4].ival; ret->soluble = cfg[4].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 1 || params->h < 1) if (params->w < 1 || params->h < 1)
return "Width and height must both be positive"; return "Width and height must both be positive";
@ -948,7 +942,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int area = params->w * params->h, i; int area = params->w * params->h, i;
const char *p = desc; const char *p = desc;
@ -1018,7 +1012,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
return NULL; return NULL;
} }
@ -1114,7 +1108,8 @@ static void game_changed_state(game_ui *ui, const game_state *oldstate,
static char *sel_movedesc(game_ui *ui, const game_state *state) static char *sel_movedesc(game_ui *ui, const game_state *state)
{ {
int i; int i;
char *ret, *sep, buf[80]; char *ret, buf[80];
const char *sep;
int retlen, retsize; int retlen, retsize;
retsize = 256; retsize = 256;
@ -1273,7 +1268,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
int x, int y, int button) int x, int y, int button)
{ {
int tx, ty; int tx, ty;
char *ret = ""; char *ret = UI_UPDATE;
ui->displaysel = 0; ui->displaysel = 0;

View file

@ -387,24 +387,19 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Start and end in corners"; ret[2].name = "Start and end in corners";
ret[2].type = C_BOOLEAN; ret[2].type = C_BOOLEAN;
ret[2].sval = NULL; ret[2].u.boolean.bval = params->force_corner_start;
ret[2].ival = params->force_corner_start;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -413,14 +408,14 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->force_corner_start = cfg[2].ival; ret->force_corner_start = cfg[2].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 1) return "Width must be at least one"; if (params->w < 1) return "Width must be at least one";
if (params->h < 1) return "Height must be at least one"; if (params->h < 1) return "Height must be at least one";
@ -502,10 +497,11 @@ static void free_game(game_state *state)
} }
static void unpick_desc(const game_params *params, const char *desc, static void unpick_desc(const game_params *params, const char *desc,
game_state **sout, char **mout) game_state **sout, const char **mout)
{ {
game_state *state = blank_game(params->w, params->h); game_state *state = blank_game(params->w, params->h);
char *msg = NULL, c; const char *msg = NULL;
char c;
int num = 0, i = 0; int num = 0, i = 0;
while (*desc) { while (*desc) {
@ -848,9 +844,9 @@ generate:
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
char *ret = NULL; const char *ret = NULL;
unpick_desc(params, desc, NULL, &ret); unpick_desc(params, desc, NULL, &ret);
return ret; return ret;
@ -1342,7 +1338,7 @@ static int solve_state(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
game_state *tosolve; game_state *tosolve;
char *ret = NULL; char *ret = NULL;
@ -1441,18 +1437,20 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->dx = COORD(ui->cx) + TILE_SIZE/2; ui->dx = COORD(ui->cx) + TILE_SIZE/2;
ui->dy = COORD(ui->cy) + TILE_SIZE/2; ui->dy = COORD(ui->cy) + TILE_SIZE/2;
} }
return ""; return UI_UPDATE;
} else if (IS_CURSOR_SELECT(button)) { } else if (IS_CURSOR_SELECT(button)) {
if (!ui->cshow) if (!ui->cshow)
ui->cshow = 1; ui->cshow = 1;
else if (ui->dragging) { else if (ui->dragging) {
ui->dragging = FALSE; ui->dragging = FALSE;
if (ui->sx == ui->cx && ui->sy == ui->cy) return ""; if (ui->sx == ui->cx && ui->sy == ui->cy) return UI_UPDATE;
if (ui->drag_is_from) { if (ui->drag_is_from) {
if (!isvalidmove(state, 0, ui->sx, ui->sy, ui->cx, ui->cy)) return ""; if (!isvalidmove(state, 0, ui->sx, ui->sy, ui->cx, ui->cy))
return UI_UPDATE;
sprintf(buf, "L%d,%d-%d,%d", ui->sx, ui->sy, ui->cx, ui->cy); sprintf(buf, "L%d,%d-%d,%d", ui->sx, ui->sy, ui->cx, ui->cy);
} else { } else {
if (!isvalidmove(state, 0, ui->cx, ui->cy, ui->sx, ui->sy)) return ""; if (!isvalidmove(state, 0, ui->cx, ui->cy, ui->sx, ui->sy))
return UI_UPDATE;
sprintf(buf, "L%d,%d-%d,%d", ui->cx, ui->cy, ui->sx, ui->sy); sprintf(buf, "L%d,%d-%d,%d", ui->cx, ui->cy, ui->sx, ui->sy);
} }
return dupstr(buf); return dupstr(buf);
@ -1464,7 +1462,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->dy = COORD(ui->cy) + TILE_SIZE/2; ui->dy = COORD(ui->cy) + TILE_SIZE/2;
ui->drag_is_from = (button == CURSOR_SELECT) ? 1 : 0; ui->drag_is_from = (button == CURSOR_SELECT) ? 1 : 0;
} }
return ""; return UI_UPDATE;
} }
if (IS_MOUSE_DOWN(button)) { if (IS_MOUSE_DOWN(button)) {
if (ui->cshow) { if (ui->cshow) {
@ -1492,29 +1490,31 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->dx = mx; ui->dx = mx;
ui->dy = my; ui->dy = my;
ui->cshow = 0; ui->cshow = 0;
return ""; return UI_UPDATE;
} else if (IS_MOUSE_DRAG(button) && ui->dragging) { } else if (IS_MOUSE_DRAG(button) && ui->dragging) {
ui->dx = mx; ui->dx = mx;
ui->dy = my; ui->dy = my;
return ""; return UI_UPDATE;
} else if (IS_MOUSE_RELEASE(button) && ui->dragging) { } else if (IS_MOUSE_RELEASE(button) && ui->dragging) {
ui->dragging = FALSE; ui->dragging = FALSE;
if (ui->sx == x && ui->sy == y) return ""; /* single click */ if (ui->sx == x && ui->sy == y) return UI_UPDATE; /* single click */
if (!INGRID(state, x, y)) { if (!INGRID(state, x, y)) {
int si = ui->sy*w+ui->sx; int si = ui->sy*w+ui->sx;
if (state->prev[si] == -1 && state->next[si] == -1) if (state->prev[si] == -1 && state->next[si] == -1)
return ""; return UI_UPDATE;
sprintf(buf, "%c%d,%d", sprintf(buf, "%c%d,%d",
(int)(ui->drag_is_from ? 'C' : 'X'), ui->sx, ui->sy); (int)(ui->drag_is_from ? 'C' : 'X'), ui->sx, ui->sy);
return dupstr(buf); return dupstr(buf);
} }
if (ui->drag_is_from) { if (ui->drag_is_from) {
if (!isvalidmove(state, 0, ui->sx, ui->sy, x, y)) return ""; if (!isvalidmove(state, 0, ui->sx, ui->sy, x, y))
return UI_UPDATE;
sprintf(buf, "L%d,%d-%d,%d", ui->sx, ui->sy, x, y); sprintf(buf, "L%d,%d-%d,%d", ui->sx, ui->sy, x, y);
} else { } else {
if (!isvalidmove(state, 0, x, y, ui->sx, ui->sy)) return ""; if (!isvalidmove(state, 0, x, y, ui->sx, ui->sy))
return UI_UPDATE;
sprintf(buf, "L%d,%d-%d,%d", x, y, ui->sx, ui->sy); sprintf(buf, "L%d,%d-%d,%d", x, y, ui->sx, ui->sy);
} }
return dupstr(buf); return dupstr(buf);
@ -1523,7 +1523,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
else if ((button == 'x' || button == 'X') && ui->cshow) { else if ((button == 'x' || button == 'X') && ui->cshow) {
int si = ui->cy*w + ui->cx; int si = ui->cy*w + ui->cx;
if (state->prev[si] == -1 && state->next[si] == -1) if (state->prev[si] == -1 && state->next[si] == -1)
return ""; return UI_UPDATE;
sprintf(buf, "%c%d,%d", sprintf(buf, "%c%d,%d",
(int)((button == 'x') ? 'C' : 'X'), ui->cx, ui->cy); (int)((button == 'x') ? 'C' : 'X'), ui->cx, ui->cy);
return dupstr(buf); return dupstr(buf);
@ -1560,7 +1560,7 @@ static game_state *execute_move(const game_state *state, const char *move)
if (move[0] == 'S') { if (move[0] == 'S') {
game_params p; game_params p;
game_state *tmp; game_state *tmp;
char *valid; const char *valid;
int i; int i;
p.w = state->w; p.h = state->h; p.w = state->w; p.h = state->h;
@ -2330,7 +2330,8 @@ static void start_soak(game_params *p, char *seedstr)
static void process_desc(char *id) static void process_desc(char *id)
{ {
char *desc, *err, *solvestr; char *desc, *solvestr;
const char *err;
game_params *p; game_params *p;
game_state *s; game_state *s;
@ -2374,7 +2375,8 @@ static void process_desc(char *id)
int main(int argc, const char *argv[]) int main(int argc, const char *argv[])
{ {
char *id = NULL, *desc, *err, *aux = NULL; char *id = NULL, *desc, *aux = NULL;
const char *err;
int soak = 0, verbose = 0, stdin_desc = 0, n = 1, i; int soak = 0, verbose = 0, stdin_desc = 0, n = 1, i;
char *seedstr = NULL, newseed[16]; char *seedstr = NULL, newseed[16];

View file

@ -222,24 +222,20 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Difficulty"; ret[2].name = "Difficulty";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = DIFFCONFIG; ret[2].u.choices.choicenames = DIFFCONFIG;
ret[2].ival = params->diff; ret[2].u.choices.selected = params->diff;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -248,14 +244,14 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->diff = cfg[2].ival; ret->diff = cfg[2].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 2 || params->h < 2) if (params->w < 2 || params->h < 2)
return "Width and neight must be at least two"; return "Width and neight must be at least two";
@ -334,10 +330,10 @@ static int c2n(char c) {
} }
static void unpick_desc(const game_params *params, const char *desc, static void unpick_desc(const game_params *params, const char *desc,
game_state **sout, char **mout) game_state **sout, const char **mout)
{ {
game_state *state = blank_game(params->w, params->h); game_state *state = blank_game(params->w, params->h);
char *msg = NULL; const char *msg = NULL;
int num = 0, i = 0; int num = 0, i = 0;
if (strlen(desc) != state->n) { if (strlen(desc) != state->n) {
@ -1185,7 +1181,7 @@ static int solve_specific(game_state *state, int diff, int sneaky)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
game_state *solved = dup_game(currstate); game_state *solved = dup_game(currstate);
char *move = NULL; char *move = NULL;
@ -1414,9 +1410,9 @@ randomise:
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
char *ret = NULL; const char *ret = NULL;
unpick_desc(params, desc, NULL, &ret); unpick_desc(params, desc, NULL, &ret);
return ret; return ret;
@ -1522,7 +1518,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
action = TOGGLE_CIRCLE; action = TOGGLE_CIRCLE;
} }
} }
if (action == UI) return ""; if (action == UI) return UI_UPDATE;
if (action == TOGGLE_BLACK || action == TOGGLE_CIRCLE) { if (action == TOGGLE_BLACK || action == TOGGLE_CIRCLE) {
i = y * state->w + x; i = y * state->w + x;
@ -1910,7 +1906,8 @@ static void start_soak(game_params *p, random_state *rs)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char *id = NULL, *desc, *desc_gen = NULL, *tgame, *err, *aux; char *id = NULL, *desc, *desc_gen = NULL, *tgame, *aux;
const char *err;
game_state *s = NULL; game_state *s = NULL;
game_params *p = NULL; game_params *p = NULL;
int soln, soak = 0, ret = 1; int soln, soak = 0, ret = 1;

View file

@ -140,25 +140,20 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Number of shuffling moves"; ret[2].name = "Number of shuffling moves";
ret[2].type = C_STRING; ret[2].type = C_STRING;
sprintf(buf, "%d", params->movetarget); sprintf(buf, "%d", params->movetarget);
ret[2].sval = dupstr(buf); ret[2].u.string.sval = dupstr(buf);
ret[2].ival = 0;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -167,14 +162,14 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->movetarget = atoi(cfg[2].sval); ret->movetarget = atoi(cfg[2].u.string.sval);
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 2 || params->h < 2) if (params->w < 2 || params->h < 2)
return "Width and height must both be at least two"; return "Width and height must both be at least two";
@ -402,10 +397,9 @@ static char *new_game_desc(const game_params *params, random_state *rs,
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
const char *p; const char *p, *err;
char *err;
int i, area; int i, area;
int *used; int *used;
@ -510,7 +504,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
return dupstr("S"); return dupstr("S");
} }
@ -619,7 +613,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (IS_CURSOR_MOVE(button) || pad) { if (IS_CURSOR_MOVE(button) || pad) {
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
if (control || shift || ui->cur_mode) { if (control || shift || ui->cur_mode) {
@ -674,7 +668,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} }
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
} }
@ -692,11 +686,11 @@ static char *interpret_move(const game_state *state, game_ui *ui,
const enum cursor_mode m = (button == CURSOR_SELECT2 ? const enum cursor_mode m = (button == CURSOR_SELECT2 ?
lock_position : lock_tile); lock_position : lock_tile);
ui->cur_mode = (ui->cur_mode == m ? unlocked : m); ui->cur_mode = (ui->cur_mode == m ? unlocked : m);
return ""; return UI_UPDATE;
} }
} else { } else {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
} else { } else {
return NULL; return NULL;
@ -711,7 +705,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
else if (cy == state->h && cx >= 0 && cx < state->w) else if (cy == state->h && cx >= 0 && cx < state->w)
dy = +1, dx = 0; dy = +1, dx = 0;
else else
return ""; /* invalid click location */ return UI_UPDATE; /* invalid click location */
/* reverse direction if right hand button is pressed */ /* reverse direction if right hand button is pressed */
if (button == RIGHT_BUTTON || button == CURSOR_SELECT2) { if (button == RIGHT_BUTTON || button == CURSOR_SELECT2) {

View file

@ -184,24 +184,20 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Difficulty"; ret[2].name = "Difficulty";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = DIFFCONFIG; ret[2].u.choices.choicenames = DIFFCONFIG;
ret[2].ival = params->diff; ret[2].u.choices.selected = params->diff;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -210,14 +206,14 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->diff = cfg[2].ival; ret->diff = cfg[2].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
/* /*
* (At least at the time of writing this comment) The grid * (At least at the time of writing this comment) The grid
@ -417,7 +413,7 @@ static void fill_square(int w, int h, int x, int y, int v,
} }
static int vbitmap_clear(int w, int h, struct solver_scratch *sc, static int vbitmap_clear(int w, int h, struct solver_scratch *sc,
int x, int y, int vbits, char *reason, ...) int x, int y, int vbits, const char *reason, ...)
{ {
int done_something = FALSE; int done_something = FALSE;
int vbit; int vbit;
@ -738,7 +734,7 @@ static int slant_solve(int w, int h, const signed char *clues,
int fs, bs, v; int fs, bs, v;
int c1, c2; int c1, c2;
#ifdef SOLVER_DIAGNOSTICS #ifdef SOLVER_DIAGNOSTICS
char *reason = "<internal error>"; const char *reason = "<internal error>";
#endif #endif
if (soln[y*w+x]) if (soln[y*w+x])
@ -1216,7 +1212,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return desc; return desc;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->w, h = params->h, W = w+1, H = h+1; int w = params->w, h = params->h, W = w+1, H = h+1;
int area = W*H; int area = W*H;
@ -1460,7 +1456,7 @@ static int check_completion(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
int w = state->p.w, h = state->p.h; int w = state->p.w, h = state->p.h;
signed char *soln; signed char *soln;
@ -1683,7 +1679,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} else if (IS_CURSOR_SELECT(button)) { } else if (IS_CURSOR_SELECT(button)) {
if (!ui->cur_visible) { if (!ui->cur_visible) {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
x = ui->cur_x; x = ui->cur_x;
y = ui->cur_y; y = ui->cur_y;
@ -1692,7 +1688,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} else if (IS_CURSOR_MOVE(button)) { } else if (IS_CURSOR_MOVE(button)) {
move_cursor(button, &ui->cur_x, &ui->cur_y, w, h, 0); move_cursor(button, &ui->cur_x, &ui->cur_y, w, h, 0);
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} else if (button == '\\' || button == '\b' || button == '/') { } else if (button == '\\' || button == '\b' || button == '/') {
int x = ui->cur_x, y = ui->cur_y; int x = ui->cur_x, y = ui->cur_y;
if (button == ("\\" "\b" "/")[state->soln[y*w + x] + 1]) return NULL; if (button == ("\\" "\b" "/")[state->soln[y*w + x] + 1]) return NULL;
@ -2193,7 +2189,8 @@ int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
game_state *s; game_state *s;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
int grade = FALSE; int grade = FALSE;
int ret, diff, really_verbose = FALSE; int ret, diff, really_verbose = FALSE;
struct solver_scratch *sc; struct solver_scratch *sc;

View file

@ -299,9 +299,9 @@ static game_params *dup_params(const game_params *params)
static int game_fetch_preset(int i, char **name, game_params **params) static int game_fetch_preset(int i, char **name, game_params **params)
{ {
static struct { static struct {
char *title; const char *title;
game_params params; game_params params;
} presets[] = { } const presets[] = {
{ "2x2 Trivial", { 2, 2, SYMM_ROT2, DIFF_BLOCK, DIFF_KMINMAX, FALSE, FALSE } }, { "2x2 Trivial", { 2, 2, SYMM_ROT2, DIFF_BLOCK, DIFF_KMINMAX, FALSE, FALSE } },
{ "2x3 Basic", { 2, 3, SYMM_ROT2, DIFF_SIMPLE, DIFF_KMINMAX, FALSE, FALSE } }, { "2x3 Basic", { 2, 3, SYMM_ROT2, DIFF_SIMPLE, DIFF_KMINMAX, FALSE, FALSE } },
{ "3x3 Trivial", { 3, 3, SYMM_ROT2, DIFF_BLOCK, DIFF_KMINMAX, FALSE, FALSE } }, { "3x3 Trivial", { 3, 3, SYMM_ROT2, DIFF_BLOCK, DIFF_KMINMAX, FALSE, FALSE } },
@ -445,46 +445,39 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Columns of sub-blocks"; ret[0].name = "Columns of sub-blocks";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->c); sprintf(buf, "%d", params->c);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Rows of sub-blocks"; ret[1].name = "Rows of sub-blocks";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->r); sprintf(buf, "%d", params->r);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "\"X\" (require every number in each main diagonal)"; ret[2].name = "\"X\" (require every number in each main diagonal)";
ret[2].type = C_BOOLEAN; ret[2].type = C_BOOLEAN;
ret[2].sval = NULL; ret[2].u.boolean.bval = params->xtype;
ret[2].ival = params->xtype;
ret[3].name = "Jigsaw (irregularly shaped sub-blocks)"; ret[3].name = "Jigsaw (irregularly shaped sub-blocks)";
ret[3].type = C_BOOLEAN; ret[3].type = C_BOOLEAN;
ret[3].sval = NULL; ret[3].u.boolean.bval = (params->r == 1);
ret[3].ival = (params->r == 1);
ret[4].name = "Killer (digit sums)"; ret[4].name = "Killer (digit sums)";
ret[4].type = C_BOOLEAN; ret[4].type = C_BOOLEAN;
ret[4].sval = NULL; ret[4].u.boolean.bval = params->killer;
ret[4].ival = params->killer;
ret[5].name = "Symmetry"; ret[5].name = "Symmetry";
ret[5].type = C_CHOICES; ret[5].type = C_CHOICES;
ret[5].sval = ":None:2-way rotation:4-way rotation:2-way mirror:" ret[5].u.choices.choicenames = ":None:2-way rotation:4-way rotation:2-way mirror:"
"2-way diagonal mirror:4-way mirror:4-way diagonal mirror:" "2-way diagonal mirror:4-way mirror:4-way diagonal mirror:"
"8-way mirror"; "8-way mirror";
ret[5].ival = params->symm; ret[5].u.choices.selected = params->symm;
ret[6].name = "Difficulty"; ret[6].name = "Difficulty";
ret[6].type = C_CHOICES; ret[6].type = C_CHOICES;
ret[6].sval = ":Trivial:Basic:Intermediate:Advanced:Extreme:Unreasonable"; ret[6].u.choices.choicenames = ":Trivial:Basic:Intermediate:Advanced:Extreme:Unreasonable";
ret[6].ival = params->diff; ret[6].u.choices.selected = params->diff;
ret[7].name = NULL; ret[7].name = NULL;
ret[7].type = C_END; ret[7].type = C_END;
ret[7].sval = NULL;
ret[7].ival = 0;
return ret; return ret;
} }
@ -493,22 +486,22 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->c = atoi(cfg[0].sval); ret->c = atoi(cfg[0].u.string.sval);
ret->r = atoi(cfg[1].sval); ret->r = atoi(cfg[1].u.string.sval);
ret->xtype = cfg[2].ival; ret->xtype = cfg[2].u.boolean.bval;
if (cfg[3].ival) { if (cfg[3].u.boolean.bval) {
ret->c *= ret->r; ret->c *= ret->r;
ret->r = 1; ret->r = 1;
} }
ret->killer = cfg[4].ival; ret->killer = cfg[4].u.boolean.bval;
ret->symm = cfg[5].ival; ret->symm = cfg[5].u.choices.selected;
ret->diff = cfg[6].ival; ret->diff = cfg[6].u.choices.selected;
ret->kdiff = DIFF_KINTERSECT; ret->kdiff = DIFF_KINTERSECT;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->c < 2) if (params->c < 2)
return "Both dimensions must be at least 2"; return "Both dimensions must be at least 2";
@ -838,19 +831,20 @@ static void solver_place(struct solver_usage *usage, int x, int y, int n)
*/ */
struct solver_scratch; struct solver_scratch;
static int solver_elim(struct solver_usage *usage, int *indices, static int solver_elim(struct solver_usage *usage, int *indices,
char *fmt, ...) __attribute__((format(printf,3,4))); const char *fmt, ...)
__attribute__((format(printf,3,4)));
static int solver_intersect(struct solver_usage *usage, static int solver_intersect(struct solver_usage *usage,
int *indices1, int *indices2, char *fmt, ...) int *indices1, int *indices2, const char *fmt, ...)
__attribute__((format(printf,4,5))); __attribute__((format(printf,4,5)));
static int solver_set(struct solver_usage *usage, static int solver_set(struct solver_usage *usage,
struct solver_scratch *scratch, struct solver_scratch *scratch,
int *indices, char *fmt, ...) int *indices, const char *fmt, ...)
__attribute__((format(printf,4,5))); __attribute__((format(printf,4,5)));
#endif #endif
static int solver_elim(struct solver_usage *usage, int *indices static int solver_elim(struct solver_usage *usage, int *indices
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
, char *fmt, ... , const char *fmt, ...
#endif #endif
) )
{ {
@ -914,7 +908,7 @@ static int solver_elim(struct solver_usage *usage, int *indices
static int solver_intersect(struct solver_usage *usage, static int solver_intersect(struct solver_usage *usage,
int *indices1, int *indices2 int *indices1, int *indices2
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
, char *fmt, ... , const char *fmt, ...
#endif #endif
) )
{ {
@ -992,7 +986,7 @@ static int solver_set(struct solver_usage *usage,
struct solver_scratch *scratch, struct solver_scratch *scratch,
int *indices int *indices
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
, char *fmt, ... , const char *fmt, ...
#endif #endif
) )
{ {
@ -1358,7 +1352,7 @@ static int solver_forcing(struct solver_usage *usage,
(ondiag1(yt*cr+xt) && ondiag1(y*cr+x)))))) { (ondiag1(yt*cr+xt) && ondiag1(y*cr+x)))))) {
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
if (solver_show_working) { if (solver_show_working) {
char *sep = ""; const char *sep = "";
int xl, yl; int xl, yl;
printf("%*sforcing chain, %d at ends of ", printf("%*sforcing chain, %d at ends of ",
solver_recurse_depth*4, "", orign); solver_recurse_depth*4, "", orign);
@ -2523,7 +2517,7 @@ static void solver(int cr, struct block_structure *blocks,
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
if (solver_show_working) { if (solver_show_working) {
char *sep = ""; const char *sep = "";
printf("%*srecursing on (%d,%d) [", printf("%*srecursing on (%d,%d) [",
solver_recurse_depth*4, "", x + 1, y + 1); solver_recurse_depth*4, "", x + 1, y + 1);
for (i = 0; i < j; i++) { for (i = 0; i < j; i++) {
@ -3161,7 +3155,8 @@ static int symmetries(const game_params *params, int x, int y,
static char *encode_solve_move(int cr, digit *grid) static char *encode_solve_move(int cr, digit *grid)
{ {
int i, len; int i, len;
char *ret, *p, *sep; char *ret, *p;
const char *sep;
/* /*
* It's surprisingly easy to work out _exactly_ how long this * It's surprisingly easy to work out _exactly_ how long this
@ -3861,7 +3856,8 @@ static const char *spec_to_grid(const char *desc, digit *grid, int area)
* end of the block spec, and return an error string or NULL if everything * end of the block spec, and return an error string or NULL if everything
* is OK. The DSF is stored in *PDSF. * is OK. The DSF is stored in *PDSF.
*/ */
static char *spec_to_dsf(const char **pdesc, int **pdsf, int cr, int area) static const char *spec_to_dsf(const char **pdesc, int **pdsf,
int cr, int area)
{ {
const char *desc = *pdesc; const char *desc = *pdesc;
int pos = 0; int pos = 0;
@ -3929,7 +3925,7 @@ static char *spec_to_dsf(const char **pdesc, int **pdsf, int cr, int area)
return NULL; return NULL;
} }
static char *validate_grid_desc(const char **pdesc, int range, int area) static const char *validate_grid_desc(const char **pdesc, int range, int area)
{ {
const char *desc = *pdesc; const char *desc = *pdesc;
int squares = 0; int squares = 0;
@ -3959,11 +3955,11 @@ static char *validate_grid_desc(const char **pdesc, int range, int area)
return NULL; return NULL;
} }
static char *validate_block_desc(const char **pdesc, int cr, int area, static const char *validate_block_desc(const char **pdesc, int cr, int area,
int min_nr_blocks, int max_nr_blocks, int min_nr_blocks, int max_nr_blocks,
int min_nr_squares, int max_nr_squares) int min_nr_squares, int max_nr_squares)
{ {
char *err; const char *err;
int *dsf; int *dsf;
err = spec_to_dsf(pdesc, &dsf, cr, area); err = spec_to_dsf(pdesc, &dsf, cr, area);
@ -4036,10 +4032,10 @@ static char *validate_block_desc(const char **pdesc, int cr, int area,
return NULL; return NULL;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int cr = params->c * params->r, area = cr*cr; int cr = params->c * params->r, area = cr*cr;
char *err; const char *err;
err = validate_grid_desc(&desc, cr, area); err = validate_grid_desc(&desc, cr, area);
if (err) if (err)
@ -4116,7 +4112,7 @@ static game_state *new_game(midend *me, const game_params *params,
state->immutable[i] = TRUE; state->immutable[i] = TRUE;
if (r == 1) { if (r == 1) {
char *err; const char *err;
int *dsf; int *dsf;
assert(*desc == ','); assert(*desc == ',');
desc++; desc++;
@ -4134,7 +4130,7 @@ static game_state *new_game(midend *me, const game_params *params,
make_blocks_from_whichblock(state->blocks); make_blocks_from_whichblock(state->blocks);
if (params->killer) { if (params->killer) {
char *err; const char *err;
int *dsf; int *dsf;
assert(*desc == ','); assert(*desc == ',');
desc++; desc++;
@ -4234,7 +4230,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *ai, char **error) const char *ai, const char **error)
{ {
int cr = state->cr; int cr = state->cr;
char *ret; char *ret;
@ -4586,7 +4582,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->hpencil = 0; ui->hpencil = 0;
} }
ui->hcursor = 0; ui->hcursor = 0;
return ""; /* UI activity occurred */ return UI_UPDATE;
} }
if (button == RIGHT_BUTTON) { if (button == RIGHT_BUTTON) {
/* /*
@ -4606,19 +4602,19 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->hshow = 0; ui->hshow = 0;
} }
ui->hcursor = 0; ui->hcursor = 0;
return ""; /* UI activity occurred */ return UI_UPDATE;
} }
} }
if (IS_CURSOR_MOVE(button)) { if (IS_CURSOR_MOVE(button)) {
move_cursor(button, &ui->hx, &ui->hy, cr, cr, 0); move_cursor(button, &ui->hx, &ui->hy, cr, cr, 0);
ui->hshow = ui->hcursor = 1; ui->hshow = ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
if (ui->hshow && if (ui->hshow &&
(button == CURSOR_SELECT)) { (button == CURSOR_SELECT)) {
ui->hpencil = 1 - ui->hpencil; ui->hpencil = 1 - ui->hpencil;
ui->hcursor = 1; ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
if (ui->hshow && if (ui->hshow &&
@ -5584,7 +5580,8 @@ int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
game_state *s; game_state *s;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
int grade = FALSE; int grade = FALSE;
struct difficulty dlev; struct difficulty dlev;

View file

@ -371,24 +371,20 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Difficulty"; ret[2].name = "Difficulty";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = DIFFCONFIG; ret[2].u.choices.choicenames = DIFFCONFIG;
ret[2].ival = params->diff; ret[2].u.choices.selected = params->diff;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -397,14 +393,14 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->diff = cfg[2].ival; ret->diff = cfg[2].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
/* /*
* Generating anything under 4x4 runs into trouble of one kind * Generating anything under 4x4 runs into trouble of one kind
@ -1190,7 +1186,7 @@ static char *new_game_desc(const game_params *params_in, random_state *rs,
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->w, h = params->h; int w = params->w, h = params->h;
int area, i; int area, i;
@ -1316,7 +1312,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
int w = state->p.w, h = state->p.h; int w = state->p.w, h = state->p.h;
@ -1559,13 +1555,14 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->dsy = ui->dey = y; ui->dsy = ui->dey = y;
ui->drag_ok = TRUE; ui->drag_ok = TRUE;
ui->cdisp = 0; ui->cdisp = 0;
return ""; /* ui updated */ return UI_UPDATE;
} }
if ((IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) && if ((IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) &&
ui->drag_button > 0) { ui->drag_button > 0) {
int xmin, ymin, xmax, ymax; int xmin, ymin, xmax, ymax;
char *buf, *sep; char *buf;
const char *sep;
int buflen, bufsize, tmplen; int buflen, bufsize, tmplen;
x = FROMCOORD(x); x = FROMCOORD(x);
@ -1590,14 +1587,14 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} }
if (IS_MOUSE_DRAG(button)) if (IS_MOUSE_DRAG(button))
return ""; /* ui updated */ return UI_UPDATE;
/* /*
* The drag has been released. Enact it. * The drag has been released. Enact it.
*/ */
if (!ui->drag_ok) { if (!ui->drag_ok) {
ui->drag_button = -1; ui->drag_button = -1;
return ""; /* drag was just cancelled */ return UI_UPDATE; /* drag was just cancelled */
} }
xmin = min(ui->dsx, ui->dex); xmin = min(ui->dsx, ui->dex);
@ -1635,7 +1632,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (buflen == 0) { if (buflen == 0) {
sfree(buf); sfree(buf);
return ""; /* ui updated (drag was terminated) */ return UI_UPDATE; /* drag was terminated */
} else { } else {
buf[buflen] = '\0'; buf[buflen] = '\0';
return buf; return buf;
@ -1663,7 +1660,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (len) return dupstr(tmpbuf); if (len) return dupstr(tmpbuf);
} else } else
move_cursor(button, &ui->cx, &ui->cy, w, h, 0); move_cursor(button, &ui->cx, &ui->cy, w, h, 0);
return ""; return UI_UPDATE;
} }
if (ui->cdisp) { if (ui->cdisp) {
char rep = 0; char rep = 0;
@ -1690,7 +1687,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} }
} else if (IS_CURSOR_SELECT(button)) { } else if (IS_CURSOR_SELECT(button)) {
ui->cdisp = 1; ui->cdisp = 1;
return ""; return UI_UPDATE;
} }
return NULL; return NULL;
@ -2654,7 +2651,8 @@ int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
game_state *s, *s2; game_state *s, *s2;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
int grade = FALSE; int grade = FALSE;
int ret, diff, really_verbose = FALSE; int ret, diff, really_verbose = FALSE;
struct solver_scratch *sc; struct solver_scratch *sc;

View file

@ -212,18 +212,15 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Grid size"; ret[0].name = "Grid size";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Difficulty"; ret[1].name = "Difficulty";
ret[1].type = C_CHOICES; ret[1].type = C_CHOICES;
ret[1].sval = DIFFCONFIG; ret[1].u.choices.choicenames = DIFFCONFIG;
ret[1].ival = params->diff; ret[1].u.choices.selected = params->diff;
ret[2].name = NULL; ret[2].name = NULL;
ret[2].type = C_END; ret[2].type = C_END;
ret[2].sval = NULL;
ret[2].ival = 0;
return ret; return ret;
} }
@ -232,13 +229,13 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->diff = cfg[1].ival; ret->diff = cfg[1].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 3 || params->w > 9) if (params->w < 3 || params->w > 9)
return "Grid size must be between 3 and 9"; return "Grid size must be between 3 and 9";
@ -802,7 +799,7 @@ done
* Gameplay. * Gameplay.
*/ */
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->w, a = w*w; int w = params->w, a = w*w;
const char *p = desc; const char *p = desc;
@ -970,7 +967,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
int w = state->par.w, a = w*w; int w = state->par.w, a = w*w;
int i, ret; int i, ret;
@ -1349,7 +1346,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->hpencil = 0; ui->hpencil = 0;
} }
ui->hcursor = 0; ui->hcursor = 0;
return ""; /* UI activity occurred */ return UI_UPDATE;
} }
if (button == RIGHT_BUTTON) { if (button == RIGHT_BUTTON) {
/* /*
@ -1369,7 +1366,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->hshow = 0; ui->hshow = 0;
} }
ui->hcursor = 0; ui->hcursor = 0;
return ""; /* UI activity occurred */ return UI_UPDATE;
} }
} else if (button == LEFT_BUTTON) { } else if (button == LEFT_BUTTON) {
if (is_clue(state, tx, ty)) { if (is_clue(state, tx, ty)) {
@ -1394,13 +1391,13 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} }
move_cursor(button, &ui->hx, &ui->hy, w, w, 0); move_cursor(button, &ui->hx, &ui->hy, w, w, 0);
ui->hshow = ui->hcursor = 1; ui->hshow = ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
if (ui->hshow && if (ui->hshow &&
(button == CURSOR_SELECT)) { (button == CURSOR_SELECT)) {
ui->hpencil = 1 - ui->hpencil; ui->hpencil = 1 - ui->hpencil;
ui->hcursor = 1; ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
if (ui->hshow && if (ui->hshow &&
@ -2021,7 +2018,8 @@ int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
game_state *s; game_state *s;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
int grade = FALSE; int grade = FALSE;
int ret, diff, really_show_working = FALSE; int ret, diff, really_show_working = FALSE;

View file

@ -148,28 +148,24 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Difficulty"; ret[2].name = "Difficulty";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = DIFFCONFIG; ret[2].u.choices.choicenames = DIFFCONFIG;
ret[2].ival = params->diff; ret[2].u.choices.selected = params->diff;
ret[3].name = "Disallow consecutive 1 clues"; ret[3].name = "Disallow consecutive 1 clues";
ret[3].type = C_BOOLEAN; ret[3].type = C_BOOLEAN;
ret[3].ival = params->single_ones; ret[3].u.boolean.bval = params->single_ones;
ret[4].name = NULL; ret[4].name = NULL;
ret[4].type = C_END; ret[4].type = C_END;
ret[4].sval = NULL;
ret[4].ival = 0;
return ret; return ret;
} }
@ -178,15 +174,15 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->diff = cfg[2].ival; ret->diff = cfg[2].u.choices.selected;
ret->single_ones = cfg[3].ival; ret->single_ones = cfg[3].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
/* /*
* Generating anything under 4x4 runs into trouble of one kind * Generating anything under 4x4 runs into trouble of one kind
@ -786,7 +782,7 @@ newpath:
return desc; return desc;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int i = 0, w = params->w, h = params->h, in = 0, out = 0; int i = 0, w = params->w, h = params->h, in = 0, out = 0;
@ -1368,7 +1364,7 @@ static char *move_string_diff(const game_state *before, const game_state *after,
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
game_state *solved; game_state *solved;
int ret; int ret;
@ -1922,13 +1918,13 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->drag_sx = ui->drag_ex = gx; ui->drag_sx = ui->drag_ex = gx;
ui->drag_sy = ui->drag_ey = gy; ui->drag_sy = ui->drag_ey = gy;
return ""; return UI_UPDATE;
} }
if (IS_MOUSE_DRAG(button)) { if (IS_MOUSE_DRAG(button)) {
ui->cursor_active = FALSE; ui->cursor_active = FALSE;
update_ui_drag(state, ui, gx, gy); update_ui_drag(state, ui, gx, gy);
return ""; return UI_UPDATE;
} }
if (IS_MOUSE_RELEASE(button)) { if (IS_MOUSE_RELEASE(button)) {
@ -1965,12 +1961,12 @@ static char *interpret_move(const game_state *state, game_ui *ui,
cy = CENTERED_COORD(gy); cy = CENTERED_COORD(gy);
if (!INGRID(state, gx, gy) || FROMCOORD(x) != gx || FROMCOORD(y) != gy) if (!INGRID(state, gx, gy) || FROMCOORD(x) != gx || FROMCOORD(y) != gy)
return ""; return UI_UPDATE;
if (max(abs(x-cx),abs(y-cy)) < TILE_SIZE/4) { if (max(abs(x-cx),abs(y-cy)) < TILE_SIZE/4) {
if (ui_can_flip_square(state, gx, gy, button == RIGHT_RELEASE)) if (ui_can_flip_square(state, gx, gy, button == RIGHT_RELEASE))
return square_flip_str(state, gx, gy, button == RIGHT_RELEASE, tmpbuf); return square_flip_str(state, gx, gy, button == RIGHT_RELEASE, tmpbuf);
return ""; return UI_UPDATE;
} else { } else {
if (abs(x-cx) < abs(y-cy)) { if (abs(x-cx) < abs(y-cy)) {
/* Closest to top/bottom edge. */ /* Closest to top/bottom edge. */
@ -1984,7 +1980,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
return edge_flip_str(state, gx, gy, direction, return edge_flip_str(state, gx, gy, direction,
button == RIGHT_RELEASE, tmpbuf); button == RIGHT_RELEASE, tmpbuf);
else else
return ""; return UI_UPDATE;
} }
} }
} }
@ -1997,7 +1993,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (!ui->cursor_active) { if (!ui->cursor_active) {
ui->cursor_active = TRUE; ui->cursor_active = TRUE;
return ""; return UI_UPDATE;
} }
ui->curx = ui->curx + dx; ui->curx = ui->curx + dx;
@ -2008,17 +2004,17 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} }
ui->curx = min(max(ui->curx, 1), 2*w-1); ui->curx = min(max(ui->curx, 1), 2*w-1);
ui->cury = min(max(ui->cury, 1), 2*h-1); ui->cury = min(max(ui->cury, 1), 2*h-1);
return ""; return UI_UPDATE;
} }
if (IS_CURSOR_SELECT(button)) { if (IS_CURSOR_SELECT(button)) {
if (!ui->cursor_active) { if (!ui->cursor_active) {
ui->cursor_active = TRUE; ui->cursor_active = TRUE;
return ""; return UI_UPDATE;
} }
/* click on square corner does nothing (shouldn't get here) */ /* click on square corner does nothing (shouldn't get here) */
if ((ui->curx % 2) == 0 && (ui->cury % 2 == 0)) if ((ui->curx % 2) == 0 && (ui->cury % 2 == 0))
return ""; return UI_UPDATE;
gx = ui->curx / 2; gx = ui->curx / 2;
gy = ui->cury / 2; gy = ui->cury / 2;
@ -2030,7 +2026,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
else if (!direction && else if (!direction &&
ui_can_flip_square(state, gx, gy, button == CURSOR_SELECT2)) ui_can_flip_square(state, gx, gy, button == CURSOR_SELECT2))
return square_flip_str(state, gx, gy, button == CURSOR_SELECT2, tmpbuf); return square_flip_str(state, gx, gy, button == CURSOR_SELECT2, tmpbuf);
return ""; return UI_UPDATE;
} }
#if 0 #if 0
@ -2140,7 +2136,7 @@ enum {
COL_GRID, COL_CLUE, COL_CURSOR, COL_GRID, COL_CLUE, COL_CURSOR,
COL_TRACK, COL_TRACK_CLUE, COL_SLEEPER, COL_TRACK, COL_TRACK_CLUE, COL_SLEEPER,
COL_DRAGON, COL_DRAGOFF, COL_DRAGON, COL_DRAGOFF,
COL_ERROR, COL_FLASH, COL_ERROR, COL_FLASH, COL_ERROR_BACKGROUND,
NCOLOURS NCOLOURS
}; };
@ -2152,11 +2148,12 @@ static float *game_colours(frontend *fe, int *ncolours)
game_mkhighlight(fe, ret, COL_BACKGROUND, COL_HIGHLIGHT, COL_LOWLIGHT); game_mkhighlight(fe, ret, COL_BACKGROUND, COL_HIGHLIGHT, COL_LOWLIGHT);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
ret[COL_TRACK_CLUE * 3 + i] = 0.0F; ret[COL_TRACK_CLUE * 3 + i] = 0.0F;
ret[COL_TRACK * 3 + i] = 0.5F; ret[COL_TRACK * 3 + i] = 0.5F;
ret[COL_CLUE * 3 + i] = 0.0F; ret[COL_CLUE * 3 + i] = 0.0F;
ret[COL_GRID * 3 + i] = 0.75F; ret[COL_GRID * 3 + i] = 0.75F;
ret[COL_CURSOR * 3 + i] = 0.6F; ret[COL_CURSOR * 3 + i] = 0.6F;
ret[COL_ERROR_BACKGROUND * 3 + i] = 1.0F;
} }
ret[COL_SLEEPER * 3 + 0] = 0.5F; ret[COL_SLEEPER * 3 + 0] = 0.5F;
@ -2417,7 +2414,7 @@ static void draw_square(drawing *dr, game_drawstate *ds,
draw_update(dr, ox, oy, TILE_SIZE, TILE_SIZE); draw_update(dr, ox, oy, TILE_SIZE, TILE_SIZE);
} }
static void draw_clue(drawing *dr, game_drawstate *ds, int w, int clue, int i, int col) static void draw_clue(drawing *dr, game_drawstate *ds, int w, int clue, int i, int col, int bg)
{ {
int cx, cy, tsz = TILE_SIZE/2; int cx, cy, tsz = TILE_SIZE/2;
char buf[20]; char buf[20];
@ -2432,7 +2429,7 @@ static void draw_clue(drawing *dr, game_drawstate *ds, int w, int clue, int i, i
draw_rect(dr, cx - tsz + GRID_LINE_TL, cy - tsz + GRID_LINE_TL, draw_rect(dr, cx - tsz + GRID_LINE_TL, cy - tsz + GRID_LINE_TL,
TILE_SIZE - GRID_LINE_ALL, TILE_SIZE - GRID_LINE_ALL, TILE_SIZE - GRID_LINE_ALL, TILE_SIZE - GRID_LINE_ALL,
COL_BACKGROUND); bg);
sprintf(buf, "%d", clue); sprintf(buf, "%d", clue);
draw_text(dr, cx, cy, FONT_VARIABLE, tsz, ALIGN_VCENTRE|ALIGN_HCENTRE, draw_text(dr, cx, cy, FONT_VARIABLE, tsz, ALIGN_VCENTRE|ALIGN_HCENTRE,
col, buf); col, buf);
@ -2518,7 +2515,8 @@ static void game_redraw(drawing *dr, game_drawstate *ds, const game_state *oldst
if (force || (state->num_errors[i] != ds->num_errors[i])) { if (force || (state->num_errors[i] != ds->num_errors[i])) {
ds->num_errors[i] = state->num_errors[i]; ds->num_errors[i] = state->num_errors[i];
draw_clue(dr, ds, w, state->numbers->numbers[i], i, draw_clue(dr, ds, w, state->numbers->numbers[i], i,
ds->num_errors[i] ? COL_ERROR : COL_CLUE); ds->num_errors[i] ? COL_ERROR : COL_CLUE,
ds->num_errors[i] ? COL_ERROR_BACKGROUND : COL_BACKGROUND);
} }
} }
@ -2608,7 +2606,8 @@ static void game_print(drawing *dr, const game_state *state, int tilesize)
/* clue numbers, and loop ends */ /* clue numbers, and loop ends */
for (i = 0; i < w+h; i++) for (i = 0; i < w+h; i++)
draw_clue(dr, ds, w, state->numbers->numbers[i], i, black); draw_clue(dr, ds, w, state->numbers->numbers[i], i,
black, COL_BACKGROUND);
draw_loop_ends(dr, ds, state, black); draw_loop_ends(dr, ds, state, black);
/* clue tracks / solution */ /* clue tracks / solution */

View file

@ -80,9 +80,9 @@ static game_params *dup_params(const game_params *params)
static int game_fetch_preset(int i, char **name, game_params **params) static int game_fetch_preset(int i, char **name, game_params **params)
{ {
static struct { static struct {
char *title; const char *title;
game_params params; game_params params;
} presets[] = { } const presets[] = {
{ "3x3 rows only", { 3, 3, 2, TRUE, FALSE } }, { "3x3 rows only", { 3, 3, 2, TRUE, FALSE } },
{ "3x3 normal", { 3, 3, 2, FALSE, FALSE } }, { "3x3 normal", { 3, 3, 2, FALSE, FALSE } },
{ "3x3 orientable", { 3, 3, 2, FALSE, TRUE } }, { "3x3 orientable", { 3, 3, 2, FALSE, TRUE } },
@ -156,41 +156,33 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Rotating block size"; ret[2].name = "Rotating block size";
ret[2].type = C_STRING; ret[2].type = C_STRING;
sprintf(buf, "%d", params->n); sprintf(buf, "%d", params->n);
ret[2].sval = dupstr(buf); ret[2].u.string.sval = dupstr(buf);
ret[2].ival = 0;
ret[3].name = "One number per row"; ret[3].name = "One number per row";
ret[3].type = C_BOOLEAN; ret[3].type = C_BOOLEAN;
ret[3].sval = NULL; ret[3].u.boolean.bval = params->rowsonly;
ret[3].ival = params->rowsonly;
ret[4].name = "Orientation matters"; ret[4].name = "Orientation matters";
ret[4].type = C_BOOLEAN; ret[4].type = C_BOOLEAN;
ret[4].sval = NULL; ret[4].u.boolean.bval = params->orientable;
ret[4].ival = params->orientable;
ret[5].name = "Number of shuffling moves"; ret[5].name = "Number of shuffling moves";
ret[5].type = C_STRING; ret[5].type = C_STRING;
sprintf(buf, "%d", params->movetarget); sprintf(buf, "%d", params->movetarget);
ret[5].sval = dupstr(buf); ret[5].u.string.sval = dupstr(buf);
ret[5].ival = 0;
ret[6].name = NULL; ret[6].name = NULL;
ret[6].type = C_END; ret[6].type = C_END;
ret[6].sval = NULL;
ret[6].ival = 0;
return ret; return ret;
} }
@ -199,17 +191,17 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->n = atoi(cfg[2].sval); ret->n = atoi(cfg[2].u.string.sval);
ret->rowsonly = cfg[3].ival; ret->rowsonly = cfg[3].u.boolean.bval;
ret->orientable = cfg[4].ival; ret->orientable = cfg[4].u.boolean.bval;
ret->movetarget = atoi(cfg[5].sval); ret->movetarget = atoi(cfg[5].u.string.sval);
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->n < 2) if (params->n < 2)
return "Rotating block size must be at least two"; return "Rotating block size must be at least two";
@ -432,7 +424,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
return ret; return ret;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
const char *p; const char *p;
int w = params->w, h = params->h, wh = w*h; int w = params->w, h = params->h, wh = w*h;
@ -543,7 +535,7 @@ static int compare_int(const void *av, const void *bv)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
return dupstr("S"); return dupstr("S");
} }
@ -663,7 +655,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (button == CURSOR_DOWN && (ui->cur_y+n) < (h)) if (button == CURSOR_DOWN && (ui->cur_y+n) < (h))
ui->cur_y++; ui->cur_y++;
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
if (button == LEFT_BUTTON || button == RIGHT_BUTTON) { if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
@ -687,7 +679,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
dir = (button == CURSOR_SELECT2) ? -1 : +1; dir = (button == CURSOR_SELECT2) ? -1 : +1;
} else { } else {
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return UI_UPDATE;
} }
} else if (button == 'a' || button == 'A' || button==MOD_NUM_KEYPAD+'7') { } else if (button == 'a' || button == 'A' || button==MOD_NUM_KEYPAD+'7') {
x = y = 0; x = y = 0;

View file

@ -163,24 +163,20 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Width"; ret[0].name = "Width";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Height"; ret[1].name = "Height";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->h); sprintf(buf, "%d", params->h);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Difficulty"; ret[2].name = "Difficulty";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = DIFFCONFIG; ret[2].u.choices.choicenames = DIFFCONFIG;
ret[2].ival = params->diff; ret[2].u.choices.selected = params->diff;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -189,13 +185,13 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].u.string.sval);
ret->diff = cfg[2].ival; ret->diff = cfg[2].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if ((params->w * params->h ) > 54) return "Grid is too big"; if ((params->w * params->h ) > 54) return "Grid is too big";
if (params->w < 3) return "Width must be at least 3"; if (params->w < 3) return "Width must be at least 3";
@ -1440,7 +1436,7 @@ static game_state *new_game(midend *me, const game_params *params,
return state; return state;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int i; int i;
int w = params->w, h = params->h; int w = params->w, h = params->h;
@ -1493,7 +1489,7 @@ static char *validate_desc(const game_params *params, const char *desc)
} }
static char *solve_game(const game_state *state_start, const game_state *currstate, static char *solve_game(const game_state *state_start, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
int p; int p;
int *old_guess; int *old_guess;
@ -1725,7 +1721,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (button == 'a' || button == 'A') { if (button == 'a' || button == 'A') {
ui->ascii = !ui->ascii; ui->ascii = !ui->ascii;
return ""; return UI_UPDATE;
} }
if (button == 'm' || button == 'M') { if (button == 'm' || button == 'M') {
@ -1771,12 +1767,12 @@ static char *interpret_move(const game_state *state, game_ui *ui,
case CURSOR_LEFT: ui->hx -= (ui->hx > 1) ? 1 : 0; break; case CURSOR_LEFT: ui->hx -= (ui->hx > 1) ? 1 : 0; break;
} }
ui->hshow = ui->hcursor = 1; ui->hshow = ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
if (ui->hshow && button == CURSOR_SELECT) { if (ui->hshow && button == CURSOR_SELECT) {
ui->hpencil = 1 - ui->hpencil; ui->hpencil = 1 - ui->hpencil;
ui->hcursor = 1; ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
if (ui->hshow == 1 && ui->hpencil == 1) { if (ui->hshow == 1 && ui->hpencil == 1) {
@ -1814,12 +1810,12 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (button == LEFT_BUTTON) { if (button == LEFT_BUTTON) {
ui->hshow = 1; ui->hpencil = 0; ui->hcursor = 0; ui->hshow = 1; ui->hpencil = 0; ui->hcursor = 0;
ui->hx = gx; ui->hy = gy; ui->hx = gx; ui->hy = gy;
return ""; return UI_UPDATE;
} }
else if (button == RIGHT_BUTTON && g == 7) { else if (button == RIGHT_BUTTON && g == 7) {
ui->hshow = 1; ui->hpencil = 1; ui->hcursor = 0; ui->hshow = 1; ui->hpencil = 1; ui->hcursor = 0;
ui->hx = gx; ui->hy = gy; ui->hx = gx; ui->hy = gy;
return ""; return UI_UPDATE;
} }
} }
else if (ui->hshow == 1) { else if (ui->hshow == 1) {
@ -1828,36 +1824,36 @@ static char *interpret_move(const game_state *state, game_ui *ui,
if (gx == ui->hx && gy == ui->hy) { if (gx == ui->hx && gy == ui->hy) {
ui->hshow = 0; ui->hpencil = 0; ui->hcursor = 0; ui->hshow = 0; ui->hpencil = 0; ui->hcursor = 0;
ui->hx = 0; ui->hy = 0; ui->hx = 0; ui->hy = 0;
return ""; return UI_UPDATE;
} }
else { else {
ui->hshow = 1; ui->hpencil = 0; ui->hcursor = 0; ui->hshow = 1; ui->hpencil = 0; ui->hcursor = 0;
ui->hx = gx; ui->hy = gy; ui->hx = gx; ui->hy = gy;
return ""; return UI_UPDATE;
} }
} }
else { else {
ui->hshow = 1; ui->hpencil = 0; ui->hcursor = 0; ui->hshow = 1; ui->hpencil = 0; ui->hcursor = 0;
ui->hx = gx; ui->hy = gy; ui->hx = gx; ui->hy = gy;
return ""; return UI_UPDATE;
} }
} }
else if (button == RIGHT_BUTTON) { else if (button == RIGHT_BUTTON) {
if (ui->hpencil == 0 && g == 7) { if (ui->hpencil == 0 && g == 7) {
ui->hshow = 1; ui->hpencil = 1; ui->hcursor = 0; ui->hshow = 1; ui->hpencil = 1; ui->hcursor = 0;
ui->hx = gx; ui->hy = gy; ui->hx = gx; ui->hy = gy;
return ""; return UI_UPDATE;
} }
else { else {
if (gx == ui->hx && gy == ui->hy) { if (gx == ui->hx && gy == ui->hy) {
ui->hshow = 0; ui->hpencil = 0; ui->hcursor = 0; ui->hshow = 0; ui->hpencil = 0; ui->hcursor = 0;
ui->hx = 0; ui->hy = 0; ui->hx = 0; ui->hy = 0;
return ""; return UI_UPDATE;
} }
else if (g == 7) { else if (g == 7) {
ui->hshow = 1; ui->hpencil = 1; ui->hcursor = 0; ui->hshow = 1; ui->hpencil = 1; ui->hcursor = 0;
ui->hx = gx; ui->hy = gy; ui->hx = gx; ui->hy = gy;
return ""; return UI_UPDATE;
} }
} }
} }

View file

@ -218,24 +218,21 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Mode"; ret[0].name = "Mode";
ret[0].type = C_CHOICES; ret[0].type = C_CHOICES;
ret[0].sval = ":Unequal:Adjacent"; ret[0].u.choices.choicenames = ":Unequal:Adjacent";
ret[0].ival = params->adjacent; ret[0].u.choices.selected = params->adjacent;
ret[1].name = "Size (s*s)"; ret[1].name = "Size (s*s)";
ret[1].type = C_STRING; ret[1].type = C_STRING;
sprintf(buf, "%d", params->order); sprintf(buf, "%d", params->order);
ret[1].sval = dupstr(buf); ret[1].u.string.sval = dupstr(buf);
ret[1].ival = 0;
ret[2].name = "Difficulty"; ret[2].name = "Difficulty";
ret[2].type = C_CHOICES; ret[2].type = C_CHOICES;
ret[2].sval = DIFFCONFIG; ret[2].u.choices.choicenames = DIFFCONFIG;
ret[2].ival = params->diff; ret[2].u.choices.selected = params->diff;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -244,14 +241,14 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->adjacent = cfg[0].ival; ret->adjacent = cfg[0].u.choices.selected;
ret->order = atoi(cfg[1].sval); ret->order = atoi(cfg[1].u.string.sval);
ret->diff = cfg[2].ival; ret->diff = cfg[2].u.choices.selected;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->order < 3 || params->order > 32) if (params->order < 3 || params->order > 32)
return "Order must be between 3 and 32"; return "Order must be between 3 and 32";
@ -1198,12 +1195,12 @@ generate:
} }
static game_state *load_game(const game_params *params, const char *desc, static game_state *load_game(const game_params *params, const char *desc,
char **why_r) const char **why_r)
{ {
game_state *state = blank_game(params->order, params->adjacent); game_state *state = blank_game(params->order, params->adjacent);
const char *p = desc; const char *p = desc;
int i = 0, n, o = params->order, x, y; int i = 0, n, o = params->order, x, y;
char *why = NULL; const char *why = NULL;
while (*p) { while (*p) {
while (*p >= 'a' && *p <= 'z') { while (*p >= 'a' && *p <= 'z') {
@ -1294,9 +1291,9 @@ static game_state *new_game(midend *me, const game_params *params,
return state; return state;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
char *why = NULL; const char *why = NULL;
game_state *dummy = load_game(params, desc, &why); game_state *dummy = load_game(params, desc, &why);
if (dummy) { if (dummy) {
free_game(dummy); free_game(dummy);
@ -1307,7 +1304,7 @@ static char *validate_desc(const game_params *params, const char *desc)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
game_state *solved; game_state *solved;
int r; int r;
@ -1425,7 +1422,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->hshow = 1; ui->hshow = 1;
} }
ui->hcursor = 0; ui->hcursor = 0;
return ""; return UI_UPDATE;
} }
if (button == RIGHT_BUTTON) { if (button == RIGHT_BUTTON) {
/* pencil highlighting for non-filled squares */ /* pencil highlighting for non-filled squares */
@ -1439,7 +1436,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->hshow = 1; ui->hshow = 1;
} }
ui->hcursor = 0; ui->hcursor = 0;
return ""; return UI_UPDATE;
} }
} }
@ -1453,11 +1450,12 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ny != ui->hy + adjthan[i].dy); ++i); ny != ui->hy + adjthan[i].dy); ++i);
if (i == 4) if (i == 4)
return ""; /* invalid direction, i.e. out of the board */ return UI_UPDATE; /* invalid direction, i.e. out of
* the board */
if (!(GRID(state, flags, ui->hx, ui->hy) & adjthan[i].f || if (!(GRID(state, flags, ui->hx, ui->hy) & adjthan[i].f ||
GRID(state, flags, nx, ny ) & adjthan[i].fo)) GRID(state, flags, nx, ny ) & adjthan[i].fo))
return ""; /* no clue to toggle */ return UI_UPDATE; /* no clue to toggle */
if (state->adjacent) if (state->adjacent)
self = (adjthan[i].dx >= 0 && adjthan[i].dy >= 0); self = (adjthan[i].dx >= 0 && adjthan[i].dy >= 0);
@ -1475,13 +1473,13 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} else { } else {
move_cursor(button, &ui->hx, &ui->hy, ds->order, ds->order, FALSE); move_cursor(button, &ui->hx, &ui->hy, ds->order, ds->order, FALSE);
ui->hshow = ui->hcursor = 1; ui->hshow = ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
} }
if (ui->hshow && IS_CURSOR_SELECT(button)) { if (ui->hshow && IS_CURSOR_SELECT(button)) {
ui->hpencil = 1 - ui->hpencil; ui->hpencil = 1 - ui->hpencil;
ui->hcursor = 1; ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
n = c2n(button, state->order); n = c2n(button, state->order);
@ -1568,7 +1566,9 @@ static game_state *execute_move(const game_state *state, const char *move)
} }
return ret; return ret;
} else if (move[0] == 'H') { } else if (move[0] == 'H') {
return solver_hint(state, NULL, DIFF_EASY, DIFF_EASY); ret = solver_hint(state, NULL, DIFF_EASY, DIFF_EASY);
check_complete(ret->nums, ret, 1);
return ret;
} else if (move[0] == 'F' && sscanf(move+1, "%d,%d,%d", &x, &y, &n) == 3 && } else if (move[0] == 'F' && sscanf(move+1, "%d,%d,%d", &x, &y, &n) == 3 &&
x >= 0 && x < state->order && y >= 0 && y < state->order) { x >= 0 && x < state->order && y >= 0 && y < state->order) {
ret = dup_game(state); ret = dup_game(state);
@ -2041,7 +2041,7 @@ const char *quis = NULL;
#if 0 /* currently unused */ #if 0 /* currently unused */
static void debug_printf(char *fmt, ...) static void debug_printf(const char *fmt, ...)
{ {
char buf[4096]; char buf[4096];
va_list ap; va_list ap;
@ -2125,7 +2125,7 @@ static int solve(game_params *p, char *desc, int debug)
static void check(game_params *p) static void check(game_params *p)
{ {
char *msg = validate_params(p, 1); const char *msg = validate_params(p, 1);
if (msg) { if (msg) {
fprintf(stderr, "%s: %s", quis, msg); fprintf(stderr, "%s: %s", quis, msg);
exit(1); exit(1);
@ -2233,7 +2233,8 @@ int main(int argc, const char *argv[])
int i; int i;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
const char *id = *argv++; const char *id = *argv++;
char *desc = strchr(id, ':'), *err; char *desc = strchr(id, ':');
const char *err;
p = default_params(); p = default_params();
if (desc) { if (desc) {
*desc++ = '\0'; *desc++ = '\0';

View file

@ -212,23 +212,19 @@ static config_item *game_configure(const game_params *params)
ret[0].name = "Grid size"; ret[0].name = "Grid size";
ret[0].type = C_STRING; ret[0].type = C_STRING;
sprintf(buf, "%d", params->w); sprintf(buf, "%d", params->w);
ret[0].sval = dupstr(buf); ret[0].u.string.sval = dupstr(buf);
ret[0].ival = 0;
ret[1].name = "Difficulty"; ret[1].name = "Difficulty";
ret[1].type = C_CHOICES; ret[1].type = C_CHOICES;
ret[1].sval = DIFFCONFIG; ret[1].u.choices.choicenames = DIFFCONFIG;
ret[1].ival = params->diff; ret[1].u.choices.selected = params->diff;
ret[2].name = "Show identity"; ret[2].name = "Show identity";
ret[2].type = C_BOOLEAN; ret[2].type = C_BOOLEAN;
ret[2].sval = NULL; ret[2].u.boolean.bval = params->id;
ret[2].ival = params->id;
ret[3].name = NULL; ret[3].name = NULL;
ret[3].type = C_END; ret[3].type = C_END;
ret[3].sval = NULL;
ret[3].ival = 0;
return ret; return ret;
} }
@ -237,14 +233,14 @@ static game_params *custom_params(const config_item *cfg)
{ {
game_params *ret = snew(game_params); game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].u.string.sval);
ret->diff = cfg[1].ival; ret->diff = cfg[1].u.choices.selected;
ret->id = cfg[2].ival; ret->id = cfg[2].u.boolean.bval;
return ret; return ret;
} }
static char *validate_params(const game_params *params, int full) static const char *validate_params(const game_params *params, int full)
{ {
if (params->w < 3 || params->w > 26) if (params->w < 3 || params->w > 26)
return "Grid size must be between 3 and 26"; return "Grid size must be between 3 and 26";
@ -781,7 +777,7 @@ done
* Gameplay. * Gameplay.
*/ */
static char *validate_grid_desc(const char **pdesc, int range, int area) static const char *validate_grid_desc(const char **pdesc, int range, int area)
{ {
const char *desc = *pdesc; const char *desc = *pdesc;
int squares = 0; int squares = 0;
@ -811,7 +807,7 @@ static char *validate_grid_desc(const char **pdesc, int range, int area)
return NULL; return NULL;
} }
static char *validate_desc(const game_params *params, const char *desc) static const char *validate_desc(const game_params *params, const char *desc)
{ {
int w = params->w, a = w*w; int w = params->w, a = w*w;
const char *p = desc; const char *p = desc;
@ -911,7 +907,7 @@ static void free_game(game_state *state)
} }
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, const char **error)
{ {
int w = state->par.w, a = w*w; int w = state->par.w, a = w*w;
int i, ret; int i, ret;
@ -1281,13 +1277,13 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->drag |= 4; /* some movement has happened */ ui->drag |= 4; /* some movement has happened */
if (tcoord >= 0 && tcoord < w) { if (tcoord >= 0 && tcoord < w) {
ui->dragpos = tcoord; ui->dragpos = tcoord;
return ""; return UI_UPDATE;
} }
} else if (IS_MOUSE_RELEASE(button)) { } else if (IS_MOUSE_RELEASE(button)) {
if (ui->drag & 4) { if (ui->drag & 4) {
ui->drag = 0; /* end drag */ ui->drag = 0; /* end drag */
if (state->sequence[ui->dragpos] == ui->dragnum) if (state->sequence[ui->dragpos] == ui->dragnum)
return ""; /* drag was a no-op overall */ return UI_UPDATE; /* drag was a no-op overall */
sprintf(buf, "D%d,%d", ui->dragnum, ui->dragpos); sprintf(buf, "D%d,%d", ui->dragnum, ui->dragpos);
return dupstr(buf); return dupstr(buf);
} else { } else {
@ -1298,7 +1294,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
state->sequence[ui->edgepos]); state->sequence[ui->edgepos]);
return dupstr(buf); return dupstr(buf);
} else } else
return ""; /* no-op */ return UI_UPDATE; /* no-op */
} }
} }
} else if (IS_MOUSE_DOWN(button)) { } else if (IS_MOUSE_DOWN(button)) {
@ -1321,7 +1317,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->hpencil = 0; ui->hpencil = 0;
} }
ui->hcursor = 0; ui->hcursor = 0;
return ""; /* UI activity occurred */ return UI_UPDATE;
} }
if (button == RIGHT_BUTTON) { if (button == RIGHT_BUTTON) {
/* /*
@ -1345,20 +1341,20 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->hshow = 0; ui->hshow = 0;
} }
ui->hcursor = 0; ui->hcursor = 0;
return ""; /* UI activity occurred */ return UI_UPDATE;
} }
} else if (tx >= 0 && tx < w && ty == -1) { } else if (tx >= 0 && tx < w && ty == -1) {
ui->drag = 2; ui->drag = 2;
ui->dragnum = state->sequence[tx]; ui->dragnum = state->sequence[tx];
ui->dragpos = tx; ui->dragpos = tx;
ui->edgepos = FROMCOORD(x + TILESIZE/2); ui->edgepos = FROMCOORD(x + TILESIZE/2);
return ""; return UI_UPDATE;
} else if (ty >= 0 && ty < w && tx == -1) { } else if (ty >= 0 && ty < w && tx == -1) {
ui->drag = 1; ui->drag = 1;
ui->dragnum = state->sequence[ty]; ui->dragnum = state->sequence[ty];
ui->dragpos = ty; ui->dragpos = ty;
ui->edgepos = FROMCOORD(y + TILESIZE/2); ui->edgepos = FROMCOORD(y + TILESIZE/2);
return ""; return UI_UPDATE;
} }
} else if (IS_MOUSE_DRAG(button)) { } else if (IS_MOUSE_DRAG(button)) {
if (!ui->hpencil && if (!ui->hpencil &&
@ -1371,7 +1367,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->odx = ui->ody = 0; ui->odx = ui->ody = 0;
ui->odn = 1; ui->odn = 1;
} }
return ""; return UI_UPDATE;
} }
if (IS_CURSOR_MOVE(button)) { if (IS_CURSOR_MOVE(button)) {
@ -1381,13 +1377,13 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->hx = state->sequence[cx]; ui->hx = state->sequence[cx];
ui->hy = state->sequence[cy]; ui->hy = state->sequence[cy];
ui->hshow = ui->hcursor = 1; ui->hshow = ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
if (ui->hshow && if (ui->hshow &&
(button == CURSOR_SELECT)) { (button == CURSOR_SELECT)) {
ui->hpencil = 1 - ui->hpencil; ui->hpencil = 1 - ui->hpencil;
ui->hcursor = 1; ui->hcursor = 1;
return ""; return UI_UPDATE;
} }
if (ui->hshow && if (ui->hshow &&
@ -2110,7 +2106,8 @@ int main(int argc, char **argv)
{ {
game_params *p; game_params *p;
game_state *s; game_state *s;
char *id = NULL, *desc, *err; char *id = NULL, *desc;
const char *err;
digit *grid; digit *grid;
int grade = FALSE; int grade = FALSE;
int ret, diff, really_show_working = FALSE; int ret, diff, really_show_working = FALSE;

Some files were not shown because too many files have changed in this diff Show more