[Tux4kids-commits] r23 - in tuxmath/trunk: . data data/images/tux data/missions data/sounds docs src

dbruce at alioth.debian.org dbruce at alioth.debian.org
Thu Mar 8 21:05:05 CET 2007


Author: dbruce
Date: 2006-09-03 16:37:34 +0000 (Sun, 03 Sep 2006)
New Revision: 23

Added:
   tuxmath/trunk/data/images/tux/console_bash.png
   tuxmath/trunk/data/missions/
   tuxmath/trunk/data/missions/options
   tuxmath/trunk/data/sounds/sizzling.wav
   tuxmath/trunk/src/fileops.c
   tuxmath/trunk/src/fileops.h
Removed:
   tuxmath/trunk/data/.tuxmath
   tuxmath/trunk/data/sounds/SIZZLING.WAV
   tuxmath/trunk/src/config.c
   tuxmath/trunk/src/config.h
   tuxmath/trunk/src/images.h
   tuxmath/trunk/src/sounds.h
Modified:
   tuxmath/trunk/Makefile
   tuxmath/trunk/docs/README.txt
   tuxmath/trunk/docs/TODO.txt
   tuxmath/trunk/docs/changelog
   tuxmath/trunk/src/credits.c
   tuxmath/trunk/src/game.c
   tuxmath/trunk/src/game.h
   tuxmath/trunk/src/mathcards.c
   tuxmath/trunk/src/options.c
   tuxmath/trunk/src/playsound.c
   tuxmath/trunk/src/setup.c
   tuxmath/trunk/src/setup.h
   tuxmath/trunk/src/title.c
   tuxmath/trunk/src/tuxmath.h
Log:
better handling of config files


Modified: tuxmath/trunk/Makefile
===================================================================
--- tuxmath/trunk/Makefile	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/Makefile	2006-09-03 16:37:34 UTC (rev 23)
@@ -32,7 +32,7 @@
 OWNER=$(shell if `groups root | grep root > /dev/null` ; then echo root:root ; else echo root:wheel ; fi)
 
 
-VERSION=tuxmath-0.92
+VERSION=tuxmath-0.93
 
 all:	tuxmath
 
@@ -67,7 +67,7 @@
 
 tuxmath:	obj/tuxmath.o obj/setup.o obj/title.o obj/game.o \
 		obj/options.o obj/credits.o obj/playsound.o \
-                obj/mathcards.o obj/config.o
+                obj/mathcards.o obj/fileops.o
 	@echo "LINKING!"
 	$(CC) $(CFLAGS) $^ -o tuxmath $(LIBS)
 
@@ -75,44 +75,43 @@
 obj:
 	mkdir -p obj
 
-obj/tuxmath.o:	src/tuxmath.c src/images.h src/sounds.h src/setup.h \
+obj/tuxmath.o:	src/tuxmath.c src/fileops.h src/setup.h \
 		src/title.h src/game.h src/options.h src/credits.h \
 		src/playsound.h 
 	@echo "BUILDING tuxmath.o"
 	-mkdir -p obj
 	$(CC) $(CFLAGS) src/tuxmath.c -c -o obj/tuxmath.o
 
-obj/setup.o:	src/setup.c src/setup.h src/sounds.h src/images.h src/game.h
+obj/setup.o:	src/setup.c src/setup.h src/fileops.h src/game.h
 	@echo "BUILDING setup.o"
 	-mkdir -p obj
 	$(CC) $(CFLAGS) src/setup.c -c -o obj/setup.o
 
-obj/title.o:	src/title.c src/title.h src/setup.h src/sounds.h src/images.h \
+obj/title.o:	src/title.c src/title.h src/setup.h src/fileops.h \
 		src/playsound.h
 	@echo "BUILDING title.o"
 	-mkdir -p obj
 	$(CC) $(CFLAGS) src/title.c -c -o obj/title.o
 
-obj/game.o:	src/game.c src/game.h src/setup.h src/sounds.h src/images.h \
+obj/game.o:	src/game.c src/game.h src/setup.h src/fileops.h \
 		src/playsound.h
 	@echo "BUILDING game.o"
 	-mkdir -p obj
 	$(CC) $(CFLAGS) src/game.c -c -o obj/game.o
 
-obj/options.o:	src/options.c src/options.h src/images.h src/setup.h \
-		src/sounds.h src/playsound.h
+obj/options.o:	src/options.c src/options.h src/fileops.h src/setup.h \
+		src/playsound.h
 	@echo "BUILDING options.o"
 	-mkdir -p obj
 	$(CC) $(CFLAGS) src/options.c -c -o obj/options.o
 
-obj/credits.o:	src/credits.c src/credits.h src/setup.h src/sounds.h \
-		src/images.h
+obj/credits.o:	src/credits.c src/credits.h src/setup.h src/fileops.h
 	@echo "BUILDING credits.o"
 	-mkdir -p obj
 	$(CC) $(CFLAGS) src/credits.c -c -o obj/credits.o
 
 obj/playsound.o:	src/playsound.c src/playsound.h src/setup.h \
-		src/sounds.h
+		src/fileops.h
 	@echo "BUILDING playsound.o"
 	-mkdir -p obj
 	$(CC) $(CFLAGS) src/playsound.c -c -o obj/playsound.o
@@ -122,7 +121,7 @@
 	-mkdir -p obj
 	$(CC) $(CFLAGS) src/mathcards.c -c -o obj/mathcards.o
 
-obj/config.o:	src/config.c src/config.h 
-	@echo "BUILDING config.o"
+obj/fileops.o:	src/fileops.c src/fileops.h 
+	@echo "BUILDING fileops.o"
 	-mkdir -p obj
-	$(CC) $(CFLAGS) src/config.c -c -o obj/config.o
+	$(CC) $(CFLAGS) src/fileops.c -c -o obj/fileops.o

Deleted: tuxmath/trunk/data/.tuxmath
===================================================================
--- tuxmath/trunk/data/.tuxmath	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/data/.tuxmath	2006-09-03 16:37:34 UTC (rev 23)
@@ -1,216 +0,0 @@
-############################################################
-#                                                          #
-#                 Tuxmath Config File                      #
-#                                                          #
-############################################################
-
-
-############################################################
-#                                                          #
-#                 General Game Options                     #
-#                                                          #
-# The following options are boolean (true/false) variables #
-# that control various aspects of Tuxmath's behavior.      #
-# The program writes the values to the file as either '0'  #
-# or '1'. However, the program accepts 'n', 'no', 'f', and #
-# 'false' as synonyms for '0', and similarly accepts 'y',  #
-# 'yes', 't', and 'true' as synonyms for '1' (all case-    #
-# insensitive).                                            #
-############################################################
-
-############################################################
-# 'per_user_config' determines whether Tuxmath will look   #
-# in the user's home directory for settings. Default is 1  #
-# (yes). If deselected, the program will ignore the user's #
-# .tuxmath file and use the the global settings in the     #
-# installation-wide config file.                           #
-# This setting cannot be changed by an ordinary user.      #
-############################################################
-per_user_config = 1
-
-# Self-explanatory, default is 1:
-use_sound = 1
-
-# Use either fullscreen at 640x480 resolution or window of that size
-# Default is 1.  Change to 0 if SDL has trouble with fullscreen.
-fullscreen = 1
-
-# Use 640x480 jpg image for background; default is 1.
-use_bkgd = 1
-
-# Program runs as demo; default is 0.
-demo_mode = 0
-
-# Use operator selection from command line; default is 0.
-oper_override = 0
-
-# Display onscreen numeric keypad; default is 0.
-use_keypad = 0
-
-############################################################
-# The remaining settings determine the speed and number    #
-# of comets.  The speed settings are float numbers (mean-  #
-# ing decimals allowed). The comet settings are integers.  #
-############################################################
-
-# Starting comet speed. Default is 1.
-speed = 1.000000
-
-# Speed is multiplied by this factor with each new wave.
-# Default is 1.2
-speedup_factor = 1.200000
-
-# Maximum speed. Default is 10.
-max_speed = 10.000000
-
-# Number of comets for first wave. Default is 2.
-starting_comets = 2
-
-# Comets to add for each successive wave. Default is 2.
-extra_comets_per_wave = 2
-
-# Maximum number of comets. Default is 10.
-max_comets = 10
-
-# Allow speed and number of comets to increase with each
-# wave.  May want to turn this off for smaller kids. Default is 1.
-allow_speedup = 1
-
-# Go back to starting speed and number of comets if player
-# misses a question. Useful for smaller kids. Default is 0.
-slow_after_wrong = 0
-
-############################################################
-#                                                          #
-#                  General Math Options                    #
-#                                                          #
-# If 'play_through_list' selected, Tuxmath will ask each   #
-# question in the defined list. The game ends when no      #
-# questions remain.  Default is 1 (i.e. 'true' or 'yes').  #
-#                                                          #
-# 'question_copies' is the number of times each question   #
-# will be asked. It can be 1 to 10 - Default is 1.         #
-#                                                          #
-# 'repeat_wrongs' tells Tuxmath whether to reinsert        #
-# incorrectly answered questions into the list to be       #
-# asked again. Default is 1 (yes).                         #
-#                                                          #
-# 'copies_repeated_wrongs' gives the number of times an    #
-# incorrectly answered question will reappear. Default     #
-# is 1.                                                    #
-#                                                          #
-# The defaults for these values result in a 'mission'      #
-# for Tux that is accomplished by answering all            #
-# questions correctly with at least one surviving city.    #
-############################################################
-
-play_through_list = 1
-question_copies = 1
-repeat_wrongs = 1
-copies_repeated_wrongs = 1
-
-############################################################
-# 'format_answer_last' (, _first, middle) control the      #
-# generation of questions with the answer in different     #
-# places in the equation.  i.e.:                           #
-#                                                          #
-#    format_answer_last:    2 + 2 = ?                      #
-#    format_answer_first:   ? + 2 = 4                      #
-#    format_answer_middle:  2 + ? = 4                      #
-#                                                          #
-# By default, 'format_answer_first' is enabled and the     #
-# other two formats are disabled.  Note that the options   #
-# are not mutually exclusive - the question list may       #
-# contain questions with different formats.                #
-############################################################
-
-format_answer_last = 1
-format_answer_first = 0
-format_answer_middle = 0
-
-############################################################
-# 'allow_negatives' allows or disallows use of negative    #
-# numbers as both operands and answers.  Default is 0      #
-# (no), which disallows questions like:                    #
-#          2 - 4 = ?                                       #
-# Note: this option must be enabled in order to set the    #
-# operand ranges to include negatives (see below). If it   #
-# is changed from 1 (yes) to 0 (no), any negative          #
-# operand limits will be reset to 0.                       #
-############################################################
-
-allow_negatives = 0
-
-############################################################
-# 'max_answer' is the largest absolute value allowed in    #
-# any value in a question (not only the answer). Default   #
-# is 144. It can be set as high as 999.                    #
-############################################################
-
-max_answer = 144
-
-############################################################
-# 'max_questions' is limit of the length of the question   #
-# list. Default is 5000 - only severe taskmasters will     #
-# need to raise it.                                        #
-############################################################
-
-max_questions = 5000
-
-############################################################
-# If 'randomize' selected, the list will be shuffled       #
-# at the start of the game.  Default is 1 (yes).           #
-############################################################
-
-randomize = 1
-
-############################################################
-#                                                          #
-#                 Math Operations Allowed                  #
-#                                                          #
-# These options enable questions for each of the four math #
-# operations.  All are 1 (yes) by default.                 #
-############################################################
-
-addition_allowed = 1
-subtraction_allowed = 1
-multiplication_allowed = 1
-division_allowed = 1
-
-############################################################
-#                                                          #
-#      Minimum and Maximum Values for Operand Ranges       #
-#                                                          #
-# Operand limits can be set to any integer up to the       #
-# value of 'max_answer'.  If 'allow_negatives' is set to 1 #
-# (yes), either negative or positive values can be used.   #
-# Tuxmath will generate questions for every value in the   #
-# specified range. The maximum must be greater than or     #
-# equal to the corresponding minimum for any questions to  #
-# be generated for that operation.                         #
-############################################################
-
-
-# Addition operands: augend + addend = sum
-min_augend = 0
-max_augend = 12
-min_addend = 0
-max_addend = 12
-
-# Subtraction operands: minuend - subtrahend = difference
-min_minuend = 0
-max_minuend = 12
-min_subtrahend = 0
-max_subtrahend = 12
-
-# Multiplication operands: multiplier * multiplicand = product
-min_multiplier = 0
-max_multiplier = 12
-min_multiplicand = 0
-max_multiplicand = 12
-
-# Division operands: dividend/divisor = quotient
-min_divisor = 0
-max_divisor = 12
-min_quotient = 0
-max_quotient = 12

Added: tuxmath/trunk/data/images/tux/console_bash.png
===================================================================
(Binary files differ)


Property changes on: tuxmath/trunk/data/images/tux/console_bash.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: tuxmath/trunk/data/missions/options
===================================================================
--- tuxmath/trunk/data/missions/options	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/data/missions/options	2006-09-03 16:37:34 UTC (rev 23)
@@ -0,0 +1,216 @@
+############################################################
+#                                                          #
+#                 Tuxmath Config File                      #
+#                                                          #
+############################################################
+
+
+############################################################
+#                                                          #
+#                 General Game Options                     #
+#                                                          #
+# The following options are boolean (true/false) variables #
+# that control various aspects of Tuxmath's behavior.      #
+# The program writes the values to the file as either '0'  #
+# or '1'. However, the program accepts 'n', 'no', 'f', and #
+# 'false' as synonyms for '0', and similarly accepts 'y',  #
+# 'yes', 't', and 'true' as synonyms for '1' (all case-    #
+# insensitive).                                            #
+############################################################
+
+############################################################
+# 'per_user_config' determines whether Tuxmath will look   #
+# in the user's home directory for settings. Default is 1  #
+# (yes). If deselected, the program will ignore the user's #
+# .tuxmath file and use the the global settings in the     #
+# installation-wide config file.                           #
+# This setting cannot be changed by an ordinary user.      #
+############################################################
+per_user_config = 1
+
+# Self-explanatory, default is 1:
+use_sound = 1
+
+# Use either fullscreen at 640x480 resolution or window of that size
+# Default is 1.  Change to 0 if SDL has trouble with fullscreen.
+fullscreen = 1
+
+# Use 640x480 jpg image for background; default is 1.
+use_bkgd = 1
+
+# Program runs as demo; default is 0.
+demo_mode = 0
+
+# Use operator selection from command line; default is 0.
+oper_override = 0
+
+# Display onscreen numeric keypad; default is 0.
+use_keypad = 0
+
+############################################################
+# The remaining settings determine the speed and number    #
+# of comets.  The speed settings are float numbers (mean-  #
+# ing decimals allowed). The comet settings are integers.  #
+############################################################
+
+# Starting comet speed. Default is 1.
+speed = 1.000000
+
+# Speed is multiplied by this factor with each new wave.
+# Default is 1.2
+speedup_factor = 1.200000
+
+# Maximum speed. Default is 10.
+max_speed = 10.000000
+
+# Number of comets for first wave. Default is 2.
+starting_comets = 2
+
+# Comets to add for each successive wave. Default is 2.
+extra_comets_per_wave = 2
+
+# Maximum number of comets. Default is 10.
+max_comets = 10
+
+# Allow speed and number of comets to increase with each
+# wave.  May want to turn this off for smaller kids. Default is 1.
+allow_speedup = 1
+
+# Go back to starting speed and number of comets if player
+# misses a question. Useful for smaller kids. Default is 0.
+slow_after_wrong = 0
+
+############################################################
+#                                                          #
+#                  General Math Options                    #
+#                                                          #
+# If 'play_through_list' selected, Tuxmath will ask each   #
+# question in the defined list. The game ends when no      #
+# questions remain.  Default is 1 (i.e. 'true' or 'yes').  #
+#                                                          #
+# 'question_copies' is the number of times each question   #
+# will be asked. It can be 1 to 10 - Default is 1.         #
+#                                                          #
+# 'repeat_wrongs' tells Tuxmath whether to reinsert        #
+# incorrectly answered questions into the list to be       #
+# asked again. Default is 1 (yes).                         #
+#                                                          #
+# 'copies_repeated_wrongs' gives the number of times an    #
+# incorrectly answered question will reappear. Default     #
+# is 1.                                                    #
+#                                                          #
+# The defaults for these values result in a 'mission'      #
+# for Tux that is accomplished by answering all            #
+# questions correctly with at least one surviving city.    #
+############################################################
+
+play_through_list = 1
+question_copies = 1
+repeat_wrongs = 1
+copies_repeated_wrongs = 1
+
+############################################################
+# 'format_answer_last' (, _first, middle) control the      #
+# generation of questions with the answer in different     #
+# places in the equation.  i.e.:                           #
+#                                                          #
+#    format_answer_last:    2 + 2 = ?                      #
+#    format_answer_first:   ? + 2 = 4                      #
+#    format_answer_middle:  2 + ? = 4                      #
+#                                                          #
+# By default, 'format_answer_first' is enabled and the     #
+# other two formats are disabled.  Note that the options   #
+# are not mutually exclusive - the question list may       #
+# contain questions with different formats.                #
+############################################################
+
+format_answer_last = 1
+format_answer_first = 0
+format_answer_middle = 0
+
+############################################################
+# 'allow_negatives' allows or disallows use of negative    #
+# numbers as both operands and answers.  Default is 0      #
+# (no), which disallows questions like:                    #
+#          2 - 4 = ?                                       #
+# Note: this option must be enabled in order to set the    #
+# operand ranges to include negatives (see below). If it   #
+# is changed from 1 (yes) to 0 (no), any negative          #
+# operand limits will be reset to 0.                       #
+############################################################
+
+allow_negatives = 0
+
+############################################################
+# 'max_answer' is the largest absolute value allowed in    #
+# any value in a question (not only the answer). Default   #
+# is 144. It can be set as high as 999.                    #
+############################################################
+
+max_answer = 144
+
+############################################################
+# 'max_questions' is limit of the length of the question   #
+# list. Default is 5000 - only severe taskmasters will     #
+# need to raise it.                                        #
+############################################################
+
+max_questions = 5000
+
+############################################################
+# If 'randomize' selected, the list will be shuffled       #
+# at the start of the game.  Default is 1 (yes).           #
+############################################################
+
+randomize = 1
+
+############################################################
+#                                                          #
+#                 Math Operations Allowed                  #
+#                                                          #
+# These options enable questions for each of the four math #
+# operations.  All are 1 (yes) by default.                 #
+############################################################
+
+addition_allowed = 1
+subtraction_allowed = 1
+multiplication_allowed = 1
+division_allowed = 1
+
+############################################################
+#                                                          #
+#      Minimum and Maximum Values for Operand Ranges       #
+#                                                          #
+# Operand limits can be set to any integer up to the       #
+# value of 'max_answer'.  If 'allow_negatives' is set to 1 #
+# (yes), either negative or positive values can be used.   #
+# Tuxmath will generate questions for every value in the   #
+# specified range. The maximum must be greater than or     #
+# equal to the corresponding minimum for any questions to  #
+# be generated for that operation.                         #
+############################################################
+
+
+# Addition operands: augend + addend = sum
+min_augend = 0
+max_augend = 12
+min_addend = 0
+max_addend = 12
+
+# Subtraction operands: minuend - subtrahend = difference
+min_minuend = 0
+max_minuend = 12
+min_subtrahend = 0
+max_subtrahend = 12
+
+# Multiplication operands: multiplier * multiplicand = product
+min_multiplier = 0
+max_multiplier = 12
+min_multiplicand = 0
+max_multiplicand = 12
+
+# Division operands: dividend/divisor = quotient
+min_divisor = 0
+max_divisor = 12
+min_quotient = 0
+max_quotient = 12

Deleted: tuxmath/trunk/data/sounds/SIZZLING.WAV
===================================================================
(Binary files differ)

Added: tuxmath/trunk/data/sounds/sizzling.wav
===================================================================
(Binary files differ)


Property changes on: tuxmath/trunk/data/sounds/sizzling.wav
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: tuxmath/trunk/docs/README.txt
===================================================================
--- tuxmath/trunk/docs/README.txt	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/docs/README.txt	2006-09-03 16:37:34 UTC (rev 23)
@@ -53,6 +53,17 @@
     behavior of Tuxmath - SEE BELOW.
 
     The following command-line options can be sent to the program.
+     --optionfile filename - play game based on settings in the named file (see
+                         below for more on tuxmath config files). Tuxmath will
+                         look for a valid config file with a matching name in
+                         the following locations:
+                         	1. current working directory
+				2. as an absolute pathname
+				3. in the missions directory with tuxmath's 
+                                   other data files.
+				4. in the user's tuxmath options directory
+                                   (e.g. /home/laura/.tuxmath/filename
+                                5. in the user's home directory.
 
      --playthroughlist - Game consists of working through a list of questions
       -r                 generated based on the selected options (or defaults).
@@ -253,7 +264,9 @@
 
   1. The program now reads and writes the settings to disk in a human-readable
   fashion, where they can be modified with a text editor. The file is created
-  in the user's home directory and is called ".tuxmath".  The file contains
+  in the user's home directory within a directory called ".tuxmath" and is 
+  simply called "options". As an example, a user "laura" on a Unix/Linux system
+  would find this at /home/laura/.tuxmath/options.  The file contains
   extensive comments describing all settings. By editing and saving this file,
   very extensive control over the program is supported, particularly with
   respect to generation of math questions. There really is no need to use

Modified: tuxmath/trunk/docs/TODO.txt
===================================================================
--- tuxmath/trunk/docs/TODO.txt	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/docs/TODO.txt	2006-09-03 16:37:34 UTC (rev 23)
@@ -1,6 +1,6 @@
 TODO.txt for "tuxmath"
 
-August 11, 2006
+September 03, 2006
 
 Build:
   * Fix certain file permissions issues when packaged as rpm.
@@ -23,6 +23,7 @@
   * More entertaining "victory" and "defeat" screens
   * Add option to review missed questions to end-of-game screens
   * Add option to play next game using missed questions from current game
+  * Lesson series of progressively harder "missions".
   * End-of-level calculations, bonuses and animations
   * Add special targets that restore shields or rebuild cities.
 
@@ -31,8 +32,7 @@
   * Finish INSTALL.txt
 
 Options:
-  * Make all of settings for MathCards backend settable at run time rather than just
-    at compile time - will require major overall of Options screen(s).
+  * Major overall of in-game Options system needed.
   * Display numbers instead of formulas if no operators are selected: "typing tutor" mode.
   * Save options.
   * Admin options screen / files

Modified: tuxmath/trunk/docs/changelog
===================================================================
--- tuxmath/trunk/docs/changelog	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/docs/changelog	2006-09-03 16:37:34 UTC (rev 23)
@@ -1,5 +1,33 @@
 changelog for "tuxmath"
 
+2006.Sep.03 (https://svn.tux4kids.net/tuxmath/ - revision 21)
+  Version 0.93
+
+  Code:
+    * config.h/c now called fileops.h/c and all code related to
+      file operations contained here (config files as well as
+      loading of image and sound data files). Both images.h and 
+      sound.h have been incorporated into fileops.h. Idea is to
+      have only one place for OS-specific code, if possible.
+    * setup() split into several smaller functions.
+    * If a sound file cannot be loaded, the program continues 
+      without sound rather than exiting. Bug fixed that caused 
+      this to turn off sound for subsequent games (thanks Tim Holy).
+    * All global data now extern'd in same place in tuxmath.h.
+  Setup:
+    * Better handling of config files.  Program now creates 
+      .tuxmath directory in user's home, config file is in this
+      directory and is called "options".  Global config file
+      located in new "missions" folder in program data (this 
+      will change to something under /etc or /usr/local/etc when
+      I have studied FHS and makefiles more).
+    * Added "--optionfile filename" command-line arg (thanks Yves
+      Combe for suggestion) - program will look for 'filename' in
+      several locations including as absolute path.
+  Docs:
+    * Updates to changelog and TODO.txt; update to usage();
+      David Bruce <dbruce at tampabay.rr.com>
+
 2006.Aug.22 (https://svn.tux4kids.net/tuxmath/ - revision 20)
   Version 0.92
 

Deleted: tuxmath/trunk/src/config.c
===================================================================
--- tuxmath/trunk/src/config.c	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/config.c	2006-09-03 16:37:34 UTC (rev 23)
@@ -1,572 +0,0 @@
-/*
-*  C Implementation: config.c
-*
-* (Note: this code was made possible by studying the file prefs.c in gtkpod:
-*  URL: http://www.gtkpod.org/
-*  URL: http://gtkpod.sourceforge.net/
-*  Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>.
-*  Licensed under GNU GPL v2.
-*  This code is a nearly complete rewrite but I would like to express my thanks.)
-*
-*
-* Description: This file contains functions to read and write config files.
-* The config file contains name-value pairs, one pair per line, to control
-* settings for the behavior of Tuxmath.
-*
-
-* 
-* Author: David Bruce <dbruce at tampabay.rr.com>, (C) 2006
-*
-* Copyright: See COPYING file that comes with this distribution (briefly, GNU GPL)
-*
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "config.h"
-#include "tuxmath.h"
-#include "setup.h"
-#include "mathcards.h"
-
-static int str_to_bool(char* val);
-
-int read_config_file(FILE *fp, int file_type)
-{
-  char buf[PATH_MAX];
-  char *parameter, *param_begin, *param_end, *value, *value_end;
-
-  #ifdef TUXMATH_DEBUG
-  printf("\nEntering read_config_file()\n");
-  #endif
-
-  /* get out if file pointer invalid: */
-  if(!fp)
-  {
-    #ifdef TUXMATH_DEBUG
-    printf("config file pointer invalid!\n");
-    printf("Leaving read_config_file()\n");
-    #endif
-
-    fprintf(stderr, "config file pointer invalid!\n");
-    return 0;
-  }
-
-  /* make sure we start at beginning: */
-  rewind(fp);
-
-  /* read in a line at a time: */
-  while (fgets (buf, PATH_MAX, fp))
-  { 
-    #ifdef TUXMATH_DEBUG
-    printf("Beginning fgets() loop\n");
-    #endif
-    /* "parameter" and "value" will contain the non-whitespace chars */
-    /* before and after the '=' sign, respectively.  e.g.:           */
-    /*                                                               */
-    /* fullscreen = 0;                                               */
-    /* parameter is "fullscreen"                                     */
-    /* value is '0'                                                  */
-    /*                                                               */
-
-    /* ignore comment lines */
-    if ((buf[0] == ';') || (buf[0] == '#'))
-    {
-      #ifdef TUXMATH_DEBUG
-      printf("Skipping comment line\n");
-      #endif
-      continue;
-    }
- 
-    /* First find parameter string and make a copy: */
-    /* start at beginning: */
-    param_begin = buf;
-    /* skip leading whitespace */
-    while (isspace(*param_begin))
-    {
-      ++param_begin;
-    }
-    /* now go from here to end of string, stopping at either */
-    /* whitespace or '=':   */
-    param_end = param_begin;
-    while (!isspace(*param_end)
-         && ('=' != (*param_end)))
-    {
-      ++param_end;
-    }
-
-    /* copy chars from start of non-whitespace up to '=': */
-    parameter = strndup(param_begin, (param_end - param_begin));
-
-    /* Now get value string: */
-    /* set value to first '=' in line: */
-    value = strchr(buf, '=');
-
-    if (!value || (value == buf))
-    {
-      #ifdef TUXMATH_DEBUG
-      fprintf(stderr, "Error while reading prefs - line with no '='!\n");
-      #endif
-
-      continue;
-    }
-
-    /* move past '=' sign: */
-    ++value;
-
-    /* skip leading whitespace */
-    while (isspace(*value))
-    { 
-      ++value;
-    }
-
-    value_end = value;
-
-    /* remove trailing whitespace or newline */
-    while (!isspace(*value_end)
-         && (0x0a != (*value_end))
-         && (*value_end))
-    {
-      ++value_end;
-    }
-    /* terminate string here: */
-    *value_end = 0;
-
-    #ifdef TUXMATH_DEBUG
-    printf("parameter = '%s'\t, length = %d\n", parameter, strlen(parameter));
-    printf("value = '%s'\t, length = %d\t, atoi() = %d\n", value, strlen(value), atoi(value));
-    #endif
-
-    /* Now ready to handle each name/value pair! */
-
-    /* Set general game_options struct (see tuxmath.h): */ 
-    /* FIXME should have error checking to make sure game_options->* */
-    /* settings are sane values (MC_Set*() functions already do this). */
-    if(0 == strcasecmp(parameter, "per_user_config")
-       && file_type == GLOBAL_CONFIG_FILE) 
-    /* Only let administrator change this setting */
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        game_options->per_user_config = v;
-    }
-
-    if(0 == strcasecmp(parameter, "use_sound"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        game_options->use_sound = v;
-    }
-
-    else if(0 == strcasecmp(parameter, "fullscreen"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        game_options->fullscreen = v;
-    }
-
-    else if(0 == strcasecmp(parameter, "use_bkgd"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        game_options->use_bkgd = v;
-    }
-
-    else if(0 == strcasecmp(parameter, "demo_mode"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        game_options->demo_mode = v;
-    }
-
-    else if(0 == strcasecmp(parameter, "oper_override"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        game_options->oper_override = v;
-    }
-
-    else if(0 == strcasecmp(parameter, "use_keypad"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        game_options->use_keypad = v;
-    }
-
-    else if(0 == strcasecmp(parameter, "speed"))
-    {
-      game_options->speed = atof(value);
-    }
-
-    else if(0 == strcasecmp(parameter, "allow_speedup"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        game_options->allow_speedup = v;
-    }
-
-    else if(0 == strcasecmp(parameter, "speedup_factor"))
-    {
-      game_options->speedup_factor = atof(value);
-    }
-
-    else if(0 == strcasecmp(parameter, "max_speed"))
-    {
-      game_options->max_speed = atof(value);
-    }
-
-    else if(0 == strcasecmp(parameter, "slow_after_wrong"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        game_options->slow_after_wrong = v;
-    }
-
-    else if(0 == strcasecmp(parameter, "starting_comets"))
-    {
-      game_options->starting_comets = atoi(value);
-    }
-
-    else if(0 == strcasecmp(parameter, "extra_comets_per_wave"))
-    {
-      game_options->extra_comets_per_wave = atoi(value);
-    }
-
-    else if(0 == strcasecmp(parameter, "max_comets"))
-    {
-      game_options->max_comets = atoi(value);
-    }
-
-
-    /* Begin setting of math question options (see mathcards.h):   */ 
-
-    /* General math options */
-
-    else if(0 == strcasecmp(parameter, "allow_negatives"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetAllowNegatives(v);
-    }
-
-    else if(0 == strcasecmp(parameter, "max_answer"))
-    {
-      MC_SetMaxAnswer(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "max_questions"))
-    {
-      MC_SetMaxQuestions(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "play_through_list"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetPlayThroughList(v);
-    }
-
-    else if(0 == strcasecmp(parameter, "repeat_wrongs"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1) 
-        MC_SetRepeatWrongs(v);
-    }
-
-    else if(0 == strcasecmp(parameter, "copies_repeated_wrongs"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetCopiesRepeatedWrongs(v);
-    }
-
-    else if(0 == strcasecmp(parameter, "format_answer_last"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetFormatAnswerLast(v);
-    }
-
-    else if(0 == strcasecmp(parameter, "format_answer_first"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetFormatAnswerFirst(v);
-    }
-
-    else if(0 == strcasecmp(parameter, "format_answer_middle"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetFormatAnswerMiddle(v);
-    }
-
-    else if(0 == strcasecmp(parameter, "format_answer_last"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetFormatAnswerLast(v);
-    }
-
-    else if(0 == strcasecmp(parameter, "question_copies"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetQuestionCopies(v);
-    }
-
-    else if(0 == strcasecmp(parameter, "randomize"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetRandomize(v);
-    }
-
-
-    /* Set the allowed math operations: */
-
-
-    else if(0 == strcasecmp(parameter, "addition_allowed"))
-    {
-      MC_SetAddAllowed(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "subtraction_allowed"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetSubAllowed(v);
-    }
-
-    else if(0 == strcasecmp(parameter, "multiplication_allowed"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetMultAllowed(v);
-    }
-
-    else if(0 == strcasecmp(parameter, "division_allowed"))
-    {
-      int v = str_to_bool(value);
-      if (v != -1)
-        MC_SetDivAllowed(v);
-    }
-
-
-    /* Set min and max for addition: */
-
-
-    else if(0 == strcasecmp(parameter, "min_augend"))
-    {
-      MC_SetAddMinAugend(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "max_augend"))
-    {
-      MC_SetAddMaxAugend(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "min_addend"))
-    {
-      MC_SetAddMinAddend(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "max_addend"))
-    {
-      MC_SetAddMaxAddend(atoi(value));
-    }
-
-
-    /* Set min and max for subtraction: */
-
-
-    else if(0 == strcasecmp(parameter, "min_minuend"))
-    {
-      MC_SetSubMinMinuend(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "max_minuend"))
-    {
-      MC_SetSubMaxMinuend(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "min_subtrahend"))
-    {
-      MC_SetSubMinSubtrahend(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "max_subtrahend"))
-    {
-      MC_SetSubMaxSubtrahend(atoi(value));
-    }
-
-
-    /* Set min and max for multiplication: */
-
-
-    else if(0 == strcasecmp(parameter, "min_multiplier"))
-    {
-      MC_SetMultMinMultiplier(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "max_multiplier"))
-    {
-      MC_SetMultMaxMultiplier(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "min_multiplicand"))
-    {
-      MC_SetMultMinMultiplicand(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "max_multiplicand"))
-    {
-      MC_SetMultMaxMultiplicand(atoi(value));
-    }
-
-
-    /* Set min and max for division: */
-
-
-    else if(0 == strcasecmp(parameter, "min_divisor"))
-    {
-      MC_SetDivMinDivisor(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "min_quotient"))
-    {
-      MC_SetDivMinQuotient(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "max_divisor"))
-    {
-      MC_SetDivMaxDivisor(atoi(value));
-    }
-
-    else if(0 == strcasecmp(parameter, "max_quotient"))
-    {
-      MC_SetDivMaxQuotient(atoi(value));
-    }
-
-
-
-    else
-    {   
-      #ifdef TUXMATH_DEBUG
-      printf("parameter not recognized: %s\n", parameter);
-      #endif    
-
-/* All leftover options will be stored into the prefs
-		 setting hash (generic options -- should have had this
-		 idea much sooner... */
-// 	      int skip = 0;
-// 	      if (1)
-// 	      {line
-// 		  if(arg_comp (line, "itdb_", NULL) == 0)
-// 		  {   /* set incorrectly in 0.90 -- delete */
-// 		      skip = 1;
-// 		  }
-// 	      }
-// 	      if (!skip)
-// 		  prefs_set_string_value (line, arg);
-    }
-    free(parameter);
-  }
-  #ifdef TUXMATH_DEBUG
-  printf("\nAfter file read in:\n");
-  print_game_options(stdout, 0);
-  MC_PrintMathOptions(stdout, 0);
-  printf("Leaving read_config_file()\n");
-  #endif
-  return 1;
-}
-
-
-
-
-/* this function writes the settings for all game options to a */
-/* human-readable file.                                        */
-/* TODO write help on each setting into file.                  */
-
-int write_config_file(FILE *fp)
-{
-  #ifdef TUXMATH_DEBUG
-  printf("\nEntering write_config_file()\n");
-  #endif
-
-  /* get out if file pointer null */
-  if(!fp)
-  {
-    fprintf (stderr, "write_config_file() - file pointer invalid/n");
-
-    #ifdef TUXMATH_DEBUG
-    printf("Leaving write_config_file()\n");
-    #endif
-
-    return 0;
-  }
-
-  fprintf(fp, 
-          "############################################################\n"
-          "#                                                          #\n"
-          "#                 Tuxmath Config File                      #\n"
-          "#                                                          #\n"
-          "############################################################\n"
-          "\n"
-  );
-
-  /* print general game options (passing '1' as second arg causes */
-  /* "help" info for each option to be written to file as comments) */
-  print_game_options(fp, 1);
-  /* print options pertaining to math questions from MathCards: */
-  MC_PrintMathOptions(fp, 1);
-
-  #ifdef TUXMATH_DEBUG
-  printf("Leaving write_config_file()\n");
-  #endif
-
-  return 1;
-}
-
-
-
-/* Allows use of "true", "YES", T, etc. in text file for boolean values. */
-/* Return value of -1 means value string is not recognized.              */
-static int str_to_bool(char* val)
-{
-  char* ptr;
-
-  /* Check for recognized boolean strings: */
-  if ((0 == strcasecmp(val, "true"))
-    ||(0 == strcasecmp(val, "t"))
-    ||(0 == strcasecmp(val, "yes"))
-    ||(0 == strcasecmp(val, "y")))
-  {
-    return 1;
-  }
-
-  if ((0 == strcasecmp(val, "false"))
-    ||(0 == strcasecmp(val, "f"))
-    ||(0 == strcasecmp(val, "no"))
-    ||(0 == strcasecmp(val, "n")))
-  {
-    return 0;
-  }  
-
-  /* Return -1 if any chars are non-digits: */
-  ptr = val;
-  while (*ptr)
-  {
-    if (!isdigit(*ptr))
-      return -1;
-    ptr++;
-  }
-
-  /* If we get to here, val should be an integer. */
-  if (atoi(val))
-    return 1;
-  else
-    return 0;
-}

Deleted: tuxmath/trunk/src/config.h
===================================================================
--- tuxmath/trunk/src/config.h	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/config.h	2006-09-03 16:37:34 UTC (rev 23)
@@ -1,26 +0,0 @@
-/*
-C Interface: config.h
-
-Description: 
-
-
-Author: David Bruce <dbruce at tampabay.rr.com>, (C) 2006
-
-Copyright: See COPYING file that comes with this distribution (briefly, GNU GPL)
-*/
-
-#ifndef CONFIG_H
-#define CONFIG_H
-
-#define PATH_MAX 4096
-
-enum {
-  USER_CONFIG_FILE,
-  GLOBAL_CONFIG_FILE
-};
-
-/* FIXME these should return errors if they fail. */
-int read_config_file(FILE* fp, int file_type);
-int write_config_file(FILE* fp);
-
-#endif

Modified: tuxmath/trunk/src/credits.c
===================================================================
--- tuxmath/trunk/src/credits.c	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/credits.c	2006-09-03 16:37:34 UTC (rev 23)
@@ -20,11 +20,13 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
 #include <SDL.h>
+
+#include "tuxmath.h"
 #include "options.h"
-#include "images.h"
+#include "fileops.h"
 #include "setup.h"
-#include "sounds.h"
 
 
 char * credit_text[] = {
@@ -45,6 +47,7 @@
   "MICHAEL BEHRISCH",
   "DONNY VISZNEKI",
   "YVES COMBE",
+  "DAVID YODER",
   "DAVID BRUCE",
   "",
   "-LEAD ARTIST",

Copied: tuxmath/trunk/src/fileops.c (from rev 21, tuxmath/trunk/src/config.c)
===================================================================
--- tuxmath/trunk/src/config.c	2006-08-13 19:53:36 UTC (rev 21)
+++ tuxmath/trunk/src/fileops.c	2006-09-03 16:37:34 UTC (rev 23)
@@ -0,0 +1,1324 @@
+/*
+*  C Implementation: fileops.c
+*
+* (Note: read_config_file() was made possible by studying the file prefs.c in gtkpod:
+*  URL: http://www.gtkpod.org/
+*  URL: http://gtkpod.sourceforge.net/
+*  Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>.
+*  Licensed under GNU GPL v2.
+*  This code is a nearly complete rewrite but I would like to express my thanks.)
+*
+*
+* Description: File operations - together, fileops.h and fileops.c contain 
+* all code involving disk operations.  The intention is to make it easier to
+* port tuxmath to other operating systems, as code to read and write as 
+* well as paths and file locations may be more OS-dependent.
+*
+* This file contains functions to read and write config files.
+* The config file contains name-value pairs, one pair per line, to control
+* settings for the behavior of Tuxmath.
+*
+* Code for loading program data from disk is now also found here.
+* 
+* Author: David Bruce <dbruce at tampabay.rr.com>, (C) 2006
+*
+* Copyright: See COPYING file that comes with this distribution (briefly, GNU GPL)
+*
+*/
+
+/* Standard C includes: */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+/* OS includes - NOTE: these may not be very portable */
+#include <dirent.h>  /* for opendir() */
+#include <sys/stat.h>/* for mkdir() */
+#include <unistd.h>  /* for getcwd() */
+
+/* SDL includes: */
+#include <SDL.h>
+
+#ifndef NOSOUND
+#include <SDL_mixer.h>
+#endif
+
+#include <SDL_image.h>
+
+
+/* Tuxmath includes: */
+#include "tuxmath.h"
+#include "fileops.h"
+#include "setup.h"
+#include "mathcards.h"
+
+
+
+/* local function prototypes: */
+static int str_to_bool(char* val);
+
+
+/* FIXME should have better file path (/etc or /usr/local/etc) and name */
+int read_global_config_file(void)
+{
+  FILE* fp;
+  fp = fopen(DATA_PREFIX "/missions/options", "r");
+  if (fp)
+  {
+    read_config_file(fp, GLOBAL_CONFIG_FILE);
+    fclose(fp);
+    fp = NULL;
+    return 1;
+  }
+  else
+    return 0;
+}
+
+/* Attempts to read in user's config file - on a *nix system, */
+/* something like: /home/laura/.tuxmath/options               */
+int read_user_config_file(void)
+{
+  FILE* fp;
+  char opt_path[PATH_MAX];
+
+  /* find $HOME and tack on file name: */
+  strcpy(opt_path, getenv("HOME"));
+  strcat(opt_path, "/.tuxmath/options");
+
+  #ifdef TUXMATH_DEBUG
+  printf("\nIn setup() full path to config file is: = %s\n", opt_path);
+  #endif
+
+  fp = fopen(opt_path, "r");
+  if (fp) /* file exists */
+  {
+    read_config_file(fp, USER_CONFIG_FILE);
+    fclose(fp);
+    fp = NULL;
+    return 1;
+  }
+  else  /* could not open config file: */
+  {
+    return 0;
+  }
+}
+
+/* Looks for matching file in various locations:        */
+/*   1. Current working directory                       */
+/*   2. As an absolute path filename                    */
+/*   3. In tuxmath's missions (i.e. lessons) directory. */
+/*   4. In user's own .tuxmath directory                */
+int read_named_config_file(char* filename)
+{
+  FILE* fp;
+  char opt_path[PATH_MAX];
+
+  #ifdef TUXMATH_DEBUG
+  printf("\nIn read_named_config_file() filename is: = %s\n", filename);
+  #endif
+
+
+  /* First look in current working directory:  */
+  getcwd(opt_path, PATH_MAX); /* get current working directory */
+  /* add separating '/' unless cwd is '/' : */
+  if (0 != strcmp("/", opt_path)) 
+  {
+    strcat(opt_path, "/");
+  }
+  strcat(opt_path, filename); /* tack on filename              */
+
+  #ifdef TUXMATH_DEBUG
+
+
+  printf("\nIn read_named_config_file() checking for %s (cwd)\n", opt_path);
+  #endif
+
+  fp = fopen(opt_path, "r");  /* try to open file */
+  if (fp) /* file exists */
+  {
+    #ifdef TUXMATH_DEBUG
+    printf("\nFound %s\n", opt_path);
+    #endif
+
+    if (read_config_file(fp, USER_CONFIG_FILE))
+    {
+      fclose(fp);
+      fp = NULL;
+      return 1;
+    }
+    else /* try matching filename elsewhere */
+    {
+      fclose(fp);
+      fp = NULL;
+    }
+  }
+
+
+  /* Next try matching filename as absolute:      */
+  /* Supply leading '/' if not already there:   */
+  if (0 == strncmp ("/", filename, 1))
+  { 
+    strcpy(opt_path, filename);
+  }
+  else
+  {
+    strcpy(opt_path, "/");
+    strcat(opt_path, filename);
+  }
+
+  #ifdef TUXMATH_DEBUG
+  printf("\nIn read_named_config_file() checking for %s (abs)\n", opt_path);
+  #endif
+
+  fp = fopen(opt_path, "r");
+  if (fp) /* file exists */
+  {
+    #ifdef TUXMATH_DEBUG
+    printf("\nFound %s\n", opt_path);
+    #endif
+
+    if (read_config_file(fp, USER_CONFIG_FILE))
+    {
+      fclose(fp);
+      fp = NULL;
+      return 1;
+    }
+    else /* keep trying to match filename elsewhere */
+    {
+      fclose(fp);
+      fp = NULL;
+    }
+  }
+
+
+  /* Next look in missions folder (for prepared "lessons curriculum"):      */
+  strcpy(opt_path, DATA_PREFIX);
+  strcat(opt_path, "missions/");
+  strcat(opt_path, filename);
+
+  #ifdef TUXMATH_DEBUG
+  printf("\nIn read_named_config_file() checking for %s (missions)\n", opt_path);
+  #endif
+
+  fp = fopen(opt_path, "r");
+  if (fp) /* file exists */
+  {
+    #ifdef TUXMATH_DEBUG
+    printf("\nFound %s\n", opt_path);
+    #endif
+
+    if (read_config_file(fp, USER_CONFIG_FILE))
+    {
+      fclose(fp);
+      fp = NULL;
+      return 1;
+    }
+    else /* keep trying to match filename elsewhere */
+    {
+      fclose(fp);
+      fp = NULL;
+    }
+  }  
+
+
+  /* Look in user's hidden .tuxmath directory  */
+  /* find $HOME and tack on file name: */
+  strcpy(opt_path, getenv("HOME"));
+  strcat(opt_path, "/.tuxmath/");
+  strcat(opt_path, filename);
+
+  #ifdef TUXMATH_DEBUG
+  printf("\nIn read_named_config_file() checking for %s (.tuxmath)\n", opt_path);
+  #endif
+
+  fp = fopen(opt_path, "r");
+  if (fp) /* file exists */
+  {
+    #ifdef TUXMATH_DEBUG
+    printf("\nFound %s\n", opt_path);
+    #endif
+
+    if (read_config_file(fp, USER_CONFIG_FILE))
+    {
+      fclose(fp);
+      fp = NULL;
+      return 1;
+    }
+    else /* keep trying to match filename elsewhere */
+    {
+      fclose(fp);
+      fp = NULL;
+    }
+  }
+
+
+  /* Look in user's home directory  */
+  /* find $HOME and tack on file name: */
+  strcpy(opt_path, getenv("HOME"));
+  strcat(opt_path, "/");
+  strcat(opt_path, filename);
+
+  #ifdef TUXMATH_DEBUG
+  printf("\nIn read_named_config_file() checking for %s (home)\n", opt_path);
+  #endif
+
+  fp = fopen(opt_path, "r");
+  if (fp) /* file exists */
+  {
+    #ifdef TUXMATH_DEBUG
+    printf("\nFound %s\n", opt_path);
+    #endif
+
+    if (read_config_file(fp, USER_CONFIG_FILE))
+    {
+      fclose(fp);
+      fp = NULL;
+      return 1;
+    }
+    else /* keep trying to match filename elsewhere */
+    {
+      fclose(fp);
+      fp = NULL;
+    }
+  }
+
+  /* Could not find file (or read it if found) in any location: */
+  #ifdef TUXMATH_DEBUG
+  printf("\nread_named_config_file() could not find/read: %s\n", opt_path);
+  #endif
+  return 0;
+}
+
+
+
+
+
+
+/* This function does the heavy lifting, so to speak:     */
+/* Note that file_type simply indicates whether or not    */
+/* to change admin-only settings such as per_user_config. */
+/* FIXME return value only tells whether file pointer valid */
+int read_config_file(FILE *fp, int file_type)
+{
+  char buf[PATH_MAX];
+  char *parameter, *param_begin, *param_end, *value, *value_end;
+
+  #ifdef TUXMATH_DEBUG
+  printf("\nEntering read_config_file()\n");
+  #endif
+
+  /* get out if file pointer invalid: */
+  if(!fp)
+  {
+    #ifdef TUXMATH_DEBUG
+    printf("config file pointer invalid!\n");
+    printf("Leaving read_config_file()\n");
+    #endif
+
+    fprintf(stderr, "config file pointer invalid!\n");
+    return 0;
+  }
+
+  /* make sure we start at beginning: */
+  rewind(fp);
+
+  /* read in a line at a time: */
+  while (fgets (buf, PATH_MAX, fp))
+  { 
+    #ifdef TUXMATH_DEBUG
+    //printf("Beginning fgets() loop\n");
+    #endif
+    /* "parameter" and "value" will contain the non-whitespace chars */
+    /* before and after the '=' sign, respectively.  e.g.:           */
+    /*                                                               */
+    /* fullscreen = 0;                                               */
+    /* parameter is "fullscreen"                                     */
+    /* value is '0'                                                  */
+    /*                                                               */
+
+    /* ignore comment lines */
+    if ((buf[0] == ';') || (buf[0] == '#'))
+    {
+      #ifdef TUXMATH_DEBUG
+      //printf("Skipping comment line\n");
+      #endif
+      continue;
+    }
+ 
+    /* First find parameter string and make a copy: */
+    /* start at beginning: */
+    param_begin = buf;
+    /* skip leading whitespace */
+    while (isspace(*param_begin))
+    {
+      ++param_begin;
+    }
+    /* now go from here to end of string, stopping at either */
+    /* whitespace or '=':   */
+    param_end = param_begin;
+    while (!isspace(*param_end)
+         && ('=' != (*param_end)))
+    {
+      ++param_end;
+    }
+
+    /* copy chars from start of non-whitespace up to '=': */
+    parameter = strndup(param_begin, (param_end - param_begin));
+
+    /* Now get value string: */
+    /* set value to first '=' in line: */
+    value = strchr(buf, '=');
+
+    if (!value || (value == buf))
+    {
+      #ifdef TUXMATH_DEBUG
+      //fprintf(stderr, "Error while reading prefs - line with no '='!\n");
+      #endif
+
+      continue;
+    }
+
+    /* move past '=' sign: */
+    ++value;
+
+    /* skip leading whitespace */
+    while (isspace(*value))
+    { 
+      ++value;
+    }
+
+    value_end = value;
+
+    /* remove trailing whitespace or newline */
+    while (!isspace(*value_end)
+         && (0x0a != (*value_end))
+         && (*value_end))
+    {
+      ++value_end;
+    }
+    /* terminate string here: */
+    *value_end = 0;
+
+    #ifdef TUXMATH_DEBUG
+    printf("parameter = '%s'\t, length = %d\n", parameter, strlen(parameter));
+    printf("value = '%s'\t, length = %d\t, atoi() = %d\n", value, strlen(value), atoi(value));
+    #endif
+
+    /* Now ready to handle each name/value pair! */
+
+    /* Set general game_options struct (see tuxmath.h): */ 
+    /* FIXME should have error checking to make sure game_options->* */
+    /* settings are sane values (MC_Set*() functions already do this). */
+    if(0 == strcasecmp(parameter, "per_user_config")
+       && file_type == GLOBAL_CONFIG_FILE) 
+    /* Only let administrator change this setting */
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        game_options->per_user_config = v;
+    }
+
+    if(0 == strcasecmp(parameter, "use_sound"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        game_options->use_sound = v;
+    }
+
+    else if(0 == strcasecmp(parameter, "fullscreen"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        game_options->fullscreen = v;
+    }
+
+    else if(0 == strcasecmp(parameter, "use_bkgd"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        game_options->use_bkgd = v;
+    }
+
+    else if(0 == strcasecmp(parameter, "demo_mode"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        game_options->demo_mode = v;
+    }
+
+    else if(0 == strcasecmp(parameter, "oper_override"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        game_options->oper_override = v;
+    }
+
+    else if(0 == strcasecmp(parameter, "use_keypad"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        game_options->use_keypad = v;
+    }
+
+    else if(0 == strcasecmp(parameter, "speed"))
+    {
+      game_options->speed = atof(value);
+    }
+
+    else if(0 == strcasecmp(parameter, "allow_speedup"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        game_options->allow_speedup = v;
+    }
+
+    else if(0 == strcasecmp(parameter, "speedup_factor"))
+    {
+      game_options->speedup_factor = atof(value);
+    }
+
+    else if(0 == strcasecmp(parameter, "max_speed"))
+    {
+      game_options->max_speed = atof(value);
+    }
+
+    else if(0 == strcasecmp(parameter, "slow_after_wrong"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        game_options->slow_after_wrong = v;
+    }
+
+    else if(0 == strcasecmp(parameter, "starting_comets"))
+    {
+      game_options->starting_comets = atoi(value);
+    }
+
+    else if(0 == strcasecmp(parameter, "extra_comets_per_wave"))
+    {
+      game_options->extra_comets_per_wave = atoi(value);
+    }
+
+    else if(0 == strcasecmp(parameter, "max_comets"))
+    {
+      game_options->max_comets = atoi(value);
+    }
+
+
+    /* Begin setting of math question options (see mathcards.h):   */ 
+
+    /* General math options */
+
+    else if(0 == strcasecmp(parameter, "allow_negatives"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetAllowNegatives(v);
+    }
+
+    else if(0 == strcasecmp(parameter, "max_answer"))
+    {
+      MC_SetMaxAnswer(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "max_questions"))
+    {
+      MC_SetMaxQuestions(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "play_through_list"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetPlayThroughList(v);
+    }
+
+    else if(0 == strcasecmp(parameter, "repeat_wrongs"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1) 
+        MC_SetRepeatWrongs(v);
+    }
+
+    else if(0 == strcasecmp(parameter, "copies_repeated_wrongs"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetCopiesRepeatedWrongs(v);
+    }
+
+    else if(0 == strcasecmp(parameter, "format_answer_last"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetFormatAnswerLast(v);
+    }
+
+    else if(0 == strcasecmp(parameter, "format_answer_first"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetFormatAnswerFirst(v);
+    }
+
+    else if(0 == strcasecmp(parameter, "format_answer_middle"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetFormatAnswerMiddle(v);
+    }
+
+    else if(0 == strcasecmp(parameter, "format_answer_last"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetFormatAnswerLast(v);
+    }
+
+    else if(0 == strcasecmp(parameter, "question_copies"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetQuestionCopies(v);
+    }
+
+    else if(0 == strcasecmp(parameter, "randomize"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetRandomize(v);
+    }
+
+
+    /* Set the allowed math operations: */
+
+
+    else if(0 == strcasecmp(parameter, "addition_allowed"))
+    {
+      MC_SetAddAllowed(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "subtraction_allowed"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetSubAllowed(v);
+    }
+
+    else if(0 == strcasecmp(parameter, "multiplication_allowed"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetMultAllowed(v);
+    }
+
+    else if(0 == strcasecmp(parameter, "division_allowed"))
+    {
+      int v = str_to_bool(value);
+      if (v != -1)
+        MC_SetDivAllowed(v);
+    }
+
+
+    /* Set min and max for addition: */
+
+
+    else if(0 == strcasecmp(parameter, "min_augend"))
+    {
+      MC_SetAddMinAugend(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "max_augend"))
+    {
+      MC_SetAddMaxAugend(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "min_addend"))
+    {
+      MC_SetAddMinAddend(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "max_addend"))
+    {
+      MC_SetAddMaxAddend(atoi(value));
+    }
+
+
+    /* Set min and max for subtraction: */
+
+
+    else if(0 == strcasecmp(parameter, "min_minuend"))
+    {
+      MC_SetSubMinMinuend(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "max_minuend"))
+    {
+      MC_SetSubMaxMinuend(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "min_subtrahend"))
+    {
+      MC_SetSubMinSubtrahend(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "max_subtrahend"))
+    {
+      MC_SetSubMaxSubtrahend(atoi(value));
+    }
+
+
+    /* Set min and max for multiplication: */
+
+
+    else if(0 == strcasecmp(parameter, "min_multiplier"))
+    {
+      MC_SetMultMinMultiplier(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "max_multiplier"))
+    {
+      MC_SetMultMaxMultiplier(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "min_multiplicand"))
+    {
+      MC_SetMultMinMultiplicand(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "max_multiplicand"))
+    {
+      MC_SetMultMaxMultiplicand(atoi(value));
+    }
+
+
+    /* Set min and max for division: */
+
+
+    else if(0 == strcasecmp(parameter, "min_divisor"))
+    {
+      MC_SetDivMinDivisor(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "min_quotient"))
+    {
+      MC_SetDivMinQuotient(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "max_divisor"))
+    {
+      MC_SetDivMaxDivisor(atoi(value));
+    }
+
+    else if(0 == strcasecmp(parameter, "max_quotient"))
+    {
+      MC_SetDivMaxQuotient(atoi(value));
+    }
+
+    else
+    {   
+      #ifdef TUXMATH_DEBUG
+      printf("parameter not recognized: %s\n", parameter);
+      #endif    
+    }
+    free(parameter);
+  }
+
+  #ifdef TUXMATH_DEBUG
+  printf("\nAfter file read in:\n");
+  print_game_options(stdout, 0);
+  MC_PrintMathOptions(stdout, 0);
+  printf("Leaving read_config_file()\n");
+  #endif
+
+  return 1;
+}
+
+
+
+int write_user_config_file(void)
+{
+  char opt_path[PATH_MAX];
+  FILE* fp;
+  DIR* dir_ptr;
+
+  /* find $HOME */
+  strcpy(opt_path, getenv("HOME"));
+
+  #ifdef TUXMATH_DEBUG
+  printf("\nIn write_user_config_file() home directory is: = %s\n", opt_path);
+  #endif
+
+  /* add rest of path to user's tuxmath dir: */
+  strcat(opt_path, "/.tuxmath");
+
+  #ifdef TUXMATH_DEBUG
+  printf("\nIn write_user_config_file() tuxmath dir is: = %s\n", opt_path);
+  #endif
+
+  /* find out if directory exists - if not, create it: */
+  dir_ptr = opendir(opt_path);
+  if (dir_ptr)  /* don't leave DIR* open if it was already there */
+  {
+    #ifdef TUXMATH_DEBUG
+    printf("\nIn write_user_config_file() tuxmath dir opened OK\n");
+    #endif
+
+    closedir(dir_ptr);
+  }
+  else /* need to create tuxmath config directory: */
+  {
+    int status;
+
+    /* if user's home has a _file_ named .tuxmath (as from previous version */
+    /* of program), need to get rid of it or directory creation will fail:  */
+    fp = fopen(opt_path, "r");
+    if (fp)
+    {
+      #ifdef TUXMATH_DEBUG
+      printf("\nIn write_user_config_file() - removing old .tuxmath file\n");
+      #endif
+
+      fclose(fp);
+      remove(opt_path);
+    }
+
+    #ifdef TUXMATH_DEBUG
+    printf("\nIn write_user_config_file() - trying to create .tuxmath dir\n");
+    #endif
+
+    status = mkdir(opt_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+
+    #ifdef TUXMATH_DEBUG
+    printf("\nIn write_user_config_file() - mkdir returned: %d\n", status);
+    #endif
+
+    /* mkdir () returns 0 if successful */
+    if (0 != status)
+    {
+      fprintf(stderr, "\nwrite_user_config_file() - mkdir failed\n");
+      return 0;
+    }
+       
+  }
+
+  /* Add filename: */
+  strcat(opt_path, "/options");
+
+  #ifdef TUXMATH_DEBUG
+  printf("\nIn write_user_config_file() full path to config file is: = %s\n", opt_path);
+  #endif
+
+  /* save settings: */
+  fp = fopen(opt_path, "w");
+  if (fp)
+  {
+    write_config_file(fp);
+    fclose(fp);
+    fp = NULL;
+    return 1;
+  }
+  else
+    return 0;
+}
+
+
+
+/* this function writes the settings for all game options to a */
+/* human-readable file.                                        */
+
+int write_config_file(FILE *fp)
+{
+  #ifdef TUXMATH_DEBUG
+  printf("\nEntering write_config_file()\n");
+  #endif
+
+  /* get out if file pointer null */
+  if(!fp)
+  {
+    fprintf (stderr, "write_config_file() - file pointer invalid/n");
+
+    #ifdef TUXMATH_DEBUG
+    printf("Leaving write_config_file()\n");
+    #endif
+
+    return 0;
+  }
+
+  fprintf(fp, 
+          "############################################################\n"
+          "#                                                          #\n"
+          "#                 Tuxmath Config File                      #\n"
+          "#                                                          #\n"
+          "############################################################\n"
+          "\n"
+  );
+
+  /* print general game options (passing '1' as second arg causes */
+  /* "help" info for each option to be written to file as comments) */
+  print_game_options(fp, 1);
+  /* print options pertaining to math questions from MathCards: */
+  MC_PrintMathOptions(fp, 1);
+
+  #ifdef TUXMATH_DEBUG
+  printf("Leaving write_config_file()\n");
+  #endif
+
+  return 1;
+}
+
+
+/* prints struct to stream: */
+void print_game_options(FILE* fp, int verbose)
+{
+ /* bail out if no struct */
+  if (!game_options)
+  {
+    fprintf(stderr, "print_game_options(): invalid game_option_type struct");
+    return;
+  }
+
+  if(verbose)
+  {
+    fprintf (fp, "\n############################################################\n" 
+                 "#                                                          #\n"
+                 "#                 General Game Options                     #\n"
+                 "#                                                          #\n"
+                 "# The following options are boolean (true/false) variables #\n"
+                 "# that control various aspects of Tuxmath's behavior.      #\n"
+                 "# The program writes the values to the file as either '0'  #\n"
+                 "# or '1'. However, the program accepts 'n', 'no', 'f', and #\n"
+                 "# 'false' as synonyms for '0', and similarly accepts 'y',  #\n"
+                 "# 'yes', 't', and 'true' as synonyms for '1' (all case-    #\n"
+                 "# insensitive).                                            #\n"
+                 "############################################################\n\n");
+  }
+
+  if(verbose)
+  {
+    fprintf (fp, "############################################################\n" 
+                 "# 'per_user_config' determines whether Tuxmath will look   #\n"
+                 "# in the user's home directory for settings. Default is 1  #\n"
+                 "# (yes). If deselected, the program will ignore the user's #\n"
+                 "# .tuxmath file and use the the global settings in the     #\n"
+                 "# installation-wide config file.                           #\n"
+                 "# This setting cannot be changed by an ordinary user.      #\n"
+                 "############################################################\n");
+  }
+  fprintf(fp, "per_user_config = %d\n", game_options->per_user_config);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Self-explanatory, default is 1:\n");
+  }
+  fprintf(fp, "use_sound = %d\n", game_options->use_sound);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Use either fullscreen at 640x480 resolution or window of that size\n"
+                 "# Default is 1.  Change to 0 if SDL has trouble with fullscreen.\n");
+  } 
+  fprintf(fp, "fullscreen = %d\n", game_options->fullscreen);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Use 640x480 jpg image for background; default is 1.\n");
+  }
+  fprintf(fp, "use_bkgd = %d\n", game_options->use_bkgd);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Program runs as demo; default is 0.\n");
+  }
+  fprintf(fp, "demo_mode = %d\n", game_options->demo_mode);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Use operator selection from command line; default is 0.\n");
+  }
+  fprintf(fp, "oper_override = %d\n", game_options->oper_override);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Display onscreen numeric keypad; default is 0.\n");
+  }
+  fprintf(fp, "use_keypad = %d\n", game_options->use_keypad);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n############################################################\n" 
+                 "# The remaining settings determine the speed and number    #\n"
+                 "# of comets.  The speed settings are float numbers (mean-  #\n"
+                 "# ing decimals allowed). The comet settings are integers.  #\n"
+                 "############################################################\n");
+  }
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Starting comet speed. Default is 1.\n");
+  }
+  fprintf(fp, "speed = %f\n", game_options->speed);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Speed is multiplied by this factor with each new wave.\n"
+                 "# Default is 1.2\n");
+  }
+  fprintf(fp, "speedup_factor = %f\n", game_options->speedup_factor);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Maximum speed. Default is 10.\n");
+  }
+  fprintf(fp, "max_speed = %f\n", game_options->max_speed);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Number of comets for first wave. Default is 2.\n");
+  }
+  fprintf(fp, "starting_comets = %d\n", game_options->starting_comets);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Comets to add for each successive wave. Default is 2.\n");
+  }
+  fprintf(fp, "extra_comets_per_wave = %d\n", game_options->extra_comets_per_wave);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Maximum number of comets. Default is 10.\n");
+  }
+  fprintf(fp, "max_comets = %d\n", game_options->max_comets);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Allow speed and number of comets to increase with each\n"
+                 "# wave.  May want to turn this off for smaller kids. Default is 1.\n");
+  }
+  fprintf(fp, "allow_speedup = %d\n", game_options->allow_speedup);
+
+  if(verbose)
+  {
+    fprintf (fp, "\n# Go back to starting speed and number of comets if player\n"
+                 "# misses a question. Useful for smaller kids. Default is 0.\n");
+  }
+  fprintf(fp, "slow_after_wrong = %d\n", game_options->slow_after_wrong);
+
+/*
+  fprintf(fp, "num_cities = %d\n", game_options->num_cities);
+  fprintf(fp, "num_bkgds = %d\n", game_options->num_bkgds);
+  fprintf(fp, "max_city_colors = %d\n", game_options->max_city_colors);
+*/
+}
+
+
+
+/* Allows use of "true", "YES", T, etc. in text file for boolean values. */
+/* Return value of -1 means value string is not recognized.              */
+static int str_to_bool(char* val)
+{
+  char* ptr;
+
+  /* Check for recognized boolean strings: */
+  if ((0 == strcasecmp(val, "true"))
+    ||(0 == strcasecmp(val, "t"))
+    ||(0 == strcasecmp(val, "yes"))
+    ||(0 == strcasecmp(val, "y")))
+  {
+    return 1;
+  }
+
+  if ((0 == strcasecmp(val, "false"))
+    ||(0 == strcasecmp(val, "f"))
+    ||(0 == strcasecmp(val, "no"))
+    ||(0 == strcasecmp(val, "n")))
+  {
+    return 0;
+  }  
+
+  /* Return -1 if any chars are non-digits: */
+  ptr = val;
+  while (*ptr)
+  {
+    if (!isdigit(*ptr))
+      return -1;
+    ptr++;
+  }
+
+  /* If we get to here, val should be an integer. */
+  if (atoi(val))
+    return 1;
+  else
+    return 0;
+}
+
+
+
+
+
+/*****************************************************************/
+/*   Loading of data files for images and sounds.                */
+/*   These functions also draw some user feedback to             */
+/*   display the progress of the loading.                        */
+/*****************************************************************/
+
+/* returns 1 if all data files successfully loaded, 0 otherwise. */
+int load_image_data()
+{
+  int total_files, i;
+
+  SDL_Rect dest;
+
+  static char* image_filenames[NUM_IMAGES] = {
+  DATA_PREFIX "/images/status/standby.png",
+  DATA_PREFIX "/images/status/loading.png",
+  DATA_PREFIX "/images/status/title.png",
+  DATA_PREFIX "/images/status/options.png",
+  DATA_PREFIX "/images/status/tux4kids.png",
+  DATA_PREFIX "/images/status/nbs.png",
+  DATA_PREFIX "/images/status/tux_helmet1.png",
+  DATA_PREFIX "/images/status/tux_helmet2.png",
+  DATA_PREFIX "/images/status/tux_helmet3.png", 
+  DATA_PREFIX "/images/status/cmd_play.png",
+  DATA_PREFIX "/images/status/cmd_options.png",
+  DATA_PREFIX "/images/status/cmd_credits.png",
+  DATA_PREFIX "/images/status/cmd_quit.png",
+  DATA_PREFIX "/images/status/opt_addition.png",
+  DATA_PREFIX "/images/status/opt_subtraction.png",
+  DATA_PREFIX "/images/status/opt_multiplication.png",
+  DATA_PREFIX "/images/status/opt_division.png",
+  DATA_PREFIX "/images/status/opt_max_answer.png",
+  DATA_PREFIX "/images/status/opt_speed.png",
+  DATA_PREFIX "/images/status/opt_q_range.png",
+  DATA_PREFIX "/images/status/opt_rng_1_5.png",
+  DATA_PREFIX "/images/status/opt_rng_1_5_on.png",
+  DATA_PREFIX "/images/status/opt_rng_6_12.png",
+  DATA_PREFIX "/images/status/opt_rng_6_12_on.png",
+  DATA_PREFIX "/images/status/opt_rng_13_20.png",
+  DATA_PREFIX "/images/status/opt_rng_13_20_on.png",
+  DATA_PREFIX "/images/status/opt_check.png",
+  DATA_PREFIX "/images/status/opt_check_on.png",
+  DATA_PREFIX "/images/cities/city-blue.png",
+  DATA_PREFIX "/images/cities/csplode-blue-1.png",
+  DATA_PREFIX "/images/cities/csplode-blue-2.png",
+  DATA_PREFIX "/images/cities/csplode-blue-3.png",
+  DATA_PREFIX "/images/cities/csplode-blue-4.png",
+  DATA_PREFIX "/images/cities/csplode-blue-5.png",
+  DATA_PREFIX "/images/cities/cdead-blue.png",
+  DATA_PREFIX "/images/cities/city-green.png",
+  DATA_PREFIX "/images/cities/csplode-green-1.png",
+  DATA_PREFIX "/images/cities/csplode-green-2.png",
+  DATA_PREFIX "/images/cities/csplode-green-3.png",
+  DATA_PREFIX "/images/cities/csplode-green-4.png",
+  DATA_PREFIX "/images/cities/csplode-green-5.png",
+  DATA_PREFIX "/images/cities/cdead-green.png",
+  DATA_PREFIX "/images/cities/city-orange.png",
+  DATA_PREFIX "/images/cities/csplode-orange-1.png",
+  DATA_PREFIX "/images/cities/csplode-orange-2.png",
+  DATA_PREFIX "/images/cities/csplode-orange-3.png",
+  DATA_PREFIX "/images/cities/csplode-orange-4.png",
+  DATA_PREFIX "/images/cities/csplode-orange-5.png",
+  DATA_PREFIX "/images/cities/cdead-orange.png",
+  DATA_PREFIX "/images/cities/city-red.png",
+  DATA_PREFIX "/images/cities/csplode-red-1.png",
+  DATA_PREFIX "/images/cities/csplode-red-2.png",
+  DATA_PREFIX "/images/cities/csplode-red-3.png",
+  DATA_PREFIX "/images/cities/csplode-red-4.png",
+  DATA_PREFIX "/images/cities/csplode-red-5.png",
+  DATA_PREFIX "/images/cities/cdead-red.png",
+  DATA_PREFIX "/images/cities/shields.png",
+  DATA_PREFIX "/images/comets/comet1.png",
+  DATA_PREFIX "/images/comets/comet2.png",
+  DATA_PREFIX "/images/comets/comet3.png",
+  DATA_PREFIX "/images/comets/cometex3.png",
+  DATA_PREFIX "/images/comets/cometex3.png",
+  DATA_PREFIX "/images/comets/cometex2.png",
+  DATA_PREFIX "/images/comets/cometex2.png",
+  DATA_PREFIX "/images/comets/cometex1a.png",
+  DATA_PREFIX "/images/comets/cometex1a.png",
+  DATA_PREFIX "/images/comets/cometex1.png",
+  DATA_PREFIX "/images/comets/cometex1.png",
+  DATA_PREFIX "/images/comets/mini_comet1.png",
+  DATA_PREFIX "/images/comets/mini_comet2.png",
+  DATA_PREFIX "/images/comets/mini_comet3.png",
+  DATA_PREFIX "/images/status/nums.png",
+  DATA_PREFIX "/images/status/lednums.png",
+  DATA_PREFIX "/images/status/led_neg_sign.png",
+  DATA_PREFIX "/images/status/paused.png",
+  DATA_PREFIX "/images/status/demo.png",
+  DATA_PREFIX "/images/status/demo-small.png",
+  DATA_PREFIX "/images/status/keypad.png",
+  DATA_PREFIX "/images/status/keypad_no_neg.png",
+  DATA_PREFIX "/images/tux/console.png",
+  DATA_PREFIX "/images/tux/console_led.png",
+  DATA_PREFIX "/images/tux/console_bash.png",
+  DATA_PREFIX "/images/tux/tux-console1.png",
+  DATA_PREFIX "/images/tux/tux-console2.png",
+  DATA_PREFIX "/images/tux/tux-console3.png",
+  DATA_PREFIX "/images/tux/tux-console4.png",
+  DATA_PREFIX "/images/tux/tux-relax1.png",
+  DATA_PREFIX "/images/tux/tux-relax2.png",
+  DATA_PREFIX "/images/tux/tux-egypt1.png",
+  DATA_PREFIX "/images/tux/tux-egypt2.png",
+  DATA_PREFIX "/images/tux/tux-egypt3.png",
+  DATA_PREFIX "/images/tux/tux-egypt4.png",
+  DATA_PREFIX "/images/tux/tux-drat.png",
+  DATA_PREFIX "/images/tux/tux-yipe.png",
+  DATA_PREFIX "/images/tux/tux-yay1.png",
+  DATA_PREFIX "/images/tux/tux-yay2.png",
+  DATA_PREFIX "/images/tux/tux-yes1.png",
+  DATA_PREFIX "/images/tux/tux-yes2.png",
+  DATA_PREFIX "/images/tux/tux-sit.png",
+  DATA_PREFIX "/images/tux/tux-fist1.png",
+  DATA_PREFIX "/images/tux/tux-fist2.png",
+  DATA_PREFIX "/images/status/wave.png",
+  DATA_PREFIX "/images/status/score.png",
+  DATA_PREFIX "/images/status/numbers.png",
+  DATA_PREFIX "/images/status/gameover.png",
+  DATA_PREFIX "/images/status/gameover_won.png"
+  };
+
+  if (opts_using_sound())
+    total_files = NUM_IMAGES + NUM_SOUNDS + NUM_MUSICS;
+  else
+    total_files = NUM_IMAGES;
+
+  /* Load images: */
+  for (i = 0; i < NUM_IMAGES; i++)
+  {
+    images[i] = IMG_Load(image_filenames[i]);
+    if (images[i] == NULL)
+      {
+	fprintf(stderr,
+		"\nError: I couldn't load a graphics file:\n"
+		"%s\n"
+		"The Simple DirectMedia error that occured was:\n"
+		"%s\n\n", image_filenames[i], SDL_GetError());
+        return 0;
+      }
+
+    /* Draw suitable user feedback during loading: */
+    if (i == IMG_STANDBY)
+      {
+	dest.x = (screen->w - images[IMG_STANDBY]->w) / 2;
+	dest.y = screen->h - images[IMG_STANDBY]->h - 10;
+	dest.w = images[IMG_STANDBY]->w;
+	dest.h = images[IMG_STANDBY]->h;
+	
+	SDL_BlitSurface(images[IMG_STANDBY], NULL, screen, &dest);
+	SDL_Flip(screen);
+      }
+    else if (i == IMG_LOADING)
+      {
+	dest.x = (screen->w - images[IMG_LOADING]->w) / 2;
+	dest.y = 0;
+	dest.w = images[IMG_LOADING]->w;
+	dest.h = images[IMG_LOADING]->h;
+	
+	SDL_BlitSurface(images[IMG_LOADING], NULL, screen, &dest);
+	SDL_Flip(screen);
+      }
+    else if (i == IMG_TITLE)
+      {
+	dest.x = (screen->w - images[IMG_TITLE]->w) / 2;
+	dest.y = images[IMG_LOADING]->h;
+	dest.w = images[IMG_TITLE]->w;
+	dest.h = images[IMG_TITLE]->h;
+	
+	SDL_BlitSurface(images[IMG_TITLE], NULL, screen, &dest);
+	SDL_Flip(screen);
+      }
+    
+    /* Green 'status bar' during loading: */
+    dest.x = 0;
+    dest.y = (screen->h) - 10;
+    dest.w = ((screen->w) * (i + 1)) / total_files;
+    dest.h = 10;
+    
+    SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 255, 0));
+    SDL_Flip(screen);
+  }
+  /* If we make it to here OK, return 1: */
+  return 1;
+}
+
+#ifndef NOSOUND
+int load_sound_data(void)
+{
+  int total_files, i;
+
+  SDL_Rect dest;
+
+  static char* sound_filenames[NUM_SOUNDS] = {
+  DATA_PREFIX "/sounds/pop.wav",
+  DATA_PREFIX "/sounds/laser.wav",
+  DATA_PREFIX "/sounds/buzz.wav",
+  DATA_PREFIX "/sounds/alarm.wav",
+  DATA_PREFIX "/sounds/shieldsdown.wav",
+  DATA_PREFIX "/sounds/explosion.wav",
+  DATA_PREFIX "/sounds/click.wav",
+  DATA_PREFIX "/sounds/sizzling.wav"
+  };
+
+  static char* music_filenames[NUM_MUSICS] = {
+  DATA_PREFIX "/sounds/game.mod",
+  DATA_PREFIX "/sounds/game2.mod",
+  DATA_PREFIX "/sounds/game3.mod"
+  };
+
+  /* skip loading sound files if sound system not available: */
+  if (opts_using_sound())
+  {
+    total_files = NUM_IMAGES + NUM_SOUNDS + NUM_MUSICS;
+
+    for (i = 0; i < NUM_SOUNDS; i++)
+    {
+      sounds[i] = Mix_LoadWAV(sound_filenames[i]);
+
+      if (sounds[i] == NULL)
+      {
+        fprintf(stderr,
+	        "\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());
+        return 0;
+      }
+      
+      dest.x = 0;
+      dest.y = (screen->h) - 10;
+      dest.w = ((screen->w) * (i + 1 + NUM_IMAGES)) / total_files;
+      dest.h = 10;
+
+      SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 255, 0));
+      SDL_Flip(screen);
+    }
+
+
+    for (i = 0; i < NUM_MUSICS; i++)
+    {
+      musics[i] = Mix_LoadMUS(music_filenames[i]);
+
+      if (musics[i] == NULL)
+      {
+        fprintf(stderr,
+	        "\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());
+        return 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_Flip(screen);
+    }
+  }
+  return 1;
+}
+#endif

Copied: tuxmath/trunk/src/fileops.h (from rev 21, tuxmath/trunk/src/config.h)
===================================================================
--- tuxmath/trunk/src/config.h	2006-08-13 19:53:36 UTC (rev 21)
+++ tuxmath/trunk/src/fileops.h	2006-09-03 16:37:34 UTC (rev 23)
@@ -0,0 +1,180 @@
+/*
+C Interface: fileops.h
+
+Description: File operations - together, fileops.h and fileops.c contain 
+all code involving disk operations. The older header files images.h and 
+sounds.h have been incorporated here. The intention is to make it easier to
+port tuxmath to other operating systems, as code to read and write as 
+well as paths and file locations may be more OS-dependent. 
+
+
+Author: David Bruce <dbruce at tampabay.rr.com>, (C) 2006
+Contains code originally written by Bill Kendrick (C) 2001.
+Copyright: See COPYING file that comes with this distribution (briefly, GNU GPL)
+*/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "tuxmath.h"
+
+/* Flag basically telling whether or not to allow admin-level */
+/* settings to be changed: */
+enum {
+  USER_CONFIG_FILE,
+  GLOBAL_CONFIG_FILE
+};
+
+/* Names for images (formerly in images.h) */
+enum {
+  IMG_STANDBY,
+  IMG_LOADING,
+  IMG_TITLE,
+  IMG_OPTIONS,
+  IMG_TUX4KIDS,
+  IMG_NBS,
+  IMG_TUX_HELMET1,
+  IMG_TUX_HELMET2,
+  IMG_TUX_HELMET3,
+  IMG_CMD_PLAY,
+  IMG_CMD_OPTIONS,
+  IMG_CMD_CREDITS,
+  IMG_CMD_QUIT,
+  IMG_OPT_ADDITION,
+  IMG_OPT_SUBTRACTION,
+  IMG_OPT_MULTIPLICATION,
+  IMG_OPT_DIVISION,
+  IMG_OPT_MAX_ANSWER,
+  IMG_OPT_SPEED,
+  IMG_OPT_Q_RANGE,
+  IMG_OPT_RNG_1_5,
+  IMG_OPT_RNG_1_5_ON,
+  IMG_OPT_RNG_6_12,
+  IMG_OPT_RNG_6_12_ON,
+  IMG_OPT_RNG_13_20,
+  IMG_OPT_RNG_13_20_ON,
+  IMG_OPT_CHECK,
+  IMG_OPT_CHECK_ON,
+  IMG_CITY_BLUE,
+  IMG_CITY_BLUE_EXPL1,
+  IMG_CITY_BLUE_EXPL2,
+  IMG_CITY_BLUE_EXPL3,
+  IMG_CITY_BLUE_EXPL4,
+  IMG_CITY_BLUE_EXPL5,
+  IMG_CITY_BLUE_DEAD,
+  IMG_CITY_GREEN,
+  IMG_CITY_GREEN_EXPL1,
+  IMG_CITY_GREEN_EXPL2,
+  IMG_CITY_GREEN_EXPL3,
+  IMG_CITY_GREEN_EXPL4,
+  IMG_CITY_GREEN_EXPL5,
+  IMG_CITY_GREEN_DEAD,
+  IMG_CITY_ORANGE,
+  IMG_CITY_ORANGE_EXPL1,
+  IMG_CITY_ORANGE_EXPL2,
+  IMG_CITY_ORANGE_EXPL3,
+  IMG_CITY_ORANGE_EXPL4,
+  IMG_CITY_ORANGE_EXPL5,
+  IMG_CITY_ORANGE_DEAD,
+  IMG_CITY_RED,
+  IMG_CITY_RED_EXPL1,
+  IMG_CITY_RED_EXPL2,
+  IMG_CITY_RED_EXPL3,
+  IMG_CITY_RED_EXPL4,
+  IMG_CITY_RED_EXPL5,
+  IMG_CITY_RED_DEAD,
+  IMG_SHIELDS,
+  IMG_COMET1,
+  IMG_COMET2,
+  IMG_COMET3,
+  IMG_COMETEX8,
+  COMET_EXPL_END = IMG_COMETEX8,
+  IMG_COMETEX7,
+  IMG_COMETEX6,
+  IMG_COMETEX5,
+  IMG_COMETEX4,
+  IMG_COMETEX3,
+  IMG_COMETEX2,
+  IMG_COMETEX1,
+  COMET_EXPL_START = IMG_COMETEX1,
+  IMG_MINI_COMET1,
+  IMG_MINI_COMET2,
+  IMG_MINI_COMET3,
+  IMG_NUMS,
+  IMG_LEDNUMS,
+  IMG_LED_NEG_SIGN,
+  IMG_PAUSED,
+  IMG_DEMO,
+  IMG_DEMO_SMALL,
+  IMG_KEYPAD,
+  IMG_KEYPAD_NO_NEG,
+  IMG_CONSOLE,
+  IMG_CONSOLE_LED,
+  IMG_CONSOLE_BASH,
+  IMG_TUX_CONSOLE1,
+  IMG_TUX_CONSOLE2,
+  IMG_TUX_CONSOLE3,
+  IMG_TUX_CONSOLE4,
+  IMG_TUX_RELAX1,
+  IMG_TUX_RELAX2,
+  IMG_TUX_EGYPT1,
+  IMG_TUX_EGYPT2,
+  IMG_TUX_EGYPT3,
+  IMG_TUX_EGYPT4,
+  IMG_TUX_DRAT,
+  IMG_TUX_YIPE,
+  IMG_TUX_YAY1,
+  IMG_TUX_YAY2,
+  IMG_TUX_YES1,
+  IMG_TUX_YES2,
+  IMG_TUX_SIT,
+  IMG_TUX_FIST1,
+  IMG_TUX_FIST2,
+  IMG_WAVE,
+  IMG_SCORE,
+  IMG_NUMBERS,
+  IMG_GAMEOVER,
+  IMG_GAMEOVER_WON,
+  NUM_IMAGES
+};
+
+/* Names for game sounds (formerly in sounds.h): */
+enum {
+  SND_POP,
+  SND_LASER,
+  SND_BUZZ,
+  SND_ALARM,
+  SND_SHIELDSDOWN,
+  SND_EXPLOSION,
+  SND_CLICK,
+  SND_SIZZLE,
+  NUM_SOUNDS
+};
+
+/* Names for background music (also formerly in sounds.h): */
+enum {
+  MUS_GAME,
+  MUS_GAME2,
+  MUS_GAME3,
+  NUM_MUSICS
+};
+
+
+
+/* These functions used by setup() to read in settings: */
+int read_global_config_file(void);
+int read_user_config_file(void);
+int read_named_config_file(char* filename);
+int write_user_config_file(void);
+
+/* FIXME these will probably become "local" functions: */
+int read_config_file(FILE* fp, int file_type);
+int write_config_file(FILE* fp);
+void print_game_options(FILE* fp, int verbose);
+
+int load_image_data();
+#ifndef NOSOUND
+int load_sound_data();
+#endif
+
+#endif

Modified: tuxmath/trunk/src/game.c
===================================================================
--- tuxmath/trunk/src/game.c	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/game.c	2006-09-03 16:37:34 UTC (rev 23)
@@ -25,9 +25,8 @@
 #endif
 #include <SDL_image.h>
 #include "game.h"
-#include "images.h"
+#include "fileops.h"
 #include "setup.h"
-#include "sounds.h"
 #include "playsound.h"
 #include "tuxmath.h"
 #include "mathcards.h"  
@@ -192,7 +191,7 @@
       /* Keep playing music: */
       
     #ifndef NOSOUND
-    if (game_options->use_sound)
+    if (opts_using_sound())
     {
       if (!Mix_PlayingMusic())
       {
@@ -262,7 +261,7 @@
         }
 
         /* draw dancing tux: */
-        draw_console_image(IMG_CONSOLE_LED);
+        draw_console_image(IMG_CONSOLE_BASH);
         /* walk tux back and forth */
         tux_offset += tux_step;
         /* select tux_egypt images according to which way tux is headed: */
@@ -363,7 +362,7 @@
 
   /* Stop music: */
 #ifndef NOSOUND
-  if (game_options->use_sound)
+  if (opts_using_sound())
   {
     if (Mix_PlayingMusic())
     {
@@ -1516,7 +1515,7 @@
 
 
 #ifndef NOSOUND
-  if (game_options->use_sound)
+  if (opts_using_sound())
     Mix_PauseMusic();
 #endif
   
@@ -1540,7 +1539,7 @@
 
 
 #ifndef NOSOUND
-  if (game_options->use_sound)
+  if (opts_using_sound())
     Mix_ResumeMusic();
 #endif
 

Modified: tuxmath/trunk/src/game.h
===================================================================
--- tuxmath/trunk/src/game.h	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/game.h	2006-09-03 16:37:34 UTC (rev 23)
@@ -37,35 +37,9 @@
   int x2, y2;
 } laser_type;
 
-enum {
-  OPER_ADD,
-  OPER_SUB,
-  OPER_MULT,
-  OPER_DIV,
-  NUM_OPERS
-};
 
-extern char operchars[NUM_OPERS];
 
-extern char * oper_opts[NUM_OPERS];
-
-extern char * oper_alt_opts[NUM_OPERS];
-
 enum {
-  Q_RANGE_1_5,
-  Q_RANGE_6_12,
-  Q_RANGE_13_20,
-  NUM_Q_RANGES
-};
-
-typedef struct range_type {
-  int min;
-  int max;
-} range_type;
-
-extern range_type ranges[NUM_Q_RANGES];
-
-enum {
   GAME_IN_PROGRESS,
   GAME_OVER_WON,
   GAME_OVER_LOST,

Deleted: tuxmath/trunk/src/images.h
===================================================================
--- tuxmath/trunk/src/images.h	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/images.h	2006-09-03 16:37:34 UTC (rev 23)
@@ -1,130 +0,0 @@
-/*
-  images.h
-
-  For TuxMath
-  Contains an enumerated list of constant values to be used to refer to
-  images, as well as a list of filenames for each image (used by the
-  loader in "setup" module)
-
-  by Bill Kendrick
-  bill at newbreedsoftware.com
-  http://www.newbreedsoftware.com/
-
-
-  Part of "Tux4Kids" Project
-  http://www.tux4kids.org/
-      
-  August 26, 2001 - February 21, 2003
-*/
-
-enum {
-  IMG_STANDBY,
-  IMG_LOADING,
-  IMG_TITLE,
-  IMG_OPTIONS,
-  IMG_TUX4KIDS,
-  IMG_NBS,
-  IMG_TUX_HELMET1,
-  IMG_TUX_HELMET2,
-  IMG_TUX_HELMET3,
-  IMG_CMD_PLAY,
-  IMG_CMD_OPTIONS,
-  IMG_CMD_CREDITS,
-  IMG_CMD_QUIT,
-  IMG_OPT_ADDITION,
-  IMG_OPT_SUBTRACTION,
-  IMG_OPT_MULTIPLICATION,
-  IMG_OPT_DIVISION,
-  IMG_OPT_MAX_ANSWER,
-  IMG_OPT_SPEED,
-  IMG_OPT_Q_RANGE,
-  IMG_OPT_RNG_1_5,
-  IMG_OPT_RNG_1_5_ON,
-  IMG_OPT_RNG_6_12,
-  IMG_OPT_RNG_6_12_ON,
-  IMG_OPT_RNG_13_20,
-  IMG_OPT_RNG_13_20_ON,
-  IMG_OPT_CHECK,
-  IMG_OPT_CHECK_ON,
-  IMG_CITY_BLUE,
-  IMG_CITY_BLUE_EXPL1,
-  IMG_CITY_BLUE_EXPL2,
-  IMG_CITY_BLUE_EXPL3,
-  IMG_CITY_BLUE_EXPL4,
-  IMG_CITY_BLUE_EXPL5,
-  IMG_CITY_BLUE_DEAD,
-  IMG_CITY_GREEN,
-  IMG_CITY_GREEN_EXPL1,
-  IMG_CITY_GREEN_EXPL2,
-  IMG_CITY_GREEN_EXPL3,
-  IMG_CITY_GREEN_EXPL4,
-  IMG_CITY_GREEN_EXPL5,
-  IMG_CITY_GREEN_DEAD,
-  IMG_CITY_ORANGE,
-  IMG_CITY_ORANGE_EXPL1,
-  IMG_CITY_ORANGE_EXPL2,
-  IMG_CITY_ORANGE_EXPL3,
-  IMG_CITY_ORANGE_EXPL4,
-  IMG_CITY_ORANGE_EXPL5,
-  IMG_CITY_ORANGE_DEAD,
-  IMG_CITY_RED,
-  IMG_CITY_RED_EXPL1,
-  IMG_CITY_RED_EXPL2,
-  IMG_CITY_RED_EXPL3,
-  IMG_CITY_RED_EXPL4,
-  IMG_CITY_RED_EXPL5,
-  IMG_CITY_RED_DEAD,
-  IMG_SHIELDS,
-  IMG_COMET1,
-  IMG_COMET2,
-  IMG_COMET3,
-  IMG_COMETEX8,
-  COMET_EXPL_END = IMG_COMETEX8,
-  IMG_COMETEX7,
-  IMG_COMETEX6,
-  IMG_COMETEX5,
-  IMG_COMETEX4,
-  IMG_COMETEX3,
-  IMG_COMETEX2,
-  IMG_COMETEX1,
-  COMET_EXPL_START = IMG_COMETEX1,
-  IMG_MINI_COMET1,
-  IMG_MINI_COMET2,
-  IMG_MINI_COMET3,
-  IMG_NUMS,
-  IMG_LEDNUMS,
-  IMG_LED_NEG_SIGN,
-  IMG_PAUSED,
-  IMG_DEMO,
-  IMG_DEMO_SMALL,
-  IMG_KEYPAD,
-  IMG_KEYPAD_NO_NEG,
-  IMG_CONSOLE,
-  IMG_CONSOLE_LED,
-  IMG_TUX_CONSOLE1,
-  IMG_TUX_CONSOLE2,
-  IMG_TUX_CONSOLE3,
-  IMG_TUX_CONSOLE4,
-  IMG_TUX_RELAX1,
-  IMG_TUX_RELAX2,
-  IMG_TUX_EGYPT1,
-  IMG_TUX_EGYPT2,
-  IMG_TUX_EGYPT3,
-  IMG_TUX_EGYPT4,
-  IMG_TUX_DRAT,
-  IMG_TUX_YIPE,
-  IMG_TUX_YAY1,
-  IMG_TUX_YAY2,
-  IMG_TUX_YES1,
-  IMG_TUX_YES2,
-  IMG_TUX_SIT,
-  IMG_TUX_FIST1,
-  IMG_TUX_FIST2,
-  IMG_WAVE,
-  IMG_SCORE,
-  IMG_NUMBERS,
-  IMG_GAMEOVER,
-  IMG_GAMEOVER_WON,
-  NUM_IMAGES
-};
-

Modified: tuxmath/trunk/src/mathcards.c
===================================================================
--- tuxmath/trunk/src/mathcards.c	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/mathcards.c	2006-09-03 16:37:34 UTC (rev 23)
@@ -425,8 +425,10 @@
 }
 
 /*  MC_AnsweredIncorrectly() is how the user interface    */
-/*  tells MathCards that the question has been answered   */
-/*  incorrectly. Returns 1 if no errors.                  */
+/*  tells MathCards that the player failed to answer the  */
+/*  question correctly. Returns 1 if no errors.           */
+/*  Note: this gets triggered only if a player's city     */
+/*  gets hit by a question, not if they "miss".           */
 int MC_AnsweredIncorrectly(MC_FlashCard* fc)
 {
   #ifdef MC_DEBUG
@@ -1899,9 +1901,13 @@
                  "#                                                          #\n"
                  "#                  General Math Options                    #\n"
                  "#                                                          #\n"
-                 "# If 'play_through_list' selected, Tuxmath will ask each   #\n"
-                 "# question in the defined list. The game ends when no      #\n"
-                 "# questions remain.  Default is 1 (i.e. 'true' or 'yes').  #\n"
+                 "# If 'play_through_list' is true, Tuxmath will ask each    #\n"
+                 "# question in an internally-generated list. The list is    #\n"
+                 "# generated based on the question ranges selected below.   #\n"
+                 "# The game ends when no questions remain.                  #\n"
+                 "# If 'play_through_list' is false, the game continues      #\n"
+                 "# until all cities are destroyed.                          #\n"
+                 "# Default is 1 (i.e. 'true' or 'yes').                     #\n"
                  "#                                                          #\n"
                  "# 'question_copies' is the number of times each question   #\n"
                  "# will be asked. It can be 1 to 10 - Default is 1.         #\n"

Modified: tuxmath/trunk/src/options.c
===================================================================
--- tuxmath/trunk/src/options.c	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/options.c	2006-09-03 16:37:34 UTC (rev 23)
@@ -25,9 +25,8 @@
 #include "mathcards.h"
 
 #include "options.h"
-#include "images.h"
+#include "fileops.h"
 #include "setup.h"
-#include "sounds.h"
 #include "playsound.h"
 #include "game.h"
 #include "tuxmath.h"
@@ -35,6 +34,9 @@
 /* FIXME figure out what oper_override is supposed to do and make sure */
 /* this file behaves accordingly! */
 
+int opers[NUM_OPERS], range_enabled[NUM_Q_RANGES];
+
+
 /* Local (to options.c) 'globals': */
 /* moved to file scope to allow update_selected_option() to use them DSB */
 static SDL_Rect dest;
@@ -64,6 +66,11 @@
   opers[OPT_OP_MUL] = MC_MultAllowed();
   opers[OPT_OP_DIV] = MC_DivAllowed();
 
+  /* FIXME range_enabled[] and oper_override will be going away */
+  for (i = 0; i < NUM_Q_RANGES; i++)
+  { 
+    range_enabled[i] = 1;
+  }
 
   /* Draw options: */
 

Modified: tuxmath/trunk/src/playsound.c
===================================================================
--- tuxmath/trunk/src/playsound.c	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/playsound.c	2006-09-03 16:37:34 UTC (rev 23)
@@ -27,7 +27,7 @@
 void playsound(int snd)
 {
 #ifndef NOSOUND
-  if (game_options->use_sound)
+  if (opts_using_sound())
     Mix_PlayChannel(-1, sounds[snd], 0);
 #endif
 }

Modified: tuxmath/trunk/src/setup.c
===================================================================
--- tuxmath/trunk/src/setup.c	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/setup.c	2006-09-03 16:37:34 UTC (rev 23)
@@ -26,7 +26,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdlib.h>
 
 /* FIXME maybe unistd.h not needed, even less sure about portability */
 //#include <unistd.h>
@@ -42,170 +41,59 @@
 #include "tuxmath.h"
 #include "mathcards.h"
 #include "setup.h"
-#include "images.h"
-#include "sounds.h"
-#include "config.h"
+#include "fileops.h"
 #include "game.h"
 
-static char * image_filenames[NUM_IMAGES] = {
-  DATA_PREFIX "/images/status/standby.png",
-  DATA_PREFIX "/images/status/loading.png",
-  DATA_PREFIX "/images/status/title.png",
-  DATA_PREFIX "/images/status/options.png",
-  DATA_PREFIX "/images/status/tux4kids.png",
-  DATA_PREFIX "/images/status/nbs.png",
-  DATA_PREFIX "/images/status/tux_helmet1.png",
-  DATA_PREFIX "/images/status/tux_helmet2.png",
-  DATA_PREFIX "/images/status/tux_helmet3.png", 
-  DATA_PREFIX "/images/status/cmd_play.png",
-  DATA_PREFIX "/images/status/cmd_options.png",
-  DATA_PREFIX "/images/status/cmd_credits.png",
-  DATA_PREFIX "/images/status/cmd_quit.png",
-  DATA_PREFIX "/images/status/opt_addition.png",
-  DATA_PREFIX "/images/status/opt_subtraction.png",
-  DATA_PREFIX "/images/status/opt_multiplication.png",
-  DATA_PREFIX "/images/status/opt_division.png",
-  DATA_PREFIX "/images/status/opt_max_answer.png",
-  DATA_PREFIX "/images/status/opt_speed.png",
-  DATA_PREFIX "/images/status/opt_q_range.png",
-  DATA_PREFIX "/images/status/opt_rng_1_5.png",
-  DATA_PREFIX "/images/status/opt_rng_1_5_on.png",
-  DATA_PREFIX "/images/status/opt_rng_6_12.png",
-  DATA_PREFIX "/images/status/opt_rng_6_12_on.png",
-  DATA_PREFIX "/images/status/opt_rng_13_20.png",
-  DATA_PREFIX "/images/status/opt_rng_13_20_on.png",
-  DATA_PREFIX "/images/status/opt_check.png",
-  DATA_PREFIX "/images/status/opt_check_on.png",
-  DATA_PREFIX "/images/cities/city-blue.png",
-  DATA_PREFIX "/images/cities/csplode-blue-1.png",
-  DATA_PREFIX "/images/cities/csplode-blue-2.png",
-  DATA_PREFIX "/images/cities/csplode-blue-3.png",
-  DATA_PREFIX "/images/cities/csplode-blue-4.png",
-  DATA_PREFIX "/images/cities/csplode-blue-5.png",
-  DATA_PREFIX "/images/cities/cdead-blue.png",
-  DATA_PREFIX "/images/cities/city-green.png",
-  DATA_PREFIX "/images/cities/csplode-green-1.png",
-  DATA_PREFIX "/images/cities/csplode-green-2.png",
-  DATA_PREFIX "/images/cities/csplode-green-3.png",
-  DATA_PREFIX "/images/cities/csplode-green-4.png",
-  DATA_PREFIX "/images/cities/csplode-green-5.png",
-  DATA_PREFIX "/images/cities/cdead-green.png",
-  DATA_PREFIX "/images/cities/city-orange.png",
-  DATA_PREFIX "/images/cities/csplode-orange-1.png",
-  DATA_PREFIX "/images/cities/csplode-orange-2.png",
-  DATA_PREFIX "/images/cities/csplode-orange-3.png",
-  DATA_PREFIX "/images/cities/csplode-orange-4.png",
-  DATA_PREFIX "/images/cities/csplode-orange-5.png",
-  DATA_PREFIX "/images/cities/cdead-orange.png",
-  DATA_PREFIX "/images/cities/city-red.png",
-  DATA_PREFIX "/images/cities/csplode-red-1.png",
-  DATA_PREFIX "/images/cities/csplode-red-2.png",
-  DATA_PREFIX "/images/cities/csplode-red-3.png",
-  DATA_PREFIX "/images/cities/csplode-red-4.png",
-  DATA_PREFIX "/images/cities/csplode-red-5.png",
-  DATA_PREFIX "/images/cities/cdead-red.png",
-  DATA_PREFIX "/images/cities/shields.png",
-  DATA_PREFIX "/images/comets/comet1.png",
-  DATA_PREFIX "/images/comets/comet2.png",
-  DATA_PREFIX "/images/comets/comet3.png",
-  DATA_PREFIX "/images/comets/cometex3.png",
-  DATA_PREFIX "/images/comets/cometex3.png",
-  DATA_PREFIX "/images/comets/cometex2.png",
-  DATA_PREFIX "/images/comets/cometex2.png",
-  DATA_PREFIX "/images/comets/cometex1a.png",
-  DATA_PREFIX "/images/comets/cometex1a.png",
-  DATA_PREFIX "/images/comets/cometex1.png",
-  DATA_PREFIX "/images/comets/cometex1.png",
-  DATA_PREFIX "/images/comets/mini_comet1.png",
-  DATA_PREFIX "/images/comets/mini_comet2.png",
-  DATA_PREFIX "/images/comets/mini_comet3.png",
-  DATA_PREFIX "/images/status/nums.png",
-  DATA_PREFIX "/images/status/lednums.png",
-  DATA_PREFIX "/images/status/led_neg_sign.png",
-  DATA_PREFIX "/images/status/paused.png",
-  DATA_PREFIX "/images/status/demo.png",
-  DATA_PREFIX "/images/status/demo-small.png",
-  DATA_PREFIX "/images/status/keypad.png",
-  DATA_PREFIX "/images/status/keypad_no_neg.png",
-  DATA_PREFIX "/images/tux/console.png",
-  DATA_PREFIX "/images/tux/console_led.png",
-  DATA_PREFIX "/images/tux/tux-console1.png",
-  DATA_PREFIX "/images/tux/tux-console2.png",
-  DATA_PREFIX "/images/tux/tux-console3.png",
-  DATA_PREFIX "/images/tux/tux-console4.png",
-  DATA_PREFIX "/images/tux/tux-relax1.png",
-  DATA_PREFIX "/images/tux/tux-relax2.png",
-  DATA_PREFIX "/images/tux/tux-egypt1.png",
-  DATA_PREFIX "/images/tux/tux-egypt2.png",
-  DATA_PREFIX "/images/tux/tux-egypt3.png",
-  DATA_PREFIX "/images/tux/tux-egypt4.png",
-  DATA_PREFIX "/images/tux/tux-drat.png",
-  DATA_PREFIX "/images/tux/tux-yipe.png",
-  DATA_PREFIX "/images/tux/tux-yay1.png",
-  DATA_PREFIX "/images/tux/tux-yay2.png",
-  DATA_PREFIX "/images/tux/tux-yes1.png",
-  DATA_PREFIX "/images/tux/tux-yes2.png",
-  DATA_PREFIX "/images/tux/tux-sit.png",
-  DATA_PREFIX "/images/tux/tux-fist1.png",
-  DATA_PREFIX "/images/tux/tux-fist2.png",
-  DATA_PREFIX "/images/status/wave.png",
-  DATA_PREFIX "/images/status/score.png",
-  DATA_PREFIX "/images/status/numbers.png",
-  DATA_PREFIX "/images/status/gameover.png",
-  DATA_PREFIX "/images/status/gameover_won.png"
-};
 
 
-static char * sound_filenames[NUM_SOUNDS] = {
-  DATA_PREFIX "/sounds/pop.wav",
-  DATA_PREFIX "/sounds/laser.wav",
-  DATA_PREFIX "/sounds/buzz.wav",
-  DATA_PREFIX "/sounds/alarm.wav",
-  DATA_PREFIX "/sounds/shieldsdown.wav",
-  DATA_PREFIX "/sounds/explosion.wav",
-  DATA_PREFIX "/sounds/click.wav",
-  DATA_PREFIX "/sounds/SIZZLING.WAV"
-};
-
-static char * music_filenames[NUM_MUSICS] = {
-  DATA_PREFIX "/sounds/game.mod",
-  DATA_PREFIX "/sounds/game2.mod",
-  DATA_PREFIX "/sounds/game3.mod"
-};
-
 /* Global data used in setup.c:              */
 /* (These need to be 'extern'd in "setup.h") */
-SDL_Surface * screen;
-SDL_Surface * images[NUM_IMAGES];
+SDL_Surface* screen;
+SDL_Surface* images[NUM_IMAGES];
 
 #ifndef NOSOUND
-Mix_Chunk * sounds[NUM_SOUNDS];
-Mix_Music * musics[NUM_MUSICS];
+Mix_Chunk* sounds[NUM_SOUNDS];
+Mix_Music* musics[NUM_MUSICS];
 #endif
 
-FILE* config_file;
 
-int opers[NUM_OPERS], range_enabled[NUM_Q_RANGES];
-
-game_option_type* game_options;
-
 /* Local function prototypes: */
+void initialize_options(void);
+void handle_command_args(int argc, char* argv[]);
+void initialize_SDL(void);
+void load_data_files(void);
 
+int initialize_game_options(void);
 void seticon(void);
 void usage(int err, char * cmd);
-int initialize_game_options(game_option_type* opts);
+
 void cleanup_memory(void);
-void cleanup_options(void);
 
-/* --- Set-up function! --- */
 
+
+/* --- Set-up function - now in four easier-to-digest courses! --- */
+
 void setup(int argc, char * argv[])
 {
-  int i, j, found, total_files;
-  SDL_Rect dest;
+  /* initialize settings and read in config files: */
+  initialize_options();
+  /* Command-line code now in own function: */
+  handle_command_args(argc, argv);
+  /* SDL setup in own function:*/
+  initialize_SDL();
+  /* Read image and sound files: */
+  load_data_files();
+}
 
-  screen = NULL;
 
+
+
+/* Set up mathcards with default values for math question options, */
+/* set up game_options with defaults for general game options,     */
+/* then read in global config file, followed if desired by user's  */
+/* own config file:                                                */
+void initialize_options(void)
+{
   /* Initialize MathCards backend for math questions: */
   if (!MC_Initialize())
   {
@@ -216,7 +104,7 @@
 
   /* initialize game_options struct with defaults DSB */
   game_options = malloc(sizeof(game_option_type));
-  if (!initialize_game_options(game_options))
+  if (!initialize_game_options())
   {
     printf("\nUnable to initialize game_options\n");
     fprintf(stderr, "\nUnable to initialize game_options\n");
@@ -227,12 +115,10 @@
   /* Now that MathCards and game_options initialized using  */
   /* hard-coded defaults, read options from disk and mofify */
   /* as needed. First read in installation-wide settings:   */
-  config_file = fopen(DATA_PREFIX ".tuxmath", "r");
-  if (config_file)
+  if (!read_global_config_file())
   {
-    read_config_file(config_file, GLOBAL_CONFIG_FILE);
-    fclose(config_file);
-    config_file = NULL;
+    fprintf(stderr, "\nCould not find global config file.\n");
+    /* can still proceed using hard-coded defaults.         */
   }
 
   /* Now read in user-specific settings, if desired.  By    */
@@ -240,63 +126,22 @@
   /* game:                                                  */
   if (game_options->per_user_config)
   {
-    /* find $HOME and tack on file name: */
-    char* home_dir;
-    home_dir = malloc(sizeof(char)*PATH_MAX);
-
-    strcpy(home_dir, getenv("HOME"));
-
-    #ifdef TUXMATH_DEBUG
-    printf("\nIn setup() home directory is: = %s\n", home_dir);
-    #endif
-
-    strcat(home_dir, "/.tuxmath");
-
-    #ifdef TUXMATH_DEBUG
-    printf("\nIn setup() config file: = %s\n", home_dir);
-    #endif
-
-    config_file = fopen(home_dir, "r");
-    if (config_file)
+    if (!read_user_config_file())
     {
-      read_config_file(config_file, USER_CONFIG_FILE);
-      fclose(config_file);
-      config_file = NULL;
+      fprintf(stderr, "\nCould not find user's config file.\n");
+      /* can still proceed using hard-coded defaults.         */
     }
-    free(home_dir);
   }
+}
 
-  for (i = 0; i < NUM_Q_RANGES; i++)
-  { 
-    range_enabled[i] = 1;
-  }
 
 
-  /* See if operator settings are being overridden by command-line: */
 
-  for (i = 1; i < argc; i++)
-  {
-    if (strcmp(argv[i], "--operator") == 0 ||
-        strcmp(argv[i], "-o") == 0)
-    {
-      game_options->oper_override = 1;
-    }
-  }
+/* Handle any arguments passed from command line */
+void handle_command_args(int argc, char* argv[])
+{
+  int i, j, found;
 
-
-  /* If operator settings are being overridden, clear them first: */
-
-  if (game_options->oper_override)
-  {
-    for (i = 0; i < NUM_OPERS; i++)
-    {
-      opers[i] = 0;
-    }
-  }
-
-
-  /* Get options from the command line: */
-
   for (i = 1; i < argc; i++)
   {
     if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0)
@@ -310,14 +155,20 @@
         "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");
 
-      printf("Note: all settings are now stored in a config file named '.tuxmath' in\n"
-             "the user's home directory as simple name/value pairs. It is much easier\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"
+             "The file consists of simple name/value pairs. It is much easier\n"
              "to edit this file to set game parameters than to use the command-line\n"
              "arguments listed below. Also, many options are not selectable from the\n"
              "command line. The config file contains extensive comments detailing how\n"
              "to configure the behavior of Tuxmath.\n\n");
 
       printf("Run the game with:\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"
+        "                         filename, tuxmath's missions directory, the user's\n"
+        "                         tuxmath directory, and the user's home.\n"
         "--playthroughlist      - to ask each question only once, allowing player to\n"
         "                         win game if all questions successfully answered\n"
 
@@ -345,8 +196,7 @@
         printf("                   \"%s\"\n", oper_alt_opts[j]);
 
       printf("\n");
-      
-
+    
       cleanup_on_error();
       exit(0);
     }
@@ -374,6 +224,23 @@
 	    
       usage(0, argv[0]);
     }
+    /* TODO implement --optionfile filename */
+    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]);
+      }
+      else /* try to read file named in following arg: */
+      {
+        if (!read_named_config_file(argv[i + 1])) 
+        {
+          fprintf(stderr, "Could not read config file: %s\n", argv[i + 1]);
+        }
+      }
+      i++; /* so program doesn't barf on next arg (the filename) */
+    }
     else if (strcmp(argv[i], "--fullscreen") == 0 ||
 	     strcmp(argv[i], "-f") == 0)
     {
@@ -451,6 +318,8 @@
 
       i++;
     }
+
+    /* FIXME this does not currently work */
     else if (strcmp(argv[i], "--operator") == 0 ||
 	     strcmp(argv[i], "-o") == 0)
     {
@@ -480,13 +349,14 @@
       i++;
     }
     else
+    /* TODO try to match unrecognized strings to config file names */
     {
       /* Display 'made' usage: */
 
       fprintf(stderr, "Unknown option: %s\n", argv[i]);
       usage(1, argv[0]);
     }
-  }
+  }/* end of command-line args */
 
 
   if (game_options->demo_mode && game_options->use_keypad)
@@ -494,58 +364,57 @@
     fprintf(stderr, "No use for keypad in demo mode!\n");
     game_options->use_keypad = 0;
   }
+}
 
+
+
+
+void initialize_SDL(void)
+{
   /* Init SDL Video: */
+  screen = NULL;
 
   if (SDL_Init(SDL_INIT_VIDEO) < 0)
-    {
-      fprintf(stderr,
-	      "\nError: I could not initialize video!\n"
-	      "The Simple DirectMedia error that occured was:\n"
-	      "%s\n\n", SDL_GetError());
-      cleanup_on_error();
-      exit(1);
-    }
+  {
+    fprintf(stderr,
+           "\nError: I could not initialize video!\n"
+	   "The Simple DirectMedia error that occured was:\n"
+	   "%s\n\n", SDL_GetError());
+    cleanup_on_error();
+    exit(1);
+  }
 
-  /* Init SDL Audio: */
 
-#ifndef NOSOUND
-
+  #ifndef NOSOUND
+  /* Init SDL Audio: */
   if (game_options->use_sound)
-    { 
-      if (SDL_Init(SDL_INIT_AUDIO) < 0)
-        {
-          fprintf(stderr,
-  	          "\nWarning: I could not initialize audio!\n"
-	          "The Simple DirectMedia error that occured was:\n"
-	          "%s\n\n", SDL_GetError());
-	  game_options->use_sound = 0;
-        }
+  { 
+    if (SDL_Init(SDL_INIT_AUDIO) < 0)
+    {
+      fprintf(stderr,
+            "\nWarning: I could not initialize audio!\n"
+            "The Simple DirectMedia error that occured was:\n"
+            "%s\n\n", SDL_GetError());
+      game_options->sound_available = 0;
     }
+  }
 
  
   if (game_options->use_sound)
   {
-       if (Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 2048) < 0)
-        {
-          printf( "\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());
+    if (Mix_OpenAudio(44100, 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());
+      game_options->sound_available = 0;
+    }
+  }
+  #endif
 
-          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());
-          game_options->use_sound = 0;
-        }
-   }
 
-#endif
-
- 
-
   if (game_options->fullscreen)
   {
     screen = SDL_SetVideoMode(640, 480, 16, SDL_FULLSCREEN | SDL_HWSURFACE);
@@ -578,193 +447,63 @@
   seticon();
 
   SDL_WM_SetCaption("Tux, of Math Command", "TuxMath");
+}
 
-  if (game_options->use_sound)
-    total_files = NUM_IMAGES + NUM_SOUNDS + NUM_MUSICS;
-  else
-    total_files = NUM_IMAGES;
 
 
-  
-  /* Load images: */
-  for (i = 0; i < NUM_IMAGES; i++)
+void load_data_files(void)
+{
+  if (!load_image_data())
   {
-    images[i] = IMG_Load(image_filenames[i]);
-    if (images[i] == NULL)
-      {
-	fprintf(stderr,
-		"\nError: I couldn't load a graphics file:\n"
-		"%s\n"
-		"The Simple DirectMedia error that occured was:\n"
-		"%s\n\n", image_filenames[i], SDL_GetError());
-        cleanup_on_error();
-	exit(1);
-      }
-
-    
-    if (i == IMG_STANDBY)
-      {
-	dest.x = (screen->w - images[IMG_STANDBY]->w) / 2;
-	dest.y = screen->h - images[IMG_STANDBY]->h - 10;
-	dest.w = images[IMG_STANDBY]->w;
-	dest.h = images[IMG_STANDBY]->h;
-	
-	SDL_BlitSurface(images[IMG_STANDBY], NULL, screen, &dest);
-	SDL_Flip(screen);
-      }
-    else if (i == IMG_LOADING)
-      {
-	dest.x = (screen->w - images[IMG_LOADING]->w) / 2;
-	dest.y = 0;
-	dest.w = images[IMG_LOADING]->w;
-	dest.h = images[IMG_LOADING]->h;
-	
-	SDL_BlitSurface(images[IMG_LOADING], NULL, screen, &dest);
-	SDL_Flip(screen);
-      }
-    else if (i == IMG_TITLE)
-      {
-	dest.x = (screen->w - images[IMG_TITLE]->w) / 2;
-	dest.y = images[IMG_LOADING]->h;
-	dest.w = images[IMG_TITLE]->w;
-	dest.h = images[IMG_TITLE]->h;
-	
-	SDL_BlitSurface(images[IMG_TITLE], NULL, screen, &dest);
-	SDL_Flip(screen);
-      }
-    
-    
-    dest.x = 0;
-    dest.y = (screen->h) - 10;
-    dest.w = ((screen->w) * (i + 1)) / total_files;
-    dest.h = 10;
-    
-    SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 255, 0));
-    SDL_Flip(screen);
+    fprintf(stderr, "\nCould not load image file - exiting!\n");
+    cleanup_on_error();
+    exit(1);
   }
-
-
-#ifndef NOSOUND
-  if (game_options->use_sound)
+  
+  if (!load_sound_data())
   {
-    for (i = 0; i < NUM_SOUNDS; i++)
-    {
-      sounds[i] = Mix_LoadWAV(sound_filenames[i]);
-
-      if (sounds[i] == NULL)
-      {
-        fprintf(stderr,
-	        "\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());
-        cleanup_on_error();
-        exit(1);
-      }
-      
-      dest.x = 0;
-      dest.y = (screen->h) - 10;
-      dest.w = ((screen->w) * (i + 1 + NUM_IMAGES)) / total_files;
-      dest.h = 10;
-
-      SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 255, 0));
-      SDL_Flip(screen);
-    }
-
-
-    for (i = 0; i < NUM_MUSICS; i++)
-    {
-      musics[i] = Mix_LoadMUS(music_filenames[i]);
-
-      if (musics[i] == NULL)
-      {
-        fprintf(stderr,
-	        "\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());
-        cleanup_on_error();
-        exit(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));
-      SDL_Flip(screen);
-    }
+    fprintf(stderr, "\nCould not load sound file - attempting to proceed without sound.\n");
+    game_options->sound_available = 0;
   }
-#endif
-  
 
-  for (i = images[IMG_LOADING]->h; i >= 0; i = i - 10)
-    {
-      SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
-
-      dest.x = (screen->w - images[IMG_TITLE]->w) / 2;
-      dest.y = i;
-      dest.w = images[IMG_TITLE]->w;
-      dest.h = images[IMG_TITLE]->h;
-      
-      SDL_BlitSurface(images[IMG_TITLE], NULL, screen, &dest);
-      SDL_Flip(screen);
-      SDL_Delay(10);
-    }
+  
+  /* FIXME what does this do? */
+//   for (i = images[IMG_LOADING]->h; i >= 0; i = i - 10)
+//     {
+//       SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
+// 
+//       dest.x = (screen->w - images[IMG_TITLE]->w) / 2;
+//       dest.y = i;
+//       dest.w = images[IMG_TITLE]->w;
+//       dest.h = images[IMG_TITLE]->h;
+//       
+//       SDL_BlitSurface(images[IMG_TITLE], NULL, screen, &dest);
+//       SDL_Flip(screen);
+//       SDL_Delay(10);
+//     }
 }
 
 /* save options and free heap */
 /* use for successful exit */
-void cleanup()
-
+void cleanup(void)
 {
-	cleanup_options();
-	cleanup_memory();
+  write_user_config_file();
+  cleanup_memory();
 }
 
+
+
 /* save options and free heap */
 /* use for fail exit */
-void cleanup_on_error()
-
+void cleanup_on_error(void)
 {
-	cleanup_memory();
+  cleanup_memory();
 }
 
-/* save options */
-void cleanup_options()
 
-{
-  /* find $HOME and tack on file name: */
-  char* home_dir;
-  home_dir = malloc(sizeof(char)*PATH_MAX);
 
-  strcpy(home_dir, getenv("HOME"));
-
-  #ifdef TUXMATH_DEBUG
-  printf("\nIn cleanup() home directory is: = %s\n", home_dir);
-  #endif
-
-  strcat(home_dir, "/.tuxmath");
-
-  #ifdef TUXMATH_DEBUG
-  printf("\nIn cleanup() config file: = %s\n", home_dir);
-  #endif
-
-  /* save settings: */
-  config_file = fopen(home_dir, "w");
-  if (config_file)
-  {
-    write_config_file(config_file);
-    fclose(config_file);
-    config_file = NULL;
-  }
-  free(home_dir);
-}
-
 /* free any heap memory used during game DSB */
-void cleanup_memory()
-
+void cleanup_memory(void)
 {
   SDL_Quit();
   if (game_options)
@@ -775,31 +514,32 @@
 
 
 
-int initialize_game_options(game_option_type* opts)
+int initialize_game_options(void)
 {
   /* bail out if no struct */
-  if (!opts)
+  if (!game_options)
     return 0;
 
   /* set general game options */
-  opts->per_user_config = DEFAULT_PER_USER_CONFIG;
-  opts->use_sound = DEFAULT_USE_SOUND;
-  opts->fullscreen = DEFAULT_FULLSCREEN;
-  opts->use_bkgd = DEFAULT_USE_BKGD;
-  opts->demo_mode = DEFAULT_DEMO_MODE;
-  opts->oper_override = DEFAULT_OPER_OVERRIDE;
-  opts->use_keypad = DEFAULT_USE_KEYPAD;
-  opts->speed = DEFAULT_SPEED;
-  opts->allow_speedup = DEFAULT_ALLOW_SPEEDUP;
-  opts->speedup_factor = DEFAULT_SPEEDUP_FACTOR;
-  opts->max_speed = DEFAULT_MAX_SPEED;
-  opts->slow_after_wrong = DEFAULT_SLOW_AFTER_WRONG;
-  opts->starting_comets = DEFAULT_STARTING_COMETS;
-  opts->extra_comets_per_wave = DEFAULT_EXTRA_COMETS_PER_WAVE;
-  opts->max_comets = DEFAULT_MAX_COMETS;
-  opts->num_cities = DEFAULT_NUM_CITIES;   /* MUST BE AN EVEN NUMBER! */
-  opts->num_bkgds = DEFAULT_NUM_BKGDS;
-  opts->max_city_colors = DEFAULT_MAX_CITY_COLORS;
+  game_options->per_user_config = DEFAULT_PER_USER_CONFIG;
+  game_options->use_sound = DEFAULT_USE_SOUND;
+  game_options->fullscreen = DEFAULT_FULLSCREEN;
+  game_options->use_bkgd = DEFAULT_USE_BKGD;
+  game_options->demo_mode = DEFAULT_DEMO_MODE;
+  game_options->oper_override = DEFAULT_OPER_OVERRIDE;
+  game_options->use_keypad = DEFAULT_USE_KEYPAD;
+  game_options->speed = DEFAULT_SPEED;
+  game_options->allow_speedup = DEFAULT_ALLOW_SPEEDUP;
+  game_options->speedup_factor = DEFAULT_SPEEDUP_FACTOR;
+  game_options->max_speed = DEFAULT_MAX_SPEED;
+  game_options->slow_after_wrong = DEFAULT_SLOW_AFTER_WRONG;
+  game_options->starting_comets = DEFAULT_STARTING_COMETS;
+  game_options->extra_comets_per_wave = DEFAULT_EXTRA_COMETS_PER_WAVE;
+  game_options->max_comets = DEFAULT_MAX_COMETS;
+  game_options->sound_available = DEFAULT_SOUND_AVAILABLE;
+  game_options->num_cities = DEFAULT_NUM_CITIES;   /* MUST BE AN EVEN NUMBER! */
+  game_options->num_bkgds = DEFAULT_NUM_BKGDS;
+  game_options->max_city_colors = DEFAULT_MAX_CITY_COLORS;
 
   #ifdef TUXMATH_DEBUG
   print_game_options(stdout, 0);
@@ -808,152 +548,15 @@
   return 1;
 }
 
-
-
-/* prints struct to stream for testing purposes */
-/* TODO include more info/help about these options in output */
-void print_game_options(FILE* fp, int verbose)
+/* Returns true if only if the player wants to use sound */
+/* and the sound system is actually available:           */
+int opts_using_sound(void)
 {
- /* bail out if no struct */
-  if (!game_options)
-  {
-    fprintf(stderr, "print_game_options(): invalid game_option_type struct");
-    return;
-  }
+  return (game_options->use_sound && game_options->sound_available);
+}
 
-  if(verbose)
-  {
-    fprintf (fp, "\n############################################################\n" 
-                 "#                                                          #\n"
-                 "#                 General Game Options                     #\n"
-                 "#                                                          #\n"
-                 "# The following options are boolean (true/false) variables #\n"
-                 "# that control various aspects of Tuxmath's behavior.      #\n"
-                 "# The program writes the values to the file as either '0'  #\n"
-                 "# or '1'. However, the program accepts 'n', 'no', 'f', and #\n"
-                 "# 'false' as synonyms for '0', and similarly accepts 'y',  #\n"
-                 "# 'yes', 't', and 'true' as synonyms for '1' (all case-    #\n"
-                 "# insensitive).                                            #\n"
-                 "############################################################\n\n");
-  }
 
-  if(verbose)
-  {
-    fprintf (fp, "############################################################\n" 
-                 "# 'per_user_config' determines whether Tuxmath will look   #\n"
-                 "# in the user's home directory for settings. Default is 1  #\n"
-                 "# (yes). If deselected, the program will ignore the user's #\n"
-                 "# .tuxmath file and use the the global settings in the     #\n"
-                 "# installation-wide config file.                           #\n"
-                 "# This setting cannot be changed by an ordinary user.      #\n"
-                 "############################################################\n");
-  }
-  fprintf(fp, "per_user_config = %d\n", game_options->per_user_config);
 
-  if(verbose)
-  {
-    fprintf (fp, "\n# Self-explanatory, default is 1:\n");
-  }
-  fprintf(fp, "use_sound = %d\n", game_options->use_sound);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Use either fullscreen at 640x480 resolution or window of that size\n"
-                 "# Default is 1.  Change to 0 if SDL has trouble with fullscreen.\n");
-  } 
-  fprintf(fp, "fullscreen = %d\n", game_options->fullscreen);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Use 640x480 jpg image for background; default is 1.\n");
-  }
-  fprintf(fp, "use_bkgd = %d\n", game_options->use_bkgd);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Program runs as demo; default is 0.\n");
-  }
-  fprintf(fp, "demo_mode = %d\n", game_options->demo_mode);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Use operator selection from command line; default is 0.\n");
-  }
-  fprintf(fp, "oper_override = %d\n", game_options->oper_override);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Display onscreen numeric keypad; default is 0.\n");
-  }
-  fprintf(fp, "use_keypad = %d\n", game_options->use_keypad);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n############################################################\n" 
-                 "# The remaining settings determine the speed and number    #\n"
-                 "# of comets.  The speed settings are float numbers (mean-  #\n"
-                 "# ing decimals allowed). The comet settings are integers.  #\n"
-                 "############################################################\n");
-  }
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Starting comet speed. Default is 1.\n");
-  }
-  fprintf(fp, "speed = %f\n", game_options->speed);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Speed is multiplied by this factor with each new wave.\n"
-                 "# Default is 1.2\n");
-  }
-  fprintf(fp, "speedup_factor = %f\n", game_options->speedup_factor);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Maximum speed. Default is 10.\n");
-  }
-  fprintf(fp, "max_speed = %f\n", game_options->max_speed);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Number of comets for first wave. Default is 2.\n");
-  }
-  fprintf(fp, "starting_comets = %d\n", game_options->starting_comets);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Comets to add for each successive wave. Default is 2.\n");
-  }
-  fprintf(fp, "extra_comets_per_wave = %d\n", game_options->extra_comets_per_wave);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Maximum number of comets. Default is 10.\n");
-  }
-  fprintf(fp, "max_comets = %d\n", game_options->max_comets);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Allow speed and number of comets to increase with each\n"
-                 "# wave.  May want to turn this off for smaller kids. Default is 1.\n");
-  }
-  fprintf(fp, "allow_speedup = %d\n", game_options->allow_speedup);
-
-  if(verbose)
-  {
-    fprintf (fp, "\n# Go back to starting speed and number of comets if player\n"
-                 "# misses a question. Useful for smaller kids. Default is 0.\n");
-  }
-  fprintf(fp, "slow_after_wrong = %d\n", game_options->slow_after_wrong);
-
-/*
-  fprintf(fp, "num_cities = %d\n", game_options->num_cities);
-  fprintf(fp, "num_bkgds = %d\n", game_options->num_bkgds);
-  fprintf(fp, "max_city_colors = %d\n", game_options->max_city_colors);
-*/
-}
-
 /* Set the application's icon: */
 
 void seticon(void)
@@ -1010,6 +613,8 @@
 
   fprintf(f,
    "\nUsage: %s {--help | --usage | --copyright}\n"
+   "          [--optionfile <filename>]\n"
+   "          [--playthroughlist] [--answersfirst] [--answersmiddle]\n"
    "       %s [--fullscreen] [--nosound] [--nobackground]\n"
    "          [--demo] [--keypad] [--allownegatives]\n"
    "          [--operator {add | subtract | multiply | divide} ...]\n"

Modified: tuxmath/trunk/src/setup.h
===================================================================
--- tuxmath/trunk/src/setup.h	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/setup.h	2006-09-03 16:37:34 UTC (rev 23)
@@ -2,10 +2,14 @@
   setup.h
 
   For TuxMath
-  Contains some globals (screen surface, images, some option flags, etc.)
-  as well as the function to load data files (images, sounds, music)
-  and display a "Loading..." screen.
+  Contains functions to initialize the settings structs, 
+  read in command-line arguments, and to clean up on exit.
+  All code involving file I/O has been moved to fileops.h/fileops.c
+  and is called from the main setup function.
 
+  Some globals are declared in setup.c - all globals throught tuxmath
+  are now extern'd in the same place in tuxmath.h
+
   by Bill Kendrick
   bill at newbreedsoftware.com
   http://www.newbreedsoftware.com/
@@ -15,33 +19,20 @@
   http://www.tux4kids.org/
       
   August 26, 2001 - February 18, 2004
+
+  Modified by David Bruce
+  dbruce at tampabay.rr.com
+  September 1, 2006
 */
 
 
 #ifndef SETUP_H
 #define SETUP_H
 
-#include <SDL.h>
 
-#ifndef NOSOUND
-#include <SDL_mixer.h>
-#endif
-
-#include "game.h"
-
-
-extern SDL_Surface * screen;
-extern SDL_Surface * images[];
-#ifndef NOSOUND
-extern Mix_Chunk * sounds[];
-extern Mix_Music * musics[];
-#endif
-
-extern int opers[NUM_OPERS], range_enabled[NUM_Q_RANGES];
-
 void setup(int argc, char * argv[]);
 void cleanup(void);
 void cleanup_on_error(void);
 
-void print_game_options(FILE* fp, int verbose);
+int opts_using_sound(void);
 #endif

Deleted: tuxmath/trunk/src/sounds.h
===================================================================
--- tuxmath/trunk/src/sounds.h	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/sounds.h	2006-09-03 16:37:34 UTC (rev 23)
@@ -1,40 +0,0 @@
-/*
-  sounds.h
-
-  For tuxmath
-
-  by Bill Kendrick
-  bill at newbreedsoftware.com
-  http://www.newbreedsoftware.com/
-
-
-  Part of "Tux4Kids" Project
-  http://www.tux4kids.org/
-      
-  August 26, 2001 - August 31, 2001
-*/
-
-
-#ifndef SOUNDS_H
-#define SOUNDS_H
-
-enum {
-  SND_POP,
-  SND_LASER,
-  SND_BUZZ,
-  SND_ALARM,
-  SND_SHIELDSDOWN,
-  SND_EXPLOSION,
-  SND_CLICK,
-  SND_SIZZLE,
-  NUM_SOUNDS
-};
-
-enum {
-  MUS_GAME,
-  MUS_GAME2,
-  MUS_GAME3,
-  NUM_MUSICS
-};
-
-#endif

Modified: tuxmath/trunk/src/title.c
===================================================================
--- tuxmath/trunk/src/title.c	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/title.c	2006-09-03 16:37:34 UTC (rev 23)
@@ -24,9 +24,8 @@
 
 #include "tuxmath.h"
 #include "title.h"
-#include "images.h"
+#include "fileops.h"
 #include "setup.h"
-#include "sounds.h"
 #include "playsound.h"
 
 

Modified: tuxmath/trunk/src/tuxmath.h
===================================================================
--- tuxmath/trunk/src/tuxmath.h	2006-08-22 10:26:25 UTC (rev 22)
+++ tuxmath/trunk/src/tuxmath.h	2006-09-03 16:37:34 UTC (rev 23)
@@ -17,13 +17,45 @@
   (briefly - GNU GPL v2 or later)
 */
 
+
+
 #ifndef TUXMATH_H
 #define TUXMATH_H
 
+#include <SDL.h>
+
+#ifndef NOSOUND
+#include <SDL_mixer.h>
+#endif
+
 //#define NOSOUND
 //#define TUXMATH_DEBUG   /* for conditional compilation of debugging output */
-#define TUXMATH_VERSION 0.92
+#define TUXMATH_VERSION 0.93
 
+#define PATH_MAX 4096
+
+/* default values for game_options */
+#define DEFAULT_PER_USER_CONFIG 1
+#define DEFAULT_USE_SOUND 1
+#define DEFAULT_FULLSCREEN 1
+#define DEFAULT_USE_BKGD 1
+#define DEFAULT_DEMO_MODE 0
+#define DEFAULT_OPER_OVERRIDE 0
+#define DEFAULT_USE_KEYPAD 0
+#define DEFAULT_SPEED 1
+#define DEFAULT_ALLOW_SPEEDUP 1
+#define DEFAULT_SPEEDUP_FACTOR 1.2
+#define DEFAULT_MAX_SPEED 10
+#define DEFAULT_SLOW_AFTER_WRONG 0
+#define DEFAULT_STARTING_COMETS 2
+#define DEFAULT_EXTRA_COMETS_PER_WAVE 2
+#define DEFAULT_MAX_COMETS 10	
+#define DEFAULT_SOUND_AVAILABLE 1
+#define DEFAULT_NUM_CITIES 4   /* MUST BE AN EVEN NUMBER! */
+#define DEFAULT_NUM_BKGDS 5
+#define DEFAULT_MAX_CITY_COLORS 4
+
+
 /* this struct contains all options regarding general       */
 /* gameplay but not having to do with math questions per se */
 typedef struct game_option_type {
@@ -43,36 +75,53 @@
   int starting_comets;
   int extra_comets_per_wave;
   int max_comets;  
+  char next_mission[PATH_MAX];
+  /* whether sound system is successfully initialized and sound files loaded: */
+  /* this flag is set by the program, not the user, and is not in the config file. */
+  int sound_available;
   /* not sure the rest of these belong in here */
   int num_cities;  /* MUST BE AN EVEN NUMBER! */
   int num_bkgds;
   int max_city_colors;
 } game_option_type;
 
+typedef struct range_type {
+  int min;
+  int max;
+} range_type;
 
-/* make option data accessible to rest of program */
+enum {
+  OPER_ADD,
+  OPER_SUB,
+  OPER_MULT,
+  OPER_DIV,
+  NUM_OPERS
+};
+
+enum {
+  Q_RANGE_1_5,
+  Q_RANGE_6_12,
+  Q_RANGE_13_20,
+  NUM_Q_RANGES
+};
+
+
+/* Global data gets 'externed' here: */
 extern game_option_type* game_options; /* used by setup.c, options.c, game.c */
 
-/* default values for game_options */
-#define DEFAULT_PER_USER_CONFIG 1
-#define DEFAULT_USE_SOUND 1
-#define DEFAULT_FULLSCREEN 1
-#define DEFAULT_USE_BKGD 1
-#define DEFAULT_DEMO_MODE 0
-#define DEFAULT_OPER_OVERRIDE 0
-#define DEFAULT_USE_KEYPAD 0
-#define DEFAULT_SPEED 1
-#define DEFAULT_ALLOW_SPEEDUP 1
-#define DEFAULT_SPEEDUP_FACTOR 1.2
-#define DEFAULT_MAX_SPEED 10
-#define DEFAULT_SLOW_AFTER_WRONG 0
-#define DEFAULT_STARTING_COMETS 2
-#define DEFAULT_EXTRA_COMETS_PER_WAVE 2
-#define DEFAULT_MAX_COMETS 10	
-#define DEFAULT_NUM_CITIES 4   /* MUST BE AN EVEN NUMBER! */
-#define DEFAULT_NUM_BKGDS 5
-#define DEFAULT_MAX_CITY_COLORS 4
+extern SDL_Surface* screen;
+extern SDL_Surface* images[];
+#ifndef NOSOUND
+extern Mix_Chunk* sounds[];
+extern Mix_Music* musics[];
+#endif
 
+extern char operchars[NUM_OPERS];
+extern char* oper_opts[NUM_OPERS];
+extern char* oper_alt_opts[NUM_OPERS];
+extern range_type ranges[NUM_Q_RANGES];
+extern int opers[NUM_OPERS], range_enabled[NUM_Q_RANGES];
+
 /* NOTE: default values for math options are now in mathcards.h */
 
 #endif




More information about the Tux4kids-commits mailing list