[Tux4kids-commits] r556 - tuxmath/branches/mathcards_newarch/src
cheezmeister-guest at alioth.debian.org
cheezmeister-guest at alioth.debian.org
Tue Jul 1 16:28:17 UTC 2008
Author: cheezmeister-guest
Date: 2008-07-01 16:28:15 +0000 (Tue, 01 Jul 2008)
New Revision: 556
Modified:
tuxmath/branches/mathcards_newarch/src/ConvertUTF.c
tuxmath/branches/mathcards_newarch/src/ConvertUTF.h
tuxmath/branches/mathcards_newarch/src/SDL_extras.c
tuxmath/branches/mathcards_newarch/src/audio.c
tuxmath/branches/mathcards_newarch/src/credits.c
tuxmath/branches/mathcards_newarch/src/fileops.c
tuxmath/branches/mathcards_newarch/src/game.c
tuxmath/branches/mathcards_newarch/src/gettext.h
tuxmath/branches/mathcards_newarch/src/highscore.c
tuxmath/branches/mathcards_newarch/src/loaders.c
tuxmath/branches/mathcards_newarch/src/mathcards.c
tuxmath/branches/mathcards_newarch/src/mathcards.h
tuxmath/branches/mathcards_newarch/src/pixels.c
tuxmath/branches/mathcards_newarch/src/scandir.c
tuxmath/branches/mathcards_newarch/src/setup.c
tuxmath/branches/mathcards_newarch/src/titlescreen.c
tuxmath/branches/mathcards_newarch/src/titlescreen.h
tuxmath/branches/mathcards_newarch/src/tuxmath.h
tuxmath/branches/mathcards_newarch/src/tuxmathadmin.c
tuxmath/branches/mathcards_newarch/src/tuxmathrc.rc
Log:
Branch: many miscellaneous additions and further work in getting new
code working. Tabs replaced with spaces. Rudimentary gameplay working.
Modified: tuxmath/branches/mathcards_newarch/src/ConvertUTF.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/ConvertUTF.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/ConvertUTF.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -26,10 +26,10 @@
Author: Mark E. Davis, 1994.
Rev History: Rick McGowan, fixes & updates May 2001.
Sept 2001: fixed const & error conditions per
- mods suggested by S. Parent & A. Lillich.
+ mods suggested by S. Parent & A. Lillich.
June 2002: Tim Dodd added detection and handling of incomplete
- source sequences, enhanced error detection, added casts
- to eliminate compiler warnings.
+ source sequences, enhanced error detection, added casts
+ to eliminate compiler warnings.
July 2003: slight mods to back out aggressive FFFE detection.
Jan 2004: updated switches in from-UTF8 conversions.
Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
@@ -53,52 +53,52 @@
#define UNI_SUR_HIGH_END (UTF32)0xDBFF
#define UNI_SUR_LOW_START (UTF32)0xDC00
#define UNI_SUR_LOW_END (UTF32)0xDFFF
-#define false 0
-#define true 1
+#define false 0
+#define true 1
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF16 (
- const UTF32** sourceStart, const UTF32* sourceEnd,
- UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
UTF16* target = *targetStart;
while (source < sourceEnd) {
- UTF32 ch;
- if (target >= targetEnd) {
- result = targetExhausted; break;
- }
- ch = *source++;
- if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
- /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
- if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
- if (flags == strictConversion) {
- --source; /* return to the illegal value itself */
- result = sourceIllegal;
- break;
- } else {
- *target++ = UNI_REPLACEMENT_CHAR;
- }
- } else {
- *target++ = (UTF16)ch; /* normal case */
- }
- } else if (ch > UNI_MAX_LEGAL_UTF32) {
- if (flags == strictConversion) {
- result = sourceIllegal;
- } else {
- *target++ = UNI_REPLACEMENT_CHAR;
- }
- } else {
- /* target is a character in range 0xFFFF - 0x10FFFF. */
- if (target + 1 >= targetEnd) {
- --source; /* Back up source pointer! */
- result = targetExhausted; break;
- }
- ch -= halfBase;
- *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
- *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
- }
+ UTF32 ch;
+ if (target >= targetEnd) {
+ result = targetExhausted; break;
+ }
+ ch = *source++;
+ if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+ /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ if (flags == strictConversion) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ *target++ = (UTF16)ch; /* normal case */
+ }
+ } else if (ch > UNI_MAX_LEGAL_UTF32) {
+ if (flags == strictConversion) {
+ result = sourceIllegal;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ /* target is a character in range 0xFFFF - 0x10FFFF. */
+ if (target + 1 >= targetEnd) {
+ --source; /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ ch -= halfBase;
+ *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+ *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+ }
}
*sourceStart = source;
*targetStart = target;
@@ -108,48 +108,48 @@
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF32 (
- const UTF16** sourceStart, const UTF16* sourceEnd,
- UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
UTF32* target = *targetStart;
UTF32 ch, ch2;
while (source < sourceEnd) {
- const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
- ch = *source++;
- /* If we have a surrogate pair, convert to UTF32 first. */
- if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
- /* If the 16 bits following the high surrogate are in the source buffer... */
- if (source < sourceEnd) {
- ch2 = *source;
- /* If it's a low surrogate, convert to UTF32. */
- if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
- ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
- + (ch2 - UNI_SUR_LOW_START) + halfBase;
- ++source;
- } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
- --source; /* return to the illegal value itself */
- result = sourceIllegal;
- break;
- }
- } else { /* We don't have the 16 bits following the high surrogate. */
- --source; /* return to the high surrogate */
- result = sourceExhausted;
- break;
- }
- } else if (flags == strictConversion) {
- /* UTF-16 surrogate values are illegal in UTF-32 */
- if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
- --source; /* return to the illegal value itself */
- result = sourceIllegal;
- break;
- }
- }
- if (target >= targetEnd) {
- source = oldSource; /* Back up source pointer! */
- result = targetExhausted; break;
- }
- *target++ = ch;
+ const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+ ch = *source++;
+ /* If we have a surrogate pair, convert to UTF32 first. */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+ /* If the 16 bits following the high surrogate are in the source buffer... */
+ if (source < sourceEnd) {
+ ch2 = *source;
+ /* If it's a low surrogate, convert to UTF32. */
+ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+ ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ + (ch2 - UNI_SUR_LOW_START) + halfBase;
+ ++source;
+ } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ } else { /* We don't have the 16 bits following the high surrogate. */
+ --source; /* return to the high surrogate */
+ result = sourceExhausted;
+ break;
+ }
+ } else if (flags == strictConversion) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ }
+ if (target >= targetEnd) {
+ source = oldSource; /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ *target++ = ch;
}
*sourceStart = source;
*targetStart = target;
@@ -188,7 +188,7 @@
* in a UTF-8 sequence.
*/
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
- 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
+ 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
/*
* Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
@@ -212,67 +212,67 @@
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF8 (
- const UTF16** sourceStart, const UTF16* sourceEnd,
- UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
UTF8* target = *targetStart;
while (source < sourceEnd) {
- UTF32 ch;
- unsigned short bytesToWrite = 0;
- const UTF32 byteMask = 0xBF;
- const UTF32 byteMark = 0x80;
- const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
- ch = *source++;
- /* If we have a surrogate pair, convert to UTF32 first. */
- if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
- /* If the 16 bits following the high surrogate are in the source buffer... */
- if (source < sourceEnd) {
- UTF32 ch2 = *source;
- /* If it's a low surrogate, convert to UTF32. */
- if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
- ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
- + (ch2 - UNI_SUR_LOW_START) + halfBase;
- ++source;
- } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
- --source; /* return to the illegal value itself */
- result = sourceIllegal;
- break;
- }
- } else { /* We don't have the 16 bits following the high surrogate. */
- --source; /* return to the high surrogate */
- result = sourceExhausted;
- break;
- }
- } else if (flags == strictConversion) {
- /* UTF-16 surrogate values are illegal in UTF-32 */
- if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
- --source; /* return to the illegal value itself */
- result = sourceIllegal;
- break;
- }
- }
- /* Figure out how many bytes the result will require */
- if (ch < (UTF32)0x80) { bytesToWrite = 1;
- } else if (ch < (UTF32)0x800) { bytesToWrite = 2;
- } else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
- } else if (ch < (UTF32)0x110000) { bytesToWrite = 4;
- } else { bytesToWrite = 3;
- ch = UNI_REPLACEMENT_CHAR;
- }
+ UTF32 ch;
+ unsigned short bytesToWrite = 0;
+ const UTF32 byteMask = 0xBF;
+ const UTF32 byteMark = 0x80;
+ const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+ ch = *source++;
+ /* If we have a surrogate pair, convert to UTF32 first. */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+ /* If the 16 bits following the high surrogate are in the source buffer... */
+ if (source < sourceEnd) {
+ UTF32 ch2 = *source;
+ /* If it's a low surrogate, convert to UTF32. */
+ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+ ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ + (ch2 - UNI_SUR_LOW_START) + halfBase;
+ ++source;
+ } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ } else { /* We don't have the 16 bits following the high surrogate. */
+ --source; /* return to the high surrogate */
+ result = sourceExhausted;
+ break;
+ }
+ } else if (flags == strictConversion) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ }
+ /* Figure out how many bytes the result will require */
+ if (ch < (UTF32)0x80) { bytesToWrite = 1;
+ } else if (ch < (UTF32)0x800) { bytesToWrite = 2;
+ } else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
+ } else if (ch < (UTF32)0x110000) { bytesToWrite = 4;
+ } else { bytesToWrite = 3;
+ ch = UNI_REPLACEMENT_CHAR;
+ }
- target += bytesToWrite;
- if (target > targetEnd) {
- source = oldSource; /* Back up source pointer! */
- target -= bytesToWrite; result = targetExhausted; break;
- }
- switch (bytesToWrite) { /* note: everything falls through. */
- case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
- case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
- case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
- case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]);
- }
- target += bytesToWrite;
+ target += bytesToWrite;
+ if (target > targetEnd) {
+ source = oldSource; /* Back up source pointer! */
+ target -= bytesToWrite; result = targetExhausted; break;
+ }
+ switch (bytesToWrite) { /* note: everything falls through. */
+ case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]);
+ }
+ target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
@@ -297,19 +297,19 @@
const UTF8 *srcptr = source+length;
switch (length) {
default: return false;
- /* Everything else falls through when "true"... */
+ /* Everything else falls through when "true"... */
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 2: if ((a = (*--srcptr)) > 0xBF) return false;
- switch (*source) {
- /* no fall-through in this inner switch */
- case 0xE0: if (a < 0xA0) return false; break;
- case 0xED: if (a > 0x9F) return false; break;
- case 0xF0: if (a < 0x90) return false; break;
- case 0xF4: if (a > 0x8F) return false; break;
- default: if (a < 0x80) return false;
- }
+ switch (*source) {
+ /* no fall-through in this inner switch */
+ case 0xE0: if (a < 0xA0) return false; break;
+ case 0xED: if (a > 0x9F) return false; break;
+ case 0xF0: if (a < 0x90) return false; break;
+ case 0xF4: if (a > 0x8F) return false; break;
+ default: if (a < 0x80) return false;
+ }
case 1: if (*source >= 0x80 && *source < 0xC2) return false;
}
@@ -326,7 +326,7 @@
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
int length = trailingBytesForUTF8[*source]+1;
if (source+length > sourceEnd) {
- return false;
+ return false;
}
return isLegalUTF8(source, length);
}
@@ -334,70 +334,70 @@
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF16 (
- const UTF8** sourceStart, const UTF8* sourceEnd,
- UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;
UTF16* target = *targetStart;
while (source < sourceEnd) {
- UTF32 ch = 0;
- unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
- if (source + extraBytesToRead >= sourceEnd) {
- result = sourceExhausted; break;
- }
- /* Do this check whether lenient or strict */
- if (! isLegalUTF8(source, extraBytesToRead+1)) {
- result = sourceIllegal;
- break;
- }
- /*
- * The cases all fall through. See "Note A" below.
- */
- switch (extraBytesToRead) {
- case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
- case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
- case 3: ch += *source++; ch <<= 6;
- case 2: ch += *source++; ch <<= 6;
- case 1: ch += *source++; ch <<= 6;
- case 0: ch += *source++;
- }
- ch -= offsetsFromUTF8[extraBytesToRead];
+ UTF32 ch = 0;
+ unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+ if (source + extraBytesToRead >= sourceEnd) {
+ result = sourceExhausted; break;
+ }
+ /* Do this check whether lenient or strict */
+ if (! isLegalUTF8(source, extraBytesToRead+1)) {
+ result = sourceIllegal;
+ break;
+ }
+ /*
+ * The cases all fall through. See "Note A" below.
+ */
+ switch (extraBytesToRead) {
+ case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+ case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+ case 3: ch += *source++; ch <<= 6;
+ case 2: ch += *source++; ch <<= 6;
+ case 1: ch += *source++; ch <<= 6;
+ case 0: ch += *source++;
+ }
+ ch -= offsetsFromUTF8[extraBytesToRead];
- if (target >= targetEnd) {
- source -= (extraBytesToRead+1); /* Back up source pointer! */
- result = targetExhausted; break;
- }
- if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
- /* UTF-16 surrogate values are illegal in UTF-32 */
- if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
- if (flags == strictConversion) {
- source -= (extraBytesToRead+1); /* return to the illegal value itself */
- result = sourceIllegal;
- break;
- } else {
- *target++ = UNI_REPLACEMENT_CHAR;
- }
- } else {
- *target++ = (UTF16)ch; /* normal case */
- }
- } else if (ch > UNI_MAX_UTF16) {
- if (flags == strictConversion) {
- result = sourceIllegal;
- source -= (extraBytesToRead+1); /* return to the start */
- break; /* Bail out; shouldn't continue */
- } else {
- *target++ = UNI_REPLACEMENT_CHAR;
- }
- } else {
- /* target is a character in range 0xFFFF - 0x10FFFF. */
- if (target + 1 >= targetEnd) {
- source -= (extraBytesToRead+1); /* Back up source pointer! */
- result = targetExhausted; break;
- }
- ch -= halfBase;
- *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
- *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
- }
+ if (target >= targetEnd) {
+ source -= (extraBytesToRead+1); /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ if (flags == strictConversion) {
+ source -= (extraBytesToRead+1); /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ *target++ = (UTF16)ch; /* normal case */
+ }
+ } else if (ch > UNI_MAX_UTF16) {
+ if (flags == strictConversion) {
+ result = sourceIllegal;
+ source -= (extraBytesToRead+1); /* return to the start */
+ break; /* Bail out; shouldn't continue */
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ /* target is a character in range 0xFFFF - 0x10FFFF. */
+ if (target + 1 >= targetEnd) {
+ source -= (extraBytesToRead+1); /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ ch -= halfBase;
+ *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+ *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+ }
}
*sourceStart = source;
*targetStart = target;
@@ -407,50 +407,50 @@
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF8 (
- const UTF32** sourceStart, const UTF32* sourceEnd,
- UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
UTF8* target = *targetStart;
while (source < sourceEnd) {
- UTF32 ch;
- unsigned short bytesToWrite = 0;
- const UTF32 byteMask = 0xBF;
- const UTF32 byteMark = 0x80;
- ch = *source++;
- if (flags == strictConversion ) {
- /* UTF-16 surrogate values are illegal in UTF-32 */
- if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
- --source; /* return to the illegal value itself */
- result = sourceIllegal;
- break;
- }
- }
- /*
- * Figure out how many bytes the result will require. Turn any
- * illegally large UTF32 things (> Plane 17) into replacement chars.
- */
- if (ch < (UTF32)0x80) { bytesToWrite = 1;
- } else if (ch < (UTF32)0x800) { bytesToWrite = 2;
- } else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
- } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4;
- } else { bytesToWrite = 3;
- ch = UNI_REPLACEMENT_CHAR;
- result = sourceIllegal;
- }
-
- target += bytesToWrite;
- if (target > targetEnd) {
- --source; /* Back up source pointer! */
- target -= bytesToWrite; result = targetExhausted; break;
- }
- switch (bytesToWrite) { /* note: everything falls through. */
- case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
- case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
- case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
- case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
- }
- target += bytesToWrite;
+ UTF32 ch;
+ unsigned short bytesToWrite = 0;
+ const UTF32 byteMask = 0xBF;
+ const UTF32 byteMark = 0x80;
+ ch = *source++;
+ if (flags == strictConversion ) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ }
+ /*
+ * Figure out how many bytes the result will require. Turn any
+ * illegally large UTF32 things (> Plane 17) into replacement chars.
+ */
+ if (ch < (UTF32)0x80) { bytesToWrite = 1;
+ } else if (ch < (UTF32)0x800) { bytesToWrite = 2;
+ } else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
+ } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4;
+ } else { bytesToWrite = 3;
+ ch = UNI_REPLACEMENT_CHAR;
+ result = sourceIllegal;
+ }
+
+ target += bytesToWrite;
+ if (target > targetEnd) {
+ --source; /* Back up source pointer! */
+ target -= bytesToWrite; result = targetExhausted; break;
+ }
+ switch (bytesToWrite) { /* note: everything falls through. */
+ case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
+ }
+ target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
@@ -460,59 +460,59 @@
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF32 (
- const UTF8** sourceStart, const UTF8* sourceEnd,
- UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;
UTF32* target = *targetStart;
while (source < sourceEnd) {
- UTF32 ch = 0;
- unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
- if (source + extraBytesToRead >= sourceEnd) {
- result = sourceExhausted; break;
- }
- /* Do this check whether lenient or strict */
- if (! isLegalUTF8(source, extraBytesToRead+1)) {
- result = sourceIllegal;
- break;
- }
- /*
- * The cases all fall through. See "Note A" below.
- */
- switch (extraBytesToRead) {
- case 5: ch += *source++; ch <<= 6;
- case 4: ch += *source++; ch <<= 6;
- case 3: ch += *source++; ch <<= 6;
- case 2: ch += *source++; ch <<= 6;
- case 1: ch += *source++; ch <<= 6;
- case 0: ch += *source++;
- }
- ch -= offsetsFromUTF8[extraBytesToRead];
+ UTF32 ch = 0;
+ unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+ if (source + extraBytesToRead >= sourceEnd) {
+ result = sourceExhausted; break;
+ }
+ /* Do this check whether lenient or strict */
+ if (! isLegalUTF8(source, extraBytesToRead+1)) {
+ result = sourceIllegal;
+ break;
+ }
+ /*
+ * The cases all fall through. See "Note A" below.
+ */
+ switch (extraBytesToRead) {
+ case 5: ch += *source++; ch <<= 6;
+ case 4: ch += *source++; ch <<= 6;
+ case 3: ch += *source++; ch <<= 6;
+ case 2: ch += *source++; ch <<= 6;
+ case 1: ch += *source++; ch <<= 6;
+ case 0: ch += *source++;
+ }
+ ch -= offsetsFromUTF8[extraBytesToRead];
- if (target >= targetEnd) {
- source -= (extraBytesToRead+1); /* Back up the source pointer! */
- result = targetExhausted; break;
- }
- if (ch <= UNI_MAX_LEGAL_UTF32) {
- /*
- * UTF-16 surrogate values are illegal in UTF-32, and anything
- * over Plane 17 (> 0x10FFFF) is illegal.
- */
- if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
- if (flags == strictConversion) {
- source -= (extraBytesToRead+1); /* return to the illegal value itself */
- result = sourceIllegal;
- break;
- } else {
- *target++ = UNI_REPLACEMENT_CHAR;
- }
- } else {
- *target++ = ch;
- }
- } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
- result = sourceIllegal;
- *target++ = UNI_REPLACEMENT_CHAR;
- }
+ if (target >= targetEnd) {
+ source -= (extraBytesToRead+1); /* Back up the source pointer! */
+ result = targetExhausted; break;
+ }
+ if (ch <= UNI_MAX_LEGAL_UTF32) {
+ /*
+ * UTF-16 surrogate values are illegal in UTF-32, and anything
+ * over Plane 17 (> 0x10FFFF) is illegal.
+ */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ if (flags == strictConversion) {
+ source -= (extraBytesToRead+1); /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ *target++ = ch;
+ }
+ } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
+ result = sourceIllegal;
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
}
*sourceStart = source;
*targetStart = target;
@@ -525,14 +525,14 @@
The fall-through switches in UTF-8 reading code save a
temp variable, some decrements & conditionals. The switches
are equivalent to the following loop:
- {
- int tmpBytesToRead = extraBytesToRead+1;
- do {
- ch += *source++;
- --tmpBytesToRead;
- if (tmpBytesToRead) ch <<= 6;
- } while (tmpBytesToRead > 0);
- }
+ {
+ int tmpBytesToRead = extraBytesToRead+1;
+ do {
+ ch += *source++;
+ --tmpBytesToRead;
+ if (tmpBytesToRead) ch <<= 6;
+ } while (tmpBytesToRead > 0);
+ }
In UTF-8 writing code, the switches on "bytesToWrite" are
similarly unrolled loops.
Modified: tuxmath/branches/mathcards_newarch/src/ConvertUTF.h
===================================================================
--- tuxmath/branches/mathcards_newarch/src/ConvertUTF.h 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/ConvertUTF.h 2008-07-01 16:28:15 UTC (rev 556)
@@ -45,12 +45,12 @@
the respective buffers.
Input parameters:
- sourceStart - pointer to a pointer to the source buffer.
- The contents of this are modified on return so that
- it points at the next thing to be converted.
- targetStart - similarly, pointer to pointer to the target buffer.
- sourceEnd, targetEnd - respectively pointers to the ends of the
- two buffers, for overflow checking only.
+ sourceStart - pointer to a pointer to the source buffer.
+ The contents of this are modified on return so that
+ it points at the next thing to be converted.
+ targetStart - similarly, pointer to pointer to the target buffer.
+ sourceEnd, targetEnd - respectively pointers to the ends of the
+ two buffers, for overflow checking only.
These conversion functions take a ConversionFlags argument. When this
flag is set to strict, both irregular sequences and isolated surrogates
@@ -67,15 +67,15 @@
they constitute an error.
Output parameters:
- The value "sourceIllegal" is returned from some routines if the input
- sequence is malformed. When "sourceIllegal" is returned, the source
- value will point to the illegal value that caused the problem. E.g.,
- in UTF-8 when a sequence is malformed, it points to the start of the
- malformed sequence.
+ The value "sourceIllegal" is returned from some routines if the input
+ sequence is malformed. When "sourceIllegal" is returned, the source
+ value will point to the illegal value that caused the problem. E.g.,
+ in UTF-8 when a sequence is malformed, it points to the start of the
+ malformed sequence.
Author: Mark E. Davis, 1994.
Rev History: Rick McGowan, fixes & updates May 2001.
- Fixes & updates, Sept 2001.
+ Fixes & updates, Sept 2001.
------------------------------------------------------------------------ */
@@ -87,10 +87,10 @@
bit mask & shift operations.
------------------------------------------------------------------------ */
-typedef unsigned long UTF32; /* at least 32 bits */
-typedef unsigned short UTF16; /* at least 16 bits */
-typedef unsigned char UTF8; /* typically 8 bits */
-typedef unsigned char Boolean; /* 0 or 1 */
+typedef unsigned long UTF32; /* at least 32 bits */
+typedef unsigned short UTF16; /* at least 16 bits */
+typedef unsigned char UTF8; /* typically 8 bits */
+typedef unsigned char Boolean; /* 0 or 1 */
/* Some fundamental constants */
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
@@ -100,15 +100,15 @@
#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
typedef enum {
- conversionOK, /* conversion successful */
- sourceExhausted, /* partial character in source, but hit end */
- targetExhausted, /* insuff. room in target for conversion */
- sourceIllegal /* source sequence is illegal/malformed */
+ conversionOK, /* conversion successful */
+ sourceExhausted, /* partial character in source, but hit end */
+ targetExhausted, /* insuff. room in target for conversion */
+ sourceIllegal /* source sequence is illegal/malformed */
} ConversionResult;
typedef enum {
- strictConversion = 0,
- lenientConversion
+ strictConversion = 0,
+ lenientConversion
} ConversionFlags;
/* This is for C++ and does no harm in C */
@@ -117,28 +117,28 @@
#endif
ConversionResult ConvertUTF8toUTF16 (
- const UTF8** sourceStart, const UTF8* sourceEnd,
- UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF16toUTF8 (
- const UTF16** sourceStart, const UTF16* sourceEnd,
- UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
-
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
ConversionResult ConvertUTF8toUTF32 (
- const UTF8** sourceStart, const UTF8* sourceEnd,
- UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF32toUTF8 (
- const UTF32** sourceStart, const UTF32* sourceEnd,
- UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
-
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
ConversionResult ConvertUTF16toUTF32 (
- const UTF16** sourceStart, const UTF16* sourceEnd,
- UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF32toUTF16 (
- const UTF32** sourceStart, const UTF32* sourceEnd,
- UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
Modified: tuxmath/branches/mathcards_newarch/src/SDL_extras.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/SDL_extras.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/SDL_extras.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -152,92 +152,92 @@
note: you can have it flip both
**********************/
SDL_Surface* Flip( SDL_Surface *in, int x, int y ) {
- SDL_Surface *out, *tmp;
- SDL_Rect from_rect, to_rect;
- Uint32 flags;
- Uint32 colorkey=0;
+ SDL_Surface *out, *tmp;
+ SDL_Rect from_rect, to_rect;
+ Uint32 flags;
+ Uint32 colorkey=0;
- /* --- grab the settings for the incoming pixmap --- */
+ /* --- grab the settings for the incoming pixmap --- */
- SDL_LockSurface(in);
- flags = in->flags;
+ SDL_LockSurface(in);
+ flags = in->flags;
- /* --- change in's flags so ignore colorkey & alpha --- */
+ /* --- change in's flags so ignore colorkey & alpha --- */
- if (flags & SDL_SRCCOLORKEY) {
- in->flags &= ~SDL_SRCCOLORKEY;
- colorkey = in->format->colorkey;
- }
- if (flags & SDL_SRCALPHA) {
- in->flags &= ~SDL_SRCALPHA;
- }
+ if (flags & SDL_SRCCOLORKEY) {
+ in->flags &= ~SDL_SRCCOLORKEY;
+ colorkey = in->format->colorkey;
+ }
+ if (flags & SDL_SRCALPHA) {
+ in->flags &= ~SDL_SRCALPHA;
+ }
- SDL_UnlockSurface(in);
+ SDL_UnlockSurface(in);
- /* --- create our new surface --- */
+ /* --- create our new surface --- */
- out = SDL_CreateRGBSurface(
- SDL_SWSURFACE,
- in->w, in->h, 32, rmask, gmask, bmask, amask);
+ out = SDL_CreateRGBSurface(
+ SDL_SWSURFACE,
+ in->w, in->h, 32, rmask, gmask, bmask, amask);
- /* --- flip horizontally if requested --- */
+ /* --- flip horizontally if requested --- */
- if (x) {
- from_rect.h = to_rect.h = in->h;
- from_rect.w = to_rect.w = 1;
- from_rect.y = to_rect.y = 0;
- from_rect.x = 0;
- to_rect.x = in->w - 1;
+ if (x) {
+ from_rect.h = to_rect.h = in->h;
+ from_rect.w = to_rect.w = 1;
+ from_rect.y = to_rect.y = 0;
+ from_rect.x = 0;
+ to_rect.x = in->w - 1;
- do {
- SDL_BlitSurface(in, &from_rect, out, &to_rect);
- from_rect.x++;
- to_rect.x--;
- } while (to_rect.x >= 0);
- }
+ do {
+ SDL_BlitSurface(in, &from_rect, out, &to_rect);
+ from_rect.x++;
+ to_rect.x--;
+ } while (to_rect.x >= 0);
+ }
- /* --- flip vertically if requested --- */
+ /* --- flip vertically if requested --- */
- if (y) {
- from_rect.h = to_rect.h = 1;
- from_rect.w = to_rect.w = in->w;
- from_rect.x = to_rect.x = 0;
- from_rect.y = 0;
- to_rect.y = in->h - 1;
+ if (y) {
+ from_rect.h = to_rect.h = 1;
+ from_rect.w = to_rect.w = in->w;
+ from_rect.x = to_rect.x = 0;
+ from_rect.y = 0;
+ to_rect.y = in->h - 1;
- do {
- SDL_BlitSurface(in, &from_rect, out, &to_rect);
- from_rect.y++;
- to_rect.y--;
- } while (to_rect.y >= 0);
- }
+ do {
+ SDL_BlitSurface(in, &from_rect, out, &to_rect);
+ from_rect.y++;
+ to_rect.y--;
+ } while (to_rect.y >= 0);
+ }
- /* --- restore colorkey & alpha on in and setup out the same --- */
+ /* --- restore colorkey & alpha on in and setup out the same --- */
- SDL_LockSurface(in);
+ SDL_LockSurface(in);
- if (flags & SDL_SRCCOLORKEY) {
- in->flags |= SDL_SRCCOLORKEY;
- in->format->colorkey = colorkey;
- tmp = SDL_DisplayFormat(out);
- SDL_FreeSurface(out);
- out = tmp;
- out->flags |= SDL_SRCCOLORKEY;
- out->format->colorkey = colorkey;
- } else if (flags & SDL_SRCALPHA) {
- in->flags |= SDL_SRCALPHA;
- tmp = SDL_DisplayFormatAlpha(out);
- SDL_FreeSurface(out);
- out = tmp;
- } else {
- tmp = SDL_DisplayFormat(out);
- SDL_FreeSurface(out);
- out = tmp;
- }
+ if (flags & SDL_SRCCOLORKEY) {
+ in->flags |= SDL_SRCCOLORKEY;
+ in->format->colorkey = colorkey;
+ tmp = SDL_DisplayFormat(out);
+ SDL_FreeSurface(out);
+ out = tmp;
+ out->flags |= SDL_SRCCOLORKEY;
+ out->format->colorkey = colorkey;
+ } else if (flags & SDL_SRCALPHA) {
+ in->flags |= SDL_SRCALPHA;
+ tmp = SDL_DisplayFormatAlpha(out);
+ SDL_FreeSurface(out);
+ out = tmp;
+ } else {
+ tmp = SDL_DisplayFormat(out);
+ SDL_FreeSurface(out);
+ out = tmp;
+ }
- SDL_UnlockSurface(in);
+ SDL_UnlockSurface(in);
- return out;
+ return out;
}
/* Blend two surfaces together. The third argument is between 0.0 and
@@ -274,7 +274,7 @@
// Check that both images have the same width dimension
if (S1->w != S2->w) {
printf("S1->w %d, S2->w %d; S1->h %d, S2->h %d\n",
- S1->w,S2->w,S1->h,S2->h);
+ S1->w,S2->w,S1->h,S2->h);
printf("Both images must have the same width dimensions\n");
return S1;
}
@@ -434,9 +434,9 @@
int inRect( SDL_Rect r, int x, int y) {
- if ((x < r.x) || (y < r.y) || (x > r.x + r.w) || (y > r.y + r.h))
- return 0;
- return 1;
+ if ((x < r.x) || (y < r.y) || (x > r.x + r.w) || (y > r.y + r.h))
+ return 0;
+ return 1;
}
/* Darkens the screen by a factor of 2^bits */
@@ -548,8 +548,8 @@
/* Create surface for zoom: */
- s = SDL_CreateRGBSurface(src->flags, /* SDL_SWSURFACE, */
- new_w, new_h, src->format->BitsPerPixel,
+ s = SDL_CreateRGBSurface(src->flags, /* SDL_SWSURFACE, */
+ new_w, new_h, src->format->BitsPerPixel,
src->format->Rmask,
src->format->Gmask,
src->format->Bmask,
@@ -558,8 +558,8 @@
if (s == NULL)
{
fprintf(stderr, "\nError: Can't build zoom surface\n"
- "The Simple DirectMedia Layer error that occurred was:\n"
- "%s\n\n", SDL_GetError());
+ "The Simple DirectMedia Layer error that occurred was:\n"
+ "%s\n\n", SDL_GetError());
return NULL;
// cleanup();
// exit(1);
@@ -714,9 +714,9 @@
&& ((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- x); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ x); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
@@ -739,9 +739,9 @@
&& ((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 2)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 2)); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
@@ -764,9 +764,9 @@
&& ((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 3)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 3)); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
@@ -801,15 +801,15 @@
&& ((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 4)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 4)); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
* to the pixel value sent in: */
- *(Uint32 *) p = pixel; // 32-bit display
+ *(Uint32 *) p = pixel; // 32-bit display
}
}
@@ -829,9 +829,9 @@
/* Set a pointer to the exact location in memory of the pixel
in question: */
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- x); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ x); /* Go in X pixels */
/* Return the correctly-sized piece of data containing the
@@ -857,9 +857,9 @@
/* Set a pointer to the exact location in memory of the pixel
in question: */
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 2)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 2)); /* Go in X pixels */
/* Return the correctly-sized piece of data containing the
@@ -886,9 +886,9 @@
/* Set a pointer to the exact location in memory of the pixel
in question: */
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 3)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 3)); /* Go in X pixels */
/* Return the correctly-sized piece of data containing the
@@ -921,16 +921,16 @@
/* Set a pointer to the exact location in memory of the pixel
in question: */
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 4)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 4)); /* Go in X pixels */
/* Return the correctly-sized piece of data containing the
* pixel's value (an 8-bit palette value, or a 16-, 24- or 32-bit
* RGB value) */
- return *(Uint32 *) p; // 32-bit display
+ return *(Uint32 *) p; // 32-bit display
}
/* Function pointer arrays to allow correct function */
Modified: tuxmath/branches/mathcards_newarch/src/audio.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/audio.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/audio.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -59,12 +59,12 @@
* loaded using the audioMusicLoad function
*/
void audioMusicUnload( void ) {
- if (!Opts_UsingSound()) return;
+ if (!Opts_UsingSound()) return;
- if ( defaultMusic )
- Mix_FreeMusic( defaultMusic );
+ if ( defaultMusic )
+ Mix_FreeMusic( defaultMusic );
- defaultMusic=NULL;
+ defaultMusic=NULL;
}
/* audioMusicPlay attempts to play the passed music data.
@@ -73,8 +73,8 @@
* Note: loops == -1 means forever
*/
void audioMusicPlay( Mix_Music *musicData, int loops ) {
- if (!Opts_UsingSound()) return;
+ if (!Opts_UsingSound()) return;
- audioMusicUnload();
- Mix_PlayMusic( musicData, loops );
+ audioMusicUnload();
+ Mix_PlayMusic( musicData, loops );
}
Modified: tuxmath/branches/mathcards_newarch/src/credits.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/credits.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/credits.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -398,30 +398,30 @@
/* Handle any incoming events: */
while (SDL_PollEvent(&event) > 0)
- {
- if (event.type == SDL_QUIT)
- {
- /* Window close event - quit! */
-
- quit = 1;
- done = 1;
- }
- else if (event.type == SDL_KEYDOWN)
- {
- key = event.key.keysym.sym;
-
- if (key == SDLK_ESCAPE)
- {
- /* Escape key - quit! */
-
- done = 1;
- }
- }
- else if (event.type == SDL_MOUSEBUTTONDOWN)
- {
+ {
+ if (event.type == SDL_QUIT)
+ {
+ /* Window close event - quit! */
+
+ quit = 1;
done = 1;
- }
- }
+ }
+ else if (event.type == SDL_KEYDOWN)
+ {
+ key = event.key.keysym.sym;
+
+ if (key == SDLK_ESCAPE)
+ {
+ /* Escape key - quit! */
+
+ done = 1;
+ }
+ }
+ else if (event.type == SDL_MOUSEBUTTONDOWN)
+ {
+ done = 1;
+ }
+ }
/* Scroll: */
@@ -452,13 +452,13 @@
if (scroll >= 9)
- {
- scroll = 0;
- line++;
-
- if (credit_text[line] == NULL)
- done = 1;
- }
+ {
+ scroll = 0;
+ line++;
+
+ if (credit_text[line] == NULL)
+ done = 1;
+ }
SDL_Flip(screen);
@@ -468,9 +468,9 @@
now_time = SDL_GetTicks();
if (now_time < last_time + (1000 / 20))
- {
- SDL_Delay(last_time + (1000 / 20) - now_time);
- }
+ {
+ SDL_Delay(last_time + (1000 / 20) - now_time);
+ }
}
while (!done);
@@ -507,50 +507,50 @@
c = -1;
if (str[i] >= '0' && str[i] <= '9')
- c = str[i] - '0';
+ c = str[i] - '0';
else if (str[i] >= 'A' && str[i] <= 'Z')
- c = str[i] - 'A' + 10;
+ c = str[i] - 'A' + 10;
else if (str[i] == ',')
- c = 36;
+ c = 36;
else if (str[i] == '.')
- c = 37;
+ c = 37;
else if (str[i] == '\'')
- c = 38;
+ c = 38;
if (c != -1)
- {
- for (y = 0; y < 5; y++)
- {
- if (hilite == 0)
- {
- r = 255 - ((line * y) % 256);
- g = 255 / (y + 2);
- b = (line * line * 2) % 256;
- }
- else
- {
- r = 128;
- g = 192;
- b = 255 - (y * 40);
- }
-
- for (x = 0; x < 5; x++)
- {
- if (chars[c][y][x] == '#')
- {
- dest.x = cur_x + (x * 3);
- dest.y = ((screen->h - (5 * 3)) + (y * 3) +
- (18 - offset * 2));
- dest.w = 3;
- dest.h = 3;
-
- SDL_FillRect(screen, &dest,
- SDL_MapRGB(screen->format, r, g, b));
- }
- }
- }
- }
+ {
+ for (y = 0; y < 5; y++)
+ {
+ if (hilite == 0)
+ {
+ r = 255 - ((line * y) % 256);
+ g = 255 / (y + 2);
+ b = (line * line * 2) % 256;
+ }
+ else
+ {
+ r = 128;
+ g = 192;
+ b = 255 - (y * 40);
+ }
+
+ for (x = 0; x < 5; x++)
+ {
+ if (chars[c][y][x] == '#')
+ {
+ dest.x = cur_x + (x * 3);
+ dest.y = ((screen->h - (5 * 3)) + (y * 3) +
+ (18 - offset * 2));
+ dest.w = 3;
+ dest.h = 3;
+
+ SDL_FillRect(screen, &dest,
+ SDL_MapRGB(screen->format, r, g, b));
+ }
+ }
+ }
+ }
/* Move virtual cursor: */
Modified: tuxmath/branches/mathcards_newarch/src/fileops.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/fileops.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/fileops.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -161,8 +161,8 @@
*/
static HRESULT ReadRegistry(const char *key, const char *option, char *value, int size)
{
- LONG res;
- HKEY hKey = NULL;
+ LONG res;
+ HKEY hKey = NULL;
res = RegOpenKeyEx(HKEY_CURRENT_USER, key, 0, KEY_READ, &hKey);
if (res != ERROR_SUCCESS)
@@ -1189,12 +1189,11 @@
/* terminate string here: */
*value_end = 0;
- #ifdef TUXMATH_DEBUG
- printf("parameter = '%s'\t, length = %zu\n", parameter, strlen(parameter));
- printf("value = '%s'\t, length = %zu\t, atoi() = %d\t, atof() = %.2f\n", value, strlen(value), atoi(value), atof(value));
- #endif
+ tmdprintf("parameter = '%s'\t, length = %zu\n", parameter, strlen(parameter));
+ tmdprintf("value = '%s'\t, length = %zu\t, atoi() = %d\t, atof() = %.2f\n", value, strlen(value), atoi(value), atof(value));
+
/* Now ready to handle each name/value pair! */
-
+
/* Set general game_options struct (see tuxmath.h): */
if(0 == strcasecmp(parameter, "per_user_config"))
{
@@ -1212,14 +1211,14 @@
/* Only let administrator change this setting */
if (file_type == GLOBAL_CONFIG_FILE && user_data_dir == NULL)
{
- /* Check to see whether the specified homedir exists */
- dir = opendir(value);
- if (dir == NULL)
- fprintf(stderr,"homedir: %s is not a directory, or it could not be read\n", value);
- else {
- set_user_data_dir(value); /* copy the homedir setting */
- closedir(dir);
- }
+ /* Check to see whether the specified homedir exists */
+ dir = opendir(value);
+ if (dir == NULL)
+ fprintf(stderr,"homedir: %s is not a directory, or it could not be read\n", value);
+ else {
+ set_user_data_dir(value); /* copy the homedir setting */
+ closedir(dir);
+ }
}
}
@@ -1689,8 +1688,8 @@
MC_SetTypeMax(atoi(value));
}
- else
#endif
+ else
{
MC_SetOp(parameter, atoi(value) ); //automatically handles bad parameters
}
@@ -2402,7 +2401,7 @@
fp = fopen(filepath1, "a"); /* "a" means append to end of file */
if (fp) {
if (write_column_names) {
- fprintf(fp,"\"User\",\"Mission\",\"Date\",\"Completed?\",\"Number answered\",\"Percent correct\",\"Time per question\"\n");
+ fprintf(fp,"\"User\",\"Mission\",\"Date\",\"Completed?\",\"Number answered\",\"Percent correct\",\"Time per question\"\n");
}
mission_name = strdup(last_config_file_name);
fprintf(fp,"\"%s\",\"%s\",%d/%d/%d,%d,%d,%d,%g\n", get_user_name(), get_file_name(mission_name), datetime.tm_year+1900, datetime.tm_mon+1, datetime.tm_mday, MC_MissionAccomplished(), total_answered, ((MC_NumAnsweredCorrectly() * 100)/ total_answered), median_time);
@@ -2871,7 +2870,7 @@
if (sounds[i] == NULL)
{
fprintf(stderr,
- "\nError: I couldn't load a sound file:\n"
+ "\nError: I couldn't load a sound file:\n"
"%s\n"
"The Simple DirectMedia error that occured was:\n"
"%s\n\n", sound_filenames[i], SDL_GetError());
@@ -2897,7 +2896,7 @@
if (musics[i] == NULL)
{
fprintf(stderr,
- "\nError: I couldn't load a music file:\n"
+ "\nError: I couldn't load a music file:\n"
"%s\n"
"The Simple DirectMedia error that occured was:\n"
"%s\n\n", music_filenames[i], SDL_GetError());
@@ -2906,12 +2905,12 @@
if (i == NUM_MUSICS - 1)
{
- dest.x = 0;
- dest.y = (screen->h) - 10;
- dest.w = ((screen->w) * (i + 1 + NUM_IMAGES + NUM_SOUNDS)) / total_files;
- dest.h = 10;
-
- SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 255, 0));
+ dest.x = 0;
+ dest.y = (screen->h) - 10;
+ dest.w = ((screen->w) * (i + 1 + NUM_IMAGES + NUM_SOUNDS)) / total_files;
+ dest.h = 10;
+
+ SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 255, 0));
SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
}
}
Modified: tuxmath/branches/mathcards_newarch/src/game.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/game.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/game.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -61,12 +61,6 @@
const int SND_IGLOO_SIZZLE = SND_SIZZLE;
const int IMG_CITY_NONE = 0;
-char operchars[4] = {
- "+-*/"
-};
-
-
-
typedef struct comet_type {
int alive;
int expl;
@@ -118,7 +112,8 @@
static float comet_feedback_height;
static float danger_level;
-static int digits[3];
+#define MAX_DIGITS 3 //should really be determined by max_answer_size
+static int digits[MAX_DIGITS];
static comet_type* comets = NULL;
static city_type* cities = NULL;
@@ -209,7 +204,7 @@
//see if the option matches the actual screen
if (Opts_Fullscreen() == !(screen->flags & SDL_FULLSCREEN) )
{
- SwitchScreenMode();
+ ;//SwitchScreenMode();
}
@@ -275,7 +270,7 @@
{
if (!Mix_PlayingMusic())
{
- Mix_PlayMusic(musics[MUS_GAME + (rand() % 3)], 0);
+ Mix_PlayMusic(musics[MUS_GAME + (rand() % 3)], 0);
}
}
#endif
@@ -289,7 +284,7 @@
// or you leave tuxmath running for 49 days...)
now_time = (last_time+MS_PER_FRAME) - now_time; // this holds the delay
if (now_time > MS_PER_FRAME)
- now_time = MS_PER_FRAME;
+ now_time = MS_PER_FRAME;
SDL_Delay(now_time);
}
}
@@ -378,7 +373,7 @@
now_time = SDL_GetTicks();
if (now_time < last_time + MS_PER_FRAME)
- SDL_Delay(last_time + MS_PER_FRAME - now_time);
+ SDL_Delay(last_time + MS_PER_FRAME - now_time);
}
while (looping);
break;
@@ -422,7 +417,7 @@
now_time = SDL_GetTicks();
if (now_time < last_time + MS_PER_FRAME)
- SDL_Delay(last_time + MS_PER_FRAME - now_time);
+ SDL_Delay(last_time + MS_PER_FRAME - now_time);
}
while (looping);
@@ -471,8 +466,10 @@
int game_initialize(void)
{
int i,img;
+
+ tmdprintf("Entering game_initialize()\n");
+
/* Clear window: */
-
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_Flip(screen);
@@ -491,6 +488,18 @@
printf("Allocation of comets failed");
return 0;
}
+ for (i = 0; i < MAX_MAX_COMETS; ++i)
+ {
+ comets[i].flashcard = MC_AllocateFlashcard();
+ if (!MC_FlashCardGood(&comets[i].flashcard) )
+ {
+ //something's wrong
+ printf("Allocation of flashcard %d failed\n", i);
+ for (; i >= 0; --i) //free anything we've already gotten
+ MC_FreeFlashcard(&comets[i].flashcard);
+ return 0;
+ }
+ }
cities = (city_type *) malloc(NUM_CITIES * sizeof(city_type));
if (cities == NULL) {
printf("Allocation of cities failed");
@@ -514,9 +523,7 @@
/* (for example) to all math operations being deselected */
if (!MC_StartGame())
{
-#ifdef TUXMATH_DEBUG
- printf("\nMC_StartGame() failed!");
-#endif
+ tmdprintf("\nMC_StartGame() failed!");
fprintf(stderr, "\nMC_StartGame() failed!");
return 0;
}
@@ -592,9 +599,7 @@
if (Opts_BonusCometInterval()) {
bonus_comet_counter = Opts_BonusCometInterval() + 1;
-#ifdef TUXMATH_DEBUG
- printf("\nInitializing with bonus_comet_counter = %d\n",bonus_comet_counter);
-#endif
+ tmdprintf("\nInitializing with bonus_comet_counter = %d\n",bonus_comet_counter);
}
extra_life_earned = 0;
cloud.status = EXTRA_LIFE_OFF;
@@ -976,8 +981,8 @@
picked_comet = (rand() % MAX_COMETS);
if (!(comets[picked_comet].alive &&
- comets[picked_comet].expl < COMET_EXPL_END)
- || comets[picked_comet].y < 80)
+ comets[picked_comet].expl < COMET_EXPL_END)
+ || comets[picked_comet].y < 80)
{
picked_comet = -1;
}
@@ -986,7 +991,7 @@
/* found a comet to blow up! */
demo_answer = comets[picked_comet].answer;
if ((rand() % 3) < 1)
- demo_answer--; // sometimes get it wrong on purpose
+ demo_answer--; // sometimes get it wrong on purpose
#ifdef TUXMATH_DEBUG
printf("Demo mode, comet %d attacked with answer %d\n",picked_comet,demo_answer);
@@ -1049,7 +1054,8 @@
void game_handle_answer(void)
{
- int i, num, lowest, lowest_y;
+ int i, j, num, lowest, lowest_y;
+ char ans[MAX_DIGITS+2]; //extra space for negative, and for final '\0'
Uint32 ctime;
if (!doing_answer)
@@ -1058,15 +1064,40 @@
}
doing_answer = 0;
-
+/*
num = (digits[0] * 100 +
digits[1] * 10 +
digits[2]);
+*/
/* negative answer support DSB */
+
+ ans[0] = '-';
+ for (i = j = (neg_answer_picked); i < MAX_DIGITS; ++i)
+ if (digits[i])
+ ans[j++] = digits[i] + '0';
+ ans[j] = '\0';
+
+/*
if (neg_answer_picked)
{
- num = -num;
+ ans[0] = '-';
+ for (i = j = 0; i < MAX_DIGITS; ++i)
+ {
+ if (digits[i] == 0)
+ continue;
+ ans[++j] = digits[i] + '0';
+ }
}
+ else
+ {
+ for (i = j = 0; i < MAX_DIGITS; ++i)
+ {
+ if (digits[i] == 0)
+ continue;
+ ans[j++] = digits[i] + '0';
+ }
+ }
+*/
/* Pick the lowest comet which has the right answer: */
/* FIXME: do we want it to prefer bonus comets to regular comets? */
@@ -1075,9 +1106,11 @@
for (i = 0; i < MAX_COMETS; i++)
{
+ mcdprintf("Comparing '%s' with '%s'\n", comets[i].flashcard.answer_string, ans);
if (comets[i].alive &&
comets[i].expl < COMET_EXPL_END &&
- comets[i].answer == num &&
+ //comets[i].answer == num &&
+ 0 == strncmp(comets[i].flashcard.answer_string, ans, MAX_DIGITS+1) &&
comets[i].y > lowest_y)
{
lowest = i;
@@ -1141,7 +1174,7 @@
/* FIXME looks like it might score a bit differently based on screen mode? */
add_score(((25 * (comets[lowest].flashcard.difficulty + 1)) *
(screen->h - comets[lowest].y + 1)) /
- screen->h);
+ screen->h);
}
else
{
@@ -1161,9 +1194,8 @@
}
/* Clear digits: */
- digits[0] = 0;
- digits[1] = 0;
- digits[2] = 0;
+ for (i = 0; i < MAX_DIGITS; ++i)
+ digits[i] = 0;
neg_answer_picked = 0;
}
@@ -1252,8 +1284,8 @@
/* Make bonus comet move faster at chosen ratio: */
if (comets[i].bonus)
{
- comets[i].y += speed * Opts_BonusSpeedRatio() *
- city_expl_height / (RES_Y - images[IMG_CITY_BLUE]->h);
+ comets[i].y += speed * Opts_BonusSpeedRatio() *
+ city_expl_height / (RES_Y - images[IMG_CITY_BLUE]->h);
}
else /* Regular comet: */
{
@@ -1263,61 +1295,61 @@
/* Does it threaten a city? */
if (comets[i].y > 3 * screen->h / 4)
- cities[this_city].threatened = 1;
+ cities[this_city].threatened = 1;
/* Did it hit a city? */
if (comets[i].y >= city_expl_height &&
- comets[i].expl < COMET_EXPL_END)
+ comets[i].expl < COMET_EXPL_END)
{
/* Tell MathCards about it - question not answered correctly: */
MC_NotAnsweredCorrectly(&(comets[i].flashcard));
- /* Store the time the question was present on screen (do this */
- /* in a way that avoids storing it if the time wrapped around */
- ctime = SDL_GetTicks();
- if (ctime > comets[i].time_started) {
- MC_AddTimeToList((float)(ctime - comets[i].time_started)/1000);
- }
+ /* Store the time the question was present on screen (do this */
+ /* in a way that avoids storing it if the time wrapped around */
+ ctime = SDL_GetTicks();
+ if (ctime > comets[i].time_started) {
+ MC_AddTimeToList((float)(ctime - comets[i].time_started)/1000);
+ }
/* Record data for speed feedback */
- /* Do this only for cities that are alive; dead cities */
+ /* Do this only for cities that are alive; dead cities */
/* might not get much protection from the player */
- if (Opts_UseFeedback() && cities[this_city].hits_left) {
- comet_feedback_number++;
+ if (Opts_UseFeedback() && cities[this_city].hits_left) {
+ comet_feedback_number++;
comet_feedback_height += 1.0 + Opts_CityExplHandicap();
#ifdef FEEDBACK_DEBUG
- printf("Added comet feedback with height %g\n",
+ printf("Added comet feedback with height %g\n",
1.0 + Opts_CityExplHandicap());
#endif
- }
+ }
/* Disable shields/destroy city/create steam cloud: */
if (cities[this_city].hits_left)
- {
- cities[this_city].status = CITY_EXPLODING;
- if (Opts_UseIgloos()) {
- playsound(SND_IGLOO_SIZZLE);
- cities[this_city].counter = IGLOO_SWITCH_START;
- steam[this_city].status = STEAM_ON;
- steam[this_city].counter = STEAM_START;
- }
- else {
- if (cities[comets[i].city].hits_left == 2) {
- playsound(SND_SHIELDSDOWN);
- cities[this_city].counter = 1; /* Will act immediately */
- }
- else {
- playsound(SND_EXPLOSION);
- cities[this_city].counter = CITY_EXPL_START;
- }
- }
- cities[this_city].hits_left--;
- }
+ {
+ cities[this_city].status = CITY_EXPLODING;
+ if (Opts_UseIgloos()) {
+ playsound(SND_IGLOO_SIZZLE);
+ cities[this_city].counter = IGLOO_SWITCH_START;
+ steam[this_city].status = STEAM_ON;
+ steam[this_city].counter = STEAM_START;
+ }
+ else {
+ if (cities[comets[i].city].hits_left == 2) {
+ playsound(SND_SHIELDSDOWN);
+ cities[this_city].counter = 1; /* Will act immediately */
+ }
+ else {
+ playsound(SND_EXPLOSION);
+ cities[this_city].counter = CITY_EXPL_START;
+ }
+ }
+ cities[this_city].hits_left--;
+ }
- /* If this was a bonus comet, restart the counter */
- if (comets[i].bonus)
- bonus_comet_counter = Opts_BonusCometInterval()+1;
+ /* If this was a bonus comet, restart the counter */
+ if (comets[i].bonus)
+ bonus_comet_counter = Opts_BonusCometInterval()+1;
/* If slow_after_wrong selected, set flag to go back to starting speed and */
/* number of attacking comets: */
@@ -1338,22 +1370,22 @@
if (comets[i].expl >= COMET_EXPL_END)
{
comets[i].expl--;
- if (comets[i].expl < COMET_EXPL_END) {
- comets[i].alive = 0;
- if (bonus_comet_counter > 1 && comets[i].zapped) {
- bonus_comet_counter--;
+ if (comets[i].expl < COMET_EXPL_END) {
+ comets[i].alive = 0;
+ if (bonus_comet_counter > 1 && comets[i].zapped) {
+ bonus_comet_counter--;
#ifdef TUXMATH_DEBUG
- printf("\nbonus_comet_counter is now %d\n",bonus_comet_counter);
+ printf("\nbonus_comet_counter is now %d\n",bonus_comet_counter);
#endif
- }
- if (comets[i].bonus && comets[i].zapped) {
- playsound(SND_EXTRA_LIFE);
- extra_life_earned = 1;
+ }
+ if (comets[i].bonus && comets[i].zapped) {
+ playsound(SND_EXTRA_LIFE);
+ extra_life_earned = 1;
#ifdef TUXMATH_DEBUG
- printf("\nExtra life earned!");
+ printf("\nExtra life earned!");
#endif
- }
- }
+ }
+ }
}
}
}
@@ -1377,9 +1409,9 @@
{
if (num_comets_alive == 0)
{
- if (!check_extra_life()) {
- /* Time for the next wave! */
- wave++;
+ if (!check_extra_life()) {
+ /* Time for the next wave! */
+ wave++;
reset_level();
}
}
@@ -1409,61 +1441,61 @@
{
cities[i].counter--;
if (cities[i].counter == 0) {
- if (cities[i].hits_left)
- cities[i].status = CITY_PRESENT;
- else {
- if (Opts_UseIgloos()) {
- cities[i].status = CITY_EVAPORATING;
- cities[i].counter = EVAPORATING_COUNTER_START;
- cities[i].img = IMG_IGLOO_MELTED1;
- } else {
- cities[i].status = CITY_GONE;
- cities[i].img = IMG_CITY_NONE;
- }
- }
+ if (cities[i].hits_left)
+ cities[i].status = CITY_PRESENT;
+ else {
+ if (Opts_UseIgloos()) {
+ cities[i].status = CITY_EVAPORATING;
+ cities[i].counter = EVAPORATING_COUNTER_START;
+ cities[i].img = IMG_IGLOO_MELTED1;
+ } else {
+ cities[i].status = CITY_GONE;
+ cities[i].img = IMG_CITY_NONE;
+ }
+ }
}
}
/* Choose the correct city/igloo image */
if (Opts_UseIgloos()) {
if (cities[i].status == CITY_EVAPORATING) {
- /* Handle the evaporation animation */
- cities[i].layer = 0; /* these have to be drawn below the penguin */
- cities[i].counter--;
- if (cities[i].counter == 0) {
- cities[i].img--;
- if (cities[i].img < IMG_IGLOO_MELTED3) {
- cities[i].img = IMG_CITY_NONE;
- cities[i].status = CITY_GONE;
- }
- else
- cities[i].counter = EVAPORATING_COUNTER_START;
- }
- } else {
- if (cities[i].status != CITY_GONE) {
- cities[i].layer = 1; /* these have to be drawn above the penguin */
- cities[i].img = IMG_IGLOO_MELTED1 + cities[i].hits_left;
- /* If we're in the middle of an "explosion," don't switch to the
- new igloo. Note the steam may have a different counter than
- the igloo on this matter; the switch is designed to occur
- halfway through the steam cloud. */
- if (cities[i].status == CITY_EXPLODING)
- cities[i].img++;
- }
+ /* Handle the evaporation animation */
+ cities[i].layer = 0; /* these have to be drawn below the penguin */
+ cities[i].counter--;
+ if (cities[i].counter == 0) {
+ cities[i].img--;
+ if (cities[i].img < IMG_IGLOO_MELTED3) {
+ cities[i].img = IMG_CITY_NONE;
+ cities[i].status = CITY_GONE;
+ }
+ else
+ cities[i].counter = EVAPORATING_COUNTER_START;
+ }
+ } else {
+ if (cities[i].status != CITY_GONE) {
+ cities[i].layer = 1; /* these have to be drawn above the penguin */
+ cities[i].img = IMG_IGLOO_MELTED1 + cities[i].hits_left;
+ /* If we're in the middle of an "explosion," don't switch to the
+ new igloo. Note the steam may have a different counter than
+ the igloo on this matter; the switch is designed to occur
+ halfway through the steam cloud. */
+ if (cities[i].status == CITY_EXPLODING)
+ cities[i].img++;
+ }
}
}
else {
/* We're using the original "city" graphics */
cities[i].layer = 0; /* No layering needed */
if (cities[i].hits_left)
- cities[i].img = IMG_CITY_BLUE;
+ cities[i].img = IMG_CITY_BLUE;
else if (cities[i].status == CITY_EXPLODING)
- cities[i].img = (IMG_CITY_BLUE_EXPL5 - (cities[i].counter / (CITY_EXPL_START / 5)));
+ cities[i].img = (IMG_CITY_BLUE_EXPL5 - (cities[i].counter / (CITY_EXPL_START / 5)));
else
- cities[i].img = IMG_CITY_BLUE_DEAD;
+ cities[i].img = IMG_CITY_BLUE_DEAD;
/* Change image to appropriate color: */
cities[i].img = cities[i].img + ((wave % MAX_CITY_COLORS) *
- (IMG_CITY_GREEN - IMG_CITY_BLUE));
+ (IMG_CITY_GREEN - IMG_CITY_BLUE));
}
}
@@ -1486,26 +1518,26 @@
penguins[i].status = PENGUIN_DUCKING;
else if (!cities[i].threatened && penguins[i].status == PENGUIN_DUCKING) {
if (cities[i].hits_left == 2)
- penguins[i].status = PENGUIN_HAPPY;
+ penguins[i].status = PENGUIN_HAPPY;
else
- penguins[i].status = PENGUIN_GRUMPY;
+ penguins[i].status = PENGUIN_GRUMPY;
}
switch (penguins[i].status) {
case PENGUIN_HAPPY:
penguins[i].img = IMG_PENGUIN_FLAPDOWN;
if (rand() % FLAPPING_INTERVAL == 0) {
- penguins[i].status = PENGUIN_FLAPPING;
- penguins[i].counter = FLAPPING_START;
+ penguins[i].status = PENGUIN_FLAPPING;
+ penguins[i].counter = FLAPPING_START;
}
break;
case PENGUIN_FLAPPING:
if (penguins[i].counter % 4 >= 2)
- penguins[i].img = IMG_PENGUIN_FLAPUP;
+ penguins[i].img = IMG_PENGUIN_FLAPUP;
else
- penguins[i].img = IMG_PENGUIN_FLAPDOWN;
+ penguins[i].img = IMG_PENGUIN_FLAPDOWN;
penguins[i].counter--;
if (penguins[i].counter == 0)
- penguins[i].status = PENGUIN_HAPPY;
+ penguins[i].status = PENGUIN_HAPPY;
break;
case PENGUIN_DUCKING:
penguins[i].img = IMG_PENGUIN_INCOMING;
@@ -1513,59 +1545,59 @@
case PENGUIN_GRUMPY:
penguins[i].img = IMG_PENGUIN_GRUMPY;
if (rand() % FLAPPING_INTERVAL == 0) {
- penguins[i].status = PENGUIN_WORRIED;
- penguins[i].counter = FLAPPING_START;
+ penguins[i].status = PENGUIN_WORRIED;
+ penguins[i].counter = FLAPPING_START;
}
break;
case PENGUIN_WORRIED:
penguins[i].img = IMG_PENGUIN_WORRIED;
penguins[i].counter--;
if (penguins[i].counter == 0)
- penguins[i].status = PENGUIN_GRUMPY;
+ penguins[i].status = PENGUIN_GRUMPY;
break;
case PENGUIN_STANDING_UP:
penguins[i].img = IMG_PENGUIN_STANDING_UP;
penguins[i].counter--;
if (penguins[i].counter == 0)
- penguins[i].status = PENGUIN_WALKING_OFF;
+ penguins[i].status = PENGUIN_WALKING_OFF;
break;
case PENGUIN_SITTING_DOWN:
penguins[i].img = IMG_PENGUIN_SITTING_DOWN;
penguins[i].counter--;
if (penguins[i].counter == 0) {
- penguins[i].status = PENGUIN_FLAPPING;
- penguins[i].counter = FLAPPING_START;
+ penguins[i].status = PENGUIN_FLAPPING;
+ penguins[i].counter = FLAPPING_START;
}
break;
case PENGUIN_WALKING_ON:
walk_counter = (penguins[i].counter % 8)/2;
if (walk_counter == 3)
- walk_counter = 1;
+ walk_counter = 1;
penguins[i].img = IMG_PENGUIN_WALK_ON1 + walk_counter;
penguins[i].counter++;
direction = 2*(i < NUM_CITIES/2)-1; /* +1 for walk right, -1 for left */
penguins[i].x += direction*PENGUIN_WALK_SPEED;
if (direction*penguins[i].x >= direction*cities[i].x) {
- penguins[i].status = PENGUIN_SITTING_DOWN;
- penguins[i].counter = STANDING_COUNTER_START;
- penguins[i].x = cities[i].x;
+ penguins[i].status = PENGUIN_SITTING_DOWN;
+ penguins[i].counter = STANDING_COUNTER_START;
+ penguins[i].x = cities[i].x;
}
penguins[i].layer = 3; /* Stand in front of steam */
break;
case PENGUIN_WALKING_OFF:
walk_counter = (penguins[i].counter % 8)/2;
if (walk_counter == 3)
- walk_counter = 1;
+ walk_counter = 1;
penguins[i].img = IMG_PENGUIN_WALK_OFF1 + walk_counter;
penguins[i].counter++;
direction = 1-2*(i < NUM_CITIES/2);
penguins[i].x += direction*PENGUIN_WALK_SPEED;
if (direction < 0) {
- if (penguins[i].x + images[IMG_PENGUIN_WALK_OFF1]->w/2 < 0)
- penguins[i].status = PENGUIN_OFFSCREEN;
+ if (penguins[i].x + images[IMG_PENGUIN_WALK_OFF1]->w/2 < 0)
+ penguins[i].status = PENGUIN_OFFSCREEN;
} else {
- if (penguins[i].x - images[IMG_PENGUIN_WALK_OFF1]->w/2 > screen->w)
- penguins[i].status = PENGUIN_OFFSCREEN;
+ if (penguins[i].x - images[IMG_PENGUIN_WALK_OFF1]->w/2 > screen->w)
+ penguins[i].status = PENGUIN_OFFSCREEN;
}
penguins[i].layer = 3;
break;
@@ -1586,16 +1618,16 @@
if (steam[i].counter) {
steam[i].counter--;
if (!steam[i].counter) {
- steam[i].status = STEAM_OFF;
- if (cloud.status != EXTRA_LIFE_ON || cloud.city != i) {
- /* The penguin was ducking, now we can stop */
+ steam[i].status = STEAM_OFF;
+ if (cloud.status != EXTRA_LIFE_ON || cloud.city != i) {
+ /* The penguin was ducking, now we can stop */
if (cities[i].hits_left)
penguins[i].status = PENGUIN_GRUMPY;
else {
penguins[i].status = PENGUIN_STANDING_UP;
- penguins[i].counter = STANDING_COUNTER_START;
- }
- }
+ penguins[i].counter = STANDING_COUNTER_START;
+ }
+ }
}
}
if (steam[i].status == STEAM_OFF)
@@ -1624,8 +1656,8 @@
fewest_index = -1;
for (i = 0; i < NUM_CITIES; i++) {
if (cities[i].hits_left < fewest_hits_left) {
- fewest_hits_left = cities[i].hits_left;
- fewest_index = i;
+ fewest_hits_left = cities[i].hits_left;
+ fewest_index = i;
}
}
if (fewest_hits_left == 2)
@@ -1682,28 +1714,28 @@
// Cloud is "parked," handle the snowfall and igloo rebuilding
cities[cloud.city].status = CITY_REBUILDING;
igloo_top = screen->h - igloo_vertical_offset
- - images[IMG_IGLOO_INTACT]->h;
+ - images[IMG_IGLOO_INTACT]->h;
for (i = 0, num_below_igloo = 0; i < NUM_SNOWFLAKES; i++) {
- cloud.snowflake_y[i] += SNOWFLAKE_SPEED;
- if (cloud.snowflake_y[i] > igloo_top)
- num_below_igloo++;
+ cloud.snowflake_y[i] += SNOWFLAKE_SPEED;
+ if (cloud.snowflake_y[i] > igloo_top)
+ num_below_igloo++;
}
if (cloud.snowflake_y[NUM_SNOWFLAKES-1] > igloo_top) {
- cities[cloud.city].hits_left = 2;
- cities[cloud.city].img = IMG_IGLOO_INTACT; // completely rebuilt
+ cities[cloud.city].hits_left = 2;
+ cities[cloud.city].img = IMG_IGLOO_INTACT; // completely rebuilt
} else if (cities[cloud.city].hits_left == 0) {
- // We're going to draw one of the blended igloos
- // FIXME: It's a hack to encode a blended igloo with a negative number!
- penguins[cloud.city].layer = 0;
- cities[cloud.city].layer = 1;
- if (num_below_igloo < 3)
- num_below_igloo = 0; // Don't show progress until a few have fallen
- cities[cloud.city].img = -((float) (num_below_igloo)/NUM_SNOWFLAKES) * NUM_BLENDED_IGLOOS;
+ // We're going to draw one of the blended igloos
+ // FIXME: It's a hack to encode a blended igloo with a negative number!
+ penguins[cloud.city].layer = 0;
+ cities[cloud.city].layer = 1;
+ if (num_below_igloo < 3)
+ num_below_igloo = 0; // Don't show progress until a few have fallen
+ cities[cloud.city].img = -((float) (num_below_igloo)/NUM_SNOWFLAKES) * NUM_BLENDED_IGLOOS;
}
if (cloud.snowflake_y[NUM_SNOWFLAKES-1] > screen->h - igloo_vertical_offset) {
- /* exit rebuilding when last snowflake at igloo bottom */
- cloud.status = EXTRA_LIFE_OFF;
- cities[cloud.city].status = CITY_PRESENT;
+ /* exit rebuilding when last snowflake at igloo bottom */
+ cloud.status = EXTRA_LIFE_OFF;
+ cities[cloud.city].status = CITY_PRESENT;
}
}
}
@@ -1731,9 +1763,9 @@
if (laser.alive)
{
draw_line(laser.x1, laser.y1, laser.x2, laser.y2,
- 255 / ((LASER_START + 1) - laser.alive),
- 192 / ((LASER_START + 1) - laser.alive),
- 64);
+ 255 / ((LASER_START + 1) - laser.alive),
+ 192 / ((LASER_START + 1) - laser.alive),
+ 64);
}
/* Draw numeric keypad: */
@@ -1835,7 +1867,7 @@
/* Decide which image to display: */
img = IMG_COMET1 + ((frame + i) % 3);
/* Display the formula (flashing, in the bottom half
- of the screen) */
+ of the screen) */
if (comets[i].y < screen->h / 2 || frame % 8 < 6)
{
comet_str = comets[i].flashcard.formula_string;
@@ -1875,7 +1907,7 @@
/* Decide which image to display: */
img = IMG_COMET1 + ((frame + i) % 3);
/* Display the formula (flashing, in the bottom half
- of the screen) */
+ of the screen) */
if (comets[i].y < screen->h / 2 || frame % 8 < 6)
{
comet_str = comets[i].flashcard.formula_string;
@@ -1924,84 +1956,84 @@
max_layer = 0;
do {
for (i = 0; i < NUM_CITIES; i++) {
- if (cities[i].status != CITY_GONE && cities[i].layer > max_layer)
- max_layer = cities[i].layer;
- if (penguins[i].status != PENGUIN_OFFSCREEN && penguins[i].layer > max_layer)
- max_layer = penguins[i].layer;
- if (steam[i].status == STEAM_ON && steam[i].layer > max_layer)
- max_layer = steam[i].layer;
- if (cities[i].layer == current_layer &&
- cities[i].img != IMG_CITY_NONE) {
- // Handle the blended igloo images, which are encoded
- // (FIXME) with a negative image number
- if (cities[i].img <= 0)
- this_image = blended_igloos[-cities[i].img];
- else
- this_image = images[cities[i].img];
- //this_image = blended_igloos[frame % NUM_BLENDED_IGLOOS];
- dest.x = cities[i].x - (this_image->w / 2);
- dest.y = (screen->h) - (this_image->h) - igloo_vertical_offset;
- if (cities[i].img == IMG_IGLOO_MELTED3 ||
- cities[i].img == IMG_IGLOO_MELTED2)
- dest.y -= (images[IMG_IGLOO_MELTED1]->h - this_image->h)/2;
- dest.w = (this_image->w);
- dest.h = (this_image->h);
- SDL_BlitSurface(this_image, NULL, screen, &dest);
- }
- if (penguins[i].layer == current_layer &&
- penguins[i].status != PENGUIN_OFFSCREEN) {
- this_image = images[penguins[i].img];
- if (penguins[i].status == PENGUIN_WALKING_OFF ||
- penguins[i].status == PENGUIN_WALKING_ON) {
- /* With walking penguins, we have to use flipped images
- when it's walking left. The other issue is that the
- images are of different widths, so aligning on the
- center produces weird forward-backward walking. The
- reliable way is the align them all on the tip of the
- beak (the right border of the unflipped image) */
- dest.x = penguins[i].x - (this_image->w / 2);
- dest.y = (screen->h) - (this_image->h);
- if ((i<NUM_CITIES/2 && penguins[i].status==PENGUIN_WALKING_OFF) ||
- (i>=NUM_CITIES/2 && penguins[i].status==PENGUIN_WALKING_ON)) {
- /* walking left */
- this_image = flipped_images[flipped_img_lookup[penguins[i].img]];
- dest.x = penguins[i].x - images[IMG_PENGUIN_WALK_OFF2]->w/2;
- } else
- dest.x = penguins[i].x - this_image->w
- + images[IMG_PENGUIN_WALK_OFF2]->w/2; /* walking right */
- }
- else {
- dest.x = penguins[i].x - (this_image->w / 2);
- dest.y = (screen->h) - (5*(this_image->h))/4 - igloo_vertical_offset;
- }
- dest.w = (this_image->w);
- dest.h = (this_image->h);
- SDL_BlitSurface(this_image, NULL, screen, &dest);
- }
- if (steam[i].layer == current_layer &&
- steam[i].status == STEAM_ON) {
- this_image = images[steam[i].img];
- dest.x = cities[i].x - (this_image->w / 2);
- dest.y = (screen->h) - this_image->h - ((4 * images[IMG_IGLOO_INTACT]->h) / 7);
- dest.w = (this_image->w);
- dest.h = (this_image->h);
- SDL_BlitSurface(this_image, NULL, screen, &dest);
- }
+ if (cities[i].status != CITY_GONE && cities[i].layer > max_layer)
+ max_layer = cities[i].layer;
+ if (penguins[i].status != PENGUIN_OFFSCREEN && penguins[i].layer > max_layer)
+ max_layer = penguins[i].layer;
+ if (steam[i].status == STEAM_ON && steam[i].layer > max_layer)
+ max_layer = steam[i].layer;
+ if (cities[i].layer == current_layer &&
+ cities[i].img != IMG_CITY_NONE) {
+ // Handle the blended igloo images, which are encoded
+ // (FIXME) with a negative image number
+ if (cities[i].img <= 0)
+ this_image = blended_igloos[-cities[i].img];
+ else
+ this_image = images[cities[i].img];
+ //this_image = blended_igloos[frame % NUM_BLENDED_IGLOOS];
+ dest.x = cities[i].x - (this_image->w / 2);
+ dest.y = (screen->h) - (this_image->h) - igloo_vertical_offset;
+ if (cities[i].img == IMG_IGLOO_MELTED3 ||
+ cities[i].img == IMG_IGLOO_MELTED2)
+ dest.y -= (images[IMG_IGLOO_MELTED1]->h - this_image->h)/2;
+ dest.w = (this_image->w);
+ dest.h = (this_image->h);
+ SDL_BlitSurface(this_image, NULL, screen, &dest);
+ }
+ if (penguins[i].layer == current_layer &&
+ penguins[i].status != PENGUIN_OFFSCREEN) {
+ this_image = images[penguins[i].img];
+ if (penguins[i].status == PENGUIN_WALKING_OFF ||
+ penguins[i].status == PENGUIN_WALKING_ON) {
+ /* With walking penguins, we have to use flipped images
+ when it's walking left. The other issue is that the
+ images are of different widths, so aligning on the
+ center produces weird forward-backward walking. The
+ reliable way is the align them all on the tip of the
+ beak (the right border of the unflipped image) */
+ dest.x = penguins[i].x - (this_image->w / 2);
+ dest.y = (screen->h) - (this_image->h);
+ if ((i<NUM_CITIES/2 && penguins[i].status==PENGUIN_WALKING_OFF) ||
+ (i>=NUM_CITIES/2 && penguins[i].status==PENGUIN_WALKING_ON)) {
+ /* walking left */
+ this_image = flipped_images[flipped_img_lookup[penguins[i].img]];
+ dest.x = penguins[i].x - images[IMG_PENGUIN_WALK_OFF2]->w/2;
+ } else
+ dest.x = penguins[i].x - this_image->w
+ + images[IMG_PENGUIN_WALK_OFF2]->w/2; /* walking right */
+ }
+ else {
+ dest.x = penguins[i].x - (this_image->w / 2);
+ dest.y = (screen->h) - (5*(this_image->h))/4 - igloo_vertical_offset;
+ }
+ dest.w = (this_image->w);
+ dest.h = (this_image->h);
+ SDL_BlitSurface(this_image, NULL, screen, &dest);
+ }
+ if (steam[i].layer == current_layer &&
+ steam[i].status == STEAM_ON) {
+ this_image = images[steam[i].img];
+ dest.x = cities[i].x - (this_image->w / 2);
+ dest.y = (screen->h) - this_image->h - ((4 * images[IMG_IGLOO_INTACT]->h) / 7);
+ dest.w = (this_image->w);
+ dest.h = (this_image->h);
+ SDL_BlitSurface(this_image, NULL, screen, &dest);
+ }
}
current_layer++;
} while (current_layer <= max_layer);
if (cloud.status == EXTRA_LIFE_ON) {
/* Render cloud & snowflakes */
for (i = 0; i < NUM_SNOWFLAKES; i++) {
- if (cloud.snowflake_y[i] > cloud.y &&
- cloud.snowflake_y[i] < screen->h - igloo_vertical_offset) {
- this_image = images[IMG_SNOW1+cloud.snowflake_size[i]];
- dest.x = cloud.snowflake_x[i] - this_image->w/2 + cloud.x;
- dest.y = cloud.snowflake_y[i] - this_image->h/2;
- dest.w = this_image->w;
- dest.h = this_image->h;
- SDL_BlitSurface(this_image, NULL, screen, &dest);
- }
+ if (cloud.snowflake_y[i] > cloud.y &&
+ cloud.snowflake_y[i] < screen->h - igloo_vertical_offset) {
+ this_image = images[IMG_SNOW1+cloud.snowflake_size[i]];
+ dest.x = cloud.snowflake_x[i] - this_image->w/2 + cloud.x;
+ dest.y = cloud.snowflake_y[i] - this_image->h/2;
+ dest.w = this_image->w;
+ dest.h = this_image->h;
+ SDL_BlitSurface(this_image, NULL, screen, &dest);
+ }
}
this_image = images[IMG_CLOUD];
dest.x = cloud.x - this_image->w/2;
@@ -2024,19 +2056,19 @@
/* Draw sheilds: */
if (cities[i].hits_left > 1) {
- for (j = (frame % 3); j < images[IMG_SHIELDS]->h; j = j + 3) {
- src.x = 0;
- src.y = j;
- src.w = images[IMG_SHIELDS]->w;
- src.h = 1;
+ for (j = (frame % 3); j < images[IMG_SHIELDS]->h; j = j + 3) {
+ src.x = 0;
+ src.y = j;
+ src.w = images[IMG_SHIELDS]->w;
+ src.h = 1;
- dest.x = cities[i].x - (images[IMG_SHIELDS]->w / 2);
- dest.y = (screen->h) - (images[IMG_SHIELDS]->h) + j;
- dest.w = src.w;
- dest.h = src.h;
+ dest.x = cities[i].x - (images[IMG_SHIELDS]->w / 2);
+ dest.y = (screen->h) - (images[IMG_SHIELDS]->h) + j;
+ dest.w = src.w;
+ dest.h = src.h;
- SDL_BlitSurface(images[IMG_SHIELDS], &src, screen, &dest);
- }
+ SDL_BlitSurface(images[IMG_SHIELDS], &src, screen, &dest);
+ }
}
}
}
@@ -2080,7 +2112,7 @@
dest.y = images[IMG_EXTRA_LIFE]->h/4;
dest.h = images[IMG_EXTRA_LIFE]->h/2;
dest.w = ((Opts_BonusCometInterval() + 1 - bonus_comet_counter)
- * images[IMG_EXTRA_LIFE]->w) / Opts_BonusCometInterval();
+ * images[IMG_EXTRA_LIFE]->w) / Opts_BonusCometInterval();
SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 255, 0));
}
@@ -2102,7 +2134,7 @@
/* Draw "score" label: */
dest.x = (screen->w - ((images[IMG_NUMBERS]->w / 10) * 7) -
- images[IMG_SCORE]->w -
+ images[IMG_SCORE]->w -
images[IMG_STOP]->w - 5);
dest.y = 0;
dest.w = images[IMG_SCORE]->w;
@@ -2255,11 +2287,10 @@
}
num_comets_alive = 0;
- /* Clear LED digits: */
+ /* Clear LED F: */
- digits[0] = 0;
- digits[1] = 0;
- digits[2] = 0;
+ for (i = 0; i < MAX_DIGITS; ++i)
+ digits[i] = 0;
neg_answer_picked = 0;
@@ -2296,10 +2327,10 @@
if (bkgd == NULL || scaled_bkgd == NULL)
{
fprintf(stderr,
- "\nWarning: Could not load background image:\n"
- "%s\n"
- "The Simple DirectMedia error that ocurred was: %s\n",
- fname, SDL_GetError());
+ "\nWarning: Could not load background image:\n"
+ "%s\n"
+ "The Simple DirectMedia error that ocurred was: %s\n",
+ fname, SDL_GetError());
Opts_SetUseBkgd(0);
}
}
@@ -2336,70 +2367,70 @@
if (use_feedback)
{
- #ifdef FEEDBACK_DEBUG
- printf("Evaluating feedback...\n old danger level = %g,",danger_level);
+ #ifdef FEEDBACK_DEBUG
+ printf("Evaluating feedback...\n old danger level = %g,",danger_level);
#endif
/* Update our danger level, i.e., the target height */
- danger_level = 1 - (1-danger_level) /
- Opts_DangerLevelSpeedup();
- if (danger_level > Opts_DangerLevelMax())
- danger_level = Opts_DangerLevelMax();
+ danger_level = 1 - (1-danger_level) /
+ Opts_DangerLevelSpeedup();
+ if (danger_level > Opts_DangerLevelMax())
+ danger_level = Opts_DangerLevelMax();
- #ifdef FEEDBACK_DEBUG
- printf(" new danger level = %g.\n",danger_level);
- #endif
+ #ifdef FEEDBACK_DEBUG
+ printf(" new danger level = %g.\n",danger_level);
+ #endif
- /* Check to see whether we have any feedback data. If not, skip it. */
- if (comet_feedback_number == 0)
+ /* Check to see whether we have any feedback data. If not, skip it. */
+ if (comet_feedback_number == 0)
{
- use_feedback = 0; /* No comets above living cities, skip feedback */
+ use_feedback = 0; /* No comets above living cities, skip feedback */
- #ifdef FEEDBACK_DEBUG
- printf("No feedback data available, aborting.\n\n");
- #endif
- }
- else
+ #ifdef FEEDBACK_DEBUG
+ printf("No feedback data available, aborting.\n\n");
+ #endif
+ }
+ else
{
- /* Compute the average height of comet destruction. */
- comet_avg_height = comet_feedback_height/comet_feedback_number;
+ /* Compute the average height of comet destruction. */
+ comet_avg_height = comet_feedback_height/comet_feedback_number;
- /* Determine how this average height compares with target. */
- height_differential = comet_avg_height - danger_level;
+ /* Determine how this average height compares with target. */
+ height_differential = comet_avg_height - danger_level;
- /* Set the speed so that we move halfway towards the target */
- /* height. That makes the changes a bit more conservative. */
+ /* Set the speed so that we move halfway towards the target */
+ /* height. That makes the changes a bit more conservative. */
- #ifdef FEEDBACK_DEBUG
- printf(" comet average height = %g, height differential = %g.\n",
+ #ifdef FEEDBACK_DEBUG
+ printf(" comet average height = %g, height differential = %g.\n",
comet_avg_height, height_differential);
- printf(" old speed = %g,",speed);
- #endif
+ printf(" old speed = %g,",speed);
+ #endif
- speed *= (1 - height_differential/danger_level/2);
+ speed *= (1 - height_differential/danger_level/2);
- /* Enforce bounds on speed */
- if (speed < MINIMUM_SPEED)
- speed = MINIMUM_SPEED;
- if (speed > Opts_MaxSpeed())
- speed = Opts_MaxSpeed();
+ /* Enforce bounds on speed */
+ if (speed < MINIMUM_SPEED)
+ speed = MINIMUM_SPEED;
+ if (speed > Opts_MaxSpeed())
+ speed = Opts_MaxSpeed();
- #ifdef FEEDBACK_DEBUG
- printf(" new speed = %g.\n",speed);
- printf("Feedback evaluation complete.\n\n");
- #endif
- }
+ #ifdef FEEDBACK_DEBUG
+ printf(" new speed = %g.\n",speed);
+ printf("Feedback evaluation complete.\n\n");
+ #endif
+ }
}
if (!use_feedback)
{
/* This is not an "else" because we might skip feedback */
- /* when comet_feedback_number == 0 */
- speed = speed * Opts_SpeedupFactor();
- if (speed > Opts_MaxSpeed())
- {
- speed = Opts_MaxSpeed();
- }
+ /* when comet_feedback_number == 0 */
+ speed = speed * Opts_SpeedupFactor();
+ if (speed > Opts_MaxSpeed())
+ {
+ speed = Opts_MaxSpeed();
+ }
}
}
}
@@ -2585,9 +2616,9 @@
for (j = 0; j < 4; j++)
{
if (str[i] == operchars[j])
- {
- c = 10 + j;
- }
+ {
+ c = 10 + j;
+ }
}
}
@@ -2605,7 +2636,7 @@
dest.h = src.h;
SDL_BlitSurface(images[IMG_NUMS], &src,
- screen, &dest);
+ screen, &dest);
/* Move the 'cursor' one character width: */
cur_x = cur_x + char_width;
}
@@ -2639,31 +2670,31 @@
/* Determine which character to display: */
if (str[i] >= '0' && str[i] <= '9')
- c = str[i] - '0';
+ c = str[i] - '0';
/* Display this character! */
if (c != -1)
- {
- src.x = c * (images[IMG_NUMBERS]->w / 10);
- src.y = 0;
- src.w = (images[IMG_NUMBERS]->w / 10);
- src.h = images[IMG_NUMBERS]->h;
+ {
+ src.x = c * (images[IMG_NUMBERS]->w / 10);
+ src.y = 0;
+ src.w = (images[IMG_NUMBERS]->w / 10);
+ src.h = images[IMG_NUMBERS]->h;
- dest.x = cur_x;
- dest.y = y;
- dest.w = src.w;
- dest.h = src.h;
+ dest.x = cur_x;
+ dest.y = y;
+ dest.w = src.w;
+ dest.h = src.h;
- SDL_BlitSurface(images[IMG_NUMBERS], &src,
- screen, &dest);
+ SDL_BlitSurface(images[IMG_NUMBERS], &src,
+ screen, &dest);
/* Move the 'cursor' one character width: */
- cur_x = cur_x + (images[IMG_NUMBERS]->w / 10);
- }
+ cur_x = cur_x + (images[IMG_NUMBERS]->w / 10);
+ }
}
}
@@ -2709,11 +2740,11 @@
while (SDL_PollEvent(&event))
{
if (event.type == SDL_KEYDOWN)
- pause_done = 1;
+ pause_done = 1;
else if (event.type == SDL_QUIT)
{
SDL_quit_received = 1;
- pause_quit = 1;
+ pause_quit = 1;
}
}
@@ -2920,7 +2951,7 @@
else
dest.x = ((screen->w - ((images[IMG_LEDNUMS]->w) / 10) * 3) / 2);
- for (i = -1; i < 3; i++) /* -1 is special case to allow minus sign */
+ for (i = -1; i < MAX_DIGITS; i++) /* -1 is special case to allow minus sign */
/* with minimal modification of existing code DSB */
{
if (-1 == i)
@@ -3142,7 +3173,7 @@
/* on-screen keypad */
void game_key_event(SDLKey key)
{
-
+ int i;
key_pressed = 1; // Signal back in cases where waiting on any key
if (key == SDLK_ESCAPE)
@@ -3219,17 +3250,25 @@
if (key >= SDLK_0 && key <= SDLK_9)
{
/* [0]-[9]: Add a new digit: */
- digits[0] = digits[1];
- digits[1] = digits[2];
- digits[2] = key - SDLK_0;
+ for (i = 0; i < MAX_DIGITS-1; ++i)
+ digits[i] = digits[i+1];
+ digits[MAX_DIGITS-1] = key - SDLK_0;
+
+// digits[0] = digits[1];
+// digits[1] = digits[2];
+// digits[2] = key - SDLK_0;
tux_pressing = 1;
}
else if (key >= SDLK_KP0 && key <= SDLK_KP9)
{
/* Keypad [0]-[9]: Add a new digit: */
- digits[0] = digits[1];
- digits[1] = digits[2];
- digits[2] = key - SDLK_KP0;
+ for (i = 0; i < MAX_DIGITS-1; ++i)
+ digits[i] = digits[i+1];
+ digits[MAX_DIGITS-1] = key - SDLK_0;
+
+// digits[0] = digits[1];
+// digits[1] = digits[2];
+// digits[2] = key - SDLK_KP0;
tux_pressing = 1;
}
/* support for negative answer input DSB */
@@ -3249,17 +3288,16 @@
}
else if (key == SDLK_BACKSPACE ||
key == SDLK_CLEAR ||
- key == SDLK_DELETE)
+ key == SDLK_DELETE)
{
/* [BKSP]: Clear digits! */
- digits[0] = 0;
- digits[1] = 0;
- digits[2] = 0;
+ for (i = 0; i < MAX_DIGITS; ++i)
+ digits[i] = 0;
tux_pressing = 1;
}
else if (key == SDLK_RETURN ||
key == SDLK_KP_ENTER ||
- key == SDLK_SPACE)
+ key == SDLK_SPACE)
{
/* [ENTER]: Accept digits! */
doing_answer = 1;
@@ -3286,8 +3324,9 @@
comets[i].x = 0;
comets[i].y = 0;
comets[i].answer = 0;
- strncpy(comets[i].flashcard.formula_string, " ", MC_FORMULA_LEN);
- strncpy(comets[i].flashcard.answer_string, " ", MC_ANSWER_LEN);
+// strncpy(comets[i].flashcard.formula_string, " ", max_formula_size);
+// strncpy(comets[i].flashcard.answer_string, " ", max_answer_size);
+ MC_ResetFlashCard(&(comets[i].flashcard) );
comets[i].bonus = 0;
}
}
@@ -3317,6 +3356,9 @@
void free_on_exit(void)
{
+ int i;
+ for (i = 0; i < MAX_MAX_COMETS; ++i)
+ MC_FreeFlashcard(&comets[i].flashcard);
free(comets);
free(cities);
free(penguins);
Modified: tuxmath/branches/mathcards_newarch/src/gettext.h
===================================================================
--- tuxmath/branches/mathcards_newarch/src/gettext.h 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/gettext.h 2008-07-01 16:28:15 UTC (rev 556)
@@ -127,8 +127,8 @@
#endif
static const char *
pgettext_aux (const char *domain,
- const char *msg_ctxt_id, const char *msgid,
- int category)
+ const char *msg_ctxt_id, const char *msgid,
+ int category)
{
const char *translation = dcgettext (domain, msg_ctxt_id, category);
if (translation == msg_ctxt_id)
@@ -146,9 +146,9 @@
#endif
static const char *
npgettext_aux (const char *domain,
- const char *msg_ctxt_id, const char *msgid,
- const char *msgid_plural, unsigned long int n,
- int category)
+ const char *msg_ctxt_id, const char *msgid,
+ const char *msgid_plural, unsigned long int n,
+ int category)
{
const char *translation =
dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
@@ -185,8 +185,8 @@
#endif
static const char *
dcpgettext_expr (const char *domain,
- const char *msgctxt, const char *msgid,
- int category)
+ const char *msgctxt, const char *msgid,
+ int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
@@ -208,10 +208,10 @@
translation = dcgettext (domain, msg_ctxt_id, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
- free (msg_ctxt_id);
+ free (msg_ctxt_id);
#endif
if (translation != msg_ctxt_id)
- return translation;
+ return translation;
}
return msgid;
}
@@ -230,9 +230,9 @@
#endif
static const char *
dcnpgettext_expr (const char *domain,
- const char *msgctxt, const char *msgid,
- const char *msgid_plural, unsigned long int n,
- int category)
+ const char *msgctxt, const char *msgid,
+ const char *msgid_plural, unsigned long int n,
+ int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
@@ -254,10 +254,10 @@
translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
- free (msg_ctxt_id);
+ free (msg_ctxt_id);
#endif
if (!(translation == msg_ctxt_id || translation == msgid_plural))
- return translation;
+ return translation;
}
return (n == 1 ? msgid : msgid_plural);
}
Modified: tuxmath/branches/mathcards_newarch/src/highscore.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/highscore.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/highscore.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -311,7 +311,7 @@
case 0: tux_frame = 1; break;
case TUX1: tux_frame = 2; break;
case TUX2: tux_frame = 3; break;
- case TUX3: tux_frame = 4; break;
+ case TUX3: tux_frame = 4; break;
case TUX4: tux_frame = 3; break;
case TUX5: tux_frame = 2; break;
default: tux_frame = 0;
@@ -568,7 +568,7 @@
case 0: tux_frame = 1; break;
case TUX1: tux_frame = 2; break;
case TUX2: tux_frame = 3; break;
- case TUX3: tux_frame = 4; break;
+ case TUX3: tux_frame = 4; break;
case TUX4: tux_frame = 3; break;
case TUX5: tux_frame = 2; break;
default: tux_frame = 0;
Modified: tuxmath/branches/mathcards_newarch/src/loaders.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/loaders.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/loaders.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -32,13 +32,13 @@
/* FIXME Doesn't seem to work consistently on all versions of Windows */
/* check to see if file exists, if so return true */
// int checkFile( const char *file ) {
-// static struct stat fileStats;
+// static struct stat fileStats;
//
-// fileStats.st_mode = 0;
+// fileStats.st_mode = 0;
//
-// stat( file, &fileStats );
-//
-// return (S_IFREG & fileStats.st_mode);
+// stat( file, &fileStats );
+//
+// return (S_IFREG & fileStats.st_mode);
// }
@@ -88,7 +88,7 @@
int max( int n1, int n2 ) {
- return (n1 > n2 ? n1 : n2);
+ return (n1 > n2 ? n1 : n2);
}
@@ -132,7 +132,7 @@
/* FIXME checkFile() not working right in Win32 - skipping. */
/***********************
- LoadImage : Load an image and set transparent if requested
+ LoadImage : Load an image and set transparent if requested
************************/
SDL_Surface* LoadImage( char *datafile, int mode )
{
@@ -211,7 +211,7 @@
}
/***********************
- LoadBkgd() : a wrapper for LoadImage() that scales the
+ LoadBkgd() : a wrapper for LoadImage() that scales the
image to the size of the screen using zoom(), taken
from TuxPaint
************************/
@@ -284,54 +284,60 @@
sprite* FlipSprite( sprite *in, int X, int Y ) {
- sprite *out;
+ sprite *out;
- out = malloc(sizeof(sprite));
- if (in->default_img != NULL)
- out->default_img = Flip( in->default_img, X, Y );
- else
- out->default_img = NULL;
- for ( out->num_frames=0; out->num_frames<in->num_frames; out->num_frames++ )
- out->frame[out->num_frames] = Flip( in->frame[out->num_frames], X, Y );
- out->cur = 0;
- return out;
+ out = malloc(sizeof(sprite));
+ if (in->default_img != NULL)
+ out->default_img = Flip( in->default_img, X, Y );
+ else
+ out->default_img = NULL;
+ for ( out->num_frames=0; out->num_frames<in->num_frames; out->num_frames++ )
+ out->frame[out->num_frames] = Flip( in->frame[out->num_frames], X, Y );
+ out->cur = 0;
+ return out;
}
sprite* LoadSprite( char* name, int MODE ) {
- sprite *new_sprite;
- char fn[PATH_MAX];
- int x;
+ sprite *new_sprite;
+ char fn[PATH_MAX];
+ int x;
- /* JA --- HACK check out what has changed with new code */
+ /* JA --- HACK check out what has changed with new code */
- new_sprite = malloc(sizeof(sprite));
+ new_sprite = malloc(sizeof(sprite));
- sprintf(fn, "%sd.png", name); // The 'd' means the default image
- new_sprite->default_img = LoadImage( fn, MODE|IMG_NOT_REQUIRED );
- for (x = 0; x < MAX_SPRITE_FRAMES; x++) {
- sprintf(fn, "%s%d.png", name, x);
- new_sprite->frame[x] = LoadImage( fn, MODE|IMG_NOT_REQUIRED );
- if ( new_sprite->frame[x] == NULL ) {
- new_sprite->cur = 0;
- new_sprite->num_frames = x;
- break;
- }
- }
+ sprintf(fn, "%sd.png", name); // The 'd' means the default image
+ new_sprite->default_img = LoadImage( fn, MODE|IMG_NOT_REQUIRED );
+ for (x = 0; x < MAX_SPRITE_FRAMES; x++) {
+ sprintf(fn, "%s%d.png", name, x);
+ new_sprite->frame[x] = LoadImage( fn, MODE|IMG_NOT_REQUIRED );
+ if ( new_sprite->frame[x] == NULL ) {
+ new_sprite->cur = 0;
+ new_sprite->num_frames = x;
+ break;
+ }
+ }
-
- return new_sprite;
+
+ return new_sprite;
}
void FreeSprite( sprite *gfx ) {
- int x;
- for (x = 0; x < gfx->num_frames; x++)
- SDL_FreeSurface( gfx->frame[x] );
- SDL_FreeSurface( gfx->default_img );
- free(gfx);
+ int x;
+ if (!gfx)
+ return;
+ for (x = 0; x < gfx->num_frames; x++)
+ {
+ tmdprintf(".");
+ SDL_FreeSurface( gfx->frame[x] );
+ }
+ tmdprintf("\nFreeing default\n");
+ SDL_FreeSurface( gfx->default_img );
+ free(gfx);
}
void next_frame(sprite* s)
@@ -341,7 +347,7 @@
}
/***************************
- LoadSound : Load a sound/music patch from a file.
+ LoadSound : Load a sound/music patch from a file.
****************************/
Mix_Chunk* LoadSound( char *datafile )
{
@@ -359,8 +365,8 @@
}
/************************
- LoadMusic : Load
- music from a datafile
+ LoadMusic : Load
+ music from a datafile
*************************/
Mix_Music *LoadMusic(char *datafile )
{
Modified: tuxmath/branches/mathcards_newarch/src/mathcards.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/mathcards.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/mathcards.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -1,11 +1,11 @@
/*
* C Implementation: mathcards.c
*
-* Description: implementation of backend for a flashcard-type math game.
+* Description: implementation of backend for a flashcard-type math game.
Developed as an enhancement to Bill Kendrick's "Tux of Math Command"
(aka tuxmath). (If tuxmath were a C++ program, this would be a C++ class).
MathCards could be used as the basis for similar games using a different interface.
-
+
*
*
* Author: David Bruce <dbruce at tampabay.rr.com>, (C) 2005
@@ -16,11 +16,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#include <time.h>
#include "mathcards.h"
/* extern'd constants */
+
const char* const MC_OPTION_TEXT[NOPTS+1] = {
"PLAY_THROUGH_LIST",
"REPEAT_WRONGS",
@@ -79,6 +81,9 @@
"RANDOMIZE",
+"AVG_LIST_LENGTH",
+"VARY_LIST_LENGTH",
+
"END_OF_OPTS"
};
@@ -90,8 +95,8 @@
999, //MAX_ANSWER
5000, //MAX_QUESTIONS
1, //QUESTION_COPIES
- 2, //MAX_FORMULA_NUMS
- 5, //MIN_FORMULA_NUMS
+ 3, //MAX_FORMULA_NUMS
+ 1, //MIN_FORMULA_NUMS
//
1, //FORMAT_ANSWER_LAST
0, //FORMAT_ANSWER_FIRST
@@ -138,12 +143,16 @@
0, //MIN_TYPING_NUM
12, //MAX_TYPING_NUM
//
- 1 //RANDOMIZE
+ 1, //RANDOMIZE
+ 100, //AVG_LIST_LENGTH
+ 1 //VARY_LIST_LENGTH
};
/* "Globals" for mathcards.c: */
+const char operchars[4] = "+-*/";
+
MC_Options* math_opts = 0;
MC_MathQuestion* question_list = 0;
MC_MathQuestion* wrong_quests = 0;
@@ -204,14 +213,15 @@
static void print_counters(void);
static MC_MathQuestion* create_node_copy(MC_MathQuestion* other);
-static MC_FlashCard* create_card_from_node(MC_MathQuestion* node);
+static MC_FlashCard create_card_from_node(MC_MathQuestion* node);
#endif
/* Functions for new mathcards architecture */
-static MC_FlashCard allocate_flashcard(void); //allocate space for a flashcard
-static void free_flashcard(MC_FlashCard fc); //be sure to free flashcards when done
+//static MC_FlashCard allocate_flashcard(void); //allocate space for a flashcard
+//static void free_flashcard(MC_FlashCard fc); //be sure to free flashcards when done
static void free_node(MC_MathQuestion* mq); //wrapper for free() that also frees card
static MC_FlashCard generate_random_flashcard(void);
+static MC_FlashCard generate_random_ooo_card_of_length(int length);
static void copy_card(const MC_FlashCard* src, MC_FlashCard* dest); //deep copy a flashcard
static MC_MathQuestion* allocate_node(void); //allocate space for a node
static int compare_card(const MC_FlashCard* a, const MC_FlashCard* b); //test for identical cards
@@ -292,23 +302,20 @@
if (!initialized)
{
- #ifdef MC_DEBUG
- printf("\nNot initialized - calling MC_Initialize()");
- #endif
+ mcdprintf("\nNot initialized - calling MC_Initialize()");
MC_Initialize();
}
if (!math_opts)
{
- #ifdef MC_DEBUG
- printf("\nCould not initialize - bailing out");
- printf("\nLeavinging MC_StartGame()\n");
- #endif
+ mcdprintf("\nCould not initialize - bailing out");
+ mcdprintf("\nLeavinging MC_StartGame()\n");
return 0;
}
/* we know math_opts exists if we make it to here */
+ srand(time(NULL));
/* clear out old lists if starting another game: (if not done already) */
delete_list(question_list);
@@ -329,7 +336,9 @@
* ((int)(log10f(MC_GLOBAL_MAX) ) + 4) //sign/operator/spaces
+ 2; //question mark for answer, and ending '\0'
max_answer_size = (int)(log10f(MC_GLOBAL_MAX) ) + 2; //sign and ending '\0'
-
+
+ mcdprintf("max answer, formula size: %d, %d\n",
+ max_answer_size, max_formula_size);
/* set up new list with pointer to top: */
question_list = generate_list();
@@ -345,27 +354,23 @@
answered_correctly = 0;
answered_wrong = 0;
questions_pending = 0;
-
+
#ifdef MC_DEBUG
print_counters();
#endif
-
+
/* make sure list now exists and has non-zero length: */
if (question_list && quest_list_length)
{
- #ifdef MC_DEBUG
- printf("\nGame set up successfully");
- printf("\nLeaving MC_StartGame()\n");
- #endif
+ mcdprintf("\nGame set up successfully");
+ mcdprintf("\nLeaving MC_StartGame()\n");
return 1;
}
else
{
- #ifdef MC_DEBUG
- printf("\nGame NOT set up successfully - no valid list");
- printf("\nLeaving MC_StartGame()\n");
- #endif
+ mcdprintf("\nGame NOT set up successfully - no valid list");
+ mcdprintf("\nLeaving MC_StartGame()\n");
return 0;
}
@@ -474,7 +479,6 @@
return 0;
}
- /* FIXME: could clean this up a bit with a copy_card() function */
copy_card(&question_list->card, fc);
// fc->num1 = question_list->card.num1;
// fc->num2 = question_list->card.num2;
@@ -733,1145 +737,22 @@
}
-///* Simple Get()- and Set()-style functions for math options settings: */
-//
-//
-///* Set general math options: */
-//void MC_SetMaxAnswer(int max)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetMaxAnswer(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[MAX_ANSWER] = sane_value(max);
-//}
-//
-//
-//void MC_SetMaxQuestions(int max)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetMaxQuestions(): math_opts not valid!\n");
-// return;
-// }
-// if (max < 0)
-// {
-// fprintf(stderr, "\nMC_SetMaxQuestions(): max_questions cannot be negative!\n");
-// return;
-// }
-// math_opts->iopts[MAX_QUESTIONS] = max;
-//}
-//
-//void MC_SetAllowNegatives(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetAllowNegatives(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[ALLOW_NEGATIVES] = int_to_bool(opt);
-// if (!opt)
-// {
-// clear_negatives();
-// }
-//}
-//
-//
-//void MC_SetPlayThroughList(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetPlayThroughList(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[PLAY_THROUGH_LIST] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetRepeatWrongs(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetRepeatWrongs(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[REPEAT_WRONGS] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetCopiesRepeatedWrongs(int copies)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetCopiesRepeatedWrongs(): math_opts not valid!\n");
-// return;
-// }
-// /* number of copies must be between 1 and 10: */
-// if (copies < 1)
-// copies = 1;
-// if (copies > 10)
-// copies = 10;
-// math_opts->iopts[COPIES_REPEATED_WRONGS] = copies;
-//}
-//
-//
-//
-///*NOTE - list can contain more than one format */
-//void MC_SetFormatAnswerLast(int opt) /* Enable questions like: a + b = ? */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatAnswerLast(): math_opts not valid!\n");
-// return;
-// }
-//
-// MC_SetFormatAddAnswerLast(opt);
-// MC_SetFormatSubAnswerLast(opt);
-// MC_SetFormatMultAnswerLast(opt);
-// MC_SetFormatDivAnswerLast(opt);
-//}
-//
-//
-//void MC_SetFormatAnswerFirst(int opt) /* Enable questions like: ? + b = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatAnswerFirst(): math_opts not valid!\n");
-// return;
-// }
-//
-// MC_SetFormatAddAnswerFirst(opt);
-// MC_SetFormatSubAnswerFirst(opt);
-// MC_SetFormatMultAnswerFirst(opt);
-// MC_SetFormatDivAnswerFirst(opt);
-//}
-//
-//
-//void MC_SetFormatAnswerMiddle(int opt) /* Enable questions like: a + ? = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatAnswerMiddle(): math_opts not valid!\n");
-// return;
-// }
-//
-// MC_SetFormatAddAnswerMiddle(opt);
-// MC_SetFormatSubAnswerMiddle(opt);
-// MC_SetFormatMultAnswerMiddle(opt);
-// MC_SetFormatDivAnswerMiddle(opt);
-//}
-//
-//
-//
-///* Addition-specific question formats: */
-//void MC_SetFormatAddAnswerLast(int opt) /* Enable questions like: a + b = ? */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatAddAnswerLast(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_ADD_ANSWER_LAST] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetFormatAddAnswerFirst(int opt) /* Enable questions like: ? + b = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatAddAnswerFirst(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_ADD_ANSWER_FIRST] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetFormatAddAnswerMiddle(int opt) /* Enable questions like: a + ? = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatAddAnswerMiddle(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_ADD_ANSWER_MIDDLE] = int_to_bool(opt);
-//}
-//
-//
-//
-///* Subtraction-specific question formats: */
-//void MC_SetFormatSubAnswerLast(int opt) /* Enable questions like: a - b = ? */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatSubAnswerLast(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_SUB_ANSWER_LAST] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetFormatSubAnswerFirst(int opt) /* Enable questions like: ? - b = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatSubAnswerFirst(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_SUB_ANSWER_FIRST] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetFormatSubAnswerMiddle(int opt) /* Enable questions like: a - ? = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatSubAnswerMiddle(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_SUB_ANSWER_MIDDLE] = int_to_bool(opt);
-//}
-//
-//
-//
-///* Multiplication-specific question formats: */
-//void MC_SetFormatMultAnswerLast(int opt) /* Enable questions like: a * b = ? */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatMultAnswerLast(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_MULT_ANSWER_LAST] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetFormatMultAnswerFirst(int opt) /* Enable questions like: ? * b = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatMultAnswerFirst(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_MULT_ANSWER_FIRST] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetFormatMultAnswerMiddle(int opt) /* Enable questions like: a * ? = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatMultAnswerMiddle(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_MULT_ANSWER_MIDDLE] = int_to_bool(opt);
-//}
-//
-//
-///* Division-specific question formats: */
-//void MC_SetFormatDivAnswerLast(int opt) /* Enable questions like: a / b = ? */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatDivAnswerLast(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_DIV_ANSWER_LAST] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetFormatDivAnswerFirst(int opt) /* Enable questions like: ? / b = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatDivAnswerFirst(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_DIV_ANSWER_FIRST] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetFormatDivAnswerMiddle(int opt) /* Enable questions like: a / ? = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetFormatDivAnswerMiddle(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[FORMAT_DIV_ANSWER_MIDDLE] = int_to_bool(opt);
-//}
-//
-//
-//
-//void MC_SetQuestionCopies(int copies) /* how many times each question is put in list */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetQuestionCopies(): math_opts not valid!\n");
-// return;
-// }
-// /* number of copies must be between 1 and 10: */
-// if (copies < 1)
-// copies = 1;
-// if (copies > 10)
-// copies = 10;
-// math_opts->iopts[QUESTION_COPIES] = copies;
-//}
-//
-//
-//void MC_SetRandomize(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetRandomize(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[RANDOMIZE] = int_to_bool(opt);
-//}
-//
-//void MC_SetFractionToKeep(float fract)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetRandomize(): math_opts not valid!\n");
-// return;
-// }
-// /* must be between 0 and 1: */
-// if (fract < 0)
-// fract = 0;
-// if (fract > 1)
-// fract = 1;
-// math_opts->fraction_to_keep = fract;
-//}
-//
-//
-///* Set math operations to be used in game: */
-//void MC_SetAddAllowed(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetAddAllowed(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[ADDITION_ALLOWED] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetSubAllowed(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetSubAllowed(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[SUBTRACTION_ALLOWED] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetMultAllowed(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetMultAllowed(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[MULTIPLICATION_ALLOWED] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetDivAllowed(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetDivAllowed(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[DIVISION_ALLOWED] = int_to_bool(opt);
-//}
-//
-//
-//void MC_SetTypingAllowed(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetTypingAllowed(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[TYPING_PRACTICE_ALLOWED] = int_to_bool(opt);
-//}
-//
-//
-//
-///* Set min and max for addition: */
-//void MC_SetAddMin(int opt)
-//{
-// MC_SetAddMinAugend(opt);
-// MC_SetAddMinAddend(opt);
-//}
-//
-//
-//void MC_SetAddMinAugend(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetAddMinAugend(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[MIN_AUGEND] = sane_value(opt);
-//}
-//
-//
-//void MC_SetAddMinAddend(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetAddMinAddend(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->iopts[MIN_ADDEND] = sane_value(opt);
-//}
-//
-//
-//void MC_SetAddMax(int opt)
-//{
-// MC_SetAddMaxAugend(opt);
-// MC_SetAddMaxAddend(opt);
-//}
-//
-//
-//void MC_SetAddMaxAugend(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetAddMaxAugend(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->max_augend = sane_value(opt);
-//}
-//
-//
-//void MC_SetAddMaxAddend(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetAddMaxAddend(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->max_addend = sane_value(opt);
-//}
-//
-//
-//
-//
-///* Set min and max for subtraction: */
-//void MC_SetSubMin(int opt)
-//{
-// MC_SetSubMinMinuend(opt);
-// MC_SetSubMinSubtrahend(opt);
-//}
-//
-//
-//void MC_SetSubMinMinuend(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_MC_SetSubMinMinuend(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->min_minuend = sane_value(opt);
-//}
-//
-//
-//void MC_SetSubMinSubtrahend(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetSubMinSubtrahend(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->min_subtrahend = sane_value(opt);
-//}
-//
-//
-//void MC_SetSubMax(int opt)
-//{
-// MC_SetSubMaxMinuend(opt);
-// MC_SetSubMaxSubtrahend(opt);
-//}
-//
-//
-//void MC_SetSubMaxMinuend(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetSubMaxMinuend(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->max_minuend = sane_value(opt);
-//}
-//
-//
-//void MC_SetSubMaxSubtrahend(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetSubMaxSubtrahend(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->max_subtrahend = sane_value(opt);
-//}
-//
-//
-//
-//
-///* Set min and max for multiplication: */
-//void MC_SetMultMin(int opt)
-//{
-// MC_SetMultMinMultiplier(opt);
-// MC_SetMultMinMultiplicand(opt);
-//}
-//
-//
-//void MC_SetMultMinMultiplier(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetMultMinMultiplier(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->min_multiplier = sane_value(opt);
-//}
-//
-//
-//void MC_SetMultMinMultiplicand(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetMultMinMultiplicand(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->min_multiplicand = sane_value(opt);
-//}
-//
-//
-//void MC_SetMultMax(int opt)
-//{
-// MC_SetMultMaxMultiplier(opt);
-// MC_SetMultMaxMultiplicand(opt);
-//}
-//
-//
-//void MC_SetMultMaxMultiplier(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetMultMaxMultiplier(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->max_multiplier = sane_value(opt);
-//}
-//
-//
-//void MC_SetMultMaxMultiplicand(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetMultMaxMultiplicand(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->max_multiplicand = sane_value(opt);
-//}
-//
-//
-//
-//
-///* Set min and max for division: */
-//void MC_SetDivMin(int opt)
-//{
-// MC_SetDivMinDivisor(opt);
-// MC_SetDivMinQuotient(opt);
-//}
-//
-//
-//void MC_SetDivMinDivisor(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetDivMinDivisor(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->min_divisor = sane_value(opt);
-//}
-//
-//
-//void MC_SetDivMinQuotient(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetDivMinQuotient(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->min_quotient = sane_value(opt);
-//}
-//
-//
-//void MC_SetDivMax(int opt)
-//{
-// MC_SetDivMaxDivisor(opt);
-// MC_SetDivMaxQuotient(opt);
-//}
-//
-//
-//void MC_SetDivMaxDivisor(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetDivMaxDivisor(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->max_divisor = sane_value(opt);
-//}
-//
-//
-//void MC_SetDivMaxQuotient(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetDivMaxQuotient(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->max_quotient = sane_value(opt);
-//}
-//
-//
-///* Set min and max for division: */
-//void MC_SetTypeMin(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetTypeMin(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->min_typing_num = sane_value(opt);
-//}
-//
-//
-//void MC_SetTypeMax(int opt)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SetTypeMax(): math_opts not valid!\n");
-// return;
-// }
-// math_opts->max_typing_num = sane_value(opt);
-//}
-//
-//
-///*"Get" type methods to query option parameters */
-//
-///* Query general math options: */
-//int MC_MaxAnswer(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_MaxAnswer(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->max_answer;
-//}
-//
-//
-//int MC_MaxQuestions(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_MaxQuestions(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->max_questions;
-//}
-//
-//
-//int MC_AllowNegatives(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_AllowNegatives(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->allow_negatives;
-//}
-//
-//
-//int MC_PlayThroughList(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_PlayThroughList(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->play_through_list;
-//}
-//
-//
-//int MC_RepeatWrongs(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_RepeatWrongs(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->repeat_wrongs;
-//}
-//
-//
-//int MC_CopiesRepeatedWrongs(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_CopiesRepeatedWrongs(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->copies_repeated_wrongs;
-//}
-//
-//
-//float MC_FractionToKeep(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FractionToKeep(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->fraction_to_keep;
-//}
-//
-//
-//
-//int MC_FormatAddAnswerLast(void) /* a + b = ? */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatAddAnswerLast(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_ADD_ANSWER_LAST];
-//}
-//
-//
-//int MC_FormatAddAnswerFirst(void) /* ? + b = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatAddAnswerFirst(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_ADD_ANSWER_FIRST];
-//}
-//
-//
-//int MC_FormatAddAnswerMiddle(void) /* a + ? = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatAddAnswerMiddle(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_ADD_ANSWER_MIDDLE];
-//}
-//
-//
-//int MC_FormatSubAnswerLast(void) /* a - b = ? */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatSubAnswerLast(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_SUB_ANSWER_LAST];
-//}
-//
-//
-//int MC_FormatSubAnswerFirst(void) /* ? - b = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatSubAnswerFirst(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_SUB_ANSWER_FIRST];
-//}
-//
-//
-//int MC_FormatSubAnswerMiddle(void) /* a - ? = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatSubAnswerMiddle(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_SUB_ANSWER_MIDDLE];
-//}
-//
-//int MC_FormatMultAnswerLast(void) /* a * b = ? */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatMultAnswerLast(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_MULT_ANSWER_LAST];
-//}
-//
-//
-//int MC_FormatMultAnswerFirst(void) /* ? * b = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatMultAnswerFirst(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_MULT_ANSWER_FIRST];
-//}
-//
-//
-//int MC_FormatMultAnswerMiddle(void) /* a * ? = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatMultAnswerMiddle(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_MULT_ANSWER_MIDDLE];
-//}
-//
-//
-//int MC_FormatDivAnswerLast(void) /* a / b = ? */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatDivAnswerLast(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_DIV_ANSWER_LAST];
-//}
-//
-//
-//int MC_FormatDivAnswerFirst(void) /* ? / b = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatDivAnswerFirst(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_DIV_ANSWER_FIRST];
-//}
-//
-//
-//int MC_FormatDivAnswerMiddle(void) /* a / ? = c */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_FormatAnswerMiddle(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->iopts[FORMAT_ADD_ANSWER_MIDDLE];
-//}
-//
-//
-//
-//int MC_QuestionCopies(void) /* how many times each question is put in list */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_QuestionCopies(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->question_copies;
-//}
-//
-//
-//int MC_Randomize(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_Randomize(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->randomize;
-//}
-//
-//
-//
-///* Query the allowed math operations: */
-//int MC_AddAllowed(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_AddAllowed(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->addition_allowed;
-//}
-//
-//
-//int MC_SubAllowed(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SubAllowed(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->subtraction_allowed;
-//}
-//
-//
-//int MC_MultAllowed(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_MultAllowed(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->multiplication_allowed;
-//}
-//
-//
-//int MC_DivAllowed(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_DivAllowed(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->division_allowed;
-//}
-//
-//
-//int MC_TypingAllowed(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_TypeAllowed(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->typing_practice_allowed;
-//}
-//
-//
-///* Query min and max for addition: */
-//int MC_AddMinAugend(void) /* the "augend" is the first addend i.e. "a" in "a + b = c" */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_AddMinAugend(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->min_augend;
-//}
-//
-//
-//int MC_AddMinAddend(void) /* options for the other addend */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_AddMinAddend(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->min_addend;
-//}
-//
-//
-//int MC_AddMaxAugend(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_AddMaxAugend(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->max_augend;
-//}
-//
-//
-//int MC_AddMaxAddend(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_AddMaxAddend(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->max_addend;
-//}
-//
-//
-//
-///* Query min and max for subtraction: */
-//int MC_SubMinMinuend(void) /* minuend - subtrahend = difference */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SubMinMinuend(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->min_minuend;
-//}
-//
-//
-//int MC_SubMinSubtrahend(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SubMinSubtrahend(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->min_subtrahend;
-//}
-//
-//
-//
-//int MC_SubMaxMinuend(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SubMaxMinuend(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->max_minuend;
-//}
-//
-//
-//
-//int MC_SubMaxSubtrahend(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_SubMaxSubtrahend(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->max_subtrahend;
-//}
-//
-//
-//
-///* Query min and max for multiplication: */
-//int MC_MultMinMultiplier(void) /* multiplier * multiplicand = product */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_MultMinMultiplier(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->min_multiplier;
-//}
-//
-//
-//int MC_MultMinMultiplicand(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_MultMinMultiplicand(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->min_multiplicand;
-//}
-//
-//
-//
-//int MC_MultMaxMultiplier(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_MultMaxMultiplier(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->max_multiplier;
-//}
-//
-//
-//
-//int MC_MultMaxMultiplicand(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_MultMaxMultiplicand(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->max_multiplicand;
-//}
-//
-//
-//
-///* Query min and max for division: */
-//int MC_DivMinDivisor(void) /* dividend/divisor = quotient */
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_DivMinDivisor(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->min_divisor;
-//}
-//
-//
-//int MC_DivMinQuotient(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_DivMinQuotient(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->min_quotient;
-//}
-//
-//
-//int MC_DivMaxDivisor(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_DivMaxDivisor(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->max_divisor;
-//}
-//
-//
-//int MC_DivMaxQuotient(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_DivMaxQuotient(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->max_quotient;
-//}
-//
-//
-///* Query min and max for typing practice: */
-//int MC_TypeMin(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_TypeMin(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->min_typing_num;
-//}
-//
-//
-//int MC_TypeMax(void)
-//{
-// if (!math_opts)
-// {
-// fprintf(stderr, "\nMC_TypeMax(): math_opts not valid!\n");
-// return MC_MATH_OPTS_INVALID;
-// }
-// return math_opts->max_typing_num;
-//}
-
/* prints struct to file */
void MC_PrintMathOptions(FILE* fp, int verbose)
{
+ int i, vcommentsprimed = 0;
+ static char* vcomments[NOPTS]; //comments when writing out verbose
+ if (!vcommentsprimed) //we only want to initialize these once
+ {
+ vcommentsprimed = 1;
+ for (i = 0; i < NOPTS; ++i)
+ vcomments[i] = NULL;
+ //TODO place comments in the slots where they should be written
+
+ }
+
+
#ifdef MC_DEBUG
printf("\nEntering MC_PrintMathOptions()\n");
#endif
@@ -1882,6 +763,15 @@
fprintf(stderr, "\nMath Options struct does not exist!\n");
return;
}
+#ifdef MC_USE_NEWARC
+ for (i = 0; i < NOPTS; ++i)
+ {
+ if (verbose && vcomments[i] != NULL)
+ fprintf(fp, vcomments[i]);
+ fprintf(fp, "%s = %d\n", MC_OPTION_TEXT[i], math_opts->iopts[i]);
+ }
+ return;
+#endif
if (verbose)
{
@@ -2597,94 +1487,16 @@
ptr->card.operation = op;
ptr->card.format = f;
*/
- ptr->card = allocate_flashcard();
+ ptr->card = MC_AllocateFlashcard();
ptr->next = NULL;
ptr->previous = NULL;
+
+ snprintf(ptr->card.formula_string, max_formula_size, "%d %c %d = ?",
+ n1, op < MC_NUM_OPERS ? operchars[op] : '\0', n2);
+ snprintf(ptr->card.answer_string, max_formula_size, "%d", ans);
+ ptr->card.difficulty = 25 * (op + 1);
-// /* creating formula_string and answer_string is a little more work: */
-// {
-// char oper_char;
-// /* find out correct operation character */
-// switch (op)
-// {
-// case MC_OPER_ADD:
-// {
-// oper_char = '+';
-// break;
-// }
-// case MC_OPER_SUB:
-// {
-// oper_char = '-';
-// break;
-// }
-// case MC_OPER_MULT:
-// {
-// oper_char = '*';
-// break;
-// }
-// case MC_OPER_DIV:
-// {
-// oper_char = '/';
-// break;
-// }
-// case MC_OPER_TYPING_PRACTICE:
-// {
-// snprintf(ptr->card.formula_string, MC_FORMULA_LEN, "%d",ptr->card.num1);
-// snprintf(ptr->card.answer_string, MC_ANSWER_LEN, "%d",ptr->card.num1);
-// return ptr; /* Don't need to look at formats for this case. */
-// }
-// default:
-// {
-// fprintf(stderr, "\nIn create_node(): invalid math operation\n");
-// free(ptr);
-// ptr = 0;
-//
-// return 0;
-// }
-// }
-//
-// switch (f) /* f is format argument */
-// {
-// case MC_FORMAT_ANS_LAST: /* e.g. num1 + num2 = ? */
-// {
-// snprintf(ptr->card.formula_string, MC_FORMULA_LEN,"%d %c %d = ?",
-// ptr->card.num1,
-// oper_char,
-// ptr->card.num2);
-// snprintf(ptr->card.answer_string, MC_ANSWER_LEN, "%d",ptr->card.num3);
-// break;
-// }
-// case MC_FORMAT_ANS_MIDDLE: /* e.g. num1 + ? = num3 */
-// {
-// snprintf(ptr->card.formula_string, MC_FORMULA_LEN,"%d %c ? = %d",
-// ptr->card.num1,
-// oper_char,
-// ptr->card.num3);
-// snprintf(ptr->card.answer_string, MC_ANSWER_LEN, "%d",ptr->card.num2);
-// break;
-// }
-// case MC_FORMAT_ANS_FIRST: /* e.g. ? + num2 = num3 */
-// {
-// snprintf(ptr->card.formula_string, MC_FORMULA_LEN,"? %c %d = %d",
-// oper_char,
-// ptr->card.num2,
-// ptr->card.num3);
-// snprintf(ptr->card.answer_string, MC_ANSWER_LEN, "%d",ptr->card.num1);
-// break;
-// }
-// default: /* should not get to here if MathCards behaves correctly */
-// {
-// fprintf(stderr, "\ncreate_node() - invalid question format\n");
-// free(ptr);
-// ptr = 0;
-//
-//
-// return 0;
-// }
-// }
-// }
-
/* ptr should now point to a properly constructed node: */
return ptr;
}
@@ -2695,8 +1507,9 @@
/* FIXME should properly return newly allocated list if more than one node DSB */
MC_MathQuestion* create_node_copy(MC_MathQuestion* other)
{
- MC_MathQuestion* ret = create_node();
- copy_card(&other->card, &ret->card);
+ MC_MathQuestion* ret = malloc(sizeof(MC_MathQuestion) );
+ if (ret)
+ copy_card(&other->card, &ret->card);
return ret;
}
#endif
@@ -2711,13 +1524,13 @@
#ifdef MC_DEBUG
/* FIXME take care of strings */
-MC_FlashCard* create_card_from_node(MC_MathQuestion* node)
+MC_FlashCard create_card_from_node(MC_MathQuestion* node)
{
- MC_FlashCard* fc;
+ MC_FlashCard fc;
if (!node)
- return 0;
- fc = create_flashcard();
- copy_card(&node->card, fc);
+ return DEFAULT_CARD;
+ fc = MC_AllocateFlashcard();
+ copy_card(&node->card, &fc);
return fc;
}
#endif
@@ -2833,7 +1646,7 @@
while (list)
{
tmp_ptr = list->next;
- free (list);
+ free_node (list);
list = tmp_ptr;
}
return list;
@@ -2892,12 +1705,8 @@
void print_card(MC_FlashCard card)
{
printf("\nprint_card():");
- printf("\n%d, %d \tOper %d \tAnswer %d \t Format %d\n",
- card.num1,
- card.num2,
- card.operation,
- card.num3,
- card.format);
+ printf("formula_string = %s, answer_string = %s\n",
+ card.formula_string, card.answer_string);
}
#endif
@@ -3144,7 +1953,7 @@
****************************************************/
/* allocate space for an MC_Flashcard */
-MC_FlashCard allocate_flashcard(void)
+MC_FlashCard MC_AllocateFlashcard(void)
{
MC_FlashCard ret;
ret.formula_string = malloc(max_formula_size * sizeof(char));
@@ -3158,26 +1967,43 @@
}
return ret;
}
-void free_flashcard(MC_FlashCard fc)
+void MC_FreeFlashcard(MC_FlashCard* fc)
{
- if (fc.formula_string)
- free(fc.formula_string);
- if (fc.answer_string)
- free(fc.answer_string);
+ if (!fc)
+ return;
+#ifndef MC_DEBUG
+ mcdprintf("Freeing formula_string\n");
+ if (fc->formula_string)
+ {
+ free(fc->formula_string);
+ fc->formula_string = NULL;
+ }
+ mcdprintf("Freeing answer_string\n");
+ if (fc->answer_string)
+ {
+ free(fc->answer_string);
+ fc->answer_string = NULL;
+ }
+#endif
}
void copy_card(const MC_FlashCard* src, MC_FlashCard* dest)
{
- strncpy(src->formula_string, dest->formula_string, max_formula_size);
- strncpy(src->answer_string, dest->answer_string, max_answer_size);
+ if (!src || !dest)
+ return;
+ mcdprintf("Copying '%s' to '%s', ", src->formula_string,dest->formula_string);
+ mcdprintf("copying '%s' to '%s'\n", src->answer_string, dest->answer_string);
+ strncpy(dest->formula_string, src->formula_string, max_formula_size);
+ strncpy(dest->answer_string, src->answer_string, max_answer_size);
dest->answer = src->answer;
+ dest->difficulty = src->difficulty;
}
void free_node(MC_MathQuestion* mq) //no, not that freenode.
{
if (!mq)
return;
- free_flashcard(mq->card);
+ MC_FreeFlashcard(&mq->card);
free(mq);
}
@@ -3188,21 +2014,169 @@
if (!ret)
printf("Could not allocate space for a new node!\n");
else
- ret->card = allocate_flashcard();
+ ret->card = MC_AllocateFlashcard();
return ret;
}
-MC_FlashCard generate_random_flashcard()
+/*
+The function that does the central dirty work pertaining to flashcard
+creation. Extensible to just about any kind of math problem, perhaps
+with the exception of those with multiple answers, such as "8 + 2 > ?"
+Simply specify how the problem is presented to the user, and the
+answer the game should look for, as strings.
+*/
+MC_FlashCard generate_random_flashcard(void)
{
- MC_FlashCard ret = allocate_flashcard();
+ int num;
+ int length;
+ MC_ProblemType pt;
+ MC_FlashCard ret;
+ mcdprintf("Entering generate_random_flashcard()\n");
+ pt = rand() % MC_NUM_PTYPES;
+ if (pt == MC_PT_TYPING) //typing practice
+ {
+ mcdprintf("Generating typing question\n");
+ ret = MC_AllocateFlashcard();
+ num = rand() % (MC_GetOpt(MAX_TYPING_NUM) - MC_GetOpt(MIN_TYPING_NUM) )
+ + MC_GetOpt(MIN_TYPING_NUM);
+ snprintf(ret.formula_string, max_formula_size, "%d", num);
+ snprintf(ret.answer_string, max_answer_size, "%d", num);
+ ret.difficulty = 10;
+ }
+ else //if (pt == MC_PT_ARITHMETIC)
+ {
+ length = rand() % (MC_GetOpt(MAX_FORMULA_NUMS)-MC_GetOpt(MIN_FORMULA_NUMS) )
+ + MC_GetOpt(MIN_FORMULA_NUMS);
+ mcdprintf("Generating question of length %d", length);
+ ret = generate_random_ooo_card_of_length(length);
+
+ }
+ //TODO comparison problems (e.g. "6 ? 9", "<")
+
+ mcdprintf("Exiting generate_random_flashcard()\n");
+
return ret;
}
+/*
+Recursively generate an order of operations problem. Hopefully this won't
+raise performance issues.
+*/
+MC_FlashCard generate_random_ooo_card_of_length(int length)
+{
+ int r1 = 0;
+ int r2 = 0;
+ int ans = 0;
+ char* tempstr[max_formula_size];
+ MC_FlashCard ret;
+ MC_Operation op;
+
+ printf(".");
+ if (length > MAX_FORMULA_NUMS)
+ return DEFAULT_CARD;
+ if (length <= 2)
+ {
+ ret = MC_AllocateFlashcard();
+ for (op = rand() % MC_NUM_OPERS; //pick a random operation
+ MC_GetOpt(op + ADDITION_ALLOWED) == 0; //make sure it's allowed
+ op = rand() % MC_NUM_OPERS);
+
+ mcdprintf("Operation is %c\n", operchars[op]);
+ if (op == MC_OPER_ADD)
+ {
+ r1 = rand() % (math_opts->iopts[MAX_AUGEND] - math_opts->iopts[MIN_AUGEND]) + math_opts->iopts[MIN_AUGEND];
+ r2 = rand() % (math_opts->iopts[MAX_ADDEND] - math_opts->iopts[MIN_ADDEND]) + math_opts->iopts[MIN_ADDEND];
+ ans = r1 + r2;
+ }
+ else if (op == MC_OPER_SUB)
+ {
+ r1 = rand() % (math_opts->iopts[MAX_MINUEND] - math_opts->iopts[MIN_MINUEND]) + math_opts->iopts[MIN_MINUEND];
+ r2 = rand() % (math_opts->iopts[MAX_SUBTRAHEND] - math_opts->iopts[MIN_SUBTRAHEND]) + math_opts->iopts[MIN_SUBTRAHEND];
+ ans = r1 - r2;
+ }
+ else if (op == MC_OPER_MULT)
+ {
+ r1 = rand() % (math_opts->iopts[MAX_MULTIPLIER] - math_opts->iopts[MIN_MULTIPLIER]) + math_opts->iopts[MIN_MULTIPLIER];
+ r2 = rand() % (math_opts->iopts[MAX_MULTIPLICAND] - math_opts->iopts[MIN_MULTIPLICAND]) + math_opts->iopts[MIN_MULTIPLICAND];
+ ans = r1 * r2;
+ }
+ else if (op == MC_OPER_DIV)
+ {
+ ans = rand() % (math_opts->iopts[MAX_QUOTIENT] - math_opts->iopts[MIN_QUOTIENT]) + math_opts->iopts[MIN_QUOTIENT];
+ r2 = rand() % (math_opts->iopts[MAX_DIVISOR] - math_opts->iopts[MIN_DIVISOR]) + math_opts->iopts[MIN_DIVISOR];
+ r1 = ans * r2;
+ }
+ else
+ mcdprintf("Invalid operator: value %d\n", op);
+
+ mcdprintf("Constructing answer_string\n");
+ snprintf(ret.answer_string, max_answer_size, "%d", ans);
+ mcdprintf("Constructing formula_string\n");
+ snprintf(ret.formula_string, max_formula_size, "%d %c %d",
+ r1, operchars[op], r2);
+ }
+ else //recurse
+ {
+ ret = generate_random_ooo_card_of_length(length - 1);
+
+ if (strchr(ret.formula_string, '+') || strchr(ret.formula_string, '-') )
+ {
+ //if the expression has addition or subtraction, we can't assume that
+ //introducing multiplication or division will produce a predictable
+ //result, so we'll limit ourselves to more addition/subtraction
+ for (op = rand() % 2 ? MC_OPER_ADD : MC_OPER_SUB;
+ MC_GetOpt(op + ADDITION_ALLOWED) == 0;
+ op = rand() % 2 ? MC_OPER_ADD : MC_OPER_SUB);
+ }
+ else
+ {
+ //the existing expression can be treated as a number in itself, so we
+ //can do anything to it and be confident of the result.
+ for (op = rand() % MC_NUM_OPERS; //pick a random operation
+ MC_GetOpt(op + ADDITION_ALLOWED) == 0; //make sure it's allowed
+ op = rand() % MC_NUM_OPERS);
+ }
+
+ //next append or prepend the new number
+ if (op == MC_OPER_SUB || op == MC_OPER_DIV || //noncommutative, append only
+ rand() % 2)
+ {
+ if (op == MC_OPER_SUB)
+ r1 = rand() % (math_opts->iopts[MAX_SUBTRAHEND] - math_opts->iopts[MIN_SUBTRAHEND]) + math_opts->iopts[MIN_SUBTRAHEND];
+ else if (op == MC_OPER_DIV)
+ r1 = 1;
+
+ sprintf(tempstr, "%c %d", operchars[op], r1);
+ }
+ else //we're prepending
+ {
+
+ }
+
+ }
+ return ret;
+}
+
MC_MathQuestion* generate_list(void)
{
+ int i;
+ int length = MC_GetOpt(AVG_LIST_LENGTH);
MC_MathQuestion* list = NULL;
+ MC_MathQuestion* end_of_list = NULL;
+ MC_MathQuestion* tnode = NULL;
+ //TODO handle AVG_LIST_LENGTH = 0, i.e. generate all valid questions
+ //TODO randomize list length
+
+ for (i = 0; i < length; ++i)
+ {
+ tnode = malloc(sizeof(MC_MathQuestion) );
+ tnode->card = generate_random_flashcard();
+ list = insert_node(list, end_of_list, tnode);
+ end_of_list = tnode;
+ }
+
return list;
}
@@ -3218,18 +2192,22 @@
return 0; //the cards are identical
}
-//Begin public functions
+/* Public functions */
unsigned int MC_MapTextToIndex(const char* text)
{
int i;
for (i = 0; i < NOPTS; ++i)
+ {
+ mcdprintf("%d: %s", i, MC_OPTION_TEXT[i] );
if (!strcasecmp(text, MC_OPTION_TEXT[i]) )
return i;
+ }
printf("Sorry, don't recognize option '%s'\n", text);
return NOT_VALID_OPTION;
}
+//TODO more intuitive function names for access by index vs. by text
void MC_SetOpt(unsigned int index, int val)
{
if (index >= NOPTS)
@@ -3290,4 +2268,18 @@
return max_answer_size;
}
+void MC_ResetFlashCard(MC_FlashCard* fc)
+{
+ if (!fc || !fc->formula_string || !fc->answer_string)
+ return;
+ strncpy(fc->formula_string, " ", max_formula_size);
+ strncpy(fc->answer_string, " ", max_answer_size);
+ fc->answer = 0;
+ fc->difficulty = 0;
+}
+
+int MC_FlashCardGood(const MC_FlashCard* fc)
+{
+ return fc && fc->formula_string && fc->answer_string;
+}
#endif
Modified: tuxmath/branches/mathcards_newarch/src/mathcards.h
===================================================================
--- tuxmath/branches/mathcards_newarch/src/mathcards.h 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/mathcards.h 2008-07-01 16:28:15 UTC (rev 556)
@@ -1,42 +1,45 @@
/*
- mathcards.h
-
- Description: contains headers for a flashcard-type math game.
+ mathcards.h
+
+ Description: contains headers for a flashcard-type math game.
This is a sort of interface-independent backend that could be used with a different
user interface. Developed as an enhancement to Bill Kendrick's "Tux of Math Command"
(aka tuxmath). If tuxmath were a C++ program, this would be a C++ class.
-
- Author: David Bruce <dbruce at tampabay.rr.com>, (C) 2006
-
- Copyright: See COPYING file that comes with this distribution (briefly, GNU GPL version 2 or later)
+
+ Author: David Bruce <dbruce at tampabay.rr.com>, (C) 2006
+
+ Copyright: See COPYING file that comes with this distribution (briefly, GNU GPL version 2 or later)
*/
#ifndef MATHCARDS_H
#define MATHCARDS_H
-//#define MC_DEBUG
+#define MC_DEBUG
#ifdef MC_DEBUG
#define mcdprintf(...) printf(__VA_ARGS__)
#else
#define mcdprintf(...) 0
#endif
-#define MC_FORMULA_LEN 16
-#define MC_ANSWER_LEN 5
-
#define MC_USE_NEWARC
-/* type of math operation used in a given question */
-enum MC_Operation {
- MC_OPER_ADD = '+',
- MC_OPER_SUB = '-',
- MC_OPER_MULT = '*',
- MC_OPER_DIV = '/',
- MC_OPER_TYPING_PRACTICE = 'P',
- MC_NUM_OPERS = 5
-};
+typedef enum _MC_ProblemType {
+ MC_PT_TYPING,
+ MC_PT_ARITHMETIC,
+ MC_PT_COMPARISON,
+ MC_NUM_PTYPES
+} MC_ProblemType;
+/* type of math operation used in an arithmetic question */
+typedef enum _MC_Operation {
+ MC_OPER_ADD,
+ MC_OPER_SUB,
+ MC_OPER_MULT,
+ MC_OPER_DIV,
+ MC_NUM_OPERS
+} MC_Operation;
+
/* math question formats: */
enum {
MC_FORMAT_ANS_LAST, /* a + b = ? */
@@ -111,10 +114,15 @@
#define RANDOMIZE 47 /* whether to shuffle cards */
-#define NOPTS 48
+#define AVG_LIST_LENGTH 48
+#define VARY_LIST_LENGTH 49
+#define NOPTS 50
+
extern const char* const MC_OPTION_TEXT[];
extern const int MC_DEFAULTS[];
+extern const char operchars[MC_NUM_OPERS];
+
/* default values for math_options */
#define MC_GLOBAL_MAX 999 /* This is the largest absolute value that */
/* can be entered for math question values.*/
@@ -123,74 +131,11 @@
#define DEFAULT_FRACTION_TO_KEEP 1
-#ifndef MC_USE_NEWARC
-/* This struct contains all options that determine what */
-/* math questions are asked during a game */
-typedef struct MC_Options {
- /* general math options */
- int play_through_list;
- int repeat_wrongs;
- int copies_repeated_wrongs;
- int allow_negatives;
- int max_answer;
- int max_questions;
- int question_copies; /* how many times each question is put in list */
- int randomize; /* whether to shuffle cards */
- float fraction_to_keep; /* Can use to have list contain a random subset */
- /* of the questions meeting selection criteria. */
-
- /* math question formats: NOTE - list can contain more than one format*/
- /* operation-specific question formats: */
- int format_add_answer_last; /* a + b = ? */
- int format_add_answer_first; /* ? + b = c */
- int format_add_answer_middle; /* a + ? = c */
- int format_sub_answer_last; /* a - b = ? */
- int format_sub_answer_first; /* ? - b = c */
- int format_sub_answer_middle; /* a - ? = c */
- int format_mult_answer_last; /* a * b = ? */
- int format_mult_answer_first; /* ? * b = c */
- int format_mult_answer_middle; /* a * ? = c */
- int format_div_answer_last; /* a / b = ? */
- int format_div_answer_first; /* ? / b = c */
- int format_div_answer_middle; /* a / ? = c */
-
- /* addition options */
- int addition_allowed;
- int min_augend; /* the "augend" is the first addend i.e. "a" in "a + b = c" */
- int max_augend;
- int min_addend; /* options for the other addend */
- int max_addend;
- /* subtraction options */
- int subtraction_allowed;
- int min_minuend; /* minuend - subtrahend = difference */
- int max_minuend;
- int min_subtrahend;
- int max_subtrahend;
- /* multiplication options */
- int multiplication_allowed;
- int min_multiplier; /* multiplier * multiplicand = product */
- int max_multiplier;
- int min_multiplicand;
- int max_multiplicand;
- /* division options */
- int division_allowed;
- int min_divisor; /* dividend/divisor = quotient */
- int max_divisor;
- int min_quotient;
- int max_quotient;
- /* typing practice options */
- int typing_practice_allowed;
- int min_typing_num;
- int max_typing_num;
-
-} MC_Options;
-#else
typedef struct _MC_Options
{
int iopts[NOPTS];
float fraction_to_keep; //being a float, we can't keep this in the same array
} MC_Options; //it'll stay a special case, unless more float options
-#endif //are introduced.
#ifndef MC_USE_NEWARC
/* struct for individual "flashcard" */
@@ -221,11 +166,11 @@
int randomizer;
} MC_MathQuestion;
+
/* "public" function prototypes: these functions are how */
/* a user interface communicates with MathCards: */
/* TODO provide comments thoroughly explaining these functions */
-
/* MC_Initialize() sets up the struct containing all of */
/* settings regarding math questions. It should be */
/* called before any other function. Many of the other */
@@ -315,150 +260,11 @@
int MC_NumNotAnsweredCorrectly(void);
float MC_MedianTimePerQuestion(void);
-/* Simple "Set/Get" type functions for option parameters: */
-
-/* Simple functions to set option parameters: */
-
-/* Set general math options: */
-//void MC_SetPlayThroughList(int opt);
-//void MC_SetRepeatWrongs(int opt);
-//void MC_SetQuestionCopies(int copies); /* how many times each question is put in list */
-//void MC_SetCopiesRepeatedWrongs(int copies);
-//void MC_SetMaxAnswer(int max);
-//void MC_SetMaxQuestions(int max);
-//void MC_SetAllowNegatives(int opt);
-//void MC_SetRandomize(int opt);
-//void MC_SetFractionToKeep(float fract);
-//
-///* Set question formats for all operations: */
-///* NOTE - list can contain more than one format */
-///* Use these to set format the same for all four operations: */
-//void MC_SetFormatAnswerLast(int opt); /* a + b = ?, a - b = ?, a * b = ?, a / b = ? */
-//void MC_SetFormatAnswerFirst(int opt); /* ? + b = c, etc */
-//void MC_SetFormatAnswerMiddle(int opt); /* a + ? = c, etc */
-///* Uset these to set operation-specific question formats: */
-//void MC_SetFormatAddAnswerLast(int opt); /* a + b = ? */
-//void MC_SetFormatAddAnswerFirst(int opt); /* ? + b = c */
-//void MC_SetFormatAddAnswerMiddle(int opt); /* a + ? = c */
-//void MC_SetFormatSubAnswerLast(int opt); /* a - b = ? */
-//void MC_SetFormatSubAnswerFirst(int opt); /* ? - b = c */
-//void MC_SetFormatSubAnswerMiddle(int opt); /* a - ? = c */
-//void MC_SetFormatMultAnswerLast(int opt); /* a * b = ? */
-//void MC_SetFormatMultAnswerFirst(int opt); /* ? * b = c */
-//void MC_SetFormatMultAnswerMiddle(int opt); /* a * ? = c */
-//void MC_SetFormatDivAnswerLast(int opt); /* a / b = ? */
-//void MC_SetFormatDivAnswerFirst(int opt); /* ? / b = c */
-//void MC_SetFormatDivAnswerMiddle(int opt); /* a / ? = c */
-//
-///* Set the allowed math operations: */
-//void MC_SetAddAllowed(int opt);
-//void MC_SetSubAllowed(int opt);
-//void MC_SetMultAllowed(int opt);
-//void MC_SetDivAllowed(int opt);
-//void MC_SetTypingAllowed(int opt);
-//
-///* Set min and max for addition: */
-//void MC_SetAddMin(int opt); /* augend + addend = sum */
-//void MC_SetAddMinAugend(int opt); /* the "augend" is the first addend i.e. "a" in "a + b = c" */
-//void MC_SetAddMinAddend(int opt); /* options for the other addend */
-//void MC_SetAddMax(int opt);
-//void MC_SetAddMaxAugend(int opt);
-//void MC_SetAddMaxAddend(int opt);
-//
-///* Set min and max for subtraction: */
-//void MC_SetSubMin(int opt);
-//void MC_SetSubMinMinuend(int opt); /* minuend - subtrahend = difference */
-//void MC_SetSubMinSubtrahend(int opt);
-//void MC_SetSubMax(int opt);
-//void MC_SetSubMaxMinuend(int opt);
-//void MC_SetSubMaxSubtrahend(int opt);
-//
-///* Set min and max for multiplication: */
-//void MC_SetMultMin(int opt);
-//void MC_SetMultMinMultiplier(int opt); /* multiplier * multiplicand = product */
-//void MC_SetMultMinMultiplicand(int opt);
-//void MC_SetMultMax(int opt);
-//void MC_SetMultMaxMultiplier(int opt);
-//void MC_SetMultMaxMultiplicand(int opt);
-//
-///* Set min and max for division: */
-//void MC_SetDivMin(int opt);
-//void MC_SetDivMinDivisor(int opt); /* dividend/divisor = quotient */
-//void MC_SetDivMinQuotient(int opt);
-//void MC_SetDivMax(int opt);
-//void MC_SetDivMaxDivisor(int opt);
-//void MC_SetDivMaxQuotient(int opt);
-//
-///* Set min and max for typing practice: */
-//void MC_SetTypeMin(int opt);
-//void MC_SetTypeMax(int opt);
-//
-///* "Get" type functions to query option parameters: */
-//
-///* Query general math options: */
-//int MC_PlayThroughList(void);
-//int MC_RepeatWrongs(void);
-//int MC_CopiesRepeatedWrongs(void);
-//int MC_MaxAnswer(void);
-//int MC_MaxQuestions(void);
-//int MC_AllowNegatives(void);
-//int MC_QuestionCopies(void); /* how many times each question is put in list */
-//int MC_Randomize(void);
-//float MC_FractionToKeep(void);
-//
-//int MC_FormatAddAnswerLast(void); /* a + b = ? */
-//int MC_FormatAddAnswerFirst(void); /* ? + b = c */
-//int MC_FormatAddAnswerMiddle(void); /* a + ? = c */
-//int MC_FormatSubAnswerLast(void); /* a - b = ? */
-//int MC_FormatSubAnswerFirst(void); /* ? - b = c */
-//int MC_FormatSubAnswerMiddle(void); /* a - ? = c */
-//int MC_FormatMultAnswerLast(void); /* a * b = ? */
-//int MC_FormatMultAnswerFirst(void); /* ? * b = c */
-//int MC_FormatMultAnswerMiddle(void); /* a * ? = c */
-//int MC_FormatDivAnswerLast(void); /* a / b = ? */
-//int MC_FormatDivAnswerFirst(void); /* ? / b = c */
-//int MC_FormatDivAnswerMiddle(void); /* a / ? = c */
-//
-//
-///* Query the allowed math operations: */
-//int MC_AddAllowed(void);
-//int MC_SubAllowed(void);
-//int MC_MultAllowed(void);
-//int MC_DivAllowed(void);
-//int MC_TypingAllowed(void);
-//
-///* Query min and max for addition: */
-//int MC_AddMinAugend(void); /* the "augend" is the first addend i.e. "a" in "a + b = c" */
-//int MC_AddMinAddend(void); /* options for the other addend */
-//int MC_AddMaxAugend(void);
-//int MC_AddMaxAddend(void);
-//
-///* Query min and max for subtraction: */
-//int MC_SubMinMinuend(void); /* minuend - subtrahend = difference */
-//int MC_SubMinSubtrahend(void);
-//int MC_SubMaxMinuend(void);
-//int MC_SubMaxSubtrahend(void);
-//
-///* Query min and max for multiplication: */
-//int MC_MultMinMultiplier(void); /* multiplier * multiplicand = product */
-//int MC_MultMinMultiplicand(void);
-//int MC_MultMaxMultiplier(void);
-//int MC_MultMaxMultiplicand(void);
-//
-///* Query min and max for division: */
-//int MC_DivMinDivisor(void); /* dividend/divisor = quotient */
-//int MC_DivMinQuotient(void);
-//int MC_DivMaxDivisor(void);
-//int MC_DivMaxQuotient(void);
-//
-///* Query min and max for typing practice: */
-//int MC_TypeMin(void);
-//int MC_TypeMax(void);
-
/********************************************
Public functions for new mathcards architecture
*********************************************/
-unsigned int MC_MapTextToIndex(const char* text); //the array index of the text
+/* Return the array index of the given text, e.g. randomize->47 */
+unsigned int MC_MapTextToIndex(const char* text);
void MC_SetOpt(unsigned int index, int val); //access directly,for internal use
int MC_GetOpt(unsigned int index);
void MC_SetOp(const char* param, int val); //access by text, for config reading
@@ -468,5 +274,9 @@
int MC_VerifyOptionListSane(void);
int MC_MaxFormulaSize(void);
int MC_MaxAnswerSize(void);
+MC_FlashCard MC_AllocateFlashcard();
+void MC_FreeFlashcard(MC_FlashCard* fc);
+void MC_ResetFlashCard(MC_FlashCard* fc);
+int MC_FlashCardGood(const MC_FlashCard* fc); //verifies a flashcard is valid
#endif
Modified: tuxmath/branches/mathcards_newarch/src/pixels.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/pixels.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/pixels.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -42,9 +42,9 @@
&& likely((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- x); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ x); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
@@ -65,9 +65,9 @@
&& likely((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 2)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 2)); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
@@ -88,9 +88,9 @@
&& likely((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 3)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 3)); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
@@ -123,15 +123,15 @@
&& likely((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 4)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 4)); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
* to the pixel value sent in: */
- *(Uint32 *) p = pixel; // 32-bit display
+ *(Uint32 *) p = pixel; // 32-bit display
}
}
@@ -149,9 +149,9 @@
/* Set a pointer to the exact location in memory of the pixel
in question: */
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- x); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ x); /* Go in X pixels */
/* Return the correctly-sized piece of data containing the
@@ -175,9 +175,9 @@
/* Set a pointer to the exact location in memory of the pixel
in question: */
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 2)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 2)); /* Go in X pixels */
/* Return the correctly-sized piece of data containing the
@@ -202,9 +202,9 @@
/* Set a pointer to the exact location in memory of the pixel
in question: */
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 3)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 3)); /* Go in X pixels */
/* Return the correctly-sized piece of data containing the
@@ -235,16 +235,16 @@
/* Set a pointer to the exact location in memory of the pixel
in question: */
- p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
- (y * surface->pitch) + /* Go down Y lines */
- (x * 4)); /* Go in X pixels */
+ p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
+ (y * surface->pitch) + /* Go down Y lines */
+ (x * 4)); /* Go in X pixels */
/* Return the correctly-sized piece of data containing the
* pixel's value (an 8-bit palette value, or a 16-, 24- or 32-bit
* RGB value) */
- return *(Uint32 *) p; // 32-bit display
+ return *(Uint32 *) p; // 32-bit display
}
void (*putpixels[]) (SDL_Surface *, int, int, Uint32) =
Modified: tuxmath/branches/mathcards_newarch/src/scandir.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/scandir.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/scandir.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -35,8 +35,8 @@
#undef DIRSIZ
#define DIRSIZ(dp) \
- ((sizeof(struct dirent) - sizeof(dp)->d_name) + \
- (((dp)->d_reclen + 1 + 3) &~ 3))
+ ((sizeof(struct dirent) - sizeof(dp)->d_name) + \
+ (((dp)->d_reclen + 1 + 3) &~ 3))
#if defined(__sun) && defined(__SVR4)
# define dirfd(d) ((d)->dd_fd)
@@ -51,7 +51,7 @@
*/
int alphasort(const void *d1, const void *d2)
{
- return strcmp((*(struct dirent * const *)d1)->d_name, (*(struct dirent * const *)d2)->d_name);
+ return strcmp((*(struct dirent * const *)d1)->d_name, (*(struct dirent * const *)d2)->d_name);
}
@@ -61,78 +61,78 @@
*/
int scandir(const char *dirname, struct dirent ***namelist, int (*sdfilter)(struct dirent *), int (*dcomp)(const void *, const void *))
{
- struct dirent *d, *p, **names;
- struct stat stb;
- size_t nitems;
- size_t arraysz;
- DIR *dirp;
+ struct dirent *d, *p, **names;
+ struct stat stb;
+ size_t nitems;
+ size_t arraysz;
+ DIR *dirp;
- if ((dirp = opendir(dirname)) == NULL)
- return(-1);
+ if ((dirp = opendir(dirname)) == NULL)
+ return(-1);
- if (fstat(dirfd(dirp), &stb) < 0)
- return(-1);
+ if (fstat(dirfd(dirp), &stb) < 0)
+ return(-1);
- /*
- * estimate the array size by taking the size of the directory file
- * and dividing it by a multiple of the minimum size entry.
- */
- arraysz = (stb.st_size / 24);
+ /*
+ * estimate the array size by taking the size of the directory file
+ * and dividing it by a multiple of the minimum size entry.
+ */
+ arraysz = (stb.st_size / 24);
- names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
- if (names == NULL)
- return(-1);
+ names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
+ if (names == NULL)
+ return(-1);
- nitems = 0;
+ nitems = 0;
- while ((d = readdir(dirp)) != NULL)
- {
+ while ((d = readdir(dirp)) != NULL)
+ {
- if (sdfilter != NULL && !(*sdfilter)(d))
- continue; /* just selected names */
+ if (sdfilter != NULL && !(*sdfilter)(d))
+ continue; /* just selected names */
- /*
- * Make a minimum size copy of the data
- */
+ /*
+ * Make a minimum size copy of the data
+ */
- p = (struct dirent *)malloc(DIRSIZ(d));
- if (p == NULL)
- return(-1);
+ p = (struct dirent *)malloc(DIRSIZ(d));
+ if (p == NULL)
+ return(-1);
- p->d_ino = d->d_ino;
- p->d_reclen = d->d_reclen;
- /*p->d_namlen = d->d_namlen;*/
- memcpy(p->d_name, d->d_name, p->d_reclen + 1);
+ p->d_ino = d->d_ino;
+ p->d_reclen = d->d_reclen;
+ /*p->d_namlen = d->d_namlen;*/
+ memcpy(p->d_name, d->d_name, p->d_reclen + 1);
- /*
- * Check to make sure the array has space left and
- * realloc the maximum size.
- */
+ /*
+ * Check to make sure the array has space left and
+ * realloc the maximum size.
+ */
- if (++nitems >= arraysz)
- {
+ if (++nitems >= arraysz)
+ {
- if (fstat(dirfd(dirp), &stb) < 0)
- return(-1); /* just might have grown */
+ if (fstat(dirfd(dirp), &stb) < 0)
+ return(-1); /* just might have grown */
- arraysz = stb.st_size / 12;
+ arraysz = stb.st_size / 12;
- names = (struct dirent **)realloc((char *)names, arraysz * sizeof(struct dirent *));
- if (names == NULL)
- return(-1);
- }
+ names = (struct dirent **)realloc((char *)names, arraysz * sizeof(struct dirent *));
+ if (names == NULL)
+ return(-1);
+ }
- names[nitems-1] = p;
- }
+ names[nitems-1] = p;
+ }
- closedir(dirp);
+ closedir(dirp);
- if (nitems && dcomp != NULL)
- qsort(names, nitems, sizeof(struct dirent *), dcomp);
+ if (nitems && dcomp != NULL)
+ qsort(names, nitems, sizeof(struct dirent *), dcomp);
- *namelist = names;
+ *namelist = names;
- return nitems;
+ return nitems;
}
@@ -153,7 +153,7 @@
*/
int alphasort(const void *d1, const void *d2)
{
- return stricmp((*(struct dirent * const *)d1)->d_name, (*(struct dirent * const *)d2)->d_name);
+ return stricmp((*(struct dirent * const *)d1)->d_name, (*(struct dirent * const *)d2)->d_name);
}
/*-----------------------------------------------------------------------*/
@@ -162,98 +162,98 @@
*/
int scandir(const char *dirname, struct dirent ***namelist, int (*sdfilter)(struct dirent *), int (*dcomp)(const void *, const void *))
{
- int len;
- char *findIn, *d;
- WIN32_FIND_DATA find;
- HANDLE h;
- int nDir = 0, NDir = 0;
- struct dirent **dir = 0, *selectDir;
- unsigned long ret;
+ int len;
+ char *findIn, *d;
+ WIN32_FIND_DATA find;
+ HANDLE h;
+ int nDir = 0, NDir = 0;
+ struct dirent **dir = 0, *selectDir;
+ unsigned long ret;
- len = strlen(dirname);
- findIn = (char *)malloc(len+5);
- strcpy(findIn, dirname);
- printf("scandir : findIn orign=%s\n", findIn);
- for (d = findIn; *d; d++)
- if (*d=='/')
- *d='\\';
- if ((len==0))
- {
- strcpy(findIn, ".\\*");
- }
- if ((len==1)&& (d[-1]=='.'))
- {
- strcpy(findIn, ".\\*");
- }
- if ((len>0) && (d[-1]=='\\'))
- {
- *d++ = '*';
- *d = 0;
- }
- if ((len>1) && (d[-1]=='.') && (d[-2]=='\\'))
- {
- d[-1] = '*';
- }
- if ((len>1) && (d[-2]!='\\') && (d[-1]!='*'))
- {
- *d++ = '\\';
- *d++ = '*';
- *d = 0;
- }
+ len = strlen(dirname);
+ findIn = (char *)malloc(len+5);
+ strcpy(findIn, dirname);
+ printf("scandir : findIn orign=%s\n", findIn);
+ for (d = findIn; *d; d++)
+ if (*d=='/')
+ *d='\\';
+ if ((len==0))
+ {
+ strcpy(findIn, ".\\*");
+ }
+ if ((len==1)&& (d[-1]=='.'))
+ {
+ strcpy(findIn, ".\\*");
+ }
+ if ((len>0) && (d[-1]=='\\'))
+ {
+ *d++ = '*';
+ *d = 0;
+ }
+ if ((len>1) && (d[-1]=='.') && (d[-2]=='\\'))
+ {
+ d[-1] = '*';
+ }
+ if ((len>1) && (d[-2]!='\\') && (d[-1]!='*'))
+ {
+ *d++ = '\\';
+ *d++ = '*';
+ *d = 0;
+ }
- printf("scandir : findIn processed=%s\n", findIn);
- if ((h=FindFirstFile(findIn, &find))==INVALID_HANDLE_VALUE)
- {
- printf("scandir : FindFirstFile error\n");
- ret = GetLastError();
- if (ret != ERROR_NO_MORE_FILES)
- {
- // TODO: return some error code
- }
- *namelist = dir;
- return nDir;
- }
- do
- {
- printf("scandir : findFile=%s\n", find.cFileName);
- selectDir=(struct dirent*)malloc(sizeof(struct dirent)+strlen(find.cFileName));
- strcpy(selectDir->d_name, find.cFileName);
- if (!sdfilter || (*sdfilter)(selectDir))
- {
- if (nDir==NDir)
- {
- struct dirent **tempDir = (struct dirent **)calloc(sizeof(struct dirent*), NDir+33);
- if (NDir)
- memcpy(tempDir, dir, sizeof(struct dirent*)*NDir);
- if (dir)
- free(dir);
- dir = tempDir;
- NDir += 32;
- }
- dir[nDir] = selectDir;
- nDir++;
- dir[nDir] = 0;
- }
- else
- {
- free(selectDir);
- }
- }
- while (FindNextFile(h, &find));
- ret = GetLastError();
- if (ret != ERROR_NO_MORE_FILES)
- {
- // TODO: return some error code
- }
- FindClose(h);
+ printf("scandir : findIn processed=%s\n", findIn);
+ if ((h=FindFirstFile(findIn, &find))==INVALID_HANDLE_VALUE)
+ {
+ printf("scandir : FindFirstFile error\n");
+ ret = GetLastError();
+ if (ret != ERROR_NO_MORE_FILES)
+ {
+ // TODO: return some error code
+ }
+ *namelist = dir;
+ return nDir;
+ }
+ do
+ {
+ printf("scandir : findFile=%s\n", find.cFileName);
+ selectDir=(struct dirent*)malloc(sizeof(struct dirent)+strlen(find.cFileName));
+ strcpy(selectDir->d_name, find.cFileName);
+ if (!sdfilter || (*sdfilter)(selectDir))
+ {
+ if (nDir==NDir)
+ {
+ struct dirent **tempDir = (struct dirent **)calloc(sizeof(struct dirent*), NDir+33);
+ if (NDir)
+ memcpy(tempDir, dir, sizeof(struct dirent*)*NDir);
+ if (dir)
+ free(dir);
+ dir = tempDir;
+ NDir += 32;
+ }
+ dir[nDir] = selectDir;
+ nDir++;
+ dir[nDir] = 0;
+ }
+ else
+ {
+ free(selectDir);
+ }
+ }
+ while (FindNextFile(h, &find));
+ ret = GetLastError();
+ if (ret != ERROR_NO_MORE_FILES)
+ {
+ // TODO: return some error code
+ }
+ FindClose(h);
- free (findIn);
+ free (findIn);
- if (dcomp)
- qsort (dir, nDir, sizeof(*dir),dcomp);
+ if (dcomp)
+ qsort (dir, nDir, sizeof(*dir),dcomp);
- *namelist = dir;
- return nDir;
+ *namelist = dir;
+ return nDir;
}
#endif /* WIN32 */
Modified: tuxmath/branches/mathcards_newarch/src/setup.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/setup.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/setup.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -214,7 +214,7 @@
"If you don't answer a comet's math equation before it hits\n"
"one of your cities, the city's shields will be destroyed.\n"
"If that city is hit by another comet, it is destroyed completely.\n"
- "When you lose all of your cities, the game ends.\n\n");
+ "When you lose all of your cities, the game ends.\n\n");
printf("Note: all settings are now stored in a config file named 'options' in\n"
"a hidden directory named './tuxmath' within the user's home directory.\n"
@@ -225,12 +225,12 @@
"to configure the behavior of Tuxmath.\n\n");
printf("Run the game with:\n"
- "--homedir dirname - seek for user home director(ies) in the specified\n"
- " location, rather than the user's actual home\n"
- " directory. You can set up a user directory tree in\n"
- " this location (see README). This option is\n"
- " especially useful for schools where all students log\n"
- " in with a single user name.\n"
+ "--homedir dirname - seek for user home director(ies) in the specified\n"
+ " location, rather than the user's actual home\n"
+ " directory. You can set up a user directory tree in\n"
+ " this location (see README). This option is\n"
+ " especially useful for schools where all students log\n"
+ " in with a single user name.\n"
"--optionfile filename - read config settings from named file. The locations\n"
" searched for a file with a matching name are the\n"
" current working directory, the absolute path of the\n"
@@ -244,15 +244,15 @@
"--answersmiddle - to ask questions in format: num1 + ? = num3\n"
" instead of default format: num1 + num2 = ?\n"
"--nosound - to disable sound/music\n"
- "--nobackground - to disable background photos (for slower systems)\n"
- "--fullscreen - to run in fullscreen, if possible (vs. windowed)\n"
+ "--nobackground - to disable background photos (for slower systems)\n"
+ "--fullscreen - to run in fullscreen, if possible (vs. windowed)\n"
"--windowed - to run in a window rather than fullscreen\n"
"--keypad - to enable the on-sceen numeric keypad\n"
- "--demo - to run the program as a cycling demonstration\n"
- "--speed S - set initial speed of the game\n"
- " (S may be fractional, default is 1.0)\n"
+ "--demo - to run the program as a cycling demonstration\n"
+ "--speed S - set initial speed of the game\n"
+ " (S may be fractional, default is 1.0)\n"
"--allownegatives - to allow answers to be less than zero\n"
- );
+ );
printf("\n");
@@ -260,24 +260,24 @@
exit(0);
}
else if (strcmp(argv[i], "--copyright") == 0 ||
- strcmp(argv[i], "-c") == 0)
+ strcmp(argv[i], "-c") == 0)
{
printf(
- "\n\"Tux, of Math Command\" version " VERSION ", Copyright (C) 2001 Bill Kendrick\n"
+ "\n\"Tux, of Math Command\" version " VERSION ", Copyright (C) 2001 Bill Kendrick\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation. See COPYING.txt\n"
- "\n"
- "This program is distributed in the hope that it will be useful,\n"
- "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
- "\n");
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+ "\n");
cleanup_on_error();
exit(0);
}
else if (strcmp(argv[i], "--usage") == 0 ||
- strcmp(argv[i], "-u") == 0)
+ strcmp(argv[i], "-u") == 0)
{
/* Display (happy) usage: */
@@ -288,26 +288,26 @@
// Parse the user choice of a non-default home directory
if (i >= argc -1)
{
- fprintf(stderr, "%s option requires an argument (dirname)\n", argv[i]);
- usage(1, argv[0]);
+ fprintf(stderr, "%s option requires an argument (dirname)\n", argv[i]);
+ usage(1, argv[0]);
}
else // see whether the specified name is a directory
{
- if ((dirp = opendir(argv[i+1])) == NULL)
- fprintf(stderr,"homedir: %s is not a directory, or it could not be read\n", argv[i+1]);
- else {
- set_user_data_dir(argv[i+1]); // copy the homedir setting
- closedir(dirp);
- }
- i++; // to pass over the next argument, so remaining options parsed
+ if ((dirp = opendir(argv[i+1])) == NULL)
+ fprintf(stderr,"homedir: %s is not a directory, or it could not be read\n", argv[i+1]);
+ else {
+ set_user_data_dir(argv[i+1]); // copy the homedir setting
+ closedir(dirp);
+ }
+ i++; // to pass over the next argument, so remaining options parsed
}
}
else if (0 == strcmp(argv[i], "--optionfile"))
{
if (i >= argc - 1)
{
- fprintf(stderr, "%s option requires an argument (filename)\n", argv[i]);
- usage(1, argv[0]);
+ fprintf(stderr, "%s option requires an argument (filename)\n", argv[i]);
+ usage(1, argv[0]);
}
else /* try to read file named in following arg: */
{
@@ -319,27 +319,27 @@
i++; /* so program doesn't barf on next arg (the filename) */
}
else if (strcmp(argv[i], "--fullscreen") == 0 ||
- strcmp(argv[i], "-f") == 0)
+ strcmp(argv[i], "-f") == 0)
{
Opts_SetFullscreen(1);
}
else if (strcmp(argv[i], "--windowed") == 0 ||
- strcmp(argv[i], "-w") == 0)
+ strcmp(argv[i], "-w") == 0)
{
Opts_SetFullscreen(0);
}
else if (strcmp(argv[i], "--nosound") == 0 ||
- strcmp(argv[i], "-s") == 0 ||
- strcmp(argv[i], "--quiet") == 0 ||
- strcmp(argv[i], "-q") == 0)
+ strcmp(argv[i], "-s") == 0 ||
+ strcmp(argv[i], "--quiet") == 0 ||
+ strcmp(argv[i], "-q") == 0)
{
Opts_SetUseSound(-1); // prevent options files from overwriting
}
else if (strcmp(argv[i], "--version") == 0 ||
- strcmp(argv[i], "-v") == 0)
+ strcmp(argv[i], "-v") == 0)
{
printf("Tux, of Math Command (\"tuxmath\")\n"
- "Version " VERSION "\n");
+ "Version " VERSION "\n");
cleanup_on_error();
exit(0);
}
@@ -349,7 +349,7 @@
Opts_SetUseBkgd(0);
}
else if (strcmp(argv[i], "--demo") == 0 ||
- strcmp(argv[i], "-d") == 0)
+ strcmp(argv[i], "-d") == 0)
{
Opts_SetDemoMode(1);
}
@@ -381,12 +381,12 @@
MC_SetOpt(FORMAT_ANSWER_MIDDLE, 1);
}
else if (strcmp(argv[i], "--speed") == 0 ||
- strcmp(argv[i], "-s") == 0)
+ strcmp(argv[i], "-s") == 0)
{
if (i >= argc - 1)
{
- fprintf(stderr, "%s option requires an argument\n", argv[i]);
- usage(1, argv[0]);
+ fprintf(stderr, "%s option requires an argument\n", argv[i]);
+ usage(1, argv[0]);
}
Opts_SetSpeed(strtod(argv[i + 1], (char **) NULL));
@@ -427,8 +427,8 @@
{
fprintf(stderr,
"\nError: I could not initialize video!\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
+ "The Simple DirectMedia error that occured was:\n"
+ "%s\n\n", SDL_GetError());
cleanup_on_error();
exit(1);
}
@@ -474,11 +474,11 @@
//if (Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 2048) < 0)
if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, AUDIO_S16SYS, 2, 2048) < 0)
{
- fprintf(stderr,
- "\nWarning: I could not set up audio for 44100 Hz "
- "16-bit stereo.\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
+ fprintf(stderr,
+ "\nWarning: I could not set up audio for 44100 Hz "
+ "16-bit stereo.\n"
+ "The Simple DirectMedia error that occured was:\n"
+ "%s\n\n", SDL_GetError());
}
}
@@ -530,8 +530,8 @@
{
fprintf(stderr,
"\nWarning: I could not open the display in fullscreen mode.\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
+ "The Simple DirectMedia error that occured was:\n"
+ "%s\n\n", SDL_GetError());
Opts_SetFullscreen(0);
}
}
@@ -545,8 +545,8 @@
{
fprintf(stderr,
"\nError: I could not open the display.\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
+ "The Simple DirectMedia error that occured was:\n"
+ "%s\n\n", SDL_GetError());
cleanup_on_error();
exit(1);
}
Modified: tuxmath/branches/mathcards_newarch/src/titlescreen.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/titlescreen.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/titlescreen.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -114,14 +114,14 @@
/* --- locations we need --- */
SDL_Rect dest,
- Tuxdest,
- Titledest,
+ Tuxdest,
+ Titledest,
stopRect,
Backrect,
Tuxback,
Titleback,
- cursor,
- beak;
+ cursor,
+ beak;
/* The background image scaled to windowed 648x480 */
SDL_Surface* bkg = NULL;
@@ -431,8 +431,12 @@
int i;
for (i = 0; i < N_SPRITES; i++)
+ {
+ tmdprintf("Freeing image %d", i);
FreeSprite(sprite_list[i]);
+ }
free(sprite_list);
+ tmdprintf("Images freed\n");
sprite_list = NULL;
}
@@ -440,9 +444,11 @@
void TitleScreen_unload_media(void)
{
+ tmdprintf("Unloading media\n");
FreeSprite(Tux);
Tux = NULL;
TitleScreen_unload_menu();
+
SDL_FreeSurface(egg);
SDL_FreeSurface(bkg);
SDL_FreeSurface(scaled_bkg);
@@ -660,40 +666,41 @@
while (choice >= 0) {
switch (choice) {
case 0: {
- // Training academy lessons
- ret = run_lessons_menu();
- break;
+ // Training academy lessons
+ ret = run_lessons_menu();
+ break;
}
case 1: {
- // Arcade games
- ret = run_arcade_menu();
- break;
+ // Arcade games
+ ret = run_arcade_menu();
+ break;
}
case 2: {
- // Custom game
- ret = run_custom_menu();
- break;
+ // Custom game
+ ret = run_custom_menu();
+ break;
}
case 3: {
- // Help
- Opts_SetHelpMode(1);
- Opts_SetDemoMode(0);
- if (Opts_MenuMusic()) //Turn menu music off for game
- {audioMusicUnload();}
- game();
- RecalcTitlePositions();
- if (Opts_MenuMusic()) //Turn menu music back on
- {audioMusicLoad( "tuxi.ogg", -1 );}
- Opts_SetHelpMode(0);
- break;
+ // Help
+ Opts_SetHelpMode(1);
+ Opts_SetDemoMode(0);
+ if (Opts_MenuMusic()) //Turn menu music off for game
+ {audioMusicUnload();}
+ game();
+ RecalcTitlePositions();
+ if (Opts_MenuMusic()) //Turn menu music back on
+ {audioMusicLoad( "tuxi.ogg", -1 );}
+ Opts_SetHelpMode(0);
+ break;
}
case 4: {
- // More options
- ret = run_options_menu();
+ // More options
+ ret = run_options_menu();
break;
}
case 5: {
- // Quit
+ // Quit
+ tmdprintf("Exiting main menu\n");
return 0;
}
}
@@ -741,36 +748,36 @@
// Play arcade game
if (read_named_config_file(arcade_config_files[choice]))
{
- audioMusicUnload();
- game();
- RecalcTitlePositions();
- if (Opts_MenuMusic()) {
- audioMusicLoad( "tuxi.ogg", -1 );
- }
- /* See if player made high score list! */
- read_high_scores(); /* Update, in case other users have added to it */
- hs_table = arcade_high_score_tables[choice];
- if (check_score_place(hs_table, Opts_LastScore()) < HIGH_SCORES_SAVED){
+ audioMusicUnload();
+ game();
+ RecalcTitlePositions();
+ if (Opts_MenuMusic()) {
+ audioMusicLoad( "tuxi.ogg", -1 );
+ }
+ /* See if player made high score list! */
+ read_high_scores(); /* Update, in case other users have added to it */
+ hs_table = arcade_high_score_tables[choice];
+ if (check_score_place(hs_table, Opts_LastScore()) < HIGH_SCORES_SAVED){
- unsigned char player_name[HIGH_SCORE_NAME_LENGTH * 3];
+ unsigned char player_name[HIGH_SCORE_NAME_LENGTH * 3];
- /* Get name from player: */
- HighScoreNameEntry(&player_name[0]);
- insert_score(player_name, hs_table, Opts_LastScore());
- /* Show the high scores. Note the user will see his/her */
- /* achievement even if (in the meantime) another player */
- /* has in fact already bumped this score off the table. */
- DisplayHighScores(hs_table);
- /* save to disk: */
- /* See "On File Locking" in fileops.c */
- append_high_score(choice,Opts_LastScore(),&player_name[0]);
+ /* Get name from player: */
+ HighScoreNameEntry(&player_name[0]);
+ insert_score(player_name, hs_table, Opts_LastScore());
+ /* Show the high scores. Note the user will see his/her */
+ /* achievement even if (in the meantime) another player */
+ /* has in fact already bumped this score off the table. */
+ DisplayHighScores(hs_table);
+ /* save to disk: */
+ /* See "On File Locking" in fileops.c */
+ append_high_score(choice,Opts_LastScore(),&player_name[0]);
#ifdef TUXMATH_DEBUG
- print_high_scores(stderr);
+ print_high_scores(stderr);
#endif
- }
+ }
} else {
- fprintf(stderr, "\nCould not find %s config file\n",arcade_config_files[choice]);
+ fprintf(stderr, "\nCould not find %s config file\n",arcade_config_files[choice]);
}
} else if (choice == 4) {
@@ -863,14 +870,14 @@
// Demo
if (read_named_config_file("demo"))
{
- audioMusicUnload();
- game();
- RecalcTitlePositions();
- if (Opts_MenuMusic()) {
- audioMusicLoad( "tuxi.ogg", -1 );
- }
+ audioMusicUnload();
+ game();
+ RecalcTitlePositions();
+ if (Opts_MenuMusic()) {
+ audioMusicLoad( "tuxi.ogg", -1 );
+ }
} else {
- fprintf(stderr, "\nCould not find demo config file\n");
+ fprintf(stderr, "\nCould not find demo config file\n");
}
break;
@@ -879,9 +886,9 @@
// Project Info
//NotImplemented();
ShowMessage(_("TuxMath is free and open-source!"),
- _("You can help make it better by reporting problems,"),
- _("suggesting improvements, or adding code."),
- _("Discuss the future at tuxmath-devel at lists.sourceforge.net"));
+ _("You can help make it better by reporting problems,"),
+ _("suggesting improvements, or adding code."),
+ _("Discuss the future at tuxmath-devel at lists.sourceforge.net"));
break;
}
case 2: {
@@ -1041,21 +1048,21 @@
// User pressed escape or selected Quit/Back, handle by quitting
// or going up a level
if (level == 0) {
- // We are going to quit without logging in.
- // Clean up memory (prob. not necessary, but prevents Valgrind errors!)
- for (i = 0; i < n_login_questions; i++)
- free(user_login_questions[i]);
- free(user_login_questions);
- for (i = 0; i < n_users; i++)
- free(user_names[i]);
- free(user_names);
- return -1;
+ // We are going to quit without logging in.
+ // Clean up memory (prob. not necessary, but prevents Valgrind errors!)
+ for (i = 0; i < n_login_questions; i++)
+ free(user_login_questions[i]);
+ free(user_login_questions);
+ for (i = 0; i < n_users; i++)
+ free(user_names[i]);
+ free(user_names);
+ return -1;
}
else {
- // Go back up one level of the directory tree
- user_data_dirname_up();
- level--;
- menu_opts.starting_entry = -1;
+ // Go back up one level of the directory tree
+ user_data_dirname_up();
+ level--;
+ menu_opts.starting_entry = -1;
}
}
else {
@@ -1205,7 +1212,7 @@
buttonheight = 0;
for (i = 0; i < n_menu_entries; i++)
if (buttonheight < menu_item_unselected[i]->h)
- buttonheight = menu_item_unselected[i]->h;
+ buttonheight = menu_item_unselected[i]->h;
buttonheight += 10;
} else
buttonheight = menu_opts.buttonheight;
@@ -1359,7 +1366,7 @@
case SDL_MOUSEMOTION:
{
- loc = -1; // By default, don't be in any entry
+ loc = -1; // By default, don't be in any entry
for (i = 0; (i < n_entries_per_screen) && (loc_screen_start + i < n_menu_entries); i++)
{
if (inRect(menu_button_rect[i], event.motion.x, event.motion.y))
@@ -1422,8 +1429,8 @@
}
loc = loc_screen_start + i;
- stop = 1;
- break;
+ stop = 1;
+ break;
}
}
@@ -1433,8 +1440,8 @@
if (loc_screen_start - n_entries_per_screen >= 0)
{
//loc = loc_screen_start - n_entries_per_screen;
- loc_screen_start -= n_entries_per_screen;
- loc = -1; // nothing selected
+ loc_screen_start -= n_entries_per_screen;
+ loc = -1; // nothing selected
if (Opts_MenuSound())
{
playsound(SND_TOCK);
@@ -1449,8 +1456,8 @@
if (loc_screen_start + n_entries_per_screen < n_menu_entries)
{
//loc = loc_screen_start + n_entries_per_screen;
- loc_screen_start += n_entries_per_screen;
- loc = -1; // nothing selected
+ loc_screen_start += n_entries_per_screen;
+ loc = -1; // nothing selected
if (Opts_MenuSound())
{
playsound(SND_TOCK);
@@ -1486,7 +1493,7 @@
{
if (Opts_MenuSound())
playsound(SND_POP);
- stop = 1;
+ stop = 1;
break;
}
@@ -1498,9 +1505,9 @@
if (Opts_MenuSound())
playsound(SND_TOCK);
if (loc_screen_start - n_entries_per_screen >= 0) {
- loc_screen_start -= n_entries_per_screen;
- loc = -1;
- }
+ loc_screen_start -= n_entries_per_screen;
+ loc = -1;
+ }
// {loc = loc_screen_start - n_entries_per_screen;}
break;
}
@@ -1513,9 +1520,9 @@
if (Opts_MenuSound())
playsound(SND_TOCK);
if (loc_screen_start + n_entries_per_screen < n_menu_entries) {
- loc_screen_start += n_entries_per_screen;
- loc = -1;
- }
+ loc_screen_start += n_entries_per_screen;
+ loc = -1;
+ }
// {loc = (loc_screen_start + n_entries_per_screen);}
break;
}
@@ -1527,15 +1534,15 @@
playsound(SND_TOCK);
if (loc > title_offset)
{loc--;}
- else if (n_menu_entries <= n_entries_per_screen) {
- loc = n_menu_entries-1; // wrap around if only 1 screen
- }
- else if (loc == -1 && loc_screen_start > 0) {
- loc = loc_screen_start-1;
- loc_screen_start -= n_entries_per_screen;
- }
- if (loc != old_loc)
- warp_mouse = 1;
+ else if (n_menu_entries <= n_entries_per_screen) {
+ loc = n_menu_entries-1; // wrap around if only 1 screen
+ }
+ else if (loc == -1 && loc_screen_start > 0) {
+ loc = loc_screen_start-1;
+ loc_screen_start -= n_entries_per_screen;
+ }
+ if (loc != old_loc)
+ warp_mouse = 1;
break;
}
@@ -1547,12 +1554,12 @@
playsound(SND_TOCK);
if (loc >= 0 && loc + 1 < n_menu_entries)
{loc++;}
- else if (n_menu_entries <= n_entries_per_screen)
- loc = title_offset; // wrap around if only 1 screen
- else if (loc == -1)
- loc = loc_screen_start;
- if (loc != old_loc)
- warp_mouse = 1;
+ else if (n_menu_entries <= n_entries_per_screen)
+ loc = title_offset; // wrap around if only 1 screen
+ else if (loc == -1)
+ loc = loc_screen_start;
+ if (loc != old_loc)
+ warp_mouse = 1;
break;
}
@@ -1636,57 +1643,57 @@
if (images[IMG_STOP])
SDL_BlitSurface(images[IMG_STOP], NULL, screen, &stopRect);
if (Tux->frame[0])
- SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
+ SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
/* Redraw the menu entries */
for (imod = 0; imod < n_entries_per_screen; imod++)
- menu_button_rect[imod].w = 0; // so undrawn buttons don't affect width
+ menu_button_rect[imod].w = 0; // so undrawn buttons don't affect width
for (i = loc_screen_start, imod = 0; i < loc_screen_start+n_entries_per_screen && i < n_menu_entries; i++, imod++) {
- menu_text_rect[imod].w = menu_item_unselected[i]->w;
- if (i >= title_offset) {
- menu_button_rect[imod].w = menu_text_rect[imod].w + 30;
- if (menu_sprites != NULL)
- menu_button_rect[imod].w += 60;
- }
+ menu_text_rect[imod].w = menu_item_unselected[i]->w;
+ if (i >= title_offset) {
+ menu_button_rect[imod].w = menu_text_rect[imod].w + 30;
+ if (menu_sprites != NULL)
+ menu_button_rect[imod].w += 60;
+ }
}
if (menu_opts.button_same_width)
- set_buttons_max_width(menu_button_rect,back_button_rect,n_entries_per_screen);
+ set_buttons_max_width(menu_button_rect,back_button_rect,n_entries_per_screen);
// Make sure the menu title mouse button didn't get turned on
if (loc_screen_start == 0 && title_offset)
- menu_button_rect[0].w = 0;
+ menu_button_rect[0].w = 0;
for (i = loc_screen_start, imod = 0; i < loc_screen_start+n_entries_per_screen && i < n_menu_entries; i++, imod++) {
- if (i == loc) { //Draw text in yellow
- DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
- SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
- }
- else { //Draw text in white
- if (menu_button_rect[imod].w > 0)
- DrawButton(&menu_button_rect[imod], 10, REG_RGBA);
- SDL_BlitSurface(menu_item_unselected[i], NULL, screen, &menu_text_rect[imod]);
- }
- if (menu_sprites != NULL && (i >= title_offset) && menu_sprites[i-title_offset] != NULL)
- SDL_BlitSurface(menu_sprites[i-title_offset]->default_img, NULL, screen, &menu_sprite_rect[imod]);
+ if (i == loc) { //Draw text in yellow
+ DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
+ SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
+ }
+ else { //Draw text in white
+ if (menu_button_rect[imod].w > 0)
+ DrawButton(&menu_button_rect[imod], 10, REG_RGBA);
+ SDL_BlitSurface(menu_item_unselected[i], NULL, screen, &menu_text_rect[imod]);
+ }
+ if (menu_sprites != NULL && (i >= title_offset) && menu_sprites[i-title_offset] != NULL)
+ SDL_BlitSurface(menu_sprites[i-title_offset]->default_img, NULL, screen, &menu_sprite_rect[imod]);
}
/* --- draw 'left' and 'right' buttons --- */
if (n_menu_entries > n_entries_per_screen) {
- if (loc_screen_start > 0) // i.e. not on first page
- {
- SDL_BlitSurface(images[IMG_LEFT], NULL, screen, &left_arrow_rect);
- }
- else /* Draw grayed-out left button: */
+ if (loc_screen_start > 0) // i.e. not on first page
{
- SDL_BlitSurface(images[IMG_LEFT_GRAY], NULL, screen, &left_arrow_rect);
- }
+ SDL_BlitSurface(images[IMG_LEFT], NULL, screen, &left_arrow_rect);
+ }
+ else /* Draw grayed-out left button: */
+ {
+ SDL_BlitSurface(images[IMG_LEFT_GRAY], NULL, screen, &left_arrow_rect);
+ }
- if (loc_screen_start + n_entries_per_screen < n_menu_entries) // not on last page
+ if (loc_screen_start + n_entries_per_screen < n_menu_entries) // not on last page
{
- SDL_BlitSurface(images[IMG_RIGHT], NULL, screen, &right_arrow_rect);
- }
- else /* Draw grayed-out right button: */
- {
- SDL_BlitSurface(images[IMG_RIGHT_GRAY], NULL, screen, &right_arrow_rect);
- }
+ SDL_BlitSurface(images[IMG_RIGHT], NULL, screen, &right_arrow_rect);
+ }
+ else /* Draw grayed-out right button: */
+ {
+ SDL_BlitSurface(images[IMG_RIGHT_GRAY], NULL, screen, &right_arrow_rect);
+ }
}
SDL_Flip(screen);//SDL_UpdateRect(screen, 0, 0, 0 ,0);
@@ -1694,68 +1701,68 @@
// This is not a full redraw, but the selected entry did change.
// By just redrawing the old and new selections, we avoid flickering.
if (old_loc >= 0) {
- imod = old_loc-loc_screen_start;
- use_sprite = (menu_sprites != NULL && old_loc >= title_offset && menu_sprites[old_loc-title_offset] != NULL);
+ imod = old_loc-loc_screen_start;
+ use_sprite = (menu_sprites != NULL && old_loc >= title_offset && menu_sprites[old_loc-title_offset] != NULL);
temp_rect = menu_button_rect[imod];
SDL_FillRect(screen, &temp_rect, 0);
- SDL_BlitSurface(current_bkg(), &back_button_rect[imod], screen, &temp_rect); // redraw background
- if (use_sprite) {
- // Some of the sprites extend beyond the menu button, so we
- // have to make sure we redraw in the sprite rects, too
- SDL_BlitSurface(current_bkg(), &back_sprite_rect[imod], screen, &temp_rect);
- }
- DrawButton(&menu_button_rect[imod], 10, REG_RGBA); // draw button
- //temp_rect = menu_text_rect[imod];
- SDL_BlitSurface(menu_item_unselected[old_loc], NULL, screen, &menu_text_rect[imod]); // draw text
- if (use_sprite) {
- temp_rect = menu_sprite_rect[imod];
- tmdprintf("Sprite %d at (%d %d)\n", imod, temp_rect.x, temp_rect.y);
- SDL_BlitSurface(menu_sprites[old_loc-title_offset]->default_img, NULL, screen, &temp_rect);
- // Also update the sprite rect (in some cases the sprite
- // extends beyond the menu button)
- SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
- }
- SDL_UpdateRect(screen, menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
+ SDL_BlitSurface(current_bkg(), &back_button_rect[imod], screen, &temp_rect); // redraw background
+ if (use_sprite) {
+ // Some of the sprites extend beyond the menu button, so we
+ // have to make sure we redraw in the sprite rects, too
+ SDL_BlitSurface(current_bkg(), &back_sprite_rect[imod], screen, &temp_rect);
+ }
+ DrawButton(&menu_button_rect[imod], 10, REG_RGBA); // draw button
+ //temp_rect = menu_text_rect[imod];
+ SDL_BlitSurface(menu_item_unselected[old_loc], NULL, screen, &menu_text_rect[imod]); // draw text
+ if (use_sprite) {
+ temp_rect = menu_sprite_rect[imod];
+ tmdprintf("Sprite %d at (%d %d)\n", imod, temp_rect.x, temp_rect.y);
+ SDL_BlitSurface(menu_sprites[old_loc-title_offset]->default_img, NULL, screen, &temp_rect);
+ // Also update the sprite rect (in some cases the sprite
+ // extends beyond the menu button)
+ SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
+ }
+ SDL_UpdateRect(screen, menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
}
if (loc >= 0) {
- imod = loc-loc_screen_start;
- use_sprite = (menu_sprites != NULL && loc >= title_offset && menu_sprites[loc] != NULL);
- temp_rect = menu_button_rect[imod];
- SDL_BlitSurface(current_bkg, &back_button_rect[imod], screen, &temp_rect);
- if (use_sprite)
- {
- temp_rect = menu_sprite_rect[imod];
- SDL_BlitSurface(current_bkg, &back_sprite_rect[imod], screen, &temp_rect);
- }
- DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
- SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
- if (use_sprite) {
- menu_sprites[loc-title_offset]->cur = 0; // start at beginning of animation sequence
- SDL_BlitSurface(menu_sprites[loc-title_offset]->frame[menu_sprites[loc-title_offset]->cur], NULL, screen, &menu_sprite_rect[imod]);
- SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
- next_frame(menu_sprites[loc-title_offset]);
- }
- SDL_UpdateRect(screen, menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
- tmdprintf("Updating rect: %d %d %d %d\n", menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
+ imod = loc-loc_screen_start;
+ use_sprite = (menu_sprites != NULL && loc >= title_offset && menu_sprites[loc] != NULL);
+ temp_rect = menu_button_rect[imod];
+ SDL_BlitSurface(current_bkg, &back_button_rect[imod], screen, &temp_rect);
+ if (use_sprite)
+ {
+ temp_rect = menu_sprite_rect[imod];
+ SDL_BlitSurface(current_bkg, &back_sprite_rect[imod], screen, &temp_rect);
+ }
+ DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
+ SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
+ if (use_sprite) {
+ menu_sprites[loc-title_offset]->cur = 0; // start at beginning of animation sequence
+ SDL_BlitSurface(menu_sprites[loc-title_offset]->frame[menu_sprites[loc-title_offset]->cur], NULL, screen, &menu_sprite_rect[imod]);
+ SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
+ next_frame(menu_sprites[loc-title_offset]);
+ }
+ SDL_UpdateRect(screen, menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
+ tmdprintf("Updating rect: %d %d %d %d\n", menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
}
} else if (frame_counter % 5 == 0 && loc >= 0) {
// No user input changed anything, but check to see if we need to
// animate the sprite
if (menu_sprites != NULL && loc >= title_offset && menu_sprites[loc-title_offset] != NULL) {
- imod = loc-loc_screen_start;
- //SDL_BlitSurface(current_bkg, &menu_button_rect[imod], screen, &menu_button_rect[imod]);
- temp_rect = menu_sprite_rect[imod];
- SDL_BlitSurface(current_bkg(), &back_sprite_rect[imod], screen, &temp_rect);
- DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
- //SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
- // Note: even though the whole button was redrawn, we don't
- // have to redraw the text & background as long as we don't
- // update that rect. If something else changes and we go to
- // full-screen updates, then remove the "commenting-out" on
- // the two lines above
- SDL_BlitSurface(menu_sprites[loc-title_offset]->frame[menu_sprites[loc-title_offset]->cur], NULL, screen, &menu_sprite_rect[imod]);
- SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
- next_frame(menu_sprites[loc-title_offset]);
+ imod = loc-loc_screen_start;
+ //SDL_BlitSurface(current_bkg, &menu_button_rect[imod], screen, &menu_button_rect[imod]);
+ temp_rect = menu_sprite_rect[imod];
+ SDL_BlitSurface(current_bkg(), &back_sprite_rect[imod], screen, &temp_rect);
+ DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
+ //SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
+ // Note: even though the whole button was redrawn, we don't
+ // have to redraw the text & background as long as we don't
+ // update that rect. If something else changes and we go to
+ // full-screen updates, then remove the "commenting-out" on
+ // the two lines above
+ SDL_BlitSurface(menu_sprites[loc-title_offset]->frame[menu_sprites[loc-title_offset]->cur], NULL, screen, &menu_sprite_rect[imod]);
+ SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
+ next_frame(menu_sprites[loc-title_offset]);
}
}
@@ -2051,28 +2058,28 @@
UpdateScreen : Update the screen and increment the frame num
***************************/
void UpdateScreen(int *frame) {
- int i;
+ int i;
- /* -- First erase everything we need to -- */
- for (i = 0; i < numupdates; i++)
- if (blits[i].type == 'E')
- SDL_LowerBlit(blits[i].src, blits[i].srcrect, screen, blits[i].dstrect);
-// SNOW_erase();
+ /* -- First erase everything we need to -- */
+ for (i = 0; i < numupdates; i++)
+ if (blits[i].type == 'E')
+ SDL_LowerBlit(blits[i].src, blits[i].srcrect, screen, blits[i].dstrect);
+// SNOW_erase();
- /* -- then draw -- */
- for (i = 0; i < numupdates; i++)
- if (blits[i].type == 'D')
- SDL_BlitSurface(blits[i].src, blits[i].srcrect, screen, blits[i].dstrect);
-// SNOW_draw();
+ /* -- then draw -- */
+ for (i = 0; i < numupdates; i++)
+ if (blits[i].type == 'D')
+ SDL_BlitSurface(blits[i].src, blits[i].srcrect, screen, blits[i].dstrect);
+// SNOW_draw();
- /* -- update the screen only where we need to! -- */
-// if (SNOW_on)
-// SDL_UpdateRects(screen, SNOW_add( (SDL_Rect*)&dstupdate, numupdates ), SNOW_rects);
-// else
- SDL_UpdateRects(screen, numupdates, dstupdate);
+ /* -- update the screen only where we need to! -- */
+// if (SNOW_on)
+// SDL_UpdateRects(screen, SNOW_add( (SDL_Rect*)&dstupdate, numupdates ), SNOW_rects);
+// else
+ SDL_UpdateRects(screen, numupdates, dstupdate);
- numupdates = 0;
- *frame = *frame + 1;
+ numupdates = 0;
+ *frame = *frame + 1;
}
Modified: tuxmath/branches/mathcards_newarch/src/titlescreen.h
===================================================================
--- tuxmath/branches/mathcards_newarch/src/titlescreen.h 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/titlescreen.h 2008-07-01 16:28:15 UTC (rev 556)
@@ -26,7 +26,7 @@
#define to_upper(c) (((c) >= 'a' && (c) <= 'z') ? (c) -32 : (c))
#define COL2RGB( col ) SDL_MapRGB( screen->format, col->r, col->g, col->b )
-//#define FNLEN 200
+//#define FNLEN 200
#define MAX_SPRITE_FRAMES 30
@@ -53,10 +53,10 @@
typedef struct {
- SDL_Surface *frame[MAX_SPRITE_FRAMES];
- SDL_Surface *default_img;
- int num_frames;
- int cur;
+ SDL_Surface *frame[MAX_SPRITE_FRAMES];
+ SDL_Surface *default_img;
+ int num_frames;
+ int cur;
} sprite;
// Options that affect how menus are presented
@@ -74,10 +74,10 @@
#define menu_font "AndikaDesRevA.ttf" /* "GenAI102.ttf" */
-#define menu_font_size 18
+#define menu_font_size 18
#define ttf_font "AndikaDesRevA.ttf" /* "GenAI102.ttf" */
-#define ttf_font_size 18
+#define ttf_font_size 18
#define MAX_LESSONS 100
#define MAX_NUM_WORDS 500
@@ -87,15 +87,15 @@
#define MAX_UPDATES 180
-#define WAIT_MS 2500
-#define FRAMES_PER_SEC 50
-#define FULL_CIRCLE 140
+#define WAIT_MS 2500
+#define FRAMES_PER_SEC 50
+#define FULL_CIRCLE 140
/* Title sequence constants */
-#define PRE_ANIM_FRAMES 10
-#define PRE_FRAME_MULT 3
-#define MENU_SEP 20
+#define PRE_ANIM_FRAMES 10
+#define PRE_FRAME_MULT 3
+#define MENU_SEP 20
/* paths */
@@ -115,7 +115,7 @@
SDL_Surface* current_bkg(); //appropriate background for current video mode
-#define MUSIC_FADE_OUT_MS 80
+#define MUSIC_FADE_OUT_MS 80
enum {
WIPE_BLINDS_VERT,
@@ -134,9 +134,9 @@
#define TITLE_MENU_DEPTH 4
#define OPTIONS_SUBMENU 4
-#define GAME_OPTIONS_SUBMENU 3
-#define ARCADE_SUBMENU 2
-#define ROOTMENU 1
+#define GAME_OPTIONS_SUBMENU 3
+#define ARCADE_SUBMENU 2
+#define ROOTMENU 1
/* --- timings for tux blinking --- */
Modified: tuxmath/branches/mathcards_newarch/src/tuxmath.h
===================================================================
--- tuxmath/branches/mathcards_newarch/src/tuxmath.h 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/tuxmath.h 2008-07-01 16:28:15 UTC (rev 556)
@@ -81,7 +81,7 @@
#define DEFAULT_STARTING_COMETS 2
#define DEFAULT_EXTRA_COMETS_PER_WAVE 2
#define DEFAULT_MAX_COMETS 10
-#define DEFAULT_SAVE_SUMMARY 1
+#define DEFAULT_SAVE_SUMMARY 1
#define DEFAULT_SOUND_HW_AVAILABLE 1
#define DEFAULT_USE_IGLOOS 1
#define DEFAULT_USE_FEEDBACK 0
@@ -115,9 +115,9 @@
#define REG_RGBA 16,16,96,96
#define SEL_RGBA 16,16,128,128
-#define RES_X 640
-#define RES_Y 480
-#define PIXEL_BITS 32
+#define RES_X 640
+#define RES_Y 480
+#define PIXEL_BITS 32
enum {
CADET_HIGH_SCORE,
Modified: tuxmath/branches/mathcards_newarch/src/tuxmathadmin.c
===================================================================
--- tuxmath/branches/mathcards_newarch/src/tuxmathadmin.c 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/tuxmathadmin.c 2008-07-01 16:28:15 UTC (rev 556)
@@ -114,66 +114,66 @@
exit(EXIT_SUCCESS);
}
else if (strcmp(argv[i], "--copyright") == 0 ||
- strcmp(argv[i], "-c") == 0)
+ strcmp(argv[i], "-c") == 0)
{
printf(
- "\ntuxmathadmin version " ADMINVERSION ", Copyright (C) 2007 Tim Holy\n"
+ "\ntuxmathadmin version " ADMINVERSION ", Copyright (C) 2007 Tim Holy\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation. See COPYING.txt\n"
- "\n"
- "This program is distributed in the hope that it will be useful,\n"
- "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
- "\n");
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+ "\n");
exit(EXIT_SUCCESS);
}
else if (strcmp(argv[i], "--usage") == 0 ||
- strcmp(argv[i], "-u") == 0) {
+ strcmp(argv[i], "-u") == 0) {
usage(0, argv[0]);
exit(EXIT_SUCCESS);
}
else if (strcmp(argv[i], "--path") == 0) {
if (i+1 > argc) {
- fprintf(stderr, "%s option requires an argument (a directory name)\n", argv[i]);
- usage(EXIT_FAILURE, argv[0]);
+ fprintf(stderr, "%s option requires an argument (a directory name)\n", argv[i]);
+ usage(EXIT_FAILURE, argv[0]);
}
else {
- path = argv[i+1];
- dir = opendir(path); // determine whether directory exists
- if (dir == NULL)
- error(EXIT_FAILURE,errno,"path:\n %s",path);
- closedir(dir);
- i++; // increment so further processing skips over the argument
+ path = argv[i+1];
+ dir = opendir(path); // determine whether directory exists
+ if (dir == NULL)
+ error(EXIT_FAILURE,errno,"path:\n %s",path);
+ closedir(dir);
+ i++; // increment so further processing skips over the argument
}
}
else if (strcmp(argv[i], "--level") == 0) {
if (i+1 > argc) {
- fprintf(stderr, "%s option requires an argument (a level number)\n", argv[i]);
- usage(EXIT_FAILURE, argv[0]);
+ fprintf(stderr, "%s option requires an argument (a level number)\n", argv[i]);
+ usage(EXIT_FAILURE, argv[0]);
}
else {
- success = sscanf(argv[i+1],"%d",&level);
- if (!success) {
- fprintf(stderr,"level: %s is not a number\n",argv[i+1]);
- exit(EXIT_FAILURE);
- }
- i++; // increment so further processing skips over the argument
+ success = sscanf(argv[i+1],"%d",&level);
+ if (!success) {
+ fprintf(stderr,"level: %s is not a number\n",argv[i+1]);
+ exit(EXIT_FAILURE);
+ }
+ i++; // increment so further processing skips over the argument
}
}
else if (strcmp(argv[i], "--createhomedirs") == 0) {
is_creatinghomedirs = 1;
if (i+1 > argc) {
- fprintf(stderr, "%s option requires an argument (a file name)\n", argv[i]);
- usage(EXIT_FAILURE, argv[0]);
+ fprintf(stderr, "%s option requires an argument (a file name)\n", argv[i]);
+ usage(EXIT_FAILURE, argv[0]);
}
else {
- file = argv[i+1];
- fp = fopen(file,"r"); // determine whether the file exists
- if (fp == NULL)
- error(EXIT_FAILURE,errno,"createhomedirs using:\n %s",file);
- fclose(fp); // don't read it yet, do that elsewhere
- i++; // increment so further processing skips over the argument
+ file = argv[i+1];
+ fp = fopen(file,"r"); // determine whether the file exists
+ if (fp == NULL)
+ error(EXIT_FAILURE,errno,"createhomedirs using:\n %s",file);
+ fclose(fp); // don't read it yet, do that elsewhere
+ i++; // increment so further processing skips over the argument
}
}
else if (strcmp(argv[i], "--confighighscores") == 0) {
@@ -277,42 +277,42 @@
void display_help(void)
{
printf("\ntuxmathadmin\n"
- "This program facilitates administering tuxmath, and is particularly\n"
- "useful for schools and the like that may have many users.\n\n"
- "Examples:\n"
- " tuxmathadmin --path /servervolume/tuxmath_users --createhomedirs users.csv\n"
- " tuxmathadmin --createhomedirs users.csv\n"
- " Creates a user directory tree in location /servervolume/tuxmath_users,\n"
- " according to the structure specified in users.csv. See configure.pdf\n"
- " for details. The second syntax is applicable if you've defined the\n"
- " homedir path in the global configuration file.\n\n"
- " tuxmathadmin --confighighscores --level 3\n"
- " Sets up sharing of high scores at level 3 of the hierarchy (top is\n"
- " level 1). If students logging in are presented with a choice of grade,\n"
- " then classroom, and then user, then level 1 is the school, level 2 is the\n"
- " grade, level 3 is the classroom, and level 4 is the individual student.\n"
- " So level 3 would set it up so that all kids in the same classroom would\n"
- " compete for high scores.\n\n"
- " tuxmathadmin --unconfighighscores\n"
- " Removes any existing highscores configuration.\n\n"
- " tuxmathadmin --clearhighscores\n"
- " Clears high scores for all users in the location specified by the homedir\n"
- " setting in the global configuration file.\n\n"
- " tuxmathadmin --path /servervolume/tuxmath_users/2ndgrade --clearhighscores\n"
- " Clears the high scores for all users inside the 2ndgrade hierarchy.\n\n"
- " tuxmathadmin --cleargoldstars\n"
- " Clears the gold stars for all users.\n\n"
- " tuxmathadmin --path /servervolume/tuxmath_users/1st\\ grade/Mrs.\\ Smith --cleargoldstars\n"
- " Clears the gold stars for all users in Mrs. Smith's first grade class.\n\n"
- " tuxmathadmin --consolidatelogs\n"
- " Creates consolidated_log.csv files at one level above the lowest level\n"
- " of the directory hierarchy. These files can be opened with a spreadsheet\n"
- " program. This may be useful for tracking student progress.\n"
- " Note also that each student has a personal log.csv file in his/her own\n"
- " directory.\n\n"
- " tuxmathadmin --clearlogs\n"
- " Deletes all log.csv files in the directory hierarchy.\n\n"
- );
+ "This program facilitates administering tuxmath, and is particularly\n"
+ "useful for schools and the like that may have many users.\n\n"
+ "Examples:\n"
+ " tuxmathadmin --path /servervolume/tuxmath_users --createhomedirs users.csv\n"
+ " tuxmathadmin --createhomedirs users.csv\n"
+ " Creates a user directory tree in location /servervolume/tuxmath_users,\n"
+ " according to the structure specified in users.csv. See configure.pdf\n"
+ " for details. The second syntax is applicable if you've defined the\n"
+ " homedir path in the global configuration file.\n\n"
+ " tuxmathadmin --confighighscores --level 3\n"
+ " Sets up sharing of high scores at level 3 of the hierarchy (top is\n"
+ " level 1). If students logging in are presented with a choice of grade,\n"
+ " then classroom, and then user, then level 1 is the school, level 2 is the\n"
+ " grade, level 3 is the classroom, and level 4 is the individual student.\n"
+ " So level 3 would set it up so that all kids in the same classroom would\n"
+ " compete for high scores.\n\n"
+ " tuxmathadmin --unconfighighscores\n"
+ " Removes any existing highscores configuration.\n\n"
+ " tuxmathadmin --clearhighscores\n"
+ " Clears high scores for all users in the location specified by the homedir\n"
+ " setting in the global configuration file.\n\n"
+ " tuxmathadmin --path /servervolume/tuxmath_users/2ndgrade --clearhighscores\n"
+ " Clears the high scores for all users inside the 2ndgrade hierarchy.\n\n"
+ " tuxmathadmin --cleargoldstars\n"
+ " Clears the gold stars for all users.\n\n"
+ " tuxmathadmin --path /servervolume/tuxmath_users/1st\\ grade/Mrs.\\ Smith --cleargoldstars\n"
+ " Clears the gold stars for all users in Mrs. Smith's first grade class.\n\n"
+ " tuxmathadmin --consolidatelogs\n"
+ " Creates consolidated_log.csv files at one level above the lowest level\n"
+ " of the directory hierarchy. These files can be opened with a spreadsheet\n"
+ " program. This may be useful for tracking student progress.\n"
+ " Note also that each student has a personal log.csv file in his/her own\n"
+ " directory.\n\n"
+ " tuxmathadmin --clearlogs\n"
+ " Deletes all log.csv files in the directory hierarchy.\n\n"
+ );
}
// This function does the work of creating the user directory tree,
@@ -359,7 +359,7 @@
line_cur = line_begin;
while (!(*line_cur == '\r' || *line_cur == '\n')) {
if (*line_cur == ',')
- this_line_total_depth++;
+ this_line_total_depth++;
line_cur++;
}
@@ -368,23 +368,23 @@
max_depth = this_line_total_depth;
current_dirtree = (char **) malloc(max_depth * sizeof(char*));
if (current_dirtree == NULL) {
- fprintf(stderr,"Error: couldn't allocate memory for directory tree.\n");
- exit(EXIT_FAILURE);
+ fprintf(stderr,"Error: couldn't allocate memory for directory tree.\n");
+ exit(EXIT_FAILURE);
}
for (i = 0; i < max_depth; i++) {
- current_dirtree[i] = (char *) malloc(PATH_MAX * sizeof(char));
- if (current_dirtree[i] == NULL){
- fprintf(stderr,"Error: couldn't allocate memory for directory tree.\n");
- exit(EXIT_FAILURE);
- } else
- *(current_dirtree[i]) = '\0'; // initialize with blank string
+ current_dirtree[i] = (char *) malloc(PATH_MAX * sizeof(char));
+ if (current_dirtree[i] == NULL){
+ fprintf(stderr,"Error: couldn't allocate memory for directory tree.\n");
+ exit(EXIT_FAILURE);
+ } else
+ *(current_dirtree[i]) = '\0'; // initialize with blank string
}
}
else {
// Check that this line doesn't change the size of the directory hierarchy
if (this_line_total_depth != max_depth) {
- fprintf(stderr,"Error: line\n '%s'\ncontains a different number of depths to the hierarchy than the previous setting (%d).\n",buf,max_depth);
- exit(EXIT_FAILURE);
+ fprintf(stderr,"Error: line\n '%s'\ncontains a different number of depths to the hierarchy than the previous setting (%d).\n",buf,max_depth);
+ exit(EXIT_FAILURE);
}
}
@@ -403,29 +403,29 @@
// the string, so don't be bothered that line_cur could get to be
// one less than line_begin.
while (line_cur >= line_begin && *line_cur != ',')
- line_cur--;
+ line_cur--;
// Determine whether we have a new directory name
if (line_cur+1 < line_cur_end) {
- // We do, copy it over including the terminal \0
- copy_start = line_cur+1;
- if (*copy_start == '\"')
- copy_start++;
- if (line_cur_end[-1] == '\"') {
- line_cur_end--;
- *line_cur_end = '\0';
- }
- memcpy(current_dirtree[current_depth],copy_start,line_cur_end-copy_start+1);
- stop_blanking = 1; // don't clear blank fields in the future
+ // We do, copy it over including the terminal \0
+ copy_start = line_cur+1;
+ if (*copy_start == '\"')
+ copy_start++;
+ if (line_cur_end[-1] == '\"') {
+ line_cur_end--;
+ *line_cur_end = '\0';
+ }
+ memcpy(current_dirtree[current_depth],copy_start,line_cur_end-copy_start+1);
+ stop_blanking = 1; // don't clear blank fields in the future
}
else {
- // Blank this particular field, because we don't want old
- // subdirectories hanging around
- if (!stop_blanking)
- *(current_dirtree[current_depth]) = '\0';
+ // Blank this particular field, because we don't want old
+ // subdirectories hanging around
+ if (!stop_blanking)
+ *(current_dirtree[current_depth]) = '\0';
}
current_depth--;
if (line_cur >= line_begin)
- *line_cur = '\0'; // end the processing at the comma
+ *line_cur = '\0'; // end the processing at the comma
line_cur_end = line_cur;
}
@@ -441,73 +441,73 @@
strncpy(fullpath+len,current_dirtree[i],PATH_MAX-len);
len = strlen(fullpath);
if (fullpath[len-1] != '/' && len+1 < PATH_MAX) {
- fullpath[len] = '/'; // append a slash, if need be
- fullpath[len+1] = '\0';
+ fullpath[len] = '/'; // append a slash, if need be
+ fullpath[len+1] = '\0';
}
}
// Create the directory
if (strlen(fullpath) < PATH_MAX) {
if (mkdir(fullpath,mask) < 0) {
- // There was some kind of error, figure out what happened.
- // Be a little more verbose than the standard library errors.
- if (errno == EEXIST) {
- fprintf(stderr,"Warning: %s already exists, continuing.\n",fullpath);
- }
- else if (errno == ENAMETOOLONG) {
- fprintf(stderr,"Error: the directory name:\n %s\nwas too long.\n",fullpath);
- exit(EXIT_FAILURE);
- }
- else if (errno == ENOENT) {
- fprintf(stderr,"Error: One of the upper-level directories in:\n %s\ndoesn't exist. Check the syntax of your configuration file.\n",fullpath);
- exit(EXIT_FAILURE);
- }
- else if (errno == ENOSPC) {
- fprintf(stderr,"Error: the device has no room available.\n");
- exit(EXIT_FAILURE);
- }
- else {
- // Fall back on the standard library for the remaining error
- // handling
- fprintf(stderr,"Error: couldn't make directory %s:\nDo you have write permission for this location?\nDo you need to be root/administrator?\n",fullpath);
- error(EXIT_FAILURE,errno,"error");
- }
+ // There was some kind of error, figure out what happened.
+ // Be a little more verbose than the standard library errors.
+ if (errno == EEXIST) {
+ fprintf(stderr,"Warning: %s already exists, continuing.\n",fullpath);
+ }
+ else if (errno == ENAMETOOLONG) {
+ fprintf(stderr,"Error: the directory name:\n %s\nwas too long.\n",fullpath);
+ exit(EXIT_FAILURE);
+ }
+ else if (errno == ENOENT) {
+ fprintf(stderr,"Error: One of the upper-level directories in:\n %s\ndoesn't exist. Check the syntax of your configuration file.\n",fullpath);
+ exit(EXIT_FAILURE);
+ }
+ else if (errno == ENOSPC) {
+ fprintf(stderr,"Error: the device has no room available.\n");
+ exit(EXIT_FAILURE);
+ }
+ else {
+ // Fall back on the standard library for the remaining error
+ // handling
+ fprintf(stderr,"Error: couldn't make directory %s:\nDo you have write permission for this location?\nDo you need to be root/administrator?\n",fullpath);
+ error(EXIT_FAILURE,errno,"error");
+ }
}
else {
- fsync(fileno(stderr));
- fprintf(stdout,"Creating %s\n",fullpath);
- fsync(fileno(stdout));
+ fsync(fileno(stderr));
+ fprintf(stdout,"Creating %s\n",fullpath);
+ fsync(fileno(stdout));
- // Append the name to the user_menu_entries file
- // First we split off the last item in fullpath
- line_begin = fullpath;
- len = strlen(line_begin);
- line_begin[len-1] = '\0'; // replace terminal '/' with \0
- line_cur = line_begin + len-1;
- while (line_cur > line_begin && *line_cur != '/')
- line_cur--;
- if (line_cur > line_begin) { // as long as not making in the root directory...a bad idea anyway!
- *line_cur = '\0'; // Split into two strings
- }
- else {
- line_begin = "/";
- }
- line_cur++; // line_cur now points to beginning of newest directory
- strncpy(buf,line_begin,PATH_MAX); // we don't need buf anymore
- buf[strlen(buf)] = '/'; // append directory separator
- len = strlen(buf);
- strncpy(buf+len,USER_MENU_ENTRIES_FILENAME,PATH_MAX-len-strlen(USER_MENU_ENTRIES_FILENAME));
- // Now do the appending
- fpue = fopen(buf,"a");
- if (!fpue) {
- fprintf(stderr,"Error: can't open file %s for writing.\n",buf);
- exit(EXIT_FAILURE);
- }
- len = fprintf(fpue,"%s\n",line_cur);
- if (len != strlen(line_cur)+1) {
- error(EXIT_FAILURE,errno,"Error writing %s to file %s.\n",line_cur,buf);
- }
- fclose(fpue);
+ // Append the name to the user_menu_entries file
+ // First we split off the last item in fullpath
+ line_begin = fullpath;
+ len = strlen(line_begin);
+ line_begin[len-1] = '\0'; // replace terminal '/' with \0
+ line_cur = line_begin + len-1;
+ while (line_cur > line_begin && *line_cur != '/')
+ line_cur--;
+ if (line_cur > line_begin) { // as long as not making in the root directory...a bad idea anyway!
+ *line_cur = '\0'; // Split into two strings
+ }
+ else {
+ line_begin = "/";
+ }
+ line_cur++; // line_cur now points to beginning of newest directory
+ strncpy(buf,line_begin,PATH_MAX); // we don't need buf anymore
+ buf[strlen(buf)] = '/'; // append directory separator
+ len = strlen(buf);
+ strncpy(buf+len,USER_MENU_ENTRIES_FILENAME,PATH_MAX-len-strlen(USER_MENU_ENTRIES_FILENAME));
+ // Now do the appending
+ fpue = fopen(buf,"a");
+ if (!fpue) {
+ fprintf(stderr,"Error: can't open file %s for writing.\n",buf);
+ exit(EXIT_FAILURE);
+ }
+ len = fprintf(fpue,"%s\n",line_cur);
+ if (len != strlen(line_cur)+1) {
+ error(EXIT_FAILURE,errno,"Error writing %s to file %s.\n",line_cur,buf);
+ }
+ fclose(fpue);
}
}
else {
@@ -538,19 +538,19 @@
n_dirs = directory_crawl(path);
success = 0; // This will change to 1 if we find a directory of the
- // right level
+ // right level
for (i = 0; i < n_dirs; i++) {
if (directory_level[i] == level) {
// Create a blank highscores file in this directory
strncpy(buf,directory[i],PATH_MAX);
strncat(buf,HIGHSCORE_FILENAME,PATH_MAX-strlen(buf)-1);
if (strlen(buf) >= PATH_MAX-1) {
- fprintf(stderr,"confighighscores: pathname %s truncated, exiting.\n",buf);
- exit(EXIT_FAILURE);
+ fprintf(stderr,"confighighscores: pathname %s truncated, exiting.\n",buf);
+ exit(EXIT_FAILURE);
}
fp = fopen(buf,"w");
if (!fp)
- error(EXIT_FAILURE,errno,"confighighscores: file:\n %s",buf);
+ error(EXIT_FAILURE,errno,"confighighscores: file:\n %s",buf);
// That creates a blank file, which is all we have to do
fclose(fp);
success = 1;
@@ -597,7 +597,7 @@
fclose(fp);
fp = fopen(buf,"w");
if (!fp)
- error(EXIT_FAILURE,errno,"clearhighscores: file:\n %s",buf);
+ error(EXIT_FAILURE,errno,"clearhighscores: file:\n %s",buf);
// That creates a blank file, which is all we have to do
fclose(fp);
}
@@ -664,30 +664,30 @@
// Skip over white space, and especially blank lines
line_begin = eatwhite(buf);
if (strlen(line_begin) == 0)
- continue;
+ continue;
// Create the full path & filename of the user's log.csv file
strncpy(buf2,directory[i],PATH_MAX);
strncat(buf2,line_begin,PATH_MAX-strlen(buf2)-1);
strncat(buf2,"/log.csv",PATH_MAX-strlen(buf2)-1);
fplogread = fopen(buf2,"r");
if (fplogread) {
- // Copy the relevant lines from the user's log.csv file to the
- // consolidated log file. Make sure only one copy of the
- // column names is written.
- while(fgets(buf3, PATH_MAX, fplogread)) {
- line_begin = eatwhite(buf3);
- if (strlen(line_begin) == 0)
- continue;
- if (strncmp(line_begin,"\"User",5) == 0) {
- if (!column_names_written) {
- fprintf(fplogwrite,"%s\n",line_begin);
- column_names_written = 1;
- }
- } else {
- fprintf(fplogwrite,"%s\n",line_begin);
- }
- }
- fclose(fplogread);
+ // Copy the relevant lines from the user's log.csv file to the
+ // consolidated log file. Make sure only one copy of the
+ // column names is written.
+ while(fgets(buf3, PATH_MAX, fplogread)) {
+ line_begin = eatwhite(buf3);
+ if (strlen(line_begin) == 0)
+ continue;
+ if (strncmp(line_begin,"\"User",5) == 0) {
+ if (!column_names_written) {
+ fprintf(fplogwrite,"%s\n",line_begin);
+ column_names_written = 1;
+ }
+ } else {
+ fprintf(fplogwrite,"%s\n",line_begin);
+ }
+ }
+ fclose(fplogread);
}
}
fclose(fpusersread);
@@ -725,7 +725,7 @@
// We found such a file, delete it
fclose(fp);
if (remove(buf) < 0)
- error(EXIT_FAILURE,errno,"%s: file:\n %s",invoke_name,buf);
+ error(EXIT_FAILURE,errno,"%s: file:\n %s",invoke_name,buf);
}
}
@@ -758,22 +758,22 @@
// Find the "=" sign
tmpvalue = strchr(param_begin+strlen(varname), '=');
if (tmpvalue == NULL)
- continue;
+ continue;
// Skip over the "=" sign
tmpvalue++;
// Skip whitespace
while (isspace(*tmpvalue))
- tmpvalue++;
+ tmpvalue++;
// Eliminate any whitespace at end
param_begin = tmpvalue;
tmpvalue = param_begin + strlen(param_begin) - 1;
while (tmpvalue > param_begin && isspace(*tmpvalue)) {
- *tmpvalue = '\0';
- tmpvalue--;
+ *tmpvalue = '\0';
+ tmpvalue--;
}
// Abort if empty
if (strlen(param_begin) == 0)
- continue;
+ continue;
// Successful, copy the result
*value = strdup(param_begin);
return 1;
@@ -829,45 +829,45 @@
// Just parse directories of the most recently-added level
// (we've already done the work for previous levels)
if (directory_level[i] == current_level) {
- // Read the user_menu_entries file, if it exists
- // Note that previous items already have "/" appended, no need
- // to worry about that here.
- strncpy(fullpath,directory[i],PATH_MAX);
- strncat(fullpath,USER_MENU_ENTRIES_FILENAME,PATH_MAX-strlen(fullpath)-1);
- fp = fopen(fullpath,"r");
- if (fp != NULL) {
- // We found the user_menu_entries file, read it and add directories
- while (fgets (buf, PATH_MAX, fp)) {
- if (current_length >= MAX_USERS) {
- fprintf(stderr,"Error: maximum number of users exceeded.");
- exit(EXIT_FAILURE);
- }
- // Skip over leading & trailing white space, and
- // especially blank lines
- line_begin = eatwhite(buf);
- if (strlen(line_begin) == 0)
- continue;
+ // Read the user_menu_entries file, if it exists
+ // Note that previous items already have "/" appended, no need
+ // to worry about that here.
+ strncpy(fullpath,directory[i],PATH_MAX);
+ strncat(fullpath,USER_MENU_ENTRIES_FILENAME,PATH_MAX-strlen(fullpath)-1);
+ fp = fopen(fullpath,"r");
+ if (fp != NULL) {
+ // We found the user_menu_entries file, read it and add directories
+ while (fgets (buf, PATH_MAX, fp)) {
+ if (current_length >= MAX_USERS) {
+ fprintf(stderr,"Error: maximum number of users exceeded.");
+ exit(EXIT_FAILURE);
+ }
+ // Skip over leading & trailing white space, and
+ // especially blank lines
+ line_begin = eatwhite(buf);
+ if (strlen(line_begin) == 0)
+ continue;
- directory[current_length] = (char *) malloc((strlen(directory[i])+strlen(line_begin)+2)*sizeof(char));
- if (directory[current_length] == NULL) {
- fprintf(stderr,"Memory allocation error in directory_crawl.\n");
- exit(EXIT_FAILURE);
- }
- // Append each new directory to the list
- strcpy(directory[current_length],directory[i]);
- strcat(directory[current_length],line_begin);
- strcat(directory[current_length],"/");
- directory_level[current_length] = current_level+1;
- // Check to make sure it's valid
- dir = opendir(directory[current_length]);
- if (dir == NULL)
- error(EXIT_FAILURE,errno,"directory:\n %s",directory[current_length]);
- closedir(dir);
- current_length++;
- }
- isdone = 0; // We know we need to check the subdirectories
- fclose(fp);
- } // end of: if (fp != NULL)
+ directory[current_length] = (char *) malloc((strlen(directory[i])+strlen(line_begin)+2)*sizeof(char));
+ if (directory[current_length] == NULL) {
+ fprintf(stderr,"Memory allocation error in directory_crawl.\n");
+ exit(EXIT_FAILURE);
+ }
+ // Append each new directory to the list
+ strcpy(directory[current_length],directory[i]);
+ strcat(directory[current_length],line_begin);
+ strcat(directory[current_length],"/");
+ directory_level[current_length] = current_level+1;
+ // Check to make sure it's valid
+ dir = opendir(directory[current_length]);
+ if (dir == NULL)
+ error(EXIT_FAILURE,errno,"directory:\n %s",directory[current_length]);
+ closedir(dir);
+ current_length++;
+ }
+ isdone = 0; // We know we need to check the subdirectories
+ fclose(fp);
+ } // end of: if (fp != NULL)
} // end of: if (directory_level[i] == current_level)
} // end of: loop over previous directories
current_level++; // We're all done parsing this level, move on
Modified: tuxmath/branches/mathcards_newarch/src/tuxmathrc.rc
===================================================================
--- tuxmath/branches/mathcards_newarch/src/tuxmathrc.rc 2008-06-25 21:39:36 UTC (rev 555)
+++ tuxmath/branches/mathcards_newarch/src/tuxmathrc.rc 2008-07-01 16:28:15 UTC (rev 556)
@@ -1,2 +1,2 @@
#define TUXMATH_ICON 104
-TUXMATH_ICON ICON "../data/images/tuxmath.ico"
+TUXMATH_ICON ICON "../data/images/tuxmath.ico"
More information about the Tux4kids-commits
mailing list