[Tux4kids-commits] r446 - in tuxtype/branches/tuxtype-new: . doc doc/en nsis src

dbruce-guest at alioth.debian.org dbruce-guest at alioth.debian.org
Sat Mar 29 14:52:15 UTC 2008


Author: dbruce-guest
Date: 2008-03-29 14:52:14 +0000 (Sat, 29 Mar 2008)
New Revision: 446

Added:
   tuxtype/branches/tuxtype-new/Makefile.am~
   tuxtype/branches/tuxtype-new/configure.ac~
   tuxtype/branches/tuxtype-new/depcomp
   tuxtype/branches/tuxtype-new/doc/
   tuxtype/branches/tuxtype-new/doc/AUTHORS
   tuxtype/branches/tuxtype-new/doc/COPYING
   tuxtype/branches/tuxtype-new/doc/ChangeLog
   tuxtype/branches/tuxtype-new/doc/INSTALL
   tuxtype/branches/tuxtype-new/doc/INSTALL-Win32
   tuxtype/branches/tuxtype-new/doc/Makefile.am
   tuxtype/branches/tuxtype-new/doc/Makefile.in
   tuxtype/branches/tuxtype-new/doc/OFL
   tuxtype/branches/tuxtype-new/doc/README
   tuxtype/branches/tuxtype-new/doc/TODO
   tuxtype/branches/tuxtype-new/doc/en/
   tuxtype/branches/tuxtype-new/doc/en/Makefile
   tuxtype/branches/tuxtype-new/doc/en/Makefile.am
   tuxtype/branches/tuxtype-new/doc/en/Makefile.in
   tuxtype/branches/tuxtype-new/doc/en/TuxType_port_Mac.txt
   tuxtype/branches/tuxtype-new/doc/en/howtotheme.html
   tuxtype/branches/tuxtype-new/install-sh
   tuxtype/branches/tuxtype-new/missing
   tuxtype/branches/tuxtype-new/mkinstalldirs
   tuxtype/branches/tuxtype-new/nsis/
   tuxtype/branches/tuxtype-new/nsis/tuxtype.nsi.in
   tuxtype/branches/tuxtype-new/src/
   tuxtype/branches/tuxtype-new/src/ConvertUTF.c
   tuxtype/branches/tuxtype-new/src/ConvertUTF.h
   tuxtype/branches/tuxtype-new/src/Makefile.am
   tuxtype/branches/tuxtype-new/src/Makefile.in
   tuxtype/branches/tuxtype-new/src/SDLMain.h
   tuxtype/branches/tuxtype-new/src/alphabet.c
   tuxtype/branches/tuxtype-new/src/audio.c
   tuxtype/branches/tuxtype-new/src/funcs.h
   tuxtype/branches/tuxtype-new/src/gettext.c
   tuxtype/branches/tuxtype-new/src/globals.h
   tuxtype/branches/tuxtype-new/src/laser.c
   tuxtype/branches/tuxtype-new/src/laser.h
   tuxtype/branches/tuxtype-new/src/loaders.c
   tuxtype/branches/tuxtype-new/src/main.c
   tuxtype/branches/tuxtype-new/src/options.c
   tuxtype/branches/tuxtype-new/src/pause.c
   tuxtype/branches/tuxtype-new/src/playgame.c
   tuxtype/branches/tuxtype-new/src/playgame.h
   tuxtype/branches/tuxtype-new/src/practice.c
   tuxtype/branches/tuxtype-new/src/scripting.c
   tuxtype/branches/tuxtype-new/src/scripting.h
   tuxtype/branches/tuxtype-new/src/setup.c
   tuxtype/branches/tuxtype-new/src/snow.c
   tuxtype/branches/tuxtype-new/src/snow.h
   tuxtype/branches/tuxtype-new/src/theme.c
   tuxtype/branches/tuxtype-new/src/titlescreen.c
   tuxtype/branches/tuxtype-new/src/titlescreen.h
   tuxtype/branches/tuxtype-new/stamp-h1
   tuxtype/branches/tuxtype-new/tuxtype.ico
   tuxtype/branches/tuxtype-new/tuxtype.lsm
   tuxtype/branches/tuxtype-new/tuxtype.spec.in
   tuxtype/branches/tuxtype-new/tuxtypereorg.kdevelop
Log:
adding tuxtype-new


Added: tuxtype/branches/tuxtype-new/Makefile.am~
===================================================================
--- tuxtype/branches/tuxtype-new/Makefile.am~	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/Makefile.am~	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,71 @@
+# Modified to include support for NSIS Windows installer - David Bruce <dbruce at tampabay.rr.com>
+MAKENSIS=@NSIS@
+
+SUBDIRS = data doc src
+
+EXTRA_DIST = AUTHORS COPYING ChangeLog INSTALL README TODO tuxtype.lsm tuxtype.spec tuxtype.spec.in config.h autorun.inf tuxtype.ico
+
+install-data-local:
+	$(MKDIR_P) $(DESTDIR)$(prefix)/doc/$(PACKAGE)
+	$(INSTALL_DATA) $(srcdir)/ChangeLog $(DESTDIR)$(prefix)/doc/$(PACKAGE)/ChangeLog
+	$(INSTALL_DATA) $(srcdir)/tuxtype.lsm $(DESTDIR)$(prefix)/doc/$(PACKAGE)/tuxtype.lsm
+	$(MKDIR_P) $(DESTDIR)$(prefix)/share/$(PACKAGE)
+	$(INSTALL_DATA) $(srcdir)/tuxtype.ico $(DESTDIR)$(prefix)/share/$(PACKAGE)/tuxtype.ico
+	$(INSTALL_DATA) $(srcdir)/autorun.inf $(DESTDIR)$(prefix)/share/$(PACKAGE)/autorun.inf
+
+uninstall-local:
+	-rm -f $(DESTDIR)$(prefix)/doc/$(PACKAGE)/ChangeLog
+	-rm -f $(DESTDIR)$(prefix)/doc/$(PACKAGE)/tuxtype.lsm
+	-rm -rf $(DESTDIR)$(prefix)/doc/$(PACKAGE)
+	-rm -f $(DESTDIR)$(prefix)/share/$(PACKAGE)/autorun.inf
+	-rm -f $(DESTDIR)$(prefix)/share/$(PACKAGE)/tuxtype.ico
+	-rm -rf $(DESTDIR)$(prefix)/share/$(PACKAGE)
+
+# Now doing this in preferred way via AM_INIT_AUTOMAKE in configure.ac:
+#AUTOMAKE_OPTIONS = foreign 
+
+
+# Rule to build tar-gzipped distribution package
+$(PACKAGE)-$(VERSION).tar.gz: distcheck
+
+# Rule to build RPM distribution package
+rpm: $(PACKAGE)-$(VERSION).tar.gz
+	rpmbuild -ta $(PACKAGE)-$(VERSION).tar.gz
+
+# Rules needed to cross-build nsis Win32 installer under Linux
+# Taken from tuxmath's Makefile.am - David Bruce
+# This rule probably kludgy (hardcoded)- DSB
+install-nsi-local: all
+	$(INSTALL) -d $(top_srcdir)/$(NSI_INSTALL_DIR)/data;
+	$(INSTALL) -d $(top_srcdir)/$(NSI_INSTALL_DIR)/docs;
+
+	(cd $(top_srcdir)/tuxtype/data ; tar cf -  --exclude "Makefile.in" --exclude "*.in" --exclude "*~" --exclude \ "Makefile" --exclude "Makefile.am" --exclude CVS --exclude .xvpics --exclude "1[1-9].ogg"  --exclude "2?.ogg" --exclude "*.svn*" * ) \
+         | ( cd $(top_srcdir)/$(NSI_INSTALL_DIR)/data ; tar xf -) ; \
+	(cd $(top_srcdir)/tuxtype/docs ; tar cf -  --exclude "Makefile.in" --exclude "*.in" --exclude "*~" --exclude \ "Makefile" --exclude "Makefile.am" --exclude CVS --exclude .xvpics --exclude "1[1-9].ogg"  --exclude "2?.ogg" --exclude "*.svn*" * ) \
+         | ( cd $(top_srcdir)/$(NSI_INSTALL_DIR)/docs ; tar xf -) ; \
+	cp $(top_srcdir)/COPYING $(top_srcdir)/$(NSI_INSTALL_DIR)/docs/COPYING.txt ; \
+	cp $(top_srcdir)/AUTHORS $(top_srcdir)/$(NSI_INSTALL_DIR)/docs/AUTHORS.txt ; \
+	cp $(top_srcdir)/INSTALL $(top_srcdir)/$(NSI_INSTALL_DIR)/docs/INSTALL.txt ; \
+	cp $(top_srcdir)/README $(top_srcdir)/$(NSI_INSTALL_DIR)/docs/README.txt ; \
+	cp $(NSI_DLL_DIR)/*.dll $(top_srcdir)/$(NSI_INSTALL_DIR) ; \
+	cp $(SUBDIRS)/tuxtype.exe $(top_srcdir)/$(NSI_INSTALL_DIR)/TuxType.exe ;
+
+#	cp $(NSI_DLL_DIR)/*.ttf $(top_srcdir)/$(NSI_INSTALL_DIR)/data/fonts ;
+
+## Bundle in fonts for distribution tar.gz to be used without package manager:
+## i.e. to make tarball to post for individual download - use 'make distcheck' for Debian.
+## (thanks to Ralf Wildenhues <Ralf.Wildenhues at gmx.de> for automake help!)
+dist_with_fonts:
+	$(MAKE) $(AM_MAKEFLAGS) distdir=$(PACKAGE)_w_fonts-$(VERSION) dist_fonts='AndikaDesRevG.ttf DoulosSILR.ttf Rachana_w01.ttf' dist
+
+install-nsi-am: install-nsi-local
+
+nsis: install-nsi-local
+	$(MAKENSIS) -NOCD nsis/tuxtype.nsi
+
+
+clean-local:
+	@$(NORMAL_CLEAN)
+	if test -d $(NSI_INSTALL_DIR); then \
+	  rm -fr $(NSI_INSTALL_DIR); \
+	fi
\ No newline at end of file

Added: tuxtype/branches/tuxtype-new/configure.ac~
===================================================================
--- tuxtype/branches/tuxtype-new/configure.ac~	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/configure.ac~	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,204 @@
+# Process this file with autoconf to produce a configure script.
+AC_INIT([Tux Typing],[1.5.16],[tux4kids-tuxtype-dev at lists.alioth.debian.org],[tuxtype])
+
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+AC_CONFIG_SRCDIR([src/funcs.h])
+
+# Tell Automake not to be as strict about packaging standards for tuxtype
+# as it would be for an official Gnu program:
+AM_INIT_AUTOMAKE(foreign)
+AC_CONFIG_HEADERS([config.h])
+
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+
+dnl Don't think we need C++:
+# AC_PROG_CPP
+# AC_PROG_CXX
+
+AC_PREFIX_DEFAULT(/usr/local)
+if test "x$prefix" = "xNONE"; then
+  prefix=$ac_default_prefix
+  ac_configure_args="$ac_configure_args --prefix $prefix"
+fi
+
+# Checks for libraries.
+# Check for SDL
+SDL_VERSION=1.2.5
+
+
+
+AM_PATH_SDL($SDL_VERSION,
+            :,
+            AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]))
+
+AC_CHECK_LIB([SDL_mixer], [Mix_PlayMusic], ,[AC_MSG_ERROR(SDL_mixer not found http://www.libsdl.org/projects/SDL_mixer, )])
+AC_CHECK_LIB([SDL_ttf], [TTF_Init], ,[AC_MSG_ERROR(SDL_ttf not found http://www.libsdl.org/projects/SDL_ttf, )])
+AC_CHECK_LIB([SDL_image], [IMG_Load], ,[AC_MSG_ERROR(SDL_image not found http://www.libsdl.org/projects/SDL_image, )])
+
+# FIXME would be better to skip check for win32 build
+AC_CHECK_LIB([SDL_Pango], [SDLPango_Init], ,[AC_MSG_WARN(SDL_Pango not found http://sdlpango.sourceforge.net/)])
+
+
+#
+SDL_CFLAGS=`sdl-config --cflags`
+CFLAGS="$CFLAGS $SDL_CFLAGS"
+
+SDL_LIBS=`sdl-config --libs`
+LIBS="$SDL_LIBS $LIBS"
+
+# Check platform - see if see if building for Windows:
+AC_MSG_CHECKING([for native Win32])
+case "$host" in
+  *-*-mingw*)
+    native_win32=yes
+    ;;
+  *)
+    native_win32=no
+    ;;
+esac
+AC_MSG_RESULT([$native_win32])
+
+AM_CONDITIONAL(BUILD_MINGW32, test "$native_win32" = yes)
+
+if test "$native_win32" = yes; then
+
+   AC_DEFINE([BUILD_MINGW32], 1,[Native MinGW32 build])
+   CFLAGS="$CFLAGS -D__GW32__"
+   LIBS="-lmingw32 -lSDLmain $LIBS -luuid -lole32 -lwsock32 -mwindows"
+   CPPFLAGS="$CPPFLAGS -idirafter $prefix/include/glibc"
+   #CPPFLAGS="$CPPFLAGS -I$prefix/include/glibc"
+   AC_PATH_PROG(WINDRES, "$target_alias-windres", no, [$PATH])
+fi
+
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([stdlib.h string.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+
+# Checks for library functions.
+AC_CHECK_FUNCS([atexit memset strchr strstr malloc])
+
+
+
+
+
+# Sam's Install Kludge-work
+CPPFLAGS="$CPPFLAGS -DDATA_PREFIX=\\\"\$(prefix)\\\""
+
+AC_CONFIG_FILES([Makefile
+data/Makefile
+data/fonts/Makefile
+data/images/Makefile
+data/images/backgrounds/Makefile
+data/images/cities/Makefile
+data/images/comets/Makefile
+data/images/hands/Makefile
+data/images/icons/Makefile
+data/images/keyboard/Makefile
+data/images/menu/Makefile
+data/images/status/Makefile
+data/images/tux/Makefile
+data/scripts/Makefile
+data/sounds/Makefile
+data/themes/Makefile
+data/themes/armenian/Makefile
+data/themes/armenian/images/Makefile
+data/themes/bokmal/Makefile
+data/themes/bokmal/words/Makefile
+data/themes/bokmal/images/Makefile
+data/themes/bokmal/images/status/Makefile
+data/themes/brazilian-portuguese/Makefile
+data/themes/brazilian-portuguese/images/Makefile
+data/themes/brazilian-portuguese/words/Makefile
+data/themes/catalan/Makefile
+data/themes/catalan/words/Makefile
+data/themes/czech/Makefile
+data/themes/czech/words/Makefile
+data/themes/dansk/Makefile
+data/themes/dansk/sounds/Makefile
+data/themes/dansk/words/Makefile
+data/themes/deutsch/Makefile
+data/themes/deutsch/words/Makefile
+data/themes/espanol/Makefile
+data/themes/espanol/images/Makefile
+data/themes/espanol/words/Makefile
+data/themes/euskara/Makefile
+data/themes/euskara/images/Makefile
+data/themes/euskara/words/Makefile
+data/themes/french/Makefile
+data/themes/french/words/Makefile
+data/themes/greek/Makefile
+data/themes/greek/words/Makefile
+data/themes/italian/Makefile
+data/themes/italian/images/Makefile
+data/themes/italian/words/Makefile
+data/themes/jamaican/Makefile
+data/themes/jamaican/images/Makefile
+data/themes/jamaican/words/Makefile
+data/themes/lithuanian/Makefile
+data/themes/lithuanian/images/Makefile
+data/themes/lithuanian/images/status/Makefile
+data/themes/lithuanian/sounds/Makefile
+data/themes/lithuanian/words/Makefile
+data/themes/malayalam/Makefile
+data/themes/malayalam/images/Makefile
+data/themes/malayalam/images/status/Makefile
+data/themes/malayalam/images/keyboard/Makefile
+data/themes/malayalam/scripts/Makefile
+data/themes/malayalam/words/Makefile
+data/themes/nederlands/Makefile
+data/themes/nederlands/words/Makefile
+data/themes/nynorsk/Makefile
+data/themes/nynorsk/images/Makefile
+data/themes/nynorsk/images/status/Makefile
+data/themes/nynorsk/words/Makefile
+data/themes/russian/Makefile
+data/themes/russian/images/Makefile
+data/themes/russian/images/status/Makefile
+data/themes/russian/words/Makefile
+data/themes/svenska/Makefile
+data/themes/svenska/words/Makefile
+data/themes/swahili/Makefile
+data/themes/swahili/words/Makefile
+data/themes/wolof/Makefile
+data/themes/wolof/images/Makefile
+data/themes/wolof/words/Makefile
+data/words/Makefile
+doc/Makefile
+doc/en/Makefile
+src/Makefile
+nsis/tuxtype.nsi
+tuxtype.spec])
+
+# Support for building NSIS Win32 installer (adapted from TuxMath NSIS):
+NSI_INSTALL_DIR=mingw32
+AC_SUBST(NSI_INSTALL_DIR)
+
+NSI_DLL_DIR=~/tuxtype_dll
+AC_ARG_WITH(dll-directory,AS_HELP_STRING([--with-dll-directory=path],[set the path where dll for TuxType are [$(NSI_DLL_DIR)]]), dll_path=$withval, dll_path=no)
+
+AM_CONDITIONAL(NSI_BUILD, test "$dll_path" = no)
+
+if test $dll_path != no; then
+NSI_DLL_DIR=$dll_path
+fi
+AC_SUBST(NSI_DLL_DIR)
+
+
+AC_PATH_PROG(NSIS, makensis, no, [$PATH])
+
+
+AC_OUTPUT
+

Added: tuxtype/branches/tuxtype-new/depcomp
===================================================================
--- tuxtype/branches/tuxtype-new/depcomp	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/depcomp	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,584 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2006-10-15.18
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
+# Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva at dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+  stat=$?
+
+  if test -f "$tmpdepfile"; then :
+  else
+    stripped=`echo "$stripped" | sed 's,^.*/,,'`
+    tmpdepfile="$stripped.u"
+  fi
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    outname="$stripped.o"
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add `dependent.h:' lines.
+    sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
+  else
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mechanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+	set fnord "$@"
+	shift
+	shift
+	;;
+    *)
+	set fnord "$@" "$arg"
+	shift
+	shift
+	;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:


Property changes on: tuxtype/branches/tuxtype-new/depcomp
___________________________________________________________________
Name: svn:executable
   + *

Added: tuxtype/branches/tuxtype-new/doc/AUTHORS
===================================================================
--- tuxtype/branches/tuxtype-new/doc/AUTHORS	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/AUTHORS	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,49 @@
+Coders:
+-------
+David Bruce <dbruce at tampabay.rr.com>
+Jesse Andrews <jdandr2 at uky.edu>
+Calvin Arndt <calarndt at tux4kids.org>
+Sam Hart <hart at geekcomix.com>  --- Sam started it all with TuxType 1!!!
+Jacob Greig <bombastic at firstlinux.net>
+Sreyas Kurumanghat <k.sreyas at gmail.com>
+Sreerenj Balachandran <bsreerenj at gmail.com>
+Vimal Ravi <vimal_ravi at rediff.com>
+Prince K. Antony <prince.kantony at gmail.com>
+Mobin Mohan <mobinmohan at gmail.com>
+
+Packaging & Ports:
+------------------
+Holger Levsen <holger at debian.org> - (Debian packager, project maintainer)
+David Bruce <dbruce at tampabay.rr.com> - (Windows crossbuild using Linux host)
+David Marshman <marshy at silvan.demon.co.uk> - (BeOS port/packages)
+Calvin Arndt <calarndt at yahoo.com> - (Red Hat 7.1+ RPMs)
+Olivier Dagenais <olivier_dagenais at canada.com> - (Windows port/packages)
+Jesse Andrews <jdandr2 at uky.edu> - (Mac OS port)
+
+Special thanks to:
+------------------
+Rich Bellamy <bellamrm at clarkson.edu> - (for several image patches)
+Frank Ellis <frank3000 at usa.net> - (for many submitted bug items and feedback)
+Nicolai Beier <nbeier at tiscali.dk> - (for Danish work in TuxType 2)
+Martin Moeller <martin at liga.dk> - (for Danish word files in TuxType 1)
+Martin Rioux <riomar2000 at hotmail.com> - (for French translation in TuxType 1)
+Karl Ove Hufthammer <karl at huftis.org> - (for Norwegian Nynorsk translation work for Tuxtype 2)
+Trond Mæhlum <trondm at skolelinux.no> - (for Norwegian Bokmål translation work for Tuxtype 2)
+Sreyas Kurumanghat <k.sreyas at gmail.com> - (for Indic language support)
+Sreerenj Balachandran <bsreerenj at gmail.com> - (for Indic language support)
+Vimal Ravi <vimal_ravi at rediff.com> - (for Indic language support)
+Prince K. Antony <prince.kantony at gmail.com> - (for Indic language support)
+Mobin Mohan <mobinmohan at gmail.com> - (for Indic language support)
+Ralf Wildenhues <Ralf.Wildenhues at gmx.de> - (for Autotools help via mailing lists)
+
+
+Note: ConvertUTF.c/.h are from Unicode, Inc. and are released under a very free (BSD-like) license:
+
+   "Unicode, Inc. hereby grants the right to freely use the information
+   supplied in this file in the creation of products supporting the
+   Unicode Standard, and to make copies of this file in any form
+   for internal or external distribution as long as this notice
+   remains attached."
+
+Note: The Andika,Doulos, and Charis fonts are from SIL International and are licensed under the Open Font 
+   License, Version 1.1 (see "OFL.txt" in this directory for the full license text). 
\ No newline at end of file

Added: tuxtype/branches/tuxtype-new/doc/COPYING
===================================================================
--- tuxtype/branches/tuxtype-new/doc/COPYING	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/COPYING	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,280 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS

Added: tuxtype/branches/tuxtype-new/doc/ChangeLog
===================================================================
--- tuxtype/branches/tuxtype-new/doc/ChangeLog	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/ChangeLog	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,396 @@
+22 Feb 2008
+[ David Bruce <dbruce at tampabay.rr.com> ]
+       - replaced many of menu icon images with new shiny ones.
+
+19 Feb 2008
+[ David Bruce <dbruce at tampabay.rr.com> ]
+       - updated remainder of Makefile.am's to use automake
+         variables rather than hard-coded 'install' and 'uninstall'
+         targets.
+
+15 Feb 2008
+[ David Bruce <dbruce at tampabay.rr.com> ]
+       - start of rewrite of Makefile.am's for data heirarchy
+         to use automake more correctly.
+
+
+v. 1.5.17 - UNRELEASED
+14 Dec 2007
+[ Holger Levsen <holger at layer-acht.org> ]
+       - corrected Greek theme, contributed by:
+	 Faidon Liambotis <paravoid at debian.org>
+
+v. 1.5.16 - svn revision 347
+29 Nov 2007
+[ David Bruce <dbruce at tampabay.rr.com> ]
+       - added Czech theme, contributed by:
+         Jaroslav Krejčí (JardaK) - <krejci at zstenis.com>
+
+28 Nov 2007
+[ David Bruce <dbruce at tampabay.rr.com> ]
+       - Corrected Russian keyboard.lst.
+       - Possible bugfix that may have prevented recognition of chars
+         beyond 255 in cascade and comet zap games.
+
+19 Nov 2007
+[ David Bruce <dbruce at tampabay.rr.com> ]
+       - added Wolof theme by Issa Dominique Rochefort.
+
+11 Oct 2007
+[ David Bruce <dbruce at tampabay.rr.com> ]
+       - updated all Makefile.am's to use the currently-preferred "MKDIR_P"
+         instead of "mkinstalldirs"; removed multiple redundant invocations
+         of "mkinstalldirs".
+       - ran Autoconf's "autoupdate" to be sure build system will work
+         properly with automake 1.10.
+
+15 Sep 2007
+[ David Bruce <dbruce at tampabay.rr.com> ]
+       - "make dist" no longer includes fonts - added new Makefile target,
+         "make dist_with_fonts" that does include them. Thanks to Ralf 
+          Wildenhues <Ralf.Wildenhues at gmx.de> for autotools help via
+          mailing lists.
+
+v 1.5.15 - svn revision 255
+15 Sep 2007
+[ David Bruce <dbruce at tampabay.rr.com> ]
+       - alphabet.c - fixed crash occurring in BlackOutline_SDLPango() when 
+         passed empty string (see Debian Bug #439071)
+       - alphabet.c - added code to check words in list to see if they have
+         chars not in keyboard.lst, and just leave out these words rather
+         than aborting the game.
+       - Corrected Makefile.am for Malayalam theme so that settings.txt
+         gets installed (needed for font selection to work).
+       - Added numerals and punctuation to German keyboard.lst (likely
+         needs to be done for many other themes).
+
+[ Holger Levsen ]
+	- added updated Spanish translation by Amaya Rodrigo 
+
+v 1.5.14 - svn revision 240
+15 Sep 2007
+[ David Bruce <dbruce at tampabay.rr.com> ]
+       - scripting.c - added UTF-8 to wchar_t conversion at needed point
+         when calling Phrases() (line ~1200).
+       - some corrections and editing of scripts projectInfo.xml, cascade.xml,
+         laser.xml - more work needed.
+
+May-Sep 2007
+Tux Type Indic Team:
+[ Sreyas Kurumanghat <k.sreyas at gmail.com> ]
+[ Sreerenj Balachandran <bsreerenj at gmail.com> ]
+[ Vimal Ravi <vimal_ravi at rediff.com> ]
+[ Prince K. Antony <prince.kantony at gmail.com> ]
+[ Mobin Mohan <mobinmohan at gmail.com> ]
+
+       - added libSDLPango to handle complex rendering issues related with 
+         Indic languages. This will eventually allow support of any of the
+         world's major languages.
+       - added an Indic language theme, Malayalam, which also contains a 
+         lesson area.
+       - new format of keyboard.lst for malayalam theme (now added to other
+         themes too).
+       - created a new file named practice.txt which contains the strings to
+         display in the practice session. Also did a major role in adding 
+         Unicode support in the practice area.
+       - removed old keymap that was limited to Unicode chars 0-255 (now
+         replaced by a scheme that can support any chars in Unicode).
+       - added series of XML lessons for Malayalam theme.
+
+v 1.5.13
+08 Sep 2007
+[ David Bruce <dbruce at tampabay.rr.com> ]
+       - more work on practice.c - nearly all strings changed to 
+         wchar_t arrays, should be able to support Unicode in
+         practice phrases.
+       - simplified format of keyboard.lst - each line now just
+         gives the fingering for a single character (e.g. "0|a").
+         The code to read in the keyboard.lst has been replaced.
+         All keyboard.lst files in the themes are updated to the
+         new format, however the Russian and Greek keyboard.lst files
+         are erroneous and prevent these themes from working.
+         TuxType now relies on the keyboard.lst files to tell it
+         what characters are permissible in the typing activities.
+         (If anyone knows of a cross-platform way to find out from
+         the OS what Unicode values are "typable" with the user's
+         current keyboard setup, please let me know!).
+
+03 Sep 2007
+[ David Bruce ]
+       - practice.c revised significantly to prevent crashes if
+         keyboard.lst erroneous or incomplete - if entry not found
+         in FINGER[] array for a character, fingering hint not
+         shown but program still functions. "Practice" now uses the
+         same RenderLetters() code as the Cascade and Comet Zap
+         activities.
+       - BlackOutLine() for single letters now uses 
+         TTF_RenderUNICODE_Blended() rather than
+         TTF_RenderGlyph_Blended() because the former version
+         renders all glyphs to a consistent baseline, simplifying
+         our code.
+
+26 Aug 2007
+[ David Bruce ]
+       - got rid of autogen.sh - autoreconf is recommended way to
+         do the same thing according to autotools folks.
+       - replaced acinclude.m4 with newer version to get rid of 
+         "underquoted AM_PATH_SDL" message.
+       - fixed bug causing crash on exit from cascade game do to 
+         double free of ptr.
+       - fixed bug with Espanol display of menus.
+       - added "static" keyword to file-scope variables.
+       - moved more of global variables to file or local scope.
+       - added hard-coded hack-work to LoadFont() to support
+         Rachana and Doulos as well as Andika in Debian.
+
+v 1.5.11
+19 Aug 2007
+[ David Bruce ]
+       - Further development of settings struct.
+       - Got rid of realPath[] - paths now part of settings struct.
+       - program now looks for a settings file under the theme dir
+         when a theme is selected, allowing themes to specify a 
+         preferred font (or other settings).
+       - Incorporated most of changes from TuxType-Indic branch.
+         Program will now require SDLPango (as well as pango itself
+         and glib) - for now, pango-related code #ifndef-ed out for
+         win32 until I figure out how to get Windows build to work.
+
+01 Aug 2007
+[ David Bruce ]
+       - Removed KEYMAP array - wasn't being used correctly anyway.
+       - Consolidated many global vars into settings struct.
+       - code cleanup.
+
+v 1.5.10 - 16 Jun 2007
+[ David Bruce ]
+       - Added ConvertUTF.c & .h from Unicode, Inc. to do UTF-8 to wcs
+         encoding conversion when glibc isn't present (i.e., in Windows
+         build). AFAICT, Windows build now handles UTF-8/Unicode properly,
+         or at least behaves the same as *nix build.
+       - Fixed Jamaican theme - words in list needed to be uppercase.
+       - Correct links in HowToTheme.html to current counterparts.
+
+15 Jun 2007
+[ David Bruce ]
+       - Comet Zap fixed to require player to type letters in proper
+         order - "shootable" flag added to comet type.
+       - More code cleanup - mostly adding checks to prevent dereferencing
+         of null or invalid pointers.
+
+07 Jun 2007
+[ David Bruce ]
+       - Code cleanup - funcs.h revised, unneeded "extern" keywords for
+         function prototypes removed, prototypes rearranged into alpha-
+         betical order
+       - All functions now have function prototypes, either in funcs.h or
+         local function prototypes with explicit static scope.
+       - const keyword added to pointer function args when appropriate,
+         usually char* args.
+       - Renaming of some functions and variables to make capitalization 
+         more internally consistent (e.g. ALLCAPS means constant or other
+         preprocessor macro, CamelCase means globally visible, while 
+         local_functions() use lowercase connected by underscores).
+
+29 May 2007
+[ David Bruce ]
+       - Fixed vertical alignment problem with certain non-US characters
+         such as "Å" by checking max_y of each glyph and adjusting
+         appropriately.
+       - Added Doulos font to svn to accomodate Russian, although no code
+         yet to use this font when it is needed.
+       - Added utility function to print keymap - it appears that the
+         existing keymap code is broken, as the KEYMAP[] array winds
+         up with KEYMAP[i] == i for all values no matter what the
+         keyboard.lst file says.
+
+24 May 2007
+[ David Bruce ]
+       - Additional work on UTF-8/Unicode issues - program now scans
+         word list to see what Unicode characters are needed instead
+         of automatically rendering everything from 0-255. It now
+         displays chars beyond this range (e.g. Russian/Cyrillic) as
+         long as the font contains the needed glyphs (which Andika 
+         does not, as of yet). Display "should" now work correctly
+         except for a cosmetic problem with vertical alignment, which
+         should be fixed soon. Files - alphabet.c, playgame.c, laser.c.
+       - Lowercase keystrokes for non-US characters converted to upper-
+         case, just like A-Z.  Not sure this addresses keyboard input
+         problems just yet.
+       - Changed font to Andika design review "G".
+
+v.1.5.9  07 May 2007
+
+[ David Bruce ]
+       - Overhauled internal handling of word lists to handle UTF-8
+         correctly. Now WORDS_use() converts the UTF-8 to wchar_t
+         (i.e. Unicode) arrays for internal handling. The letters for
+         the fish and comets are now generated by black_outline_wchar(),
+         which is a modification of black_outline() that uses
+         TTF_RenderGlyph() instead of TTF_RenderUTF8().  It now seems
+         to work correctly, but for now is limited to the 0-255 range.
+
+v.1.5.8  29 Apr 2007
+
+[ Karl Ove Hufthammer ]
+       - Converted all the translation to use the UTF-8 characters.
+       - Changed word files to UTF-8. 
+	   - Added improved French word files commited by the French
+	     Skolelinux/Debian-edu team during DevCamp in Soissons.
+	   - Added Brazilian Portuguese translation by
+	     Hudson Gonçalves Manieri Figueredo.
+
+[ David Bruce ]
+       - Changed TTF_RenderText to TTF_RenderUTF8 everywhere in 
+         playgame.c, mainly by removing ttf_letter() and using
+         black_outline() instead.
+       - Added some checks for null pointers to prevent segfaults.
+       - Changed backgrounds from png to jpg to save space.
+       - Removed other unused backgrounds
+         (now in people/dbruce/unused_images)
+
+[ David Bruce ] 21 Apr 2007
+       - (mostly) removed used of checkFile() as it doesn't work
+         reliably on Windows and isn't really necessary. 
+
+
+v.1.5.7
+
+[ David Bruce ]
+       - Changed font to Andika (hopefully will have this in Debian
+         and other OS in future so we don't have to bundle it
+         indefinitely)
+       - Fixed black_outline() to make it work more or less as was
+         intended, from what I can tell.
+
+v1.5.6	the "make it simply work, stupid" release (a pun on KISS)
+
+[ Holger Levsen ]
+       - tagged as release in svn
+       - brought back the tuxtype2 logo
+       - updated TODO and README
+       - reverted utf8-changes from r16-20, as utf8 support needs more code
+         changes
+       - workaround debian bug #374062
+       - remove funkbrt.it as its not used
+       - font-loading is still a ugly hack :-( but works on debian with
+         ttf-gentium, which requires a little code-change for a sarge backport
+       - macosx and windows version untested...
+
+v1.5.5   development version, not released (still font+sound issues)
+
+[ Calvin Arndt ]
+       - closing all the mem leaks I know of 
+       - remove redundant print_phrase()
+       - remove hard coded xy positions in print_at() (calculate wrapped y position)
+       - remove uneeded cast in Phrases()
+[ Holger Levsen ]
+       - renamed to tuxtype (from tuxtype2), also modified the logo :)
+       - Solving the sound file licence issues (removed one (tickle.wav, was
+         unused), updated README_SOUNDS.TXT - this is not finished yet!!!!
+       - removed all fonts. The font-handling is still a hack,
+         see loaders.c - it only uses fonts from ttf-freefont
+         and not yet from ttf-dejavu (for non-latini fonts) - and it only
+         works on Debian probably (fixed path, not suitable for Windows,
+         MacOS and probably other linux distributions)
+
+v1.5.4 - Added Norwegian Bokmål translation. Improved Norwegian
+         Nynorsk translation.
+
+v1.5.3 - Initial lesson code started. Changed Set Keyboard to
+	 be a project info page. Fixed CometZap random segfaults on
+	 versions of NT. Added scripting for lessons. Used scripting
+	 mimic old instructions for Fish Cascade. Replaced
+	 SDL_WM_ToggleFullScreen() in favor of a more portable 
+	 routine to accomplish window size toggling. F10 in menu
+	 toggles screen size. Added saving sound volumes and windows
+	 state in the config file. Tuxtype2 now remembers both!
+	 Added translations Euskara, Italian and Jamaican. Added
+	 code for a map and photo for each theme/translation.
+
+v1.5.1 - Changed to get word list name from first line of file.
+         More language fixes. Added spanish translation. Fix 
+	 typos in source. Build system fixes. Added spanish
+	 translation. New word files for nynorsk translation.
+	 Danish translation bug fixes and cleanup. Changed format
+	 of keyboard.lst file. Added mouse click selection in language
+	 screen. And much more. Enjoy!
+
+v1.5.0 - First release in almost a year!!!
+
+v.0.2 - First elliminated need for SDL_Plus (which was useless
+        anyway.)
+
+v.0.3 - FIRST WORKING VERSION OF KEYCASCADE! Works at all
+        difficulty settings and levels.
+
+v.0.4pre1 - KEYCASCADE cleaned up and tweaked (works quite well
+        asside from a /few/ minor quirks). Also added soundFX
+        and music as well as tutorial for KeyCascade.
+
+v.0.4pre2 - Fixed WaitFrame() usage (more coherent now)
+        Also ensured that frame rate can stay constant over
+        different speed systems, and added --speed option.
+
+v.0.4 - Switched from UpdateRect to SDL_Flip() on title screen to
+	try to ensure constant frame-rate on title screen across
+	platforms. Various bug-fixes. Added surface based cursor
+	to titlescreen to prevent cursor-loss on certain systems
+	(such as my laptop >:/ )
+	
+v.0.5pre1 - Begin work on WORDCASCADE: All screens found and added-
+	Added word loading option and words- levels cycle- not
+	yet playable. Also fixed permissions on "missing" as well
+	as added the special hidden option (see readme in image dir).
+	
+v.0.5pre2 - WORDCASCADE now works. May need minor tweaking as time
+  goes by... but I will deal with that eventuality when it occurs.
+
+v.0.5 - Work on docs, small bugfixes for release.
+
+v.0.5-2 - Second 0.5 release. Fixed embarrasing word file location
+	problem!!!
+	
+v.0.6 - Many Mandrake 7.2 fixes. "Free Typing" added. Various code
+	clean-up and bugfixes.
+	
+v.0.7pre1 - Fixed sound bug:
+  (http://sourceforge.net/bugs/?func=detailbug&bug_id=131474&group_id=12715)
+  as well as first BeOS port.
+
+v.0.7 - Major code cleanup. /Probably/ fixed the clipping bug.
+
+v.0.8pre1 - Began work on the Word Cascade Tutorial. Patch to fix some
+        menu glitches.
+
+v.0.8 - Fixed SDL_Flip(..) related bugg in title screen:
+   (http://sourceforge.net/tracker/index.php?func=detail&aid=421508&group_id=12715&atid=112715)
+   as well as minor code clean-up and finish word cascade tutorial.
+
+v.0.9pre1 - Fixed GIF->PNG bug as well as "yellow outline" in gameplay
+   bug (thx to Rich Bellamy <bellamrm at clarkson.edu>)
+
+v.0.9pre2 - Fixed many of the troubles causing the tutorial screen
+   crashes:
+   (http://sourceforge.net/tracker/index.php?func=detail&aid=414339&group_id=12715&atid=112715)
+
+v.0.9pre3 - Added code from Olivier Dagenais <olivier_dagenais at canada.com>
+   which allows for compilation under Win32 using MS VisualC++. Also
+   fixed Kdevelop/SDL integration issues which prevents Tux Typing from
+   compiling on other OSes.
+
+v.0.9 - Fixed the tutorial screen crashing bug. Also removed double buffering
+   support temporarily to resolve the issue later.
+
+v.0.9-1 - Added keyboard support on main menu.
+
+v.1.0pre1 - Added Theming/Alt-Language support (preliminary). Fixed rect clipping
+    blit problem and added option for alpha blitting to emphasize slow falling words.
+    Other misc bugfixes and cleanup. Began transition to KDevelop 1.4 env and
+    future repair of build process.
+
+v.1.0 - Tweaked gameplay speed. Tweaked menu speed. Changed free typing from
+    hard defaults to easy defaults. Fixed word cascade bug:
+    http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=104456&repeatmerged=yes
+
+v1.0.1 - Build process bugfix.

Added: tuxtype/branches/tuxtype-new/doc/INSTALL
===================================================================
--- tuxtype/branches/tuxtype-new/doc/INSTALL	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/INSTALL	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,206 @@
+Quick Installation
+==================
+
+ Tuxtype should compile out of the box if you have a sane tool chain
+ and the following SDL libraries:
+ 
+ SDL-1.2.5            http://www.libsdl.org
+ SDL_image-1.2.3      http://www.libsdl.org/projects/SDL_image
+ SDL_mixer-1.2.5      http://www.libsdl.org/projects/SDL_mixer
+ SDL_ttf-2.0.5        http://www.libsdl.org/projects/SDL_ttf
+
+Notes:
+freetype2 is required for SDL_ttf
+SDL_2.0.6 is known not to compile on RH9
+
+For most people using Linux
+
+./configure --prefix=[your prefix here]
+make
+make install
+
+if you run into problems rerun:
+
+autoreconf --install
+
+We want this to work for everybody, everywhere, if it doesn't
+work for you please contact calarndt at tux4kids.org
+
+While I've made every attempt to get build system right,
+I am an autoconf/automake newbie. If you encounter issues
+please feel free to contact me directly at:
+
+Calvin Arndt <calarndt at tux4kids.net>
+
+
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.ac' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.ac' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes a while.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Type `make install' to install the programs and any data files and
+     documentation.
+
+  4. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.
+
+  5. You can uninstall the program by typing `make uninstall' (trust me
+     this really does work ;)
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+

Added: tuxtype/branches/tuxtype-new/doc/INSTALL-Win32
===================================================================
--- tuxtype/branches/tuxtype-new/doc/INSTALL-Win32	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/INSTALL-Win32	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,34 @@
+Tux Typing for Windows
+----------------------
+
+Updated Aug 25 2007
+
+2006-present Lead Developer:
+	David Bruce <dbruce at tampabay.rr.com>
+
+Previous Project Manager:
+	Sam Hart <hart at geekcomix.com>
+Developers:
+	Jacob Greig <bombastic at firstlinux.net>
+	Jesse Andrews <jdandr2 at sheffield.cslab.uky.edu>
+Original Windows Port by:
+	Olivier Dagenais <olivier_dagenais at canada.com>
+Windows Crossbuild by
+	David Bruce <dbruce at tampabay.rr.com>
+	(based on TuxMath Windows crossbuild by Yves Combe)
+
+To install the binary package for Tux Typing for Windows:
+
+1. Run the nsis installer file (e.g. tuxtype-1.5.11-win32-installer.exe)
+2. Click to accept the terms of the GPL
+3. Click OK to install in default path (C:\Program Files\TuxType) or
+select alternate location (perhaps if you are logged in as a user
+without privileges to write to C:\Program Files).
+4. The installer will create menu entries and a desktop icon for Tux
+Typing if permissions allow.
+
+Please read the COPYING.TXT file for the copyright for Tux Typing,
+and read the SDL-COPYING.TXT file for the copyright information for
+SDL. Basically, this software is open-source and free-software.
+
+Enjoy!

Added: tuxtype/branches/tuxtype-new/doc/Makefile.am
===================================================================
--- tuxtype/branches/tuxtype-new/doc/Makefile.am	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/Makefile.am	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,11 @@
+## Makefile.am for tuxtype docs:
+## Process with AutoMake:
+
+dist_doc_DATA = AUTHORS \
+  COPYING \
+  ChangeLog \
+  INSTALL \
+  OFL \
+  README \
+  TODO
+ 

Added: tuxtype/branches/tuxtype-new/doc/Makefile.in
===================================================================
--- tuxtype/branches/tuxtype-new/doc/Makefile.in	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/Makefile.in	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,353 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = doc
+DIST_COMMON = README $(dist_doc_DATA) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in AUTHORS COPYING ChangeLog INSTALL TODO
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(docdir)"
+dist_docDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(dist_doc_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NSIS = @NSIS@
+NSI_DLL_DIR = @NSI_DLL_DIR@
+NSI_INSTALL_DIR = @NSI_INSTALL_DIR@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_CONFIG = @SDL_CONFIG@
+SDL_LIBS = @SDL_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+dist_doc_DATA = AUTHORS \
+  COPYING \
+  ChangeLog \
+  INSTALL \
+  OFL \
+  README \
+  TODO
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  doc/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign  doc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-dist_docDATA: $(dist_doc_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)"
+	@list='$(dist_doc_DATA)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f=$(am__strip_dir) \
+	  echo " $(dist_docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \
+	  $(dist_docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \
+	done
+
+uninstall-dist_docDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(dist_doc_DATA)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(docdir)/$$f"; \
+	done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+	for dir in "$(DESTDIR)$(docdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_docDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_docDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am \
+	install-dist_docDATA install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am uninstall uninstall-am uninstall-dist_docDATA
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

Added: tuxtype/branches/tuxtype-new/doc/OFL
===================================================================
--- tuxtype/branches/tuxtype-new/doc/OFL	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/OFL	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,97 @@
+Copyright (c) <dates>, <Copyright Holder> (<URL|email>),
+with Reserved Font Name <Reserved Font Name>.
+Copyright (c) <dates>, <additional Copyright Holder> (<URL|email>),
+with Reserved Font Name <additional Reserved Font Name>.
+Copyright (c) <dates>, <additional Copyright Holder> (<URL|email>).
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.

Added: tuxtype/branches/tuxtype-new/doc/README
===================================================================
--- tuxtype/branches/tuxtype-new/doc/README	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/README	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,44 @@
+Tux Typing:
+An Educational Typing Tutor Game Starring Tux, the Linux Penguin
+----------------------------------------------------------------
+
+(To install the game on your system, please read the INSTALL file.)
+
+    If you are interested in Translation/moving this game to another 
+    language, please send a mail to David Bruce <dbruce at tampabay.rr.com>, 
+    Holger Levsen <debian at layer-acht.org>,  or to:
+
+    <tux4kids-tuxtype-dev at lists.alioth.debian.org>
+
+    Additional information on this subject is covered in "HowToTheme.html"
+    in the "docs" directory of this package.
+
+This is version 1.5.15 of Tux Typing.
+
+In Fish Cascade you control Tux as he searches for fish to eat. Fish fall
+from the top of the screen. These fish have letters on them.  Unforunately
+for Tux, eating a fish with a letter on it will cause his stomach to
+become ill, so it is up to you to help Tux eat fish!  By typing the
+letters, it will cause them to disappear so tux can chow down on the 
+fish.
+
+In Comet Zap you control Tux as he defends the cities from comets.  To
+protect a city from a comet, type the letter on the comet and it will
+cause Tux to destroy it with a laser! (In case you wondered, Comet Zap
+is an adaptation of the *great* math drill game, "Tux, of Math Command").
+
+"Lessons" and "Practice" are additional typing activities that we have
+not yet completed. You will find other menu entries for planned features
+that still need to be implemented.
+
+Tux Typing is Free-Software, distributable under the GNU General Public
+License. Please read COPYING for more info.
+
+Also, for those who may or may not be wondering: Yes, the rumors are
+true.... Tux Typing has a few special `hidden' options. See if you can 
+figure out what it is... ;)
+
+Enjoy!
+
+-Jesse Andrews -- jdandr2 at uky.edu
+ http://tux4kids.net/~jdandr2

Added: tuxtype/branches/tuxtype-new/doc/TODO
===================================================================
--- tuxtype/branches/tuxtype-new/doc/TODO	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/TODO	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,109 @@
+-Clean up this TODO and reflect the current status!
+
+-Replace the five remaining files which are non-free accoring to 
+ Debians Free Software Guidelines with free ones. click.wav and
+ kmus(1-4).wav are only free for non-commercial use.
+
+-check that SVN is free of generated files. create release-script, 
+  keep release tarballs (after augen.sh is run) in SVN?
+
+-Test it under MacOSX and windows
+
+-make the code use UTF8 internally
+
+-fix the font handling issues
+
+-Clean up code! (Someone beat it severely with the "oogly stick"!)
+
+  o  SOUND: I think the way laser.c handles sound playing should
+     be adopted by the rest of the app (via a function so we don't have
+     all these "if (sys_sound)" all over the place
+
+     ---  MAKE THE RUN SOUND NOT HAPPEN IF IT DOESN'T NEED TO!!!
+          & STOP IT ONCE IT IS DONE!
+
+  o  COMET ZAP: clean up the way text is generated...  right now
+     it is being generated every time! -- plus maybe switch to the
+     AA text
+
+     --- idea: once the player gets "done" with a wave, they can
+               continue playing on the wave until they are ready 
+	       to move on.  They do so by hitting a key 
+	       (ENTER/SPACE ??) which causes TUX to destroy all
+	       comets at once!
+ 
+  o  OBJECTs: ClearObject, EraseObject, ...  needs to be reworked.
+     while these are "objects", I think we should retitle these
+     sprites, as clearobject, eraseobject does not do what one
+     might think (removing from memory)...  Plus we can probably
+     simplify the "realeraseobject" vs. "eraseobject"
+
+  o  LOCALE: gettext & locales...  enough said
+
+  o  MAKE STUFF: Cal is working on it for *nix.  We need to make
+     sure we can build for others (win, mac).
+
+  o  THEMES: after gettext is set up, a way to specify font,
+     fontsize, and other graphical options for the theme...
+     (on top of the already supported images)
+
+     --- Currently when we are loading a image, it will first
+         search through all the theme paths, and then it will
+         search through all the default paths, which is nice
+         except when the theme has "icons" for the menu.  Then
+         the program will try to load as many icons and since
+         a theme may use fewer images than the default images,
+         the theme will have EXTRA frames that shouldn't be 
+         included!
+
+  o  INPUT: can TT2 determine if the user presses "fancy" latin
+     characters such as n~, ...  I don't know...  a way to test
+     exists now though :)
+
+  o  TRANSLATION: once we have gettext working, TT2 will be less
+     of a moving target for translators...
+
+  o  Tux Recommend: add tux giving friendly reminders about proper
+     hand location, erogomics, ...
+
+
+
+The following is a mail with a list of ideas, this is not really a todo (yet).
+
+From: Steve McCuen <smccuen.tux at gmail.com>
+To: tuxmath-devel at lists.sourceforge.net
+Date: Wed, 16 May 2007 20:25:15 -0700
+Message-Id: <1179372315.31920.15.camel at mccuen01.mccuenlabs.net>
+Subject: [Tuxmath-devel] tuxtype: feature request list, for comment
+
+This is the list of requests that came from students using tuxtype.  In
+looking at the list, some are very possible to do.
+
+* More kinds of games
+        * Some suggested maybe a racing game
+        * Some suggested pinball typing the right letters would make the
+flippers work
+        * Space wars, and battle games with space ships
+* Different background music
+* Different colors
+* Different backgrounds
+* Practice typing letter groups (finger exercises like Mavis)
+* In fish arcade, when you type the letter it highlights in Red, which
+is hard to see.
+* Too much repetition within the games there are
+* More short words, and generally more variety in words and letters
+* High score list
+* More diversity in difficulty, not just speeding up
+* Bonus points, and get more weapons, and rebuild cities
+* More then just comets that come down
+* Younger grades suggested the following:
+        * Fish Cascade to go slower
+        * Say the letter as they come down
+        * Not only saying the words, make the words tell a story
+        * Stops when you miss a letter and gives you a chance to get it right.
+* More levels in Fish Cascade and Comet Zap
+* Ability to choose whether one comet will destroy a city, or several
+* Levels to be longer and harder before switching
+* In Space Cadet, get points for hitting target, and takes away if you
+miss, and if a city is destroyed it doesn't take away points.
+* More shields

Added: tuxtype/branches/tuxtype-new/doc/en/Makefile
===================================================================
--- tuxtype/branches/tuxtype-new/doc/en/Makefile	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/en/Makefile	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,348 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# doc/en/Makefile.  Generated from Makefile.in by configure.
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+
+
+pkgdatadir = $(datadir)/tuxtype
+pkglibdir = $(libdir)/tuxtype
+pkgincludedir = $(includedir)/tuxtype
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = x86_64-unknown-linux-gnu
+host_triplet = x86_64-unknown-linux-gnu
+target_triplet = x86_64-unknown-linux-gnu
+subdir = doc/en
+DIST_COMMON = $(dist_doc_DATA) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(docdir)"
+dist_docDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(dist_doc_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = ${SHELL} /home/dbruce/tux4kids/tuxtype/branches/tuxtype-reorg/missing --run aclocal-1.10
+AMTAR = ${SHELL} /home/dbruce/tux4kids/tuxtype/branches/tuxtype-reorg/missing --run tar
+AUTOCONF = ${SHELL} /home/dbruce/tux4kids/tuxtype/branches/tuxtype-reorg/missing --run autoconf
+AUTOHEADER = ${SHELL} /home/dbruce/tux4kids/tuxtype/branches/tuxtype-reorg/missing --run autoheader
+AUTOMAKE = ${SHELL} /home/dbruce/tux4kids/tuxtype/branches/tuxtype-reorg/missing --run automake-1.10
+AWK = mawk
+CC = gcc
+CCDEPMODE = depmode=gcc3
+CFLAGS = -g -O2 -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT
+CPP = gcc -E
+CPPFLAGS =  -DDATA_PREFIX=\"$(prefix)\"
+CYGPATH_W = echo
+DEFS = -DHAVE_CONFIG_H
+DEPDIR = .deps
+ECHO_C = 
+ECHO_N = -n
+ECHO_T = 
+EGREP = /bin/grep -E
+EXEEXT = 
+GREP = /bin/grep
+INSTALL = /usr/bin/install -c
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_SCRIPT = ${INSTALL}
+INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
+LDFLAGS = 
+LIBOBJS = 
+LIBS = -L/usr/lib -lSDL -lSDL_Pango -lSDL_image -lSDL_ttf -lSDL_mixer 
+LN_S = ln -s
+LTLIBOBJS = 
+MAKEINFO = ${SHELL} /home/dbruce/tux4kids/tuxtype/branches/tuxtype-reorg/missing --run makeinfo
+MKDIR_P = /bin/mkdir -p
+NSIS = /usr/bin/makensis
+NSI_DLL_DIR = /home/dbruce/tuxtype_dll
+NSI_INSTALL_DIR = mingw32
+OBJEXT = o
+PACKAGE = tuxtype
+PACKAGE_BUGREPORT = tux4kids-tuxtype-dev at lists.alioth.debian.org
+PACKAGE_NAME = Tux Typing
+PACKAGE_STRING = Tux Typing 1.5.16
+PACKAGE_TARNAME = tuxtype
+PACKAGE_VERSION = 1.5.16
+PATH_SEPARATOR = :
+SDL_CFLAGS = -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT
+SDL_CONFIG = /usr/bin/sdl-config
+SDL_LIBS = -L/usr/lib -lSDL
+SET_MAKE = 
+SHELL = /bin/sh
+STRIP = 
+VERSION = 1.5.16
+WINDRES = 
+abs_builddir = /home/dbruce/tux4kids/tuxtype/branches/tuxtype-reorg/doc/en
+abs_srcdir = /home/dbruce/tux4kids/tuxtype/branches/tuxtype-reorg/doc/en
+abs_top_builddir = /home/dbruce/tux4kids/tuxtype/branches/tuxtype-reorg
+abs_top_srcdir = /home/dbruce/tux4kids/tuxtype/branches/tuxtype-reorg
+ac_ct_CC = gcc
+am__include = include
+am__leading_dot = .
+am__quote = 
+am__tar = ${AMTAR} chof - "$$tardir"
+am__untar = ${AMTAR} xf -
+bindir = ${exec_prefix}/bin
+build = x86_64-unknown-linux-gnu
+build_alias = 
+build_cpu = x86_64
+build_os = linux-gnu
+build_vendor = unknown
+builddir = .
+datadir = ${datarootdir}
+datarootdir = ${prefix}/share
+docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
+dvidir = ${docdir}
+exec_prefix = ${prefix}
+host = x86_64-unknown-linux-gnu
+host_alias = 
+host_cpu = x86_64
+host_os = linux-gnu
+host_vendor = unknown
+htmldir = ${docdir}
+includedir = ${prefix}/include
+infodir = ${datarootdir}/info
+install_sh = $(SHELL) /home/dbruce/tux4kids/tuxtype/branches/tuxtype-reorg/install-sh
+libdir = ${exec_prefix}/lib
+libexecdir = ${exec_prefix}/libexec
+localedir = ${datarootdir}/locale
+localstatedir = ${prefix}/var
+mandir = ${datarootdir}/man
+mkdir_p = /bin/mkdir -p
+oldincludedir = /usr/include
+pdfdir = ${docdir}
+prefix = /usr/local
+program_transform_name = s,x,x,
+psdir = ${docdir}
+sbindir = ${exec_prefix}/sbin
+sharedstatedir = ${prefix}/com
+srcdir = .
+sysconfdir = ${prefix}/etc
+target = x86_64-unknown-linux-gnu
+target_alias = 
+target_cpu = x86_64
+target_os = linux-gnu
+target_vendor = unknown
+top_builddir = ../..
+top_srcdir = ../..
+dist_doc_DATA = howtotheme.html \
+  TuxType_port_Mac.txt
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  doc/en/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign  doc/en/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-dist_docDATA: $(dist_doc_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)"
+	@list='$(dist_doc_DATA)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f=$(am__strip_dir) \
+	  echo " $(dist_docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \
+	  $(dist_docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \
+	done
+
+uninstall-dist_docDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(dist_doc_DATA)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(docdir)/$$f"; \
+	done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+	for dir in "$(DESTDIR)$(docdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_docDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_docDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am \
+	install-dist_docDATA install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am uninstall uninstall-am uninstall-dist_docDATA
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

Added: tuxtype/branches/tuxtype-new/doc/en/Makefile.am
===================================================================
--- tuxtype/branches/tuxtype-new/doc/en/Makefile.am	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/en/Makefile.am	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,5 @@
+## Makefile.am for tuxtype - docs/en
+## Process with Automake to create Makefile.in
+
+dist_doc_DATA = howtotheme.html \
+  TuxType_port_Mac.txt

Added: tuxtype/branches/tuxtype-new/doc/en/Makefile.in
===================================================================
--- tuxtype/branches/tuxtype-new/doc/en/Makefile.in	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/en/Makefile.in	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,348 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = doc/en
+DIST_COMMON = $(dist_doc_DATA) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(docdir)"
+dist_docDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(dist_doc_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NSIS = @NSIS@
+NSI_DLL_DIR = @NSI_DLL_DIR@
+NSI_INSTALL_DIR = @NSI_INSTALL_DIR@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_CONFIG = @SDL_CONFIG@
+SDL_LIBS = @SDL_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+dist_doc_DATA = howtotheme.html \
+  TuxType_port_Mac.txt
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  doc/en/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign  doc/en/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-dist_docDATA: $(dist_doc_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)"
+	@list='$(dist_doc_DATA)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f=$(am__strip_dir) \
+	  echo " $(dist_docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \
+	  $(dist_docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \
+	done
+
+uninstall-dist_docDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(dist_doc_DATA)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(docdir)/$$f"; \
+	done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+	for dir in "$(DESTDIR)$(docdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_docDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_docDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am \
+	install-dist_docDATA install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am uninstall uninstall-am uninstall-dist_docDATA
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

Added: tuxtype/branches/tuxtype-new/doc/en/TuxType_port_Mac.txt
===================================================================
--- tuxtype/branches/tuxtype-new/doc/en/TuxType_port_Mac.txt	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/en/TuxType_port_Mac.txt	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,52 @@
+How I Ported Tuxtype to Mac OS X:
+
+**Note** I am writing this from memory.  These steps should work, but if they do not, contact the tuxtype developer team and search google for answers.  That is how I was able to port tuxtype.
+
+**Note** My tuxtye.xcodeproj should exist in the Tuxtype SVN.  Open that to see my settings for the project.
+
+Requirements:  
+1. Mac OS 10.4 or higher (10.3, SDL, and Quicktime causes an error, so use 10.4)
+2. Xcode 2.5 [a free download from Apple's website] (or Xcode 3 should work but has not been tested)
+
+
+Steps to get Tuxtype working on a Mac:
+
+1. Download the following source codes:
+     a. SDL       (I used version 1.2.12) [http://www.libsdl.org/download-1.2.php]
+     b. SDL_image (I used version 1.2.6)  [http://www.libsdl.org/projects/SDL_image/]
+     c. SDL_mixer (I used version 1.2.8)  [http://www.libsdl.org/projects/SDL_mixer/]
+     d. SDL_ttf   (I used version 2.0.9)  [http://www.libsdl.org/projects/SDL_ttf/]
+
+2. Once you have SDL, open the SDL directory and unzip the Xcode.tar.gz.  Open the Xcode folder, then the SDL folder, then open SDL.xcodeproj in Xcode.  Change the Active Target to Framework and the Active Build Configuration to Deployment.  Click Build.  You now have the framework for SDL. Repeat these steps for SDL_image, SDL_mixer, and SDL_ttf to build their frameworks.
+
+3. Download the source code for Tuxtype.  
+
+4. Go back to your SDL folder, open Xcode, TemplatesForXcode, SDL Application, and then SDLApp.xcodeproj.  This will be the base of our project.
+
+5. Delete the file Main.c (this is the SDL demo one, we will add the main.c from tuxtype later).
+
+6. Under linked frameworks, add the following frameworks you built: SDL.framework, SDL_ttf.framework, SDL_image.framework, and SDL_mixer.framework.
+
+7. Add all of the files from the Tuxtype sourcecode to the project.  Ensure that under "classes" is SDLMain.h and SDLMain.m.  Under "other sources" is all the .c and .h files.  Under "Resources" is the "data" folder and all its contents inside it.  Ensure that under "resources" is the data file, otherwise Tuxtype won't know where to look for program files.
+
+8. Rename <<PROJECTNAME>>.app to tuxtype.app
+
+9. Disable SDLPango.  To do this, open alphabet.c and ensure that #IFNDEF MACOSX and #endif enclose all the code for SDLPango.  This should already be done and is done for WIN32 as well. 
+
+10. Open setup.c.  Ensure that DATA_PREFIX is on the of PATHS.  This should already be done.
+
+11. Time to set the compiler options.  Go to Project -> Edit project settings, then Build.  Architecture should be "ppc i386," "prebinding" unchecked, "prepocessor Macros" are MACOSX=1  DATA_PREFIX=/"tuxtype.app\Contents\Resources\data/"  Under Header Search Paths, ensure the location to the SDL frameworks is included.  My header search paths are "/Library/Frameworks/SDL.Framework/Headers" "/Library/Frameworks/SDL_image.framework/Headers" etc.
+
+12. In the main xcode screen, change Active Build Configuration to release.
+
+13. Pray, then hit Build.  You should now have a tuxtype.app in the build/release/ folder of your xcode project.
+
+14. Search Google for how to add an icon to a .app.  Also search for how to create a .dmg.  Many good tutorials exist for these, so I will not add instructions for them.
+
+**Note:  A very good SVN client for Mac is SmartSVN.  It has the built in svn+ssh support for alioth.debian.org**
+**Note: If you run into odd compiler errorrs listing many problems in SDL functions, try rebuilding the SDL frameworks.**
+**Note: Tuxtype on 10.3 will require a different build then on 10.4.  This is because 10.3 uses gcc3.3 and 10.4 uses gcc4.0.  To compile an app for 10.3, see http://bura-bura.com/blog/archives/2005/08/02/how-to-compile-an-application-for-102-or-103-using-xcode-21/**   
+
+Best of luck,
+Alex Shorthouse
+ashorthouse at rsd13.org
\ No newline at end of file

Added: tuxtype/branches/tuxtype-new/doc/en/howtotheme.html
===================================================================
--- tuxtype/branches/tuxtype-new/doc/en/howtotheme.html	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/doc/en/howtotheme.html	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,153 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title>How to create a theme for Tux Typing 1.5.13</title>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+</head>
+<body bgcolor="#ffffff">
+<h2>Theming in Tux Typing 1.5.13</h2>
+<p>A "Theme" is a method to change the data which Tuxtyping uses.  While this could be used to change the game about Tux and fish, to a game about a Cat and mice, more likely you are interested in making Tuxtyping work in another language. (if you are intersted in creating a new graphical theme like "Racecars" or ... that is cool too, but if things don't act right, please <a href="http://tux4kids.alioth.debian.org">contact us</a>).
+<p>I will walk through how I created the "French" theme in boxes in this text.
+<h3>Difference to Tuxtyping 1.0</h3>
+<p>In Tuxtyping 1.0, to create a theme, you needed to recreate every image file that was used by the game.  This means you had to include every image even if you didn't change it.  Plus all the text in the game were actually pre-created graphics, and the game could only use A-Z.
+<p>In Tuxtyping 1.5, you can can include changes to the image files, but if you don't include one, we will just use the default image included with the default theme (English).  Also instead of all the text in the game being pre-created, it is all rendered, so you can change the font and/or the text very easily.  Plus, you can change it so you include numbers, or anything else you can type!
+
+<center><table bgcolor="#ffcccc" width="80%" border=1 cellspacing=2><tr><td>
+<b>Changes since 1.5.0 Theming Howto</a>:</b>
+<ul><li>Keyboard.lst format changed to eliminate redundant information
+<li>themes.txt is no longer used... we create the list dynamically
+<li>words.lst is no longer used.. we create the list dynamically
+<li>The title of a wordlist is the first line of the file
+</ul>
+All these changes were done to make it even easier to theme...
+</td></tr></table></center>
+
+<h3>Components of a Theme</h3>
+
+<ol>
+<li>Creating the directory and adding it to menu system
+
+<p>Themes are located in the data directory of Tux Typing.  This will be different depending on which operating system you are using.  If you have trouble finding where the data directory is for your system, contact <a href="mailto:tuxmath-devel at lists.sourceforge.net">us</a>.  I will refer to this directory containing themes as <b>data/themes/</b>
+<p>Each theme has its own directory in the <b>data/themes/</b> directory.  For instance if you are creating a French theme, you would create a directory called <b>french</b> in the themes directory, so you have <b>data/themes/french</b>.  All of the data for your theme will be located in this directory.
+<p>Now if you go into the game, you should see a new entry in the "Setup Languages" menu for your theme.
+<center><table bgcolor="#ccccff" width="75%" border=1 cellpadding=4><tr><td> 
+<pre>    cd data/themes
+
+    mkdir french
+</pre>
+
+</td></tr></table></center>
+<br>
+<li>Fonts
+<p>Tux Typing currently uses three fonts (AndikaDesRevG.ttf, DoulosSILR.ttf, and Rachana_w01.ttf) to provide glyphs for the included themes. The default font is Andika, which has glyphs for English and other Western European languages. Doulos has wider coverage, and is included to support the Cyrillic characters needed for the Russian theme. Rachana provides glyphs for the Malayalam theme. If your theme works with the default Andika font, you do not need to specify anything.  If one of the other fonts is needed, your theme directory needs to have a file "settings.txt" containing a line indicating your font selection, e.g.:
+<br>
+theme_font_name=Rachana_w01.ttf
+<br>
+
+Currently, the font name must exactly match one of the supported fonts, or you will wind up with the default.  Note - all non-ASCII text needs to be encoded as UTF-8.  This is not an issue for file names, but it is an issue when adding themes that require Unicode support.
+
+<p>If you want to customize Tux Typing with another font, you can copy the *.ttf font file into data/fonts/ (alongside Andika, Doulos, and Rachana) and put the exact font file name into your theme's settings.txt file, and Tux Typing will use it.
+
+<center><table bgcolor="#ccccff" width="75%" border=1 cellpadding=4><tr><td> 
+
+
+<p>
+<li>Translation
+<p>To change the words that are within the menus and other parts of the game, you will need to create and edit a <b>lang.po</b> file.  We have created a master lang.po file that is located in the <b>data/themes</b> directory.  To start with, you should copy this file into your theme's directory.
+
+<center><table bgcolor="#ccccff" width="75%" border=1 cellpadding=4><tr><td> 
+<pre>    cd data/themes
+
+    cp lang.po french/lang.po
+</pre>
+</td></tr></table></center>
+
+<p>This file is your your standard "gettext" type .po file.  It is comprised of a sequence of msgid & msgstr pairs.  The msgid is the string of words in English, what you will need to do is after edit each msgstr in the file so it corresponds to the msgid right about it.  If your language uses non-Western Unicode characters, be sure to use a UTF-8 encoding for this file!
+
+<center><table bgcolor="#ccccff" width="75%" border=1 cellpadding=4><tr><td> 
+For instance my <b>data/themes/french/lang.po</b> has the following lines:
+<pre>
+    msgid "Fish"
+    msgstr "le Fish"
+
+    msgid "Lives"
+    msgstr "le Lives"
+
+    msgid "Level"
+    msgstr "le Level"
+
+    msgid "Alphabet"
+    msgstr "le Alphabet"
+</pre>
+
+<br>Since I do not know french, but if I did, I may have had the following in the file:
+<pre>
+    msgid "Fish"
+    msgstr "Poissons"
+</pre>
+</td></tr></table></center>
+<p>
+<li>Setup the keyboard
+<p>Now you need to setup what characters (like ABCDEFGHIJKLMNOPQRSTUVWXYZ), you are going to have the player hit within the game.  There are several things you need to specify.  First let me explain with an example.  In the English version, we don't mind if the user hit "A" or "a", we want it to mean the same thing "A" (we choose uppercase (capital) letters since they are easier to read).  We also need to specify that the player would normally use the "0" finger to hit the key (see image)
+<p>
+<center><img src="numhand.jpg" alt="0 1 2 3 4 5 6 7 8 9"></center>
+<p>So you need to create a <b>keyboard.lst</b> file.  This file will contain all the characters that you wish to be typable.  The format for the file is:
+<center>0|A</center>
+<p>
+First you list the finger(s) that the player should use to press this letter, then a seperator |, then the character that the user can press. Each character is on its own line (this is changed from earlier versions of Tux Typing).  Thus, one line should be "0|A" and another line "0|a".  Tux Typing generates the list of allowed characters from this file.  This is not the same as your theme's alphabet, which should consist only of the characters that correspond to "letters".
+<p>
+<center><table bgcolor="#ccccff" width="75%" border=1 cellpadding=4><tr><td> 
+<pre>    cd data/themes/french
+
+    vi keyboard.lst
+</pre>
+Then I add the following lines to the keyboard.lst file:
+<pre>
+    0|A
+    0|a
+    3|B
+    3|b
+    2|C
+    2|c
+    2|D
+    2|d
+    2|E
+    2|e
+    3|F
+    3|f
+</pre>
+and so on for each letter including non A-Z characters if needed! Tux Typing will use this list to determine which characters to pre-render (as well as for fingering hints), so be sure to include *all* characters needed for your theme, as omitted characters may not be able to be displayed. (I am trying to find a cross-platform way to query the OS as to what Unicode values can be typed by the user's current keyboard setup - if anyone has any ideas, please post to <a href="mailto:tuxmath-devel at lists.sourceforge.net">the dev list</a>).
+
+</td></tr></table></center>
+<p>
+
+<li>Word Lists
+<p>This is where you create the words that the player will have to type within the game.  The word lists reside within the directory words in your theme's directory.  Create this directory now.
+<center><table bgcolor="#ccccff" width="75%" border=1 cellpadding=4><tr><td> 
+<pre>    cd data/themes/french
+
+    mkdir words
+</pre>
+</td></tr></table></center>
+<p>Then all that is left to be done is to create these word lists (soon this will be able to do this from within the game!)   The first line of each wordlist should be the title of the wordlist.  After that, list all the words (one on each line). If list contains any non-Western Unicode characters (i.e. Unicode value > 256), the file must be encoded as UTF-8.
+For instance <b>data/themes/french/words/words1.txt</b> is:
+<center><table bgcolor="#ccccff" width="75%" border=1 cellpadding=4><tr><td> 
+<pre>    Jesse's French Words
+    LIV
+    POISSION
+</pre>
+</td></tr></table></center>
+<p>The only thing you need to remember is that each word can only be up to 8 characters long.  Also the game ignores ANYTHING after the first space.  If this is an issue, please let us know!
+</ol>
+
+<h3>The <B>MOST</b> important step.</h3>
+<p>You should send this file into the Tux Typing group so that it can be included in the distribution.  That way anyone who downloads Tux Typing can use your theme without having to download your theme as well!
+
+<hr>
+<center><a href="http://tux4kids.alioth.debian.org">TuxTyping Homepage</a> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
+<a href="http://alioth.debian.org/forum/?group_id=31080">TuxTyping Forums</a> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
+<a href="mailto:dbruce at tampabay.rr.com">dbruce at tampabay.rr.com</a>
+<br><br>
+<font size="-2">Last edited Sept 04, 2007 but by no means fully up-to-date!</font>
+</center>
+</body>

Added: tuxtype/branches/tuxtype-new/install-sh
===================================================================
--- tuxtype/branches/tuxtype-new/install-sh	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/install-sh	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,507 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2006-10-14.15
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+posix_glob=
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chmodcmd=$chmodprog
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c         (ignored)
+-d         create directories instead of installing files.
+-g GROUP   $chgrpprog installed files to GROUP.
+-m MODE    $chmodprog installed files to MODE.
+-o USER    $chownprog installed files to USER.
+-s         $stripprog installed files.
+-t DIRECTORY  install into DIRECTORY.
+-T         report an error if DSTFILE is a directory.
+--help     display this help and exit.
+--version  display version info and exit.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+        shift
+        shift
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t) dstarg=$2
+	shift
+	shift
+	continue;;
+
+    -T) no_target_directory=true
+	shift
+	continue;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dstarg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dstarg"
+      shift # fnord
+    fi
+    shift # arg
+    dstarg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src ;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dstarg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dstarg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix=/ ;;
+	-*) prefix=./ ;;
+	*)  prefix= ;;
+      esac
+
+      case $posix_glob in
+        '')
+	  if (set -f) 2>/dev/null; then
+	    posix_glob=true
+	  else
+	    posix_glob=false
+	  fi ;;
+      esac
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob && set -f
+      set fnord $dstdir
+      shift
+      $posix_glob && set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # Now rename the file to the real destination.
+    { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
+      || {
+	   # The rename failed, perhaps because mv can't rename something else
+	   # to itself, or perhaps because mv is so ancient that it does not
+	   # support -f.
+
+	   # Now remove or move aside any old file at destination location.
+	   # We try this two ways since rm can't unlink itself on some
+	   # systems and the destination file might be busy for other
+	   # reasons.  In this case, the final cleanup might fail but the new
+	   # file should still install successfully.
+	   {
+	     if test -f "$dst"; then
+	       $doit $rmcmd -f "$dst" 2>/dev/null \
+	       || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
+		     && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
+	       || {
+		 echo "$0: cannot unlink or rename $dst" >&2
+		 (exit 1); exit 1
+	       }
+	     else
+	       :
+	     fi
+	   } &&
+
+	   # Now rename the file to the real destination.
+	   $doit $mvcmd "$dsttmp" "$dst"
+	 }
+    } || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:


Property changes on: tuxtype/branches/tuxtype-new/install-sh
___________________________________________________________________
Name: svn:executable
   + *

Added: tuxtype/branches/tuxtype-new/missing
===================================================================
--- tuxtype/branches/tuxtype-new/missing	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/missing	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,367 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2006-05-10.23
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
+#   Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  autom4te     touch the output file, or create a stub one
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake at gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case $1 in
+  lex|yacc)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $1 in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case $f in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f y.tab.h; then
+	echo >y.tab.h
+    fi
+    if test ! -f y.tab.c; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f lex.yy.c; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit 1
+    fi
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '
+	/^@setfilename/{
+	  s/.* \([^ ]*\) *$/\1/
+	  p
+	  q
+	}' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case $firstarg in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case $firstarg in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:


Property changes on: tuxtype/branches/tuxtype-new/missing
___________________________________________________________________
Name: svn:executable
   + *

Added: tuxtype/branches/tuxtype-new/mkinstalldirs
===================================================================
--- tuxtype/branches/tuxtype-new/mkinstalldirs	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/mkinstalldirs	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,161 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2006-05-11.19
+
+# Original author: Noah Friedman <friedman at prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+nl='
+'
+IFS=" ""	$nl"
+errstatus=0
+dirmode=
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake at gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage"
+      exit $?
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --version)
+      echo "$0 $scriptversion"
+      exit $?
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error.  This is a problem when calling mkinstalldirs
+# from a parallel make.  We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+  '')
+    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    else
+      # On NextStep and OpenStep, the `mkdir' command does not
+      # recognize any option.  It will interpret all options as
+      # directories to create, and then abort because `.' already
+      # exists.
+      test -d ./-p && rmdir ./-p
+      test -d ./--version && rmdir ./--version
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+       test ! -d ./--version; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    else
+      # Clean up after NextStep and OpenStep mkdir.
+      for d in ./-m ./-p ./--version "./$dirmode";
+      do
+        test -d $d && rmdir $d
+      done
+    fi
+    ;;
+esac
+
+for file
+do
+  case $file in
+    /*) pathcomp=/ ;;
+    *)  pathcomp= ;;
+  esac
+  oIFS=$IFS
+  IFS=/
+  set fnord $file
+  shift
+  IFS=$oIFS
+
+  for d
+  do
+    test "x$d" = x && continue
+
+    pathcomp=$pathcomp$d
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+	errstatus=$lasterr
+      else
+	if test ! -z "$dirmode"; then
+	  echo "chmod $dirmode $pathcomp"
+	  lasterr=
+	  chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+	  if test ! -z "$lasterr"; then
+	    errstatus=$lasterr
+	  fi
+	fi
+      fi
+    fi
+
+    pathcomp=$pathcomp/
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:


Property changes on: tuxtype/branches/tuxtype-new/mkinstalldirs
___________________________________________________________________
Name: svn:executable
   + *

Added: tuxtype/branches/tuxtype-new/nsis/tuxtype.nsi.in
===================================================================
--- tuxtype/branches/tuxtype-new/nsis/tuxtype.nsi.in	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/nsis/tuxtype.nsi.in	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,108 @@
+# vim: noai et ts=4 tw=0
+# with a few tiny modifications by Phil Harper(philh at theopencd.org)
+# modified for tuxmath by Yves Combe (yves at ycombe.net)
+# modified for tuxtype by David Bruce (dbruce at tampabay.rr.com)
+
+!define PKG_VERSION "@VERSION@"
+!define PKG_PREFIX  "tuxtype"
+
+!define APP_PREFIX  "TuxType"
+!define APP_EXE     "${APP_PREFIX}.exe"
+!define APP_NAME    "Tux Typing"
+
+OutFile     "${PKG_PREFIX}-${PKG_VERSION}-win32-installer.exe"
+Name        "${APP_NAME}"
+Caption     ""
+CRCCheck    on
+WindowIcon  off
+BGGradient  off
+
+# Default to not silent
+SilentInstall   normal
+SilentUnInstall normal
+
+# Various default text options
+MiscButtonText
+InstallButtonText
+FileErrorText
+
+# Default installation dir and registry key of install directory
+InstallDir  "$PROGRAMFILES\${APP_PREFIX}"
+InstallDirRegKey HKLM SOFTWARE\${APP_PREFIX} "Install_Dir"
+
+# Licence text
+LicenseText "You must agree to this license before installing ${APP_NAME}"
+LicenseData "mingw32\docs\COPYING.txt"
+
+# Directory browsing
+# DirShow           show
+ComponentText       "This will install ${APP_NAME} on your computer. Select which optional things you want installed."
+DirText             "Choose a directory to install ${APP_NAME} in to:"
+AllowRootDirInstall false
+
+# Install page stuff
+InstProgressFlags   smooth
+AutoCloseWindow     true
+
+Section
+  SetOutPath $INSTDIR
+  File "mingw32\${APP_EXE}"
+  File "mingw32\*.dll"
+  SetOutPath $INSTDIR\data
+  File /r "mingw32\data\*.*"
+  SetOutPath $INSTDIR\docs
+  File /r "mingw32\docs\*.*"
+
+  WriteRegStr HKLM SOFTWARE\${APP_PREFIX} "Install_Dir" "$INSTDIR"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_PREFIX}" "DisplayName" "${APP_NAME} (remove only)"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_PREFIX}" "UninstallString" '"$INSTDIR\uninstall.exe"'
+  WriteUninstaller "uninstall.exe"
+SectionEnd
+
+
+Section "Start Menu Shortcuts"
+  SetShellVarContext all
+  SetOutPath $INSTDIR
+  CreateDirectory "$SMPROGRAMS\${APP_NAME}"
+  CreateShortCut  "$SMPROGRAMS\${APP_NAME}\${APP_NAME} (Full Screen).lnk" "$INSTDIR\${APP_EXE}" "-f" "$INSTDIR\data\images\icons\tuxtype.ico" 0 "" "" "Start TuxType2 in Fullscreen mode"
+  CreateShortCut  "$SMPROGRAMS\${APP_NAME}\${APP_NAME} (Windowed).lnk" "$INSTDIR\${APP_EXE}" "-w" "$INSTDIR\data\images\icons\tuxtype.ico" 0 "" "" "Start TuxType2 in a Window"
+  CreateShortCut  "$SMPROGRAMS\${APP_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 "" "" "Remove Tux Typing 2"
+SectionEnd
+
+
+Section "Desktop Shortcut"
+  SetShellVarContext all
+  SetOutPath $INSTDIR
+  CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${APP_EXE}" "" "$INSTDIR\data\images\icons\tuxtype.ico" 0  "" "" "Run Tux Typing 2"
+SectionEnd
+
+;Function .onInstSuccess
+;  BringToFront
+;  MessageBox MB_YESNO|MB_ICONQUESTION \
+;             "${APP_NAME} was installed. Would you like to run ${APP_NAME} now ?" \
+;             IDNO NoExec
+;    Exec '$INSTDIR\${APP_EXE}'
+;  NoExec:
+;FunctionEnd
+
+; uninstall stuff
+
+UninstallText "This will uninstall ${APP_NAME}. Hit 'Uninstall' to continue."
+
+; special uninstall section.
+Section "Uninstall"
+  SetShellVarContext all
+  ; remove registry keys
+  DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_PREFIX}"
+  DeleteRegKey HKLM SOFTWARE\${APP_PREFIX}
+
+  RMDir  /r "$INSTDIR\data"
+  RMDir  /r "$INSTDIR\docs"
+  Delete    "$INSTDIR\*.*"
+
+  Delete "$DESKTOP\${APP_NAME}.lnk"
+  Delete "$SMPROGRAMS\${APP_NAME}\*.*"
+  RMDir  "$SMPROGRAMS\${APP_NAME}"
+SectionEnd
+
+

Added: tuxtype/branches/tuxtype-new/src/ConvertUTF.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/ConvertUTF.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/ConvertUTF.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,539 @@
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ * 
+ * Disclaimer
+ * 
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ * 
+ * Limitations on Rights to Redistribute This Code
+ * 
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+    Conversions between UTF32, UTF-16, and UTF-8. Source code file.
+    Author: Mark E. Davis, 1994.
+    Rev History: Rick McGowan, fixes & updates May 2001.
+    Sept 2001: fixed const & error conditions per
+	mods suggested by S. Parent & A. Lillich.
+    June 2002: Tim Dodd added detection and handling of incomplete
+	source sequences, enhanced error detection, added casts
+	to eliminate compiler warnings.
+    July 2003: slight mods to back out aggressive FFFE detection.
+    Jan 2004: updated switches in from-UTF8 conversions.
+    Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
+
+    See the header file "ConvertUTF.h" for complete documentation.
+
+------------------------------------------------------------------------ */
+
+
+#include "ConvertUTF.h"
+#ifdef CVTUTF_DEBUG
+#include <stdio.h>
+#endif
+
+static const int halfShift  = 10; /* used for shifting by 10 bits */
+
+static const UTF32 halfBase = 0x0010000UL;
+static const UTF32 halfMask = 0x3FFUL;
+
+#define UNI_SUR_HIGH_START  (UTF32)0xD800
+#define UNI_SUR_HIGH_END    (UTF32)0xDBFF
+#define UNI_SUR_LOW_START   (UTF32)0xDC00
+#define UNI_SUR_LOW_END     (UTF32)0xDFFF
+#define false	   0
+#define true	    1
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF16 (
+	const UTF32** sourceStart, const UTF32* sourceEnd, 
+	UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF32* source = *sourceStart;
+    UTF16* target = *targetStart;
+    while (source < sourceEnd) {
+	UTF32 ch;
+	if (target >= targetEnd) {
+	    result = targetExhausted; break;
+	}
+	ch = *source++;
+	if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+	    /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+		if (flags == strictConversion) {
+		    --source; /* return to the illegal value itself */
+		    result = sourceIllegal;
+		    break;
+		} else {
+		    *target++ = UNI_REPLACEMENT_CHAR;
+		}
+	    } else {
+		*target++ = (UTF16)ch; /* normal case */
+	    }
+	} else if (ch > UNI_MAX_LEGAL_UTF32) {
+	    if (flags == strictConversion) {
+		result = sourceIllegal;
+	    } else {
+		*target++ = UNI_REPLACEMENT_CHAR;
+	    }
+	} else {
+	    /* target is a character in range 0xFFFF - 0x10FFFF. */
+	    if (target + 1 >= targetEnd) {
+		--source; /* Back up source pointer! */
+		result = targetExhausted; break;
+	    }
+	    ch -= halfBase;
+	    *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+	    *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+	}
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF32 (
+	const UTF16** sourceStart, const UTF16* sourceEnd, 
+	UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF16* source = *sourceStart;
+    UTF32* target = *targetStart;
+    UTF32 ch, ch2;
+    while (source < sourceEnd) {
+	const UTF16* oldSource = source; /*  In case we have to back up because of target overflow. */
+	ch = *source++;
+	/* If we have a surrogate pair, convert to UTF32 first. */
+	if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+	    /* If the 16 bits following the high surrogate are in the source buffer... */
+	    if (source < sourceEnd) {
+		ch2 = *source;
+		/* If it's a low surrogate, convert to UTF32. */
+		if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+		    ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+			+ (ch2 - UNI_SUR_LOW_START) + halfBase;
+		    ++source;
+		} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+		    --source; /* return to the illegal value itself */
+		    result = sourceIllegal;
+		    break;
+		}
+	    } else { /* We don't have the 16 bits following the high surrogate. */
+		--source; /* return to the high surrogate */
+		result = sourceExhausted;
+		break;
+	    }
+	} else if (flags == strictConversion) {
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+		--source; /* return to the illegal value itself */
+		result = sourceIllegal;
+		break;
+	    }
+	}
+	if (target >= targetEnd) {
+	    source = oldSource; /* Back up source pointer! */
+	    result = targetExhausted; break;
+	}
+	*target++ = ch;
+    }
+    *sourceStart = source;
+    *targetStart = target;
+#ifdef CVTUTF_DEBUG
+if (result == sourceIllegal) {
+    fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
+    fflush(stderr);
+}
+#endif
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Index into the table below with the first byte of a UTF-8 sequence to
+ * get the number of trailing bytes that are supposed to follow it.
+ * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
+ * left as-is for anyone who may want to do such conversion, which was
+ * allowed in earlier algorithms.
+ */
+static const char trailingBytesForUTF8[256] = {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+/*
+ * Magic values subtracted from a buffer value during UTF8 conversion.
+ * This table contains as many values as there might be trailing bytes
+ * in a UTF-8 sequence.
+ */
+static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 
+		     0x03C82080UL, 0xFA082080UL, 0x82082080UL };
+
+/*
+ * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
+ * into the first byte, depending on how many bytes follow.  There are
+ * as many entries in this table as there are UTF-8 sequence types.
+ * (I.e., one byte sequence, two byte... etc.). Remember that sequencs
+ * for *legal* UTF-8 will be 4 or fewer bytes total.
+ */
+static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+/* --------------------------------------------------------------------- */
+
+/* The interface converts a whole buffer to avoid function-call overhead.
+ * Constants have been gathered. Loops & conditionals have been removed as
+ * much as possible for efficiency, in favor of drop-through switches.
+ * (See "Note A" at the bottom of the file for equivalent code.)
+ * If your compiler supports it, the "isLegalUTF8" call can be turned
+ * into an inline function.
+ */
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF8 (
+	const UTF16** sourceStart, const UTF16* sourceEnd, 
+	UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF16* source = *sourceStart;
+    UTF8* target = *targetStart;
+    while (source < sourceEnd) {
+	UTF32 ch;
+	unsigned short bytesToWrite = 0;
+	const UTF32 byteMask = 0xBF;
+	const UTF32 byteMark = 0x80; 
+	const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+	ch = *source++;
+	/* If we have a surrogate pair, convert to UTF32 first. */
+	if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+	    /* If the 16 bits following the high surrogate are in the source buffer... */
+	    if (source < sourceEnd) {
+		UTF32 ch2 = *source;
+		/* If it's a low surrogate, convert to UTF32. */
+		if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+		    ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+			+ (ch2 - UNI_SUR_LOW_START) + halfBase;
+		    ++source;
+		} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+		    --source; /* return to the illegal value itself */
+		    result = sourceIllegal;
+		    break;
+		}
+	    } else { /* We don't have the 16 bits following the high surrogate. */
+		--source; /* return to the high surrogate */
+		result = sourceExhausted;
+		break;
+	    }
+	} else if (flags == strictConversion) {
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+		--source; /* return to the illegal value itself */
+		result = sourceIllegal;
+		break;
+	    }
+	}
+	/* Figure out how many bytes the result will require */
+	if (ch < (UTF32)0x80) {	     bytesToWrite = 1;
+	} else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
+	} else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
+	} else if (ch < (UTF32)0x110000) {  bytesToWrite = 4;
+	} else {			    bytesToWrite = 3;
+					    ch = UNI_REPLACEMENT_CHAR;
+	}
+
+	target += bytesToWrite;
+	if (target > targetEnd) {
+	    source = oldSource; /* Back up source pointer! */
+	    target -= bytesToWrite; result = targetExhausted; break;
+	}
+	switch (bytesToWrite) { /* note: everything falls through. */
+	    case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
+	}
+	target += bytesToWrite;
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Utility routine to tell whether a sequence of bytes is legal UTF-8.
+ * This must be called with the length pre-determined by the first byte.
+ * If not calling this from ConvertUTF8to*, then the length can be set by:
+ *  length = trailingBytesForUTF8[*source]+1;
+ * and the sequence is illegal right away if there aren't that many bytes
+ * available.
+ * If presented with a length > 4, this returns false.  The Unicode
+ * definition of UTF-8 goes up to 4-byte sequences.
+ */
+
+static Boolean isLegalUTF8(const UTF8 *source, int length) {
+    UTF8 a;
+    const UTF8 *srcptr = source+length;
+    switch (length) {
+    default: return false;
+	/* Everything else falls through when "true"... */
+    case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+    case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+    case 2: if ((a = (*--srcptr)) > 0xBF) return false;
+
+	switch (*source) {
+	    /* no fall-through in this inner switch */
+	    case 0xE0: if (a < 0xA0) return false; break;
+	    case 0xED: if (a > 0x9F) return false; break;
+	    case 0xF0: if (a < 0x90) return false; break;
+	    case 0xF4: if (a > 0x8F) return false; break;
+	    default:   if (a < 0x80) return false;
+	}
+
+    case 1: if (*source >= 0x80 && *source < 0xC2) return false;
+    }
+    if (*source > 0xF4) return false;
+    return true;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Exported function to return whether a UTF-8 sequence is legal or not.
+ * This is not used here; it's just exported.
+ */
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
+    int length = trailingBytesForUTF8[*source]+1;
+    if (source+length > sourceEnd) {
+	return false;
+    }
+    return isLegalUTF8(source, length);
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF16 (
+	const UTF8** sourceStart, const UTF8* sourceEnd, 
+	UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF8* source = *sourceStart;
+    UTF16* target = *targetStart;
+    while (source < sourceEnd) {
+	UTF32 ch = 0;
+	unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+	if (source + extraBytesToRead >= sourceEnd) {
+	    result = sourceExhausted; break;
+	}
+	/* Do this check whether lenient or strict */
+	if (! isLegalUTF8(source, extraBytesToRead+1)) {
+	    result = sourceIllegal;
+	    break;
+	}
+	/*
+	 * The cases all fall through. See "Note A" below.
+	 */
+	switch (extraBytesToRead) {
+	    case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+	    case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+	    case 3: ch += *source++; ch <<= 6;
+	    case 2: ch += *source++; ch <<= 6;
+	    case 1: ch += *source++; ch <<= 6;
+	    case 0: ch += *source++;
+	}
+	ch -= offsetsFromUTF8[extraBytesToRead];
+
+	if (target >= targetEnd) {
+	    source -= (extraBytesToRead+1); /* Back up source pointer! */
+	    result = targetExhausted; break;
+	}
+	if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+		if (flags == strictConversion) {
+		    source -= (extraBytesToRead+1); /* return to the illegal value itself */
+		    result = sourceIllegal;
+		    break;
+		} else {
+		    *target++ = UNI_REPLACEMENT_CHAR;
+		}
+	    } else {
+		*target++ = (UTF16)ch; /* normal case */
+	    }
+	} else if (ch > UNI_MAX_UTF16) {
+	    if (flags == strictConversion) {
+		result = sourceIllegal;
+		source -= (extraBytesToRead+1); /* return to the start */
+		break; /* Bail out; shouldn't continue */
+	    } else {
+		*target++ = UNI_REPLACEMENT_CHAR;
+	    }
+	} else {
+	    /* target is a character in range 0xFFFF - 0x10FFFF. */
+	    if (target + 1 >= targetEnd) {
+		source -= (extraBytesToRead+1); /* Back up source pointer! */
+		result = targetExhausted; break;
+	    }
+	    ch -= halfBase;
+	    *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+	    *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+	}
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF8 (
+	const UTF32** sourceStart, const UTF32* sourceEnd, 
+	UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF32* source = *sourceStart;
+    UTF8* target = *targetStart;
+    while (source < sourceEnd) {
+	UTF32 ch;
+	unsigned short bytesToWrite = 0;
+	const UTF32 byteMask = 0xBF;
+	const UTF32 byteMark = 0x80; 
+	ch = *source++;
+	if (flags == strictConversion ) {
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+		--source; /* return to the illegal value itself */
+		result = sourceIllegal;
+		break;
+	    }
+	}
+	/*
+	 * Figure out how many bytes the result will require. Turn any
+	 * illegally large UTF32 things (> Plane 17) into replacement chars.
+	 */
+	if (ch < (UTF32)0x80) {	     bytesToWrite = 1;
+	} else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
+	} else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
+	} else if (ch <= UNI_MAX_LEGAL_UTF32) {  bytesToWrite = 4;
+	} else {			    bytesToWrite = 3;
+					    ch = UNI_REPLACEMENT_CHAR;
+					    result = sourceIllegal;
+	}
+	
+	target += bytesToWrite;
+	if (target > targetEnd) {
+	    --source; /* Back up source pointer! */
+	    target -= bytesToWrite; result = targetExhausted; break;
+	}
+	switch (bytesToWrite) { /* note: everything falls through. */
+	    case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
+	}
+	target += bytesToWrite;
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF32 (
+	const UTF8** sourceStart, const UTF8* sourceEnd, 
+	UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF8* source = *sourceStart;
+    UTF32* target = *targetStart;
+    while (source < sourceEnd) {
+	UTF32 ch = 0;
+	unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+	if (source + extraBytesToRead >= sourceEnd) {
+	    result = sourceExhausted; break;
+	}
+	/* Do this check whether lenient or strict */
+	if (! isLegalUTF8(source, extraBytesToRead+1)) {
+	    result = sourceIllegal;
+	    break;
+	}
+	/*
+	 * The cases all fall through. See "Note A" below.
+	 */
+	switch (extraBytesToRead) {
+	    case 5: ch += *source++; ch <<= 6;
+	    case 4: ch += *source++; ch <<= 6;
+	    case 3: ch += *source++; ch <<= 6;
+	    case 2: ch += *source++; ch <<= 6;
+	    case 1: ch += *source++; ch <<= 6;
+	    case 0: ch += *source++;
+	}
+	ch -= offsetsFromUTF8[extraBytesToRead];
+
+	if (target >= targetEnd) {
+	    source -= (extraBytesToRead+1); /* Back up the source pointer! */
+	    result = targetExhausted; break;
+	}
+	if (ch <= UNI_MAX_LEGAL_UTF32) {
+	    /*
+	     * UTF-16 surrogate values are illegal in UTF-32, and anything
+	     * over Plane 17 (> 0x10FFFF) is illegal.
+	     */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+		if (flags == strictConversion) {
+		    source -= (extraBytesToRead+1); /* return to the illegal value itself */
+		    result = sourceIllegal;
+		    break;
+		} else {
+		    *target++ = UNI_REPLACEMENT_CHAR;
+		}
+	    } else {
+		*target++ = ch;
+	    }
+	} else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
+	    result = sourceIllegal;
+	    *target++ = UNI_REPLACEMENT_CHAR;
+	}
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* ---------------------------------------------------------------------
+
+    Note A.
+    The fall-through switches in UTF-8 reading code save a
+    temp variable, some decrements & conditionals.  The switches
+    are equivalent to the following loop:
+	{
+	    int tmpBytesToRead = extraBytesToRead+1;
+	    do {
+		ch += *source++;
+		--tmpBytesToRead;
+		if (tmpBytesToRead) ch <<= 6;
+	    } while (tmpBytesToRead > 0);
+	}
+    In UTF-8 writing code, the switches on "bytesToWrite" are
+    similarly unrolled loops.
+
+   --------------------------------------------------------------------- */

Added: tuxtype/branches/tuxtype-new/src/ConvertUTF.h
===================================================================
--- tuxtype/branches/tuxtype-new/src/ConvertUTF.h	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/ConvertUTF.h	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ * 
+ * Disclaimer
+ * 
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ * 
+ * Limitations on Rights to Redistribute This Code
+ * 
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+    Conversions between UTF32, UTF-16, and UTF-8.  Header file.
+
+    Several funtions are included here, forming a complete set of
+    conversions between the three formats.  UTF-7 is not included
+    here, but is handled in a separate source file.
+
+    Each of these routines takes pointers to input buffers and output
+    buffers.  The input buffers are const.
+
+    Each routine converts the text between *sourceStart and sourceEnd,
+    putting the result into the buffer between *targetStart and
+    targetEnd. Note: the end pointers are *after* the last item: e.g. 
+    *(sourceEnd - 1) is the last item.
+
+    The return result indicates whether the conversion was successful,
+    and if not, whether the problem was in the source or target buffers.
+    (Only the first encountered problem is indicated.)
+
+    After the conversion, *sourceStart and *targetStart are both
+    updated to point to the end of last text successfully converted in
+    the respective buffers.
+
+    Input parameters:
+	sourceStart - pointer to a pointer to the source buffer.
+		The contents of this are modified on return so that
+		it points at the next thing to be converted.
+	targetStart - similarly, pointer to pointer to the target buffer.
+	sourceEnd, targetEnd - respectively pointers to the ends of the
+		two buffers, for overflow checking only.
+
+    These conversion functions take a ConversionFlags argument. When this
+    flag is set to strict, both irregular sequences and isolated surrogates
+    will cause an error.  When the flag is set to lenient, both irregular
+    sequences and isolated surrogates are converted.
+
+    Whether the flag is strict or lenient, all illegal sequences will cause
+    an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
+    or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
+    must check for illegal sequences.
+
+    When the flag is set to lenient, characters over 0x10FFFF are converted
+    to the replacement character; otherwise (when the flag is set to strict)
+    they constitute an error.
+
+    Output parameters:
+	The value "sourceIllegal" is returned from some routines if the input
+	sequence is malformed.  When "sourceIllegal" is returned, the source
+	value will point to the illegal value that caused the problem. E.g.,
+	in UTF-8 when a sequence is malformed, it points to the start of the
+	malformed sequence.  
+
+    Author: Mark E. Davis, 1994.
+    Rev History: Rick McGowan, fixes & updates May 2001.
+		 Fixes & updates, Sept 2001.
+
+------------------------------------------------------------------------ */
+
+/* ---------------------------------------------------------------------
+    The following 4 definitions are compiler-specific.
+    The C standard does not guarantee that wchar_t has at least
+    16 bits, so wchar_t is no less portable than unsigned short!
+    All should be unsigned values to avoid sign extension during
+    bit mask & shift operations.
+------------------------------------------------------------------------ */
+
+typedef unsigned long	UTF32;	/* at least 32 bits */
+typedef unsigned short	UTF16;	/* at least 16 bits */
+typedef unsigned char	UTF8;	/* typically 8 bits */
+typedef unsigned char	Boolean; /* 0 or 1 */
+
+/* Some fundamental constants */
+#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
+#define UNI_MAX_BMP (UTF32)0x0000FFFF
+#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
+#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
+#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
+
+typedef enum {
+	conversionOK, 		/* conversion successful */
+	sourceExhausted,	/* partial character in source, but hit end */
+	targetExhausted,	/* insuff. room in target for conversion */
+	sourceIllegal		/* source sequence is illegal/malformed */
+} ConversionResult;
+
+typedef enum {
+	strictConversion = 0,
+	lenientConversion
+} ConversionFlags;
+
+/* This is for C++ and does no harm in C */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ConversionResult ConvertUTF8toUTF16 (
+		const UTF8** sourceStart, const UTF8* sourceEnd, 
+		UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF8 (
+		const UTF16** sourceStart, const UTF16* sourceEnd, 
+		UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+		
+ConversionResult ConvertUTF8toUTF32 (
+		const UTF8** sourceStart, const UTF8* sourceEnd, 
+		UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF8 (
+		const UTF32** sourceStart, const UTF32* sourceEnd, 
+		UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+		
+ConversionResult ConvertUTF16toUTF32 (
+		const UTF16** sourceStart, const UTF16* sourceEnd, 
+		UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF16 (
+		const UTF32** sourceStart, const UTF32* sourceEnd, 
+		UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* --------------------------------------------------------------------- */

Added: tuxtype/branches/tuxtype-new/src/Makefile.am
===================================================================
--- tuxtype/branches/tuxtype-new/src/Makefile.am	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/Makefile.am	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,32 @@
+## Process with Automake to create Makefile.in
+
+##DATA_PREFIX=${pkgdatadir}
+
+bin_PROGRAMS = tuxtype
+
+tuxtype_SOURCES = 	\
+	playgame.c	\
+	main.c		\
+	titlescreen.c	\
+	loaders.c	\
+	setup.c		\
+	laser.c		\
+	alphabet.c	\
+	theme.c		\
+	practice.c	\
+	audio.c		\
+	gettext.c	\
+	snow.c		\
+	scripting.c	\
+	pause.c		\
+	ConvertUTF.c	\
+	options.c
+
+EXTRA_DIST = titlescreen.h \
+	playgame.h 	\
+	laser.h		\
+	globals.h 	\
+	funcs.h 	\
+	scripting.h	\
+	snow.h		\
+	ConvertUTF.h

Added: tuxtype/branches/tuxtype-new/src/Makefile.in
===================================================================
--- tuxtype/branches/tuxtype-new/src/Makefile.in	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/Makefile.in	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,476 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+bin_PROGRAMS = tuxtype$(EXEEXT)
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_tuxtype_OBJECTS = playgame.$(OBJEXT) main.$(OBJEXT) \
+	titlescreen.$(OBJEXT) loaders.$(OBJEXT) setup.$(OBJEXT) \
+	laser.$(OBJEXT) alphabet.$(OBJEXT) theme.$(OBJEXT) \
+	practice.$(OBJEXT) audio.$(OBJEXT) gettext.$(OBJEXT) \
+	snow.$(OBJEXT) scripting.$(OBJEXT) pause.$(OBJEXT) \
+	ConvertUTF.$(OBJEXT) options.$(OBJEXT)
+tuxtype_OBJECTS = $(am_tuxtype_OBJECTS)
+tuxtype_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(tuxtype_SOURCES)
+DIST_SOURCES = $(tuxtype_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NSIS = @NSIS@
+NSI_DLL_DIR = @NSI_DLL_DIR@
+NSI_INSTALL_DIR = @NSI_INSTALL_DIR@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_CONFIG = @SDL_CONFIG@
+SDL_LIBS = @SDL_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+tuxtype_SOURCES = \
+	playgame.c	\
+	main.c		\
+	titlescreen.c	\
+	loaders.c	\
+	setup.c		\
+	laser.c		\
+	alphabet.c	\
+	theme.c		\
+	practice.c	\
+	audio.c		\
+	gettext.c	\
+	snow.c		\
+	scripting.c	\
+	pause.c		\
+	ConvertUTF.c	\
+	options.c
+
+EXTRA_DIST = titlescreen.h \
+	playgame.h 	\
+	laser.h		\
+	globals.h 	\
+	funcs.h 	\
+	scripting.h	\
+	snow.h		\
+	ConvertUTF.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign  src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+	@list='$(bin_PROGRAMS)'; for p in $$list; do \
+	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+	  if test -f $$p \
+	  ; then \
+	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+	   echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+	   $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+	  else :; fi; \
+	done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; for p in $$list; do \
+	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+	  echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(bindir)/$$f"; \
+	done
+
+clean-binPROGRAMS:
+	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+tuxtype$(EXEEXT): $(tuxtype_OBJECTS) $(tuxtype_DEPENDENCIES) 
+	@rm -f tuxtype$(EXEEXT)
+	$(LINK) $(tuxtype_OBJECTS) $(tuxtype_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ConvertUTF.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/alphabet.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audio.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gettext.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/laser.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/loaders.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/main.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/options.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pause.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/playgame.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/practice.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/scripting.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/setup.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/snow.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/theme.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/titlescreen.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+	clean-generic ctags distclean distclean-compile \
+	distclean-generic distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-binPROGRAMS \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am uninstall-binPROGRAMS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

Added: tuxtype/branches/tuxtype-new/src/SDLMain.h
===================================================================
--- tuxtype/branches/tuxtype-new/src/SDLMain.h	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/SDLMain.h	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,19 @@
+/*   SDLMain.m - main entry point for our Cocoa-ized SDL app
+       Initial Version: Darrell Walisser <dwaliss1 at purdue.edu>
+       Non-NIB-Code & other changes: Max Horn <max at quendi.de>
+
+    Feel free to customize this file to suit your needs
+*/
+
+#import <Cocoa/Cocoa.h>
+
+ at interface SDLMain : NSObject
+{
+}
+- (IBAction)prefsMenu:(id)sender;
+- (IBAction)newGame:(id)sender;
+- (IBAction)openGame:(id)sender;
+- (IBAction)saveGame:(id)sender;
+- (IBAction)saveGameAs:(id)sender;
+- (IBAction)help:(id)sender;
+ at end


Property changes on: tuxtype/branches/tuxtype-new/src/SDLMain.h
___________________________________________________________________
Name: svn:executable
   + *

Added: tuxtype/branches/tuxtype-new/src/alphabet.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/alphabet.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/alphabet.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,1167 @@
+/***************************************************************************
+                          alphabet.c 
+ -  description: Init SDL
+                             -------------------
+    begin                : Jan 6 2003
+    copyright            : (C) 2003 by Jesse Andrews
+    email                : jdandr2 at tux4kids.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+
+/* Needed to handle rendering issues for Indic languages*/
+#ifndef WIN32
+#ifndef MACOSX
+#include <SDL_Pango.h>
+#endif
+#endif
+
+/* Needed to convert UTF-8 under Windows because we don't have glibc: */
+#include "ConvertUTF.h"  
+
+#include "globals.h"
+#include "funcs.h"
+
+
+/* NOTE these are externed in globals.h so not static */
+/* the colors we use throughout the game */
+SDL_Color black;
+SDL_Color gray;
+SDL_Color dark_blue;
+SDL_Color red;
+SDL_Color white;
+SDL_Color yellow;
+
+
+
+/* An individual item in the list of cached unicode characters that are rendered at   */
+/* the start of each game.                                                            */
+typedef struct uni_glyph {
+  wchar_t unicode_value;
+  SDL_Surface* white_glyph;
+  SDL_Surface* red_glyph;
+} uni_glyph;
+
+/* These are the arrays for the red and white letters: */
+static uni_glyph char_glyphs[MAX_UNICODES] = {0, NULL, NULL};
+
+/* An individual item in the list of unicode characters in the keyboard setup.   */
+/* Basically, just the Unicode value for the key and the finger used to type it. */
+typedef struct kbd_char {
+  wchar_t unicode_value;
+  char finger;
+} kbd_char;
+
+/* List with one entry for each typable character in keyboard setup - has the */
+/* Unicode value of the key and the associated fingering.                     */
+static kbd_char keyboard_list[MAX_UNICODES] = {0, -1};
+
+
+
+static TTF_Font* font = NULL;
+
+/* Used for word list functions (see below): */
+static int num_words;
+static wchar_t word_list[MAX_NUM_WORDS][MAX_WORD_SIZE + 1];
+static wchar_t char_list[MAX_UNICODES];  // List of distinct letters in word list
+static int num_chars_used = 0;       // Number of different letters in word list
+
+
+
+/* Local function prototypes: */
+static void gen_char_list(void);
+static int add_char(wchar_t uc);
+static void set_letters(unsigned char* t);
+static void show_letters(void);
+static void clear_keyboard(void);
+static int unicode_in_key_list(wchar_t uni_char);
+int check_needed_unicodes_str(const wchar_t* s);
+
+#ifndef WIN32
+#ifndef MACOSX
+static SDLPango_Matrix* SDL_Colour_to_SDLPango_Matrix(const SDL_Color* cl);
+#endif
+#endif
+
+
+
+/*****************************************************/
+/*                                                   */
+/*          "Public" Functions                       */
+/*                                                   */
+/*****************************************************/
+
+
+
+/* FIXME would be better to get keymap from system somehow (SDL? X11?) - */
+/* all this does now is fiddle with the ALPHABET and FINGER arrays */
+int LoadKeyboard(void)
+{
+  unsigned char fn[FNLEN];
+  int found = 0;
+
+  clear_keyboard();
+
+  /* First look for keyboard.lst in theme path, if desired: */
+  if (!settings.use_english)
+  {
+    sprintf(fn , "%s/keyboard.lst", settings.theme_data_path);
+    if (CheckFile(fn))
+    {
+      found = 1;
+    }
+  }
+
+  /* Now look in default path if desired or needed: */
+  if (!found)
+  {
+    sprintf(fn , "%s/keyboard.lst", settings.default_data_path);
+    if (CheckFile(fn))
+    {
+      found = 1;
+    }
+  }
+
+  if (!found)
+  {
+    fprintf(stderr, "LoadKeyboard(): Error finding file for keyboard setup!\n");
+    return 0;
+  }
+  
+  /* fn should now contain valid path to keyboard.lst: */
+  DEBUGCODE{fprintf(stderr, "fn = %s\n", fn);}
+
+  {
+    unsigned char str[255];
+    wchar_t wide_str[255];
+
+    FILE* f;
+    int i = 0, j = 0, k = 0;
+
+    f = fopen( fn, "r" );
+
+    if (f == NULL)
+    {
+      LOG("LoadKeyboard() - could not open keyboard.lst\n");
+      return 0;
+    }
+
+
+    do
+    {
+      fscanf( f, "%[^\n]\n", str);
+      /* Convert to wcs from UTF-8, if needed; */
+      //mbstowcs(wide_str, str, strlen(str) + 1);
+      ConvertFromUTF8(wide_str, str);
+
+      /* Line must have 3 chars (if more, rest are ignored) */
+      /* Format is: FINGER|Char  e.g   "3|d"                */
+      /* wide_str[0] == finger used to type char            */
+      /* wide_str[1] =='|'
+      /* wide_str[2] == Unicode value of character          */
+
+      /* FIXME - this might be a good place to use a    */
+      /* hash table to avoid n^2 performance problems.  */
+      /* Some sanity checks:  */
+      if ((wcslen(wide_str) >=3)
+       && (wcstol(&wide_str[0], NULL, 0) >=0)   /* These lines just make sure the */
+       && (wcstol(&wide_str[0], NULL, 0) < 10)  /* finger is between 0 and 10     */
+       && (wide_str[1] == '|')
+       && (k < MAX_UNICODES)
+       && !unicode_in_key_list(wide_str[2])) /* Make sure char not already added */
+      {
+        DEBUGCODE
+        {
+          fprintf(stderr, "Adding key: Unicode char = '%C'\tUnicode value = %d\tfinger = %d\n",
+                  wide_str[2], wide_str[2], wcstol(&wide_str[0], NULL, 0)); 
+        }
+
+        /* Just plug values into array: */
+        keyboard_list[k].unicode_value = wide_str[2];
+        keyboard_list[k].finger = wcstol(&wide_str[0], NULL, 0);
+        k++;
+      }
+    } while (!feof(f));
+
+
+    fclose(f);
+
+    LOG("Leaving LoadKeyboard()\n");
+    return 1;
+  }
+}
+
+/* Returns the finger hint(0-9) associated with a given Unicode value */
+/* in the keyboard_list:                                              */
+/* Returns -1 if somehow no finger associated with a Unicode value    */
+/* in the list (shouldn't happen).                                    */
+/* Returns -2 if Unicode value not in list.                           */
+int GetFinger(wchar_t uni_char)
+{
+  int i = 0;
+
+  while ((i < MAX_UNICODES)
+     &&  (keyboard_list[i].unicode_value != uni_char))
+  {
+    i++;
+  }
+
+  if (i == MAX_UNICODES)
+  {
+    fprintf(stderr, "GetFinger() - Unicode char '%C' not found in list.\n");
+    return -2;
+  }
+
+  if ((keyboard_list[i].finger < 0)
+   || (keyboard_list[i].finger > 9))
+  {
+    fprintf(stderr, "GetFinger() - Unicode char '%C' has no valid finger.\n");
+    return -1;
+  }  
+
+  return (int)keyboard_list[i].finger; /* Keep compiler from complaining */
+}
+
+
+
+int unicode_in_key_list(wchar_t uni_char)
+{
+  int i = 0;
+  while ((i < MAX_UNICODES)
+     &&  (keyboard_list[i].unicode_value != uni_char))
+  {
+    i++;
+  }
+  if (i == MAX_UNICODES)
+    return 0;
+  else
+    return 1;
+}
+
+/* NOTE if we can consistently use SDLPango on all platforms, we can simply */
+/* rename the pango version to BlackOutline() and get rid of this one.      */
+/* The input for this function should be UTF-8.                             */
+SDL_Surface* BlackOutline(const unsigned char* t, const TTF_Font* font, const SDL_Color* c)
+{
+  SDL_Surface* out = NULL;
+  SDL_Surface* black_letters = NULL;
+  SDL_Surface* white_letters = NULL;
+  SDL_Surface* bg = NULL;
+  SDL_Rect dstrect;
+  Uint32 color_key;
+
+  LOG("Entering BlackOutline()\n");
+
+/* Simply passthrough to SDLPango version if available (i.e. not under Windows):*/
+#ifndef WIN32
+#ifndef MACOSX
+return BlackOutline_SDLPango(t, font, c);
+#endif
+#endif
+
+
+  if (!t || !font || !c)
+  {
+    fprintf(stderr, "BlackOutline(): invalid ptr parameter, returning.");
+    return NULL;
+  }
+
+  black_letters = TTF_RenderUTF8_Blended((TTF_Font*)font, t, black);
+
+  if (!black_letters)
+  {
+    fprintf (stderr, "Warning - BlackOutline() could not create image for %s\n", t);
+    return NULL;
+  }
+
+  bg = SDL_CreateRGBSurface(SDL_SWSURFACE,
+                            (black_letters->w) + 5,
+                            (black_letters->h) + 5,
+                             32,
+                             RMASK, GMASK, BMASK, AMASK);
+  /* Use color key for eventual transparency: */
+  color_key = SDL_MapRGB(bg->format, 10, 10, 10);
+  SDL_FillRect(bg, NULL, color_key);
+
+  /* Now draw black outline/shadow 2 pixels on each side: */
+  dstrect.w = black_letters->w;
+  dstrect.h = black_letters->h;
+
+  /* NOTE: can make the "shadow" more or less pronounced by */
+  /* changing the parameters of these loops.                */
+  for (dstrect.x = 1; dstrect.x < 4; dstrect.x++)
+    for (dstrect.y = 1; dstrect.y < 3; dstrect.y++)
+      SDL_BlitSurface(black_letters , NULL, bg, &dstrect );
+
+  SDL_FreeSurface(black_letters);
+
+  /* --- Put the color version of the text on top! --- */
+  /* NOTE we cast away the 'const-ness' to keep compliler from complaining: */
+  white_letters = TTF_RenderUTF8_Blended((TTF_Font*)font, t, *c);
+  dstrect.x = 1;
+  dstrect.y = 1;
+  SDL_BlitSurface(white_letters, NULL, bg, &dstrect);
+  SDL_FreeSurface(white_letters);
+
+  /* --- Convert to the screen format for quicker blits --- */
+  SDL_SetColorKey(bg, SDL_SRCCOLORKEY|SDL_RLEACCEL, color_key);
+  out = SDL_DisplayFormatAlpha(bg);
+  SDL_FreeSurface(bg);
+
+  LOG("Leaving BlackOutline()\n");
+
+  return out;
+}
+
+
+
+#ifndef WIN32
+#ifndef MACOSX
+/*Convert SDL_Colour to SDLPango_Matrix*/
+
+SDLPango_Matrix* SDL_Colour_to_SDLPango_Matrix(const SDL_Color *cl)
+{
+  SDLPango_Matrix *colour;
+  colour=malloc(sizeof(SDLPango_Matrix));
+  int k;
+  for(k=0;k<4;k++){
+  	(*colour).m[0][k]=(*cl).r;
+  	(*colour).m[1][k]=(*cl).g;
+  	(*colour).m[2][k]=(*cl).b;
+  }
+  (*colour).m[3][0]=0;
+  (*colour).m[3][1]=255;
+  (*colour).m[3][2]=0;
+  (*colour).m[3][3]=0;
+
+  return colour;
+}
+
+
+
+/* This version basically uses the SDLPango lib instead of */
+/* TTF_RenderUTF*_Blended() to properly render Indic text. */
+SDL_Surface* BlackOutline_SDLPango(const unsigned char* t, const TTF_Font* font, const SDL_Color* c)
+{
+  SDL_Surface* out = NULL;
+  SDL_Surface* black_letters = NULL;
+  SDL_Surface* white_letters = NULL;
+  SDL_Surface* bg = NULL;
+  SDL_Rect dstrect;
+  Uint32 color_key;
+  /* To covert SDL_Colour to SDLPango_Matrix */
+  SDLPango_Matrix* colour = NULL;
+  /* Create a context which contains Pango objects.*/
+  SDLPango_Context* context = NULL;
+
+  LOG("\nEntering BlackOutline_SDLPango()\n");
+  DEBUGCODE{ fprintf(stderr, "will attempt to render: %s\n", t); }
+
+  if (!t || !font || !c)
+  {
+    fprintf(stderr, "BlackOutline_SDLPango(): invalid ptr parameter, returning.");
+    return NULL;
+  }
+
+  /* SDLPango crashes on 64 bit machines if passed empty string - Debian Bug#439071 */
+  if (*t == '\0')
+  {
+    fprintf(stderr, "BlackOutline_SDLPango(): empty string arg - must return to avoid segfault.");
+    return NULL;
+  }
+
+  colour = SDL_Colour_to_SDLPango_Matrix(c);
+  
+  /* Create the context */
+  context = SDLPango_CreateContext();	
+  SDLPango_SetDpi(context, 125.0, 125.0);
+  /* Set the color */
+  SDLPango_SetDefaultColor(context, MATRIX_TRANSPARENT_BACK_BLACK_LETTER );
+  SDLPango_SetBaseDirection(context, SDLPANGO_DIRECTION_LTR);
+  /* Set text to context */ 
+  SDLPango_SetMarkup(context, t, -1); 
+
+  if (!context)
+  {
+    fprintf (stderr, "In BlackOutline_SDLPango(), could not create context for %s", t);
+    return NULL;
+  }
+
+  black_letters = SDLPango_CreateSurfaceDraw(context);
+
+  if (!black_letters)
+  {
+    fprintf (stderr, "Warning - BlackOutline_SDLPango() could not create image for %s\n", t);
+    return NULL;
+  }
+
+  bg = SDL_CreateRGBSurface(SDL_SWSURFACE,
+                            (black_letters->w) + 5,
+                            (black_letters->h) + 5,
+                             32,
+                             RMASK, GMASK, BMASK, AMASK);
+  if (!bg)
+  {
+    fprintf (stderr, "Warning - BlackOutline()_SDLPango - bg creation failed\n");
+    SDL_FreeSurface(black_letters);
+    return NULL;
+  }
+
+  /* Draw text on a existing surface */
+  SDLPango_Draw(context, bg, 0, 0);
+
+  /* Use color key for eventual transparency: */
+  color_key = SDL_MapRGB(bg->format, 10, 10, 10);
+  SDL_FillRect(bg, NULL, color_key);
+
+  /* Now draw black outline/shadow 2 pixels on each side: */
+  dstrect.w = black_letters->w;
+  dstrect.h = black_letters->h;
+
+  /* NOTE: can make the "shadow" more or less pronounced by */
+  /* changing the parameters of these loops.                */
+  for (dstrect.x = 1; dstrect.x < 4; dstrect.x++)
+    for (dstrect.y = 1; dstrect.y < 3; dstrect.y++)
+      SDL_BlitSurface(black_letters , NULL, bg, &dstrect );
+
+  SDL_FreeSurface(black_letters);
+
+  /* --- Put the color version of the text on top! --- */
+  SDLPango_SetDefaultColor(context, colour);
+  white_letters = SDLPango_CreateSurfaceDraw(context);
+  dstrect.x = 1;
+  dstrect.y = 1;
+  SDL_BlitSurface(white_letters, NULL, bg, &dstrect);
+  SDL_FreeSurface(white_letters);
+
+  /* --- Convert to the screen format for quicker blits --- */
+  SDL_SetColorKey(bg, SDL_SRCCOLORKEY|SDL_RLEACCEL, color_key);
+  out = SDL_DisplayFormatAlpha(bg);
+  SDL_FreeSurface(bg);
+
+  LOG("Leaving BlackOutline_SDLPango()\n\n");
+
+  return out;
+}
+
+#endif
+#endif
+/* End of win32-excluded coded */
+
+
+
+
+/* This version takes a wide character string and renders it with the */
+/* Unicode string versions of the SDL_ttf functions:                  */
+SDL_Surface* BlackOutline_Unicode(const Uint16* t, const TTF_Font* font, const SDL_Color* c)
+{
+  SDL_Surface* out = NULL;
+  SDL_Surface* black_letters = NULL;
+  SDL_Surface* white_letters = NULL;
+  SDL_Surface* bg = NULL;
+  SDL_Rect dstrect;
+  Uint32 color_key;
+
+  if (!font || !c)
+  {
+    fprintf(stderr, "BlackOutline_wchar(): invalid ptr parameter, returning.");
+    return NULL;
+  }
+                                        /* (cast to stop compiler complaint) */
+  black_letters = TTF_RenderUNICODE_Blended((TTF_Font*)font, t, black);
+
+  if (!black_letters)
+  {
+    fprintf (stderr, "Warning - BlackOutline_wchar() could not create image for %S\n", t);
+    return NULL;
+  }
+
+  bg = SDL_CreateRGBSurface(SDL_SWSURFACE,
+                            (black_letters->w) + 5,
+                            (black_letters->h) + 5,
+                             32,
+                             RMASK, GMASK, BMASK, AMASK);
+  /* Use color key for eventual transparency: */
+  color_key = SDL_MapRGB(bg->format, 10, 10, 10);
+  SDL_FillRect(bg, NULL, color_key);
+
+  /* Now draw black outline/shadow 2 pixels on each side: */
+  dstrect.w = black_letters->w;
+  dstrect.h = black_letters->h;
+
+  /* NOTE: can make the "shadow" more or less pronounced by */
+  /* changing the parameters of these loops.                */
+  for (dstrect.x = 1; dstrect.x < 4; dstrect.x++)
+    for (dstrect.y = 1; dstrect.y < 3; dstrect.y++)
+      SDL_BlitSurface(black_letters , NULL, bg, &dstrect );
+
+  SDL_FreeSurface(black_letters);
+
+  /* --- Put the color version of the text on top! --- */
+                                       /* (cast to stop compiler complaint) */
+  white_letters = TTF_RenderUNICODE_Blended((TTF_Font*)font, t, *c);
+  dstrect.x = 1;
+  dstrect.y = 1;
+  SDL_BlitSurface(white_letters, NULL, bg, &dstrect);
+  SDL_FreeSurface(white_letters);
+
+  /* --- Convert to the screen format for quicker blits --- */
+  SDL_SetColorKey(bg, SDL_SRCCOLORKEY|SDL_RLEACCEL, color_key);
+  out = SDL_DisplayFormatAlpha(bg);
+  SDL_FreeSurface(bg);
+
+  return out;
+}
+
+
+/* FIXME dead code but could be useful*/
+static void show_letters(void)
+{
+	int i, l = 0;
+	SDL_Surface* abit;
+	SDL_Rect dst;
+	int stop = 0;
+	unsigned char t[255];
+
+	for (i=0; i<256; i++)
+		if (ALPHABET[i])
+			t[l++]=i;
+
+	t[l] = 0;
+
+	abit = BlackOutline(t, font, &white);
+
+	dst.x = 320 - (abit->w / 2);
+	dst.y = 275;
+	dst.w = abit->w;
+	dst.h = abit->h;
+
+	SDL_BlitSurface(abit, NULL, screen, &dst);
+
+	SDL_FreeSurface(abit);
+
+	abit = BlackOutline("Alphabet Set To:", font, &white);
+	dst.x = 320 - (abit->w / 2);
+	dst.y = 200;
+	dst.w = abit->w;
+	dst.h = abit->h;
+
+	SDL_BlitSurface(abit, NULL, screen, &dst);
+
+	SDL_UpdateRect(screen, 0, 0, 0 ,0);
+
+	while (!stop) 
+		while (SDL_PollEvent(&event)) 
+			switch (event.type) {
+				case SDL_QUIT:
+					exit(0);
+				case SDL_KEYDOWN:
+				case SDL_MOUSEBUTTONDOWN:
+					stop = 1;
+			}
+
+	SDL_FreeSurface(abit);
+}
+
+
+/* Returns a random Unicode char from the char_glyphs list: */
+/* --- get a letter --- */
+wchar_t GetRandLetter(void)
+{
+  static wchar_t last = -1; // we don't want to return same letter twice in a row
+  wchar_t letter;
+  int i = 0;
+
+  if (!num_chars_used)
+  {
+    fprintf(stderr, "GetRandLetter() - no letters in list!\n");
+    last = -1;
+    return -1;
+  }
+
+  do
+  {
+    i = rand() % num_chars_used;
+    letter = char_glyphs[i].unicode_value;
+  } while (letter == last);
+
+  last = letter;
+
+  return letter;
+}
+
+/******************************************************************************
+*                           WORD FILE & DATA STRUCTURE                        *
+******************************************************************************/
+
+
+
+/* ClearWordList: clears the number of words
+ */
+void ClearWordList(void)
+{
+  int i;
+  for (i = 0; i < num_words; i++)
+  {
+    word_list[i][0] = '\0';
+  }
+  num_words = 0;
+}
+
+/* FIXME need a better i18n-compatible way to do this: */
+/* UseAlphabet(): setups the word_list so that it really
+ * returns a LETTER when GetWord() is called
+ */
+// void UseAlphabet(void)
+// {
+// 	int i;
+// 
+// 	LOG("Entering UseAlphabet()\n");
+// 
+// 	num_words = 0;
+// 	/* This totally mucks up i18n abilities :( */
+// 	for (i=65; i<90; i++) 
+// 	{
+// 		//if (ALPHABET[i])
+//                 {
+// 			word_list[num_words][0] = (unsigned char)i;
+// 			word_list[num_words][1] = '\0';
+// 			num_words++;
+// 
+// 			DEBUGCODE { fprintf(stderr, "Adding %c\n", (unsigned char)i); }
+// 		}
+// 	}
+// 	/* Make sure list is terminated with null character */
+// 	word_list[num_words][0] = '\0';
+// 
+// 	/* Make list of all unicode characters used in word list: */
+// 	gen_char_list();
+// 
+// 	DOUT(num_words);
+// 	LOG("Leaving UseAlphabet()\n");
+// }
+
+/* GetWord: returns a random word that wasn't returned
+ * the previous time (unless there is only 1 word!!!)
+ */
+wchar_t* GetWord(void)
+{
+	static int last_choice = -1;
+	int choice;
+
+	LOG("Entering GetWord()\n");
+	DEBUGCODE { fprintf(stderr, "num_words is: %d\n", num_words); }
+
+	/* Now count list to make sure num_words is correct: */
+
+	num_words = 0;
+	while (word_list[num_words][0] != '\0')
+	{
+	  num_words++;
+	}
+
+	DEBUGCODE { fprintf(stderr, "After count, num_words is: %d\n", num_words); }
+
+        if (0 == num_words)
+	{
+	  LOG("No words in list\n");
+          return NULL;
+	}
+
+        if (num_words > MAX_NUM_WORDS)
+	{
+	  LOG("Error: num_words greater than array size\n");
+          return NULL;
+	}
+
+        if (num_words < 0)
+	{
+	  LOG("Error: num_words negative\n");
+          return NULL;
+	}
+
+	do {
+		choice = (rand() % num_words);
+	} while ((choice == last_choice) || (num_words < 2));
+
+	last_choice = choice;
+
+	/* NOTE need %S rather than %s because of wide characters */
+	DEBUGCODE { fprintf(stderr, "Selected word is: %S\n", word_list[choice]); }
+
+	return word_list[choice];
+}
+
+
+
+/* GenerateWordList(): adds the words from a given wordlist
+ * it ignores any words too long or that has bad
+ * character (such as #)
+ */
+
+/* Now returns the number of words in the list, so if no words */
+/* returns "false"                                             */
+int GenerateWordList(const char* wordFn)
+{
+  int j;
+  unsigned char temp_word[FNLEN];
+  wchar_t temp_wide_word[FNLEN];
+  size_t length;
+
+  FILE* wordFile=NULL;
+
+  DEBUGCODE { fprintf(stderr, "Entering GenerateWordList() for file: %s\n", wordFn); }
+
+  num_words = 0;
+
+  /* --- open the file --- */
+
+  wordFile = fopen( wordFn, "r" );
+
+  if ( wordFile == NULL )
+  {
+    fprintf(stderr, "ERROR: could not load wordlist: %s\n", wordFn );
+//    UseAlphabet( );
+    return 0;
+  }
+
+
+  /* --- load words from file named as argument: */
+
+  DEBUGCODE { fprintf(stderr, "WORD FILE OPENNED @ %s\n", wordFn); }
+
+  /* ignore the title (i.e. first line) */
+  fscanf( wordFile, "%[^\n]\n", temp_word);
+
+  while (!feof(wordFile) && (num_words < MAX_NUM_WORDS))
+  {
+    fscanf( wordFile, "%[^\n]\n", temp_word);
+    DEBUGCODE {fprintf(stderr, "temp_word = %s\n", temp_word);}
+
+    for (j = 0; j < strlen(temp_word); j++)
+    {
+      if (temp_word[j] == '\n' || temp_word[j] == '\r')
+        temp_word[j] = '\0';
+    }
+
+    /* Convert from UTF-8 to wcs and make sure word is usable: */
+    /* NOTE need to add one to length arg so terminating '\0' gets added: */
+    //length = mbstowcs(temp_wide_word, temp_word, strlen(temp_word) + 1);
+
+    length = ConvertFromUTF8(temp_wide_word, temp_word);
+    DOUT(length);
+
+    if (length == -1)  /* Means invalid UTF-8 sequence or conversion failed */
+    {
+      fprintf(stderr, "Word '%s' not added - invalid UTF-8 sequence!\n", temp_word);
+      continue;
+    }
+
+    if (length == 0)
+    {
+      fprintf(stderr, "Word '%ls' not added - length is zero\n", temp_wide_word);
+      continue;
+    }
+
+    if (length > MAX_WORD_SIZE)
+    {
+      fprintf(stderr, "Word '%s' not added - exceeds %d characters\n",
+              temp_word, MAX_WORD_SIZE);
+      continue;
+    }
+
+    if (num_words >= MAX_NUM_WORDS)
+    {
+      fprintf(stderr, "Word '%s' not added - list has reached max of %d characters\n",
+              temp_word, MAX_NUM_WORDS);
+      continue;
+    }
+
+    if (!check_needed_unicodes_str(temp_wide_word))
+    {
+      fprintf(stderr, "Word '%S' not added - contains Unicode chars not in keyboard list\n",
+              temp_wide_word);
+      continue;
+    }
+
+    /* If we make it to here, OK to add word: */
+    /* NOTE we have to add one to the length argument */
+    /* to include the terminating null.  */
+    DEBUGCODE
+    {
+      fprintf(stderr, "Adding word: %ls\n", temp_wide_word);
+    }
+
+    wcsncpy(word_list[num_words], temp_wide_word, strlen(temp_word) + 1);
+    num_words++;
+  }
+        
+  /* Make sure list is terminated with null character */
+  word_list[num_words][0] = '\0';
+
+  DOUT(num_words);
+
+//  if (num_words == 0)
+//    UseAlphabet( );
+
+  fclose(wordFile);
+
+  /* Make list of all unicode characters used in word list: */
+  /* (we use this to check to make sure all are "typable"); */
+  gen_char_list();
+
+  LOG("Leaving GenerateWordList()\n");
+
+  return (num_words);
+}
+
+
+
+
+
+
+/* This version creates the letters using TTF_RenderUNICODE_Blended */
+int RenderLetters(const TTF_Font* letter_font)
+{
+  Uint16 t[2];
+  int i, j;  /* i is chars attempted, j is chars actually rendered. */
+
+  if (!letter_font)
+  {
+    fprintf(stderr, "RenderLetters() - invalid TTF_Font* argument!\n");
+    return 0;
+  }
+
+  i = j = num_chars_used = 0;
+
+  t[1] = '\0';
+
+  while (i < MAX_UNICODES)
+  {
+    t[0] = keyboard_list[i].unicode_value;
+
+    if (t[0] != 0)
+    {
+      DEBUGCODE
+      {
+        fprintf(stderr, "Creating SDL_Surface for list element %d, char = '%lc', Unicode value = %d\n", i, *t, *t);
+      }
+
+      char_glyphs[j].unicode_value = t[0];
+      char_glyphs[j].white_glyph = BlackOutline_Unicode(t, letter_font, &white);
+      char_glyphs[j].red_glyph = BlackOutline_Unicode(t, letter_font, &red);
+
+      j++;
+      num_chars_used++;
+    }
+    i++;
+  }
+
+  return num_chars_used;
+}
+
+
+
+void FreeLetters(void)
+{
+  int i;
+
+  for (i = 0; i < num_chars_used; i++)
+  {
+    SDL_FreeSurface(char_glyphs[i].white_glyph);
+    SDL_FreeSurface(char_glyphs[i].red_glyph);
+    char_glyphs[i].unicode_value = 0;
+    char_glyphs[i].white_glyph = NULL;
+    char_glyphs[i].red_glyph = NULL;
+  } 
+  /* List now empty: */
+  num_chars_used = 0;
+}
+
+
+SDL_Surface* GetWhiteGlyph(wchar_t t)
+{
+  int i;
+
+  for (i = 0;
+       (char_glyphs[i].unicode_value != t) && (i <= num_chars_used);
+       i++)
+  {}
+
+  /* Now return appropriate pointer: */
+  if (i > num_chars_used)
+  {
+    /* Didn't find character: */
+    fprintf(stderr, "Could not find glyph for Unicode char '%C', value = %d\n", t, t);
+    return NULL;
+  }
+  
+  /* Return corresponding surface for blitting: */
+  return char_glyphs[i].white_glyph;
+}
+
+
+
+SDL_Surface* GetRedGlyph(wchar_t t)
+{
+  int i;
+
+  for (i = 0;
+       char_glyphs[i].unicode_value != t && i <= num_chars_used;
+       i++)
+  {}
+
+  /* Now return appropriate pointer: */
+  if (i > num_chars_used)
+  {
+    /* Didn't find character: */
+    fprintf(stderr, "Could not find glyph for unicode character %lc\n", t);
+    return NULL;
+  }
+  
+  /* Return corresponding surface for blitting: */
+  return char_glyphs[i].red_glyph;
+}
+
+
+/* Checks to see if all of the glyphs needed by the word list have been     */
+/* successfully rendered based on the Unicode values given in keyboard.lst. */
+/* If not, then the list contains characters that will not display and (if  */
+/* keyboard.lst is correct) cannot be typed. Most likely, this means that   */
+/* keyboard.lst is not correct.
+/* Returns 1 if all needed chars found, 0 otherwise.                        */
+int CheckNeededGlyphs(void)
+{
+  int i = 0;
+
+  while ((i < MAX_UNICODES)
+      && (char_list[i] != '\0'))
+  {
+    if (!GetWhiteGlyph(char_list[i]))
+    {
+      fprintf(stderr, "\nCheckNeededGlyphs() - needed char '%C' (Unicode value = %d) not found.\n",
+              char_list[i], char_list[i]);
+      fprintf(stderr, "This probably means that the theme's 'keyboard.lst' file is incorrect or incomplete.\n");
+      return 0;
+    }
+    i++;
+  }
+  LOG("CheckNeededGlyphs() - all chars found.\n");
+  return 1;
+}
+
+int check_needed_unicodes_str(const wchar_t* s)
+{
+  int i = 0;
+
+  while ((i < MAX_WORD_SIZE)
+      && (s[i] != '\0'))
+  {
+    if (!unicode_in_key_list(s[i]))
+    {
+      fprintf(stderr, "\ncheck_needed_unicodes_str() - needed char '%C' (Unicode value = %d) not found.\n",
+              s[i], s[i]);
+      return 0;
+    }
+    i++;
+  }
+  return 1;
+}
+
+/****************************************************/
+/*                                                  */
+/*       Local ("private") functions:               */
+/*                                                  */
+/****************************************************/
+
+
+/* Creates a list of distinct Unicode characters in */
+/* word_list[][] (so the program knows what         */
+/* needs to be rendered for the games)              */
+static void gen_char_list(void)
+{
+  int i, j;
+  i = j = 0;
+  char_list[0] = '\0';
+
+  while (word_list[i][0] != '\0' && i < MAX_NUM_WORDS) 
+  {
+    j = 0;
+
+    while (word_list[i][j]!= '\0' && j < MAX_WORD_SIZE)
+    {
+      add_char(word_list[i][j]);
+      j++;
+    }
+
+    i++;
+  }
+
+  DEBUGCODE
+  {
+    fprintf(stderr, "char_list = %S\n", char_list);
+  }
+}
+
+
+
+void ResetCharList(void)
+{
+  char_list[0] = '\0';
+}
+
+
+
+/* Creates a list of distinct Unicode characters in       */
+/* the argument string for subsequent rendering.          */
+/* Like gen_char_list() but takes a string argument       */
+/* instead of going through the currently selected        */
+/* word list. Argument should be UTF-8                    */
+/* Can be called multiple times on different strings      */
+/* to accumulate entire repertoire - call ResetCharList() */
+/* to start over                                          */
+void GenCharListFromString(const unsigned char* UTF8_str)
+{
+  int i = 0;
+  wchar_t wchar_buf[MAX_UNICODES];
+
+  ConvertFromUTF8(wchar_buf, UTF8_str);
+
+  /* FNLEN is max length of phrase (I think) */
+  while (wchar_buf[i] != '\0' && i < FNLEN) 
+  {
+    add_char(wchar_buf[i]);
+    i++;
+  }
+
+  DEBUGCODE
+  {
+    fprintf(stderr, "char_list = %S\n", char_list);
+  }
+}
+
+
+
+/* FIXME this function is currently dead code */
+/* --- setup the alphabet --- */
+static void set_letters(unsigned char *t) {
+	int i;
+
+	ALPHABET_SIZE = 0;
+	for (i=0; i<256; i++)
+		ALPHABET[i]=0;
+
+	for (i=0; i<strlen(t); i++)
+		if (t[i]!=' ') {
+			ALPHABET[(int)t[i]]=1;
+			ALPHABET_SIZE++;
+		}
+}
+
+
+
+/* Checks to see if the argument is already in the list and adds    */
+/* it if necessary.  Returns 1 if char added, 0 if already in list, */
+/* -1 if list already up to maximum size:                           */
+/* FIXME performance would be better with hashtable                 */
+static int add_char(wchar_t uc)
+{
+  int i = 0;
+  while ((char_list[i] != uc)
+      && (char_list[i] != '\0')
+      && (i < MAX_UNICODES - 1))          //Because 1 need for null terminator
+  {
+    i++;
+  }
+
+  /* unicode already in list: */
+  if (char_list[i] == uc)
+  {
+    DEBUGCODE{ fprintf(stderr,
+                       "Unicode value: %d\tcharacter %lc already in list\n",
+                        uc, uc);}
+    return 0;
+  }
+
+  if (char_list[i] == '\0')
+  {
+    DEBUGCODE{ fprintf(stderr, "Adding unicode value: %d\tcharacter %lc\n", uc, uc);}
+    char_list[i] = uc;
+    char_list[i + 1] = '\0';
+    return 1;
+  }
+
+  if (i == MAX_UNICODES - 1)            //Because 1 need for null terminator
+  {
+    LOG ("Unable to add unicode - list at max capacity");
+    return -1;
+  }
+}
+
+
+
+static void clear_keyboard(void)
+{
+  int i = 0;
+  for (i = 0; i < MAX_UNICODES; i++)
+  {
+    keyboard_list[i].unicode_value = 0;
+    keyboard_list[i].finger = -1;
+  }
+}
+
+
+/* This function just tidies up all the ptr args needed for      */
+/* ConvertUTF8toUTF32() from Unicode, Inc. into a neat wrapper.  */
+/* It returns -1 on error, otherwise returns the length of the   */
+/* converted, null-terminated wchar_t* string now stored in the  */
+/* location of the 'wide_word' pointer.                          */
+int ConvertFromUTF8(wchar_t* wide_word, const unsigned char* UTF8_word)
+{
+  int i = 0;
+  ConversionResult result;
+  UTF8 temp_UTF8[FNLEN];
+  UTF32 temp_UTF32[FNLEN];
+
+  const UTF8* UTF8_Start = temp_UTF8;
+  const UTF8* UTF8_End = &temp_UTF8[FNLEN-1];
+  UTF32* UTF32_Start = temp_UTF32;
+  UTF32* UTF32_End = &temp_UTF32[FNLEN-1];
+
+  strncpy(temp_UTF8, UTF8_word, FNLEN);
+
+  ConvertUTF8toUTF32(&UTF8_Start, UTF8_End,
+                     &UTF32_Start, UTF32_End, 0);
+
+  wide_word[0] = '\0';
+
+  while ((i < FNLEN) && (temp_UTF32[i] != '\0'))
+  {
+    wide_word[i] = temp_UTF32[i];
+    i++; 
+  }
+
+  if (i >= FNLEN)
+  {
+    fprintf(stderr, "convert_from_UTF8(): buffer overflow\n");
+    return -1;
+  }
+  else  //need terminating null:
+  {
+    wide_word[i] = '\0';
+  }
+
+  DEBUGCODE {fprintf(stderr, "wide_word = %ls\n", wide_word);}
+
+  return wcslen(wide_word);
+}
+
+

Added: tuxtype/branches/tuxtype-new/src/audio.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/audio.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/audio.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,66 @@
+/***************************************************************************
+ -  file: audio.c
+ -  description: this file contains audio related functions
+                            -------------------
+    begin                : Jan 22, 2003
+    copyright            : Sam Hart, Jesse Andrews (C) 2003
+    email                : tuxtype-dev at tux4kids.net
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+
+static Mix_Music* defaultMusic = NULL; // holds music for audioMusicLoad/unload
+
+
+void PlaySound(Mix_Chunk* snd) {
+	if (!settings.sys_sound) return;
+
+	Mix_PlayChannel(-1, snd, 0);
+}
+
+/* MusicLoad attempts to load and play the music file 
+ * Note: loops == -1 means forever
+ */
+void MusicLoad(const char *musicFilename, int loops ) {
+	if (!settings.sys_sound) return;
+
+	MusicUnload(); // make sure defaultMusic is clear
+
+	defaultMusic = LoadMusic( musicFilename );
+	Mix_PlayMusic( defaultMusic, loops );
+}
+
+/* MusicUnload attempts to unload any music data that was
+ * loaded using the audioMusicLoad function
+ */
+void MusicUnload( void ) {
+	if (!settings.sys_sound) return;
+
+	if ( defaultMusic )
+		Mix_FreeMusic( defaultMusic );
+
+	defaultMusic = NULL;
+}
+
+/* audioMusicPlay attempts to play the passed music data. 
+ * if a music file was loaded using the audioMusicLoad
+ * it will be stopped and unloaded
+ * Note: loops == -1 means forever
+ */
+void MusicPlay(Mix_Music* musicData, int loops)
+{ 
+  if (!settings.sys_sound) return;
+  /* Stop previous music before playing new one: */
+  MusicUnload();	
+  Mix_PlayMusic(musicData, loops);
+}

Added: tuxtype/branches/tuxtype-new/src/funcs.h
===================================================================
--- tuxtype/branches/tuxtype-new/src/funcs.h	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/funcs.h	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,122 @@
+/***************************************************************************
+                          funcs.h
+  description: function header
+                             -------------------
+    begin                : Sat May 6 2000
+    copyright            : (C) 2000 by Sam Hart
+    email                : hart at geekcomix.com
+ 
+  Modified by David Bruce
+  dbruce at tampabay.rr.com
+  2007
+
+***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+/* NOTE - there is no reason to declare functions using "extern", as all */
+/* non-local functions are visible throughout the program.               */ 
+
+
+/* In alphabet.c */
+SDL_Surface* BlackOutline(const unsigned char* t, const TTF_Font* font, const SDL_Color* c);
+SDL_Surface* BlackOutline_Unicode(const Uint16* t, const TTF_Font* font, const SDL_Color* c);
+
+#ifndef WIN32
+SDL_Surface* BlackOutline_SDLPango(const unsigned char* t, const TTF_Font* font, const SDL_Color* c);
+#endif
+
+/* (still in alphabet.c:) */
+int CheckNeededGlyphs(void);
+void ClearWordList(void);
+int ConvertFromUTF8(wchar_t* wide_word, const unsigned char* UTF8_word);
+void FreeLetters(void);
+int GenerateWordList(const char* wordFn);
+void GenCharListFromString(const unsigned char* UTF8_str);
+void ResetCharList(void);
+wchar_t GetLetter(void);
+wchar_t* GetWord(void);
+SDL_Surface* GetWhiteGlyph(wchar_t t);
+SDL_Surface* GetRedGlyph(wchar_t t);
+int LoadKeyboard(void);
+int GetFinger(wchar_t uni_char);
+int RenderLetters(const TTF_Font* letter_font);
+
+//void UseAlphabet(void);
+
+
+/* In audio.c:   */
+void PlaySound(Mix_Chunk* snd);
+void MusicLoad(const char* musicFilename, int repeatQty);
+void MusicUnload(void);
+void MusicPlay(Mix_Music* musicData, int repeatQty);
+
+
+/* In gettext.c:  */
+unsigned char* gettext(const unsigned char* in);
+int Load_PO_File(const char* file);
+
+
+/* In laser.c:        */
+int PlayLaserGame(int diff_level);
+
+
+/* In loaders.c: */
+int CheckFile(const char* file);
+sprite* FlipSprite(sprite* in, int X, int Y);
+void FreeSprite(sprite* gfx);
+TTF_Font* LoadFont(const char* fontfile, int fontsize);
+SDL_Surface* LoadImage(const char* datafile, int mode);
+void LoadLang(void);
+Mix_Music* LoadMusic(const char* datafile);
+Mix_Chunk* LoadSound(const char* datafile);
+sprite* LoadSprite(const char* name, int MODE);
+
+/* In options.c: */
+void Opts_Initialize(void);
+
+/* In pause.c: */
+int  Pause(void);
+int  inRect(SDL_Rect r, int x, int y);
+
+
+/* In playgame.c: */
+int PlayCascade(int level);
+void InitEngine(void);
+int TransWipe(SDL_Surface* newbkg, int type, int var1, int var2);
+
+
+/* In practice.c: */
+int Phrases(wchar_t* practice_phrase);
+
+
+/* In scripting.c: */
+int TestLesson(void);
+void ProjectInfo(void);
+void InstructCascade(void);
+void InstructLaser(void);
+
+
+/* In setup.c: */
+void GraphicsInit(Uint32 video_flags);
+void LibInit(Uint32 lib_flags);
+void LoadSettings(void);
+void SaveSettings(void);
+int SetupPaths(const char* theme_dir);
+void Cleanup(void);
+
+/* In theme.c: */
+void ChooseTheme(void);
+
+
+/* In titlescreen.c: */
+void SwitchScreenMode(void);
+void TitleScreen(void);
+

Added: tuxtype/branches/tuxtype-new/src/gettext.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/gettext.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/gettext.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,198 @@
+/***************************************************************************
+gettext.c 
+-  description: a crossplatform minimal gettext library
+-------------------
+begin                : Sunday Feb 23, 2003
+copyright            : (C) 2003 by Jesse Andrews
+email                : jdandr2 at uky.edu
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************/
+
+#include "stdio.h"
+#include "globals.h"
+
+/* we will store our list in a linked list since
+ * we don't expect too large of a list (famous last words!)
+ */
+
+/* FIXME not sure if this file's code is UTF-8/Unicode compatible DSB */
+
+struct node {
+	unsigned char *in;          // the english
+	unsigned char *out;         // the translation
+	struct node *next; // ptr to next in list, NULL if last
+};
+
+typedef struct node item; 
+
+static item* HEAD = NULL;
+
+/* Local function prototypes: */
+static void add_word(unsigned char* in, unsigned char* out);
+
+/* --- add a word to the linked list --- */
+
+void add_word(unsigned char* in, unsigned char* out) {
+	item* cur;
+	/* -- allocate space for the node in the list -- */
+	cur = (item *)malloc(sizeof(item));
+
+	/* -- allocate space for strings, and copy over -- */
+	cur->in = (unsigned char *)malloc(strlen(in)+2);
+	strncpy(cur->in, in, strlen(in)+1);
+	cur->out = (unsigned char *)malloc(strlen(out)+2);
+	strncpy(cur->out, out, strlen(out)+1);
+
+	/* -- add to the front of the list -- */
+	cur->next = HEAD;
+	HEAD = cur;
+}
+
+int Load_PO_File(const char* file) {
+	/* this function will load the passed file (a .po file)
+	 * if need be, it should erase any previously loaded
+	 * translations.
+	 *
+	 * the filename passed must exist!
+	 *
+	 * returns: 0 if ok
+	 * 	-1 if file could not be located
+	 * 	-2 if file has errors in it
+	 */
+
+	item* ptr;
+	FILE* f;
+	unsigned char str[FNLEN];
+	unsigned char in[FNLEN];
+	unsigned char out[FNLEN];
+
+	LOG( "Clearing previous translation list\n" );
+
+	while(HEAD != NULL) {
+		ptr = HEAD->next;
+		free(HEAD);
+		HEAD = ptr;
+	}
+
+	/* Yes, I know, I should use YACC/LEX
+	 * but, until you provide an GPL YACC/LEX 
+	 * implimentation on Mac OS _CLASSIC_, we have
+	 * to do things so they are portable, which
+	 * means, we have to parse our files by hand
+	 * using "state machines"
+	 */
+
+
+	LOG( "Loading translation file\n" );
+	f = fopen( file, "r" );
+
+	if (f == NULL)
+        {
+          DEBUGCODE
+          {
+            fprintf(stderr, "Load_PO_File() - could not open %s\n", file);
+          }
+          return -1;
+	}
+	/* ### ADD ERROR CHECKING ### */
+
+	do {
+		fscanf(f, "%[^\n]\n", str);
+
+		/* get rid of any comments! */
+		{
+			unsigned char mode='O';
+			int i;
+			for (i = 0; i < strlen(str); i++) {
+				if (mode == 'O') {
+					switch (str[i]) {
+						case '"': mode = 'I'; break;
+						case '#': str[i]='\0'; break;
+					}
+				} else {
+					switch (str[i]) {
+						case '\\': 
+							if (mode != 'S') mode = 'S';
+							else mode = 'I';
+							break;
+						case '"': 
+							if (mode != 'S') mode ='O'; 
+							break;
+						default:
+							mode = 'I'; // get rid of any /
+					}
+				}
+			}
+		}
+
+		/* we force msgid or msgstr to be at the begining of the line! */
+
+		if (strncmp(str, "msgid", 5) == 0) {
+			int start=0, endloc=0, i;
+			for (i=0; i<strlen(str); i++)
+				if (str[i] == '"') {
+					if (!start)
+						start = i;
+					else
+						endloc = i;
+				}
+			str[endloc]='\0';
+			strcpy(in, str+start+1);
+		}
+		if (strncmp(str, "msgstr", 6) == 0) {
+			int start=0,endloc=0, i;
+			for (i=0; i<strlen(str); i++)
+				if (str[i] == '"') {
+					if (!start)
+						start = i;
+					else
+						endloc = i;
+				}
+			str[endloc]='\0';
+			strcpy(out, str+start+1);
+			add_word(in, out);
+		}
+
+	} while( !feof(f) );
+
+	LOG( "Completed loading of translation file\n" );
+
+	return 0;
+}
+
+unsigned char* gettext(const unsigned char* in ) {
+	/* this function will attempt to translate the string
+	 * "in" to an "translation of in" if one exists.
+	 * if it doesn't exist in the translation set, it 
+	 * returns "in".
+	 */
+
+	/* go through each time until we find what we want...
+	 * if the number of translated words we use increases, 
+	 * we should move to a hash table.
+	 */
+
+	item* cur = HEAD;
+
+	if (settings.use_english)
+		// the cast is to keep the compiler from complaining
+                // about "discarded qualifiers"
+		return (unsigned char*)in;
+
+	while (cur != NULL) 
+		if (strcmp(cur->in, in) == 0)
+			return cur->out;
+		else
+			cur = cur->next;
+
+	/* if we didn't find anything return what we were asked */
+	return (unsigned char*)in;
+}

Added: tuxtype/branches/tuxtype-new/src/globals.h
===================================================================
--- tuxtype/branches/tuxtype-new/src/globals.h	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/globals.h	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,235 @@
+/***************************************************************************
+                          globals.h
+  description: global varis
+                             -------------------
+    begin                : Fri May 5 2000
+    copyright            : (C) 2000 by Sam Hart
+    email                : hart at geekcomix.com
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#define to_upper(c) (((c) >= 'a' && (c) <= 'z') ? (c) -32 : (c))
+#define COL2RGB( col ) SDL_MapRGB( screen->format, col->r, col->g, col->b )
+
+#define FNLEN	200
+
+#define RES_X	640
+#define RES_Y	480
+#define BPP	16	
+
+#ifdef WIN32 
+#undef DATA_PREFIX
+#define DATA_PREFIX ".//"
+#endif
+
+#ifndef __GLOBALS_H__
+#define __GLOBALS_H__
+
+#define MAX_SPRITE_FRAMES 30
+
+#include <string.h>
+#include <wchar.h>
+#include <math.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <locale.h>
+
+#include "../config.h"
+
+#include "SDL.h"
+#include "SDL_image.h"
+#include "SDL_mixer.h"
+#include "SDL_ttf.h"
+
+#endif //  __GLOBALS_H__
+
+#define NEXT_FRAME(SPRITE) if ((SPRITE)->num_frames) (SPRITE)->cur = (((SPRITE)->cur)+1) % (SPRITE)->num_frames;
+#define REWIND(SPRITE) (SPRITE)->cur = 0;
+
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+
+/* Goal is to have all global settings here */
+/* (renamed from 'settings' to match tuxmath) */
+typedef struct game_option_type{
+  char default_data_path[FNLEN];
+  char theme_data_path[FNLEN];
+  char user_settings_path[FNLEN];
+  char global_settings_path[FNLEN];
+  char theme_name[FNLEN];
+  char lang[FNLEN];
+  char theme_font_name[FNLEN];
+  int use_english;
+  int fullscreen;
+  int sys_sound;
+  int sfx_volume;
+  int mus_volume;
+  int menu_music;
+  int menu_sound;
+  int speed_up;
+  int show_tux4kids;
+  int debug_on;
+  int o_lives;
+  int sound_vol;
+  int hidden; // Read the README file in the image directory for info on this ;)
+} game_option_type;
+
+/* Default values for game_option_type struct */
+/* They can be changed in the struct to other values at run-time */
+#define DEFAULT_MENU_FONT       "AndikaDesRevG.ttf"
+#define DEFAULT_GAME_FONT       "AndikaDesRevG.ttf" 
+#define DEFAULT_USE_ENGLISH 1
+#define DEFAULT_FULLSCREEN 1
+#define DEFAULT_SYS_SOUND 1
+#define DEFAULT_SFX_VOLUME 100
+#define DEFAULT_MUS_VOLUME 100
+#define DEFAULT_MENU_MUSIC 1
+#define DEFAULT_MENU_SOUND 1
+#define DEFAULT_SPEED_UP 0
+#define DEFAULT_SHOW_TUX4KIDS 1
+#define DEFAULT_DEBUG_ON 0
+#define DEFAULT_O_LIVES 0
+#define DEFAULT_SOUND_VOL 100
+#define DEFAULT_HIDDEN 0
+
+
+
+typedef struct {
+  SDL_Surface* frame[MAX_SPRITE_FRAMES];
+  SDL_Surface* default_img;
+  int num_frames;
+  int cur;
+} sprite;
+
+#define _(str) gettext (str)
+#define gettext_noop(str) (str)
+
+/* LOGGING works as such:
+ *
+ * - Use LOG if you want to output a string LOG( "Hello World");
+ *   
+ * - Use DOUT if you want to output a value of a variable and the
+ *   name of the variable gives enough context:
+ *   DOUT( specialCode );  would add to stderr: "specialCode = 1\n" or
+ *   whatever value specialCode had
+ *   
+ * - Use DEBUGCODE if you need to do something more complicated like
+ *   DEBUGCODE { fprintf(stderr, "examining letter %d\n", x); }
+ *   since DOUT(x) "x = 1\n" gives little information since x is used
+ *   all over the place!
+ */
+
+#define LOG( str ) if (settings.debug_on) fprintf( stderr, str );
+#define DEBUGCODE if (settings.debug_on) 
+#define DOUT(x) if (settings.debug_on) fprintf(stderr, "%s = %d\n", #x, x);
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+#define RMASK 0xff000000
+#define GMASK 0x00ff0000
+#define BMASK 0x0000ff00
+#define AMASK 0x000000ff
+#else
+#define RMASK 0x000000ff
+#define GMASK 0x0000ff00
+#define BMASK 0x00ff0000
+#define AMASK 0xff000000
+#endif
+
+
+
+#define MENU_FONT_SIZE	20
+#define GAME_FONT_SIZE	20
+
+/* Limits on word list size, word length, and on the number of distinct characters */
+/* that can be present within a word list: */
+#define MAX_NUM_WORDS   500
+#define MAX_WORD_SIZE   8
+#define MAX_UNICODES    1024
+
+#define WAIT_MS		2500
+#define	FRAMES_PER_SEC	50
+#define FULL_CIRCLE	140
+
+/* Menu Prototypes */
+enum Game_Type { 
+  QUIT_GAME, CASCADE, OPTIONS, LESSONS,
+  INSTRUCT_CASCADE, CASCADE1, CASCADE2, CASCADE3, CASCADE4,
+  INSTRUCT_LASER, LASER1, LASER2, LASER3, LASER4,
+  FREETYPE, ASDF, ALL, MAIN, SET_LANGUAGE, PROJECT_INFO, EDIT_WORDLIST,
+  LEVEL1, LEVEL2, LEVEL3, LEVEL4, LASER, INSTRUCT, NOT_CODED, NONE};
+
+/* Title sequence constants */
+#define PRE_ANIM_FRAMES	 10
+#define PRE_FRAME_MULT	 3
+#define MENU_SEP	 20
+
+
+#define IMG_REGULAR  0x01
+#define IMG_COLORKEY 0x02
+#define IMG_ALPHA    0x04
+#define IMG_MODES    0x07
+
+#define IMG_NOT_REQUIRED 0x10
+#define IMG_NO_THEME     0x20
+
+//Game difficulty levels
+enum { EASY, MEDIUM, HARD, INSANE, INF_PRACT };
+#define NUM_LEVELS  4
+
+extern game_option_type settings;
+
+/* FIXME get rid of as much global data as possible, esp. pointers */
+
+extern SDL_Surface* screen;
+//extern TTF_Font* font;
+extern SDL_Event  event;
+
+extern SDL_Color black;
+extern SDL_Color gray;
+extern SDL_Color dark_blue;
+extern SDL_Color red;
+extern SDL_Color white;
+extern SDL_Color yellow;
+
+extern SDL_Surface* letters[255]; /* Will be going away */
+
+/* These need some work to support Unicode & i18n: */
+extern wchar_t ALPHABET[256];
+extern int ALPHABET_SIZE;
+
+
+enum {
+	WIN_WAV,
+	BITE_WAV,
+	LOSE_WAV,
+	RUN_WAV,
+	SPLAT_WAV,
+	WINFINAL_WAV,
+	EXCUSEME_WAV,
+	PAUSE_WAV,
+	NUM_WAVES
+};
+
+#define MUSIC_FADE_OUT_MS	80
+
+enum {
+    WIPE_BLINDS_VERT,
+    WIPE_BLINDS_HORIZ,
+    WIPE_BLINDS_BOX,
+    RANDOM_WIPE,
+
+    NUM_WIPES
+};
+
+

Added: tuxtype/branches/tuxtype-new/src/laser.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/laser.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/laser.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,1080 @@
+/***************************************************************************
+ -  file: laser.c
+ -  description: a modification of TuxMath for typing :)
+                            -------------------
+    begin                : 
+    copyright            : Bill Kendrick (C) 2002
+                           Jesse Andrews (C) 2003
+    email                : tuxtype-dev at tux4kids.net
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+#include "laser.h"
+
+
+#define FPS (1000 / 15)   /* 15 fps max */
+#define CITY_EXPL_START 3 * 5  /* Must be mult. of 5 (number of expl frames) */
+#define COMET_EXPL_START 2 * 2 /* Must be mult. of 2 (number of expl frames) */
+#define ANIM_FRAME_START 4 * 2 /* Must be mult. of 2 (number of tux frames) */
+#define GAMEOVER_COUNTER_START 75
+#define LEVEL_START_WAIT_START 20
+#define LASER_START 5
+#define NUM_ANS 8
+#define COMET_ZAP_FONT_SIZE 32
+
+/* Local (to laser.c) 'globals': */
+static sprite* shield = NULL;
+static SDL_Surface* images[NUM_IMAGES] = {NULL};
+static Mix_Chunk* sounds[NUM_SOUNDS] = {NULL};
+static Mix_Music* musics[NUM_MUSICS] = {NULL};
+static SDL_Surface* bkgd = NULL;
+static TTF_Font* font = NULL;
+
+static int wave, speed, score, pre_wave_score, num_attackers, distanceMoved;
+static wchar_t ans[NUM_ANS];
+static int ans_num;
+
+static comet_type comets[MAX_COMETS];
+static city_type cities[NUM_CITIES];
+static laser_type laser;
+
+/* Local function prototypes: */
+static void laser_add_comet(int diff_level);
+static void laser_add_score(int inc);
+static void laser_draw_console_image(int i);
+static void laser_draw_let(wchar_t c, int x, int y);
+static void laser_draw_line(int x1, int y1, int x2, int y2, int r, int g, int b);
+static void laser_draw_numbers(const unsigned char* str, int x);
+static void laser_load_data(void);
+static void laser_reset_level(int diff_level);
+static void laser_putpixel(SDL_Surface* surface, int x, int y, Uint32 pixel);
+static void laser_unload_data(void);
+
+/* --- MAIN GAME FUNCTION!!! --- */
+
+/* TODO modify game to allow longer words (12 chars or so) */
+
+int PlayLaserGame(int diff_level)
+{
+	int i, img, done, quit, frame, lowest, lowest_y, 
+	    tux_img, old_tux_img, tux_pressing, tux_anim, tux_anim_frame,
+	    tux_same_counter, level_start_wait, num_cities_alive,
+	    num_comets_alive, paused, picked_comet, 
+	    gameover;
+
+	Uint16 key_unicode;
+
+	SDL_Event event;
+	Uint32    last_time, now_time;
+	SDLKey    key;
+	SDL_Rect  src, dest;
+	/* str[] is a buffer to draw the scores, waves, etc. (don't need wchar_t) */
+	unsigned char str[64]; 
+
+	LOG( "starting Comet Zap game\n" );
+	DOUT( diff_level );
+
+	SDL_ShowCursor(0);
+	laser_load_data();
+
+	/* Clear window: */
+  
+	SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
+	SDL_Flip(screen);
+
+	/* --- MAIN GAME LOOP: --- */
+
+	done = 0;
+	quit = 0;
+  
+	/* Prepare to start the game: */
+  
+	wave = 1;
+	score = 0;
+	gameover = 0;
+	level_start_wait = LEVEL_START_WAIT_START;
+
+	
+	/* (Create and position cities) */
+  
+	for (i = 0; i < NUM_CITIES; i++) {
+		cities[i].alive = 1;
+		cities[i].expl = 0;
+		cities[i].shields = 1;
+
+		if (NUM_CITIES % 2 == 0) {
+			/* Left vs. Right - makes room for Tux and the console */
+
+			if (i < NUM_CITIES / 2) 
+				cities[i].x = (((screen->w / (NUM_CITIES + 1)) * i) + ((images[IMG_CITY_BLUE] -> w) / 2));
+			else
+				cities[i].x = (screen->w - ((((screen->w / (NUM_CITIES + 1)) * (i - (NUM_CITIES / 2)) + ((images[IMG_CITY_BLUE] -> w) / 2)))));
+		} else {
+			/* put them in order across the bottom of     *
+			 * the screen so we can do word's in order!!! */
+			cities[i].x = i*screen->w / (NUM_CITIES) + images[IMG_CITY_BLUE]->w/2;
+		}
+	}
+
+	num_cities_alive = NUM_CITIES;
+	num_comets_alive = 0;
+
+
+	/* (Clear laser) */
+
+	laser.alive = 0;
+
+  
+	/* Reset remaining stuff: */
+ 
+	bkgd = NULL;
+	laser_reset_level(diff_level);
+  
+	/* --- MAIN GAME LOOP!!! --- */
+  
+	frame = 0;
+	paused = 0;
+	picked_comet = -1;
+	tux_img = IMG_TUX_RELAX1;
+	tux_anim = -1;
+	tux_anim_frame = 0;
+	tux_same_counter = 0;
+	ans_num = 0;
+
+	MusicPlay(musics[MUS_GAME + (rand() % NUM_MUSICS)], 0);
+
+	do {
+
+		frame++;
+		last_time = SDL_GetTicks();
+
+		old_tux_img = tux_img;
+		tux_pressing = 0;
+
+		/* Handle any incoming events: */
+     
+		while (SDL_PollEvent(&event) > 0) {
+
+			if (event.type == SDL_QUIT) {
+				/* Window close event - quit! */
+				exit(0);
+	      
+			} else if (event.type == SDL_KEYDOWN) {
+
+				key = event.key.keysym.sym;
+				if (key == SDLK_F10) 
+					SwitchScreenMode();	      
+				if (key == SDLK_F11)
+					SDL_SaveBMP( screen, "laser.bmp");
+
+				if (key == SDLK_ESCAPE)
+					paused = 1;
+
+				/* --- eat other keys until level wait has passed --- */ 
+				if (level_start_wait > 0) 
+					key = SDLK_UNKNOWN;
+				
+				key_unicode = event.key.keysym.unicode;
+				//key_unicode = event.key.keysym.unicode & 0xff;
+
+				DEBUGCODE
+				{
+				  fprintf(stderr, "key_unicode = %d\n", key_unicode);
+				}
+
+				/* For now, tuxtype is case-insensitive for input, */
+                                /* with only uppercase for answers:                */
+                                if (key_unicode >= 97 && key_unicode <= 122)
+                                  key_unicode -= 32;  //convert lowercase to uppercase
+                                if (key_unicode >= 224 && key_unicode <= 255)
+                                  key_unicode -= 32; //same for non-US chars
+
+				LOG ("After checking for lower case:\n");
+				DEBUGCODE
+				{
+				  fprintf(stderr,
+                                   "key_unicode = %d\n", key_unicode);
+				}
+				/* Now update with case-folded value: */
+				ans[ans_num++] = key_unicode;
+
+			}
+		}
+      
+      
+		/* Handle answer: */
+
+		for (;ans_num>0;ans_num--) {
+
+			/*  Pick the lowest shootable comet which has the right answer: */
+	
+			lowest_y = 0;
+			lowest = -1;
+	
+			for (i = 0; i < MAX_COMETS; i++)
+				if (comets[i].alive
+				 && comets[i].shootable 
+				 && comets[i].expl == 0
+				 && comets[i].ch == ans[ans_num -1 ] 
+				 && comets[i].y > lowest_y)
+				{
+					lowest = i;
+					lowest_y = comets[i].y;
+				}
+	
+	
+			/* If there was an comet with this answer, destroy it! */
+	
+			if (lowest != -1) {
+
+				/* Destroy comet: */
+		  
+				comets[lowest].expl = COMET_EXPL_START;
+				/* Make next letter in word shootable: */
+				comets[lowest].shootable = 0;
+                                if (comets[lowest].next)
+                                  comets[lowest].next->shootable = 1;
+
+				/* Fire laser: */
+				laser.alive = LASER_START;
+
+				/* this is a hack so drawing to the center of the screen works */
+				if (abs(comets[lowest].x - screen->w/2) < 10) {
+					laser.x1 = screen->w / 2;
+					laser.y1 = screen->h;
+	    
+					laser.x2 = laser.x1;
+					laser.y2 = comets[lowest].y;
+				} else {
+					laser.x1 = screen->w / 2;
+					laser.y1 = screen->h;
+	    
+					laser.x2 = comets[lowest].x;
+					laser.y2 = comets[lowest].y;
+				}
+	    
+				PlaySound(sounds[SND_LASER]);
+	    
+				/* 50% of the time.. */
+	    
+				if (0 == (rand() % 2))  {
+
+					/* ... pick an animation to play: */ 
+					if (0 == (rand() % 2))
+						tux_anim = IMG_TUX_YES1;
+					else
+						tux_anim = IMG_TUX_YAY1;
+	        
+					tux_anim_frame = ANIM_FRAME_START;
+				}
+
+				/* Increment score: */
+
+				laser_add_score( (diff_level+1) * 5 * ((screen->h - comets[lowest].y)/20 ));
+
+			} else {
+
+				/* Didn't hit anything! */
+	    
+				PlaySound(sounds[SND_BUZZ]);
+	    
+				if (0 == (rand() % 2))
+					tux_img = IMG_TUX_DRAT;
+				else
+					tux_img = IMG_TUX_YIPE;
+
+				laser_add_score( -25 * wave);
+			}
+		}
+
+      
+		/* Handle start-wait countdown: */
+      
+		if (level_start_wait > 0) {
+
+			level_start_wait--;
+	  
+			if (level_start_wait > LEVEL_START_WAIT_START / 4)
+				tux_img = IMG_TUX_RELAX1;
+			else if (level_start_wait > 0)
+				tux_img = IMG_TUX_RELAX2;
+			else
+				tux_img = IMG_TUX_SIT;
+	  
+			if (level_start_wait == LEVEL_START_WAIT_START / 4)
+				PlaySound(sounds[SND_ALARM]);
+		}
+
+      
+		/* If Tux pressed a button, pick a new (different!) stance: */
+	  
+		if (tux_pressing) {
+			while (tux_img == old_tux_img)
+				tux_img = IMG_TUX_CONSOLE1 + (rand() % 3);
+
+			playsound(sounds[SND_CLICK]);
+		}
+      
+      
+		/* If Tux is being animated, show the animation: */
+
+		if (tux_anim != -1) {
+			tux_anim_frame--;
+
+			if (tux_anim_frame < 0)
+				tux_anim = -1;
+			else
+				tux_img = tux_anim + 1 - (tux_anim_frame / (ANIM_FRAME_START / 2));
+		}
+
+
+		/* Reset Tux to sitting if he's been doing nothing for a while: */
+
+		if (old_tux_img == tux_img) {
+			tux_same_counter++;
+
+			if (tux_same_counter >= 20)
+				old_tux_img = tux_img = IMG_TUX_SIT;
+			if (tux_same_counter >= 60)
+				old_tux_img = tux_img = IMG_TUX_RELAX1;
+		} else
+			tux_same_counter = 0;
+
+
+		/* Handle comets: */
+     
+		num_comets_alive = 0;
+
+		distanceMoved += speed;
+      
+		for (i = 0; i < MAX_COMETS; i++) {
+			if (comets[i].alive) {
+
+				num_comets_alive++;
+
+				comets[i].x = comets[i].x + 0;
+				comets[i].y = comets[i].y + speed;
+	      
+				if (comets[i].y >= (screen->h - images[IMG_CITY_BLUE]->h) && comets[i].expl == 0) {
+
+					/* Disable shields or destroy city: */
+		      
+					if (cities[comets[i].city].shields) {
+						cities[comets[i].city].shields = 0;
+						PlaySound(sounds[SND_SHIELDSDOWN]);
+						laser_add_score(-500 * (diff_level+1));
+					} else {
+						cities[comets[i].city].expl = CITY_EXPL_START;
+						PlaySound(sounds[SND_EXPLOSION]);
+						laser_add_score(-1000 * (diff_level+1));
+					}
+
+					tux_anim = IMG_TUX_FIST1;
+					tux_anim_frame = ANIM_FRAME_START;
+
+					/* Destroy comet: */
+
+					comets[i].expl = COMET_EXPL_START;
+				}
+
+				/* Handle comet explosion animation: */
+
+				if (comets[i].expl != 0) {
+					comets[i].expl--;
+
+					if (comets[i].expl == 0)
+						comets[i].alive = 0;
+				}
+			}
+		}
+
+
+		/* Handle laser: */
+
+		if (laser.alive > 0)
+			laser.alive--;
+     
+		/* Comet time! */
+
+		if (level_start_wait == 0 && (frame % 5) == 0 && gameover == 0) {
+			if (num_attackers > 0) {
+
+				/* More comets to add during this wave! */
+		
+				if ((num_comets_alive < 2 || ((rand() % 4) == 0)) && distanceMoved > 40) {
+					distanceMoved = 0;
+					laser_add_comet(diff_level);
+					num_attackers--;
+				}
+			} else {
+				if (num_comets_alive == 0) {
+
+					/* Time for the next wave! */
+
+					/* FIXME: End of level stuff goes here */
+
+					if (num_cities_alive > 0) {
+
+						/* Go on to the next wave: */
+						wave++;
+						laser_reset_level(diff_level);
+
+					} else {
+
+						/* No more cities!  Game over! */
+						gameover = GAMEOVER_COUNTER_START;
+					}
+				}
+			}
+		}
+
+
+		/* Handle cities: */
+     
+		num_cities_alive = 0;
+
+		for (i = 0; i < NUM_CITIES; i++) 
+			if (cities[i].alive) {
+
+				num_cities_alive++;
+
+				/* Handle animated explosion: */
+
+				if (cities[i].expl) {
+					cities[i].expl--;
+		  
+					if (cities[i].expl == 0)
+						cities[i].alive = 0;
+				}
+			}
+                        
+
+		/* Handle game-over: */
+
+		if (gameover > 0) {
+			gameover--;
+
+			if (gameover == 0)
+				done = 1;
+		}
+                
+                if ((num_cities_alive==0) && (gameover == 0))
+                    gameover = GAMEOVER_COUNTER_START;
+      
+		/* Draw background: */
+     
+		SDL_BlitSurface(bkgd, NULL, screen, NULL);
+
+		/* Draw wave: */
+
+		dest.x = 0;
+		dest.y = 0;
+		dest.w = images[IMG_WAVE]->w;
+		dest.h = images[IMG_WAVE]->h;
+
+		SDL_BlitSurface(images[IMG_WAVE], NULL, screen, &dest);
+
+		sprintf(str, "%d", wave);
+		laser_draw_numbers(str, images[IMG_WAVE]->w + (images[IMG_NUMBERS]->w / 10));
+
+
+		/* Draw score: */
+
+		dest.x = (screen->w - ((images[IMG_NUMBERS]->w / 10) * 7) - images[IMG_SCORE]->w);
+		dest.y = 0;
+		dest.w = images[IMG_SCORE]->w;
+		dest.h = images[IMG_SCORE]->h;
+
+		SDL_BlitSurface(images[IMG_SCORE], NULL, screen, &dest);
+      
+		sprintf(str, "%.6d", score);
+		laser_draw_numbers(str, screen->w - ((images[IMG_NUMBERS]->w / 10) * 6));
+      
+      
+		/* Draw comets: */
+      
+		for (i = 0; i < MAX_COMETS; i++) 
+			if (comets[i].alive) {
+
+				/* Decide which image to display: */
+				if (comets[i].expl == 0)
+					img = IMG_COMET1 + ((frame + i) % 3);
+				else
+					img = (IMG_COMETEX2 - (comets[i].expl / (COMET_EXPL_START / 2)));
+	      
+
+				/* Draw it! */
+
+				dest.x = comets[i].x - (images[img]->w / 2);
+				dest.y = comets[i].y - images[img]->h;
+				dest.w = images[img]->w;
+				dest.h = images[img]->h;
+	      
+				SDL_BlitSurface(images[img], NULL, screen, &dest);
+			}
+
+
+		/* Draw letters: */
+
+		for (i = 0; i < MAX_COMETS; i++)
+			if (comets[i].alive && comets[i].expl == 0)
+				laser_draw_let(comets[i].ch, comets[i].x, comets[i].y);
+      
+		/* Draw cities: */
+      
+		if (frame%2 == 0) NEXT_FRAME(shield);
+		for (i = 0; i < NUM_CITIES; i++) {
+
+			/* Decide which image to display: */
+	 
+			if (cities[i].alive) {
+				if (cities[i].expl == 0)
+					img = IMG_CITY_BLUE;
+				else
+					img = (IMG_CITY_BLUE_EXPL5 - (cities[i].expl / (CITY_EXPL_START / 5)));
+			} else 
+				img = IMG_CITY_BLUE_DEAD;
+	  
+	  
+			/* Change image to appropriate color: */
+	  
+			img += ((wave % MAX_CITY_COLORS) * (IMG_CITY_GREEN - IMG_CITY_BLUE));
+	  
+	  
+			/* Draw it! */
+	  
+			dest.x = cities[i].x - (images[img]->w / 2);
+			dest.y = (screen->h) - (images[img]->h);
+			dest.w = (images[img]->w);
+			dest.h = (images[img]->h);
+	  
+			SDL_BlitSurface(images[img], NULL, screen, &dest);
+
+			/* Draw sheilds: */
+
+			if (cities[i].shields) {
+
+				dest.x = cities[i].x - (shield->frame[shield->cur]->w / 2);
+				dest.h = (screen->h) - (shield->frame[shield->cur]->h);
+				dest.w = src.w;
+				dest.h = src.h;
+				SDL_BlitSurface( shield->frame[shield->cur], NULL, screen, &dest);
+
+			}
+		}
+
+
+		/* Draw laser: */
+
+		if (laser.alive)
+			laser_draw_line(laser.x1, laser.y1, laser.x2, laser.y2, 255 / (LASER_START - laser.alive),
+			                192 / (LASER_START - laser.alive), 64);
+
+		laser_draw_console_image(IMG_CONSOLE);
+
+		if (gameover > 0)
+			tux_img = IMG_TUX_FIST1 + ((frame / 2) % 2);
+
+		laser_draw_console_image(tux_img);
+
+
+		/* Draw "Game Over" */
+
+		if (gameover > 0) {
+
+			dest.x = (screen->w - images[IMG_GAMEOVER]->w) / 2;
+			dest.y = (screen->h - images[IMG_GAMEOVER]->h) / 2;
+			dest.w = images[IMG_GAMEOVER]->w;
+			dest.h = images[IMG_GAMEOVER]->h;
+	
+			SDL_BlitSurface(images[IMG_GAMEOVER], NULL, screen, &dest);
+		}
+      
+      
+		/* Swap buffers: */
+      
+		SDL_Flip(screen);
+
+
+		/* If we're in "PAUSE" mode, pause! */
+
+		if (paused) {
+			quit = Pause();
+			paused = 0;
+		}
+
+      
+		/* Keep playing music: */
+      
+		if (settings.sys_sound && !Mix_PlayingMusic())
+			MusicPlay(musics[MUS_GAME + (rand() % NUM_MUSICS)], 0);
+      
+		/* Pause (keep frame-rate event) */
+      
+		now_time = SDL_GetTicks();
+		if (now_time < last_time + FPS)
+			SDL_Delay(last_time + FPS - now_time);
+	}
+		while (!done && !quit);
+
+  
+	/* Free background: */
+
+	if (bkgd != NULL)
+		SDL_FreeSurface(bkgd);
+
+	/* Stop music: */
+	if ((settings.sys_sound) && (Mix_PlayingMusic()))
+		Mix_HaltMusic();
+ 
+	laser_unload_data();
+ 
+	return 1;
+}
+
+
+/*****************************************************/
+/*                                                   */
+/*          Local ("private") functions:             */
+/*                                                   */
+/*****************************************************/
+
+
+
+
+/* --- Load all media --- */
+static void laser_load_data(void)
+{
+	int i;
+
+	/* Create the SDL_Surfaces for all of the characters */
+        /* used in the word list: */
+	font = LoadFont(settings.theme_font_name, COMET_ZAP_FONT_SIZE);
+	RenderLetters(font);
+
+	/* Load images: */
+	for (i = 0; i < NUM_IMAGES; i++) 
+		images[i] = LoadImage(image_filenames[i], IMG_ALPHA);
+	shield = LoadSprite( "cities/shield", IMG_ALPHA );
+
+	if (settings.sys_sound) {
+		for (i = 0; i < NUM_SOUNDS; i++)
+			sounds[i] = LoadSound(sound_filenames[i]);
+
+		for (i = 0; i < NUM_MUSICS; i++)
+			musics[i] = LoadMusic(music_filenames[i]);
+	}
+
+//	PauseLoadMedia();
+}
+
+
+/* --- unload all media --- */
+static void laser_unload_data(void) {
+	int i;
+
+	FreeLetters();
+
+	for (i = 0; i < NUM_IMAGES; i++)
+		SDL_FreeSurface(images[i]);
+
+	if (settings.sys_sound) {
+		for (i = 0; i < NUM_SOUNDS; i++)
+			Mix_FreeChunk(sounds[i]);
+		for (i = 0; i < NUM_MUSICS; i++)
+			Mix_FreeMusic(musics[i]);
+	}
+
+	FreeSprite(shield);
+        shield = NULL;
+
+//	PauseUnloadMedia();
+
+	TTF_CloseFont(font);
+        font = NULL;
+}
+
+
+/* Reset stuff for the next level! */
+
+static void laser_reset_level(int diff_level)
+{
+  unsigned char fname[1024];
+  static int last_bkgd = -1;
+  int i;
+  
+  /* Clear all comets: */
+  
+  for (i = 0; i < MAX_COMETS; i++)
+    comets[i].alive = 0;
+  
+  /* Load diffrent random background image: */
+  LOG("Loading background in laser_reset_level()\n");
+
+  do {
+    i = rand() % NUM_BKGDS;
+    DOUT(i);
+  }
+  while (i == last_bkgd);
+
+  last_bkgd = i;
+
+  DOUT(i);
+
+  sprintf(fname, "backgrounds/%d.jpg", i);
+
+  LOG("Will try to load file:");
+  LOG(fname);
+
+  if (bkgd != NULL)
+    SDL_FreeSurface(bkgd);
+
+  bkgd = LoadImage(fname, IMG_REGULAR);
+
+  if (bkgd == NULL)
+  {
+    fprintf(stderr,
+     "\nWarning: Could not load background image:\n"
+     "%s\n"
+     "The Simple DirectMedia error that ocurred was: %s\n",
+     fname, SDL_GetError());
+  }
+
+  /* Record score before this wave: */
+
+  pre_wave_score = score;
+
+  /* Set number of attackers & speed for this wave: */
+
+  switch (diff_level) {
+    case 0 : speed = 1 + (wave/5); num_attackers=15; break;
+    case 1 : speed = 1 + (wave/4); num_attackers=15; break;
+    case 2 : speed = 1 + ((wave<<1)/3); num_attackers=(wave<<1); break;
+    case 3 : speed = 1 + wave; num_attackers=(wave<<1); break;
+    default: LOG("diff_level not recognized!\n");
+  }
+
+  distanceMoved = 100; // so that we don't have to wait to start the level
+  LOG("Leaving laser_reset_level()\n");
+}
+
+
+/* Add an comet to the game (if there's room): */
+
+static void laser_add_comet(int diff_level) {
+
+	int target, location = 0;
+	static int last = -1;
+	int targeted[NUM_CITIES] = { 0 };
+	int add = (rand() % (diff_level + 2));
+
+	LOG ("Entering laser_add_comet()\n");
+	DEBUGCODE { fprintf(stderr, "Adding %d comets \n", add); }
+
+	if (0 == NUM_CITIES % 2) /* Even number of cities */
+	{
+          LOG("NUM_CITIES is even\n");
+	  while ((add > 0) && (location != MAX_COMETS))
+	  {
+            /* Look for a free comet slot: */
+            while ((comets[location].alive == 1) && (location < MAX_COMETS))
+            {
+              location++; 
+            }
+            if (location < MAX_COMETS)
+            {
+              comets[location].alive = 1;
+              /* Pick a city to attack: */
+              do
+              { 
+                target = (rand() % NUM_CITIES);
+              } while (target == last || targeted[target] == 1);
+
+              last = target;
+              targeted[target] = 1;
+
+              /* Set comet to target that city: */
+              comets[location].city = target; 
+
+              /* Start at the top, above the city in question: */
+              comets[location].x = cities[target].x;
+              comets[location].y = 0;
+
+              /* Pick a letter */
+              comets[location].ch = GetLetter();
+              /* single letters always shootable: */
+              comets[location].shootable = 1;
+              comets[location].next = NULL;
+
+              add--;
+            }
+            DEBUGCODE {if (location == MAX_COMETS) 
+			printf("Location == MAX_COMETS, we have max on screen\n");}
+	  } 
+	}
+	else /* Odd number of cities (is this a hack that means we are using words?) */
+        {
+          LOG("NUM_CITIES is odd\n");
+          wchar_t* word = GetWord();
+          int i = 0;
+          comet_type* prev_comet = NULL;
+
+          DEBUGCODE {fprintf(stderr, "word is: %S\tlength is: %d\n", word, (int)wcslen(word));}
+          do
+          { 
+  	    target = rand() % (NUM_CITIES - wcslen(word) + 1);
+          } while (target == last);
+          last = target;
+
+		for (i=0; i < wcslen(word); i++)
+		{
+ 			while ((comets[location].alive == 1) && (location < MAX_COMETS))
+				location++; 
+
+  			if (location < MAX_COMETS)
+			{
+				/* First comet in word is shootable: */
+				if (0 == i)
+				  comets[location].shootable = 1;
+				else
+				  comets[location].shootable = 0;
+
+				comets[location].alive = 1;
+				comets[location].city = target + i; 
+				comets[location].x = cities[target + i].x;
+				comets[location].y = 0;
+				comets[location].ch = word[i];
+				comets[location].next = NULL;
+
+				/* Take care of link from previous letter's comet: */
+				if (prev_comet)
+				  prev_comet->next = &comets[location];
+				/* Save pointer for next time through: */
+                                prev_comet = &comets[location];
+
+				DEBUGCODE {fprintf(stderr, "Assigning letter to comet: %C\n", word[i]);}
+			}
+		}
+	}
+	LOG ("Leaving laser_add_comet()\n");
+}
+
+
+/* Draw numbers/symbols over the attacker: */
+
+static void laser_draw_let(wchar_t c, int x, int y)
+{
+  /* Draw letter in correct place relative to comet: */
+  const int offset_x = -10; /* Values determined by trial and error: */
+  const int offset_y = -50;
+
+  SDL_Rect dst;
+  SDL_Surface* s;
+  dst.x = x + offset_x;
+  dst.y = y + offset_y;
+  s = GetWhiteGlyph(c);
+  if (s)
+    SDL_BlitSurface(s, NULL, screen, &dst); 
+}
+
+
+/* Draw status numbers: */
+
+static void laser_draw_numbers(const unsigned char* str, int x)
+{
+  int i, cur_x, c;
+  SDL_Rect src, dest;
+
+
+  cur_x = x;
+
+
+  /* Draw each character: */
+  
+  for (i = 0; i < strlen(str); i++)
+    {
+      c = -1;
+
+
+      /* Determine which character to display: */
+      
+      if (str[i] >= '0' && str[i] <= '9')
+	c = str[i] - '0';
+      
+
+      /* Display this character! */
+      
+      if (c != -1)
+	{
+	  src.x = c * (images[IMG_NUMBERS]->w / 10);
+	  src.y = 0;
+	  src.w = (images[IMG_NUMBERS]->w / 10);
+	  src.h = images[IMG_NUMBERS]->h;
+	  
+	  dest.x = cur_x;
+	  dest.y = 0;
+	  dest.w = src.w;
+	  dest.h = src.h;
+	  
+	  SDL_BlitSurface(images[IMG_NUMBERS], &src,
+			  screen, &dest);
+
+
+          /* Move the 'cursor' one character width: */
+
+	  cur_x = cur_x + (images[IMG_NUMBERS]->w / 10);
+	}
+    }
+}
+
+/* Draw a line: */
+
+static void laser_draw_line(int x1, int y1, int x2, int y2, int red, int grn, int blu)
+{
+  int dx, dy, tmp;
+  float m, b;
+  Uint32 pixel;
+  SDL_Rect dest;
+ 
+  pixel = SDL_MapRGB(screen->format, red, grn, blu);
+
+  dx = x2 - x1;
+  dy = y2 - y1;
+
+  laser_putpixel(screen, x1, y1, pixel);
+  
+  if (dx != 0)
+  {
+    m = ((float) dy) / ((float) dx);
+    b = y1 - m * x1;
+
+    if (x2 > x1)
+      dx = 1;
+    else
+      dx = -1;
+
+    while (x1 != x2)
+    {
+      x1 = x1 + dx;
+      y1 = m * x1 + b;
+      
+      laser_putpixel(screen, x1, y1, pixel);
+    }
+  }
+  else
+  {
+    if (y1 > y2)
+    {
+      tmp = y1;
+      y1 = y2;
+      y2 = tmp;
+    }
+    
+    dest.x = x1;
+    dest.y = y1;
+    dest.w = 3;
+    dest.h = y2 - y1;
+
+    SDL_FillRect(screen, &dest, pixel);
+  }
+}
+
+
+/* Draw a single pixel into the surface: */
+
+static void laser_putpixel(SDL_Surface * surface, int x, int y, Uint32 pixel)
+{
+#ifdef PUTPIXEL_RAW
+  int bpp;
+  Uint8 * p;
+  
+  /* Determine bytes-per-pixel for the surface in question: */
+  
+  bpp = surface->format->BytesPerPixel;
+  
+  
+  /* Set a pointer to the exact location in memory of the pixel
+     in question: */
+  
+  p = (Uint8 *) (surface->pixels +       /* Start at beginning of RAM */
+                 (y * surface->pitch) +  /* Go down Y lines */
+                 (x * bpp));             /* Go in X pixels */
+  
+  
+  /* Assuming the X/Y values are within the bounds of this surface... */
+  
+  if (x >= 0 && y >= 0 && x < surface -> w && y < surface -> h)
+    {
+      /* Set the (correctly-sized) piece of data in the surface's RAM
+         to the pixel value sent in: */
+      
+      if (bpp == 1)
+        *p = pixel;
+      else if (bpp == 2)
+        *(Uint16 *)p = pixel;
+      else if (bpp == 3)
+        {
+          if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+            {
+              p[0] = (pixel >> 16) & 0xff;
+              p[1] = (pixel >> 8) & 0xff;
+              p[2] = pixel & 0xff;
+            }
+          else
+            {
+              p[0] = pixel & 0xff;
+              p[1] = (pixel >> 8) & 0xff;
+              p[2] = (pixel >> 16) & 0xff;
+            }
+        }
+      else if (bpp == 4)
+        {
+          *(Uint32 *)p = pixel;
+        }
+    }
+#else
+  SDL_Rect dest;
+
+  dest.x = x;
+  dest.y = y;
+  dest.w = 3;
+  dest.h = 4;
+
+  SDL_FillRect(surface, &dest, pixel);
+#endif
+}
+
+
+/* Draw image at lower center of screen: */
+
+static void laser_draw_console_image(int i)
+{
+  SDL_Rect dest;
+
+  dest.x = (screen->w - images[i]->w) / 2;
+  dest.y = (screen->h - images[i]->h);
+  dest.w = images[i]->w;
+  dest.h = images[i]->h;
+
+  SDL_BlitSurface(images[i], NULL, screen, &dest);
+}
+
+
+/* Increment score: */
+
+static void laser_add_score(int inc)
+{
+  score += inc;
+  if (score < 0) score = 0;
+}
+

Added: tuxtype/branches/tuxtype-new/src/laser.h
===================================================================
--- tuxtype/branches/tuxtype-new/src/laser.h	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/laser.h	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,188 @@
+
+#ifndef LASER_H
+#define LASER_H
+
+#define MAX_COMETS 30
+#define NUM_CITIES 9   /* MUST BE AN EVEN NUMBER! */
+
+#define NUM_BKGDS 5
+#define MAX_CITY_COLORS 4
+
+typedef struct comet_type {
+  int alive;
+  int expl;
+  int city;
+  int x, y;
+  int shootable;
+  struct comet_type* next;
+  wchar_t ch;
+} comet_type;
+
+typedef struct city_type {
+  int alive, expl, shields;
+  int x;
+} city_type;
+
+typedef struct laser_type {
+  int alive;
+  int x1, y1;
+  int x2, y2;
+} laser_type;
+
+enum {
+  IMG_TUX_HELMET1,
+  IMG_TUX_HELMET2,
+  IMG_TUX_HELMET3,
+  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_COMET1,
+  IMG_COMET2,
+  IMG_COMET3,
+  IMG_COMETEX1,
+  IMG_COMETEX2,
+  IMG_CONSOLE,
+  IMG_TUX_CONSOLE1,
+  IMG_TUX_CONSOLE2,
+  IMG_TUX_CONSOLE3,
+  IMG_TUX_CONSOLE4,
+  IMG_TUX_RELAX1,
+  IMG_TUX_RELAX2,
+  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,
+  NUM_IMAGES
+};
+
+
+static unsigned char * image_filenames[NUM_IMAGES] = {
+  "status/tux_helmet1.png",
+  "status/tux_helmet2.png",
+  "status/tux_helmet3.png", 
+  "cities/city-blue.png",
+  "cities/csplode-blue-1.png",
+  "cities/csplode-blue-2.png",
+  "cities/csplode-blue-3.png",
+  "cities/csplode-blue-4.png",
+  "cities/csplode-blue-5.png",
+  "cities/cdead-blue.png",
+  "cities/city-green.png",
+  "cities/csplode-green-1.png",
+  "cities/csplode-green-2.png",
+  "cities/csplode-green-3.png",
+  "cities/csplode-green-4.png",
+  "cities/csplode-green-5.png",
+  "cities/cdead-green.png",
+  "cities/city-orange.png",
+  "cities/csplode-orange-1.png",
+  "cities/csplode-orange-2.png",
+  "cities/csplode-orange-3.png",
+  "cities/csplode-orange-4.png",
+  "cities/csplode-orange-5.png",
+  "cities/cdead-orange.png",
+  "cities/city-red.png",
+  "cities/csplode-red-1.png",
+  "cities/csplode-red-2.png",
+  "cities/csplode-red-3.png",
+  "cities/csplode-red-4.png",
+  "cities/csplode-red-5.png",
+  "cities/cdead-red.png",
+  "comets/comet1.png",
+  "comets/comet2.png",
+  "comets/comet3.png",
+  "comets/cometex1.png",
+  "comets/cometex2.png",
+  "tux/console.png",
+  "tux/tux-console1.png",
+  "tux/tux-console2.png",
+  "tux/tux-console3.png",
+  "tux/tux-console4.png",
+  "tux/tux-relax1.png",
+  "tux/tux-relax2.png",
+  "tux/tux-drat.png",
+  "tux/tux-yipe.png",
+  "tux/tux-yay1.png",
+  "tux/tux-yay2.png",
+  "tux/tux-yes1.png",
+  "tux/tux-yes2.png",
+  "tux/tux-sit.png",
+  "tux/tux-fist0.png",
+  "tux/tux-fist1.png",
+  "status/wave.png",
+  "status/score.png",
+  "status/numbers.png",
+  "status/gameover.png"
+};
+
+enum {
+  SND_POP,
+  SND_LASER,
+  SND_BUZZ,
+  SND_ALARM,
+  SND_SHIELDSDOWN,
+  SND_EXPLOSION,
+  SND_CLICK,
+  NUM_SOUNDS
+};
+
+
+static unsigned char * sound_filenames[NUM_SOUNDS] = {
+  "pop.wav",
+  "laser.wav",
+  "buzz.wav",
+  "alarm.wav",
+  "shieldsdown.wav",
+  "explosion.wav",
+  "click.wav"
+};
+
+
+enum {
+  MUS_GAME,
+  MUS_GAME2,
+  MUS_GAME3,
+  NUM_MUSICS
+};
+
+static unsigned char * music_filenames[NUM_MUSICS] = {
+  "game.mod",
+  "game2.mod",
+  "game3.mod"
+};
+
+#endif

Added: tuxtype/branches/tuxtype-new/src/loaders.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/loaders.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/loaders.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,450 @@
+/***************************************************************************
+ -  file: loaders.c
+ -  description: Functions to load multimedia for Tux Typing
+                             -------------------
+    begin                : Thu May 4 2000
+    copyright            : (C) 2000 by Sam Hart
+                         : (C) 2003 by Jesse Andrews
+    email                : tuxtype-dev at tux4kids.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+
+/* Local function prototypes: */
+static int max(int n1, int n2);
+static SDL_Surface* flip(SDL_Surface *in, int x, int y);
+
+/* Returns 1 if valid file, 2 if valid dir, 0 if neither: */
+int CheckFile(const char* file)
+{
+  FILE* fp = NULL;
+  DIR* dp = NULL;
+
+  if (!file)
+  {
+    fprintf(stderr, "CheckFile(): invalid char* argument!");
+    return;
+  }
+
+  DEBUGCODE {fprintf(stderr, "CheckFile() - checking: %s\n", file);} 
+
+  dp = opendir(file);
+  if (dp)
+  {
+    LOG("Opened successfully as DIR\n");
+
+    closedir(dp);
+    return 2;
+  }
+
+  fp = fopen(file, "r");
+  if (fp)
+  {
+    LOG("Opened successfully as FILE\n");
+    fclose(fp);
+    return 1;
+  }
+
+  LOG("Unable to open as either FILE or DIR\n");
+  return 0;
+}
+
+
+/* FIXME need to read language's font name, if needed - e.g. Russian. */
+/* also should have return value reflect success or failure.     */
+void LoadLang(void)
+{
+  char fn[FNLEN];
+
+  /* we only need to load a lang.po file if we
+   * are actually using a theme, so this is a little
+   * different than the other loaders 
+   */ 
+
+  if (settings.use_english)
+  {
+    /* We need to set the locale to something supporting UTF-8: */
+    if (!setlocale(LC_CTYPE, "en_US.UTF-8"))
+      fprintf(stderr, "Cannot support UTF-8, ASCII-only words will be used\n");
+    return;
+  }
+
+  /* --- create full path to the lang.po file --- */
+  sprintf( fn, "%s/lang.po", settings.theme_data_path);
+
+  /* FIXME should have program try to setlocale() to lang-specific locale -  */
+  /* for now, at least get a default UTF-8 encoding set: */
+  if (!setlocale(LC_CTYPE, "en_US.UTF-8"))
+    fprintf(stderr, "Cannot support UTF-8, ASCII-only words will be used\n");
+
+  /* This function confusingly returns 0 if successful! */
+  if (0 != Load_PO_File( fn ))  /* Meaning it failed! */
+  {
+    /* failed to find a lang.po file, clear gettext & return */
+    fprintf(stderr, "LoadLang() - could not load lang.po file for %s\n", fn);
+    return;
+  }
+}
+
+int max(int n1, int n2)
+{
+	return (n1 > n2 ? n1 : n2);
+}
+
+/**********************
+ Flip:
+   input: a SDL_Surface, x, y
+   output: a copy of the SDL_Surface flipped via rules:
+
+     if x is a positive value, then flip horizontally
+     if y is a positive value, then flip vertically
+
+     note: you can have it flip both
+**********************/
+SDL_Surface* flip(SDL_Surface* in, int x, int y ) {
+	SDL_Surface *out, *tmp;
+	SDL_Rect from_rect, to_rect;
+	Uint32	flags;
+	Uint32  colorkey=0;
+
+	/* --- grab the settings for the incoming pixmap --- */
+
+	SDL_LockSurface(in);
+	flags = in->flags;
+
+	/* --- change in's flags so ignore colorkey & alpha --- */
+
+	if (flags & SDL_SRCCOLORKEY) {
+		in->flags &= ~SDL_SRCCOLORKEY;
+		colorkey = in->format->colorkey;
+	}
+	if (flags & SDL_SRCALPHA) {
+		in->flags &= ~SDL_SRCALPHA;
+	}
+
+	SDL_UnlockSurface(in);
+
+	/* --- create our new surface --- */
+
+	out = SDL_CreateRGBSurface(
+		SDL_SWSURFACE,
+		in->w, in->h, 32, RMASK, GMASK, BMASK, AMASK);
+
+	/* --- flip horizontally if requested --- */
+
+	if (x) {
+		from_rect.h = to_rect.h = in->h;
+		from_rect.w = to_rect.w = 1;
+		from_rect.y = to_rect.y = 0;
+		from_rect.x = 0;
+		to_rect.x = in->w - 1;
+
+		do {
+			SDL_BlitSurface(in, &from_rect, out, &to_rect);
+			from_rect.x++;
+			to_rect.x--;
+		} while (to_rect.x >= 0);
+	}
+
+	/* --- flip vertically if requested --- */
+
+	if (y) {
+		from_rect.h = to_rect.h = 1;
+		from_rect.w = to_rect.w = in->w;
+		from_rect.x = to_rect.x = 0;
+		from_rect.y = 0;
+		to_rect.y = in->h - 1;
+
+		do {
+			SDL_BlitSurface(in, &from_rect, out, &to_rect);
+			from_rect.y++;
+			to_rect.y--;
+		} while (to_rect.y >= 0);
+	}
+
+	/* --- restore colorkey & alpha on in and setup out the same --- */
+
+	SDL_LockSurface(in);
+
+	if (flags & SDL_SRCCOLORKEY) {
+		in->flags |= SDL_SRCCOLORKEY;
+		in->format->colorkey = colorkey;
+		tmp = SDL_DisplayFormat(out);
+		SDL_FreeSurface(out);
+		out = tmp;
+		out->flags |= SDL_SRCCOLORKEY;
+		out->format->colorkey = colorkey;
+	} else if (flags & SDL_SRCALPHA) {
+		in->flags |= SDL_SRCALPHA;
+		tmp = SDL_DisplayFormatAlpha(out);
+		SDL_FreeSurface(out);
+		out = tmp;
+	} else {
+		tmp = SDL_DisplayFormat(out);
+		SDL_FreeSurface(out);
+		out = tmp;
+	}
+
+	SDL_UnlockSurface(in);
+
+	return out;
+}
+
+
+/* FIXME need code to search for font paths on different platforms */
+TTF_Font* LoadFont(const char* font_name, int font_size )
+{
+  TTF_Font* loaded_font = NULL;
+  char fn[FNLEN];
+  int i;
+
+  /* try to find font in default data dir: */
+  sprintf(fn, "%s/fonts/%s", settings.default_data_path, font_name );
+
+  DEBUGCODE { fprintf(stderr, "LoadFont(): looking for %s using data paths\n", fn); }
+
+  /* try to load the font, if successful, return font*/
+  loaded_font = TTF_OpenFont(fn, font_size);
+  if (loaded_font != NULL)
+    return loaded_font;
+		
+
+  /* HACK hard-coded for Debian (and current exact font names): */ 
+
+  if (strncmp(font_name, "AndikaDesRevG.ttf", FNLEN ) == 0)
+    sprintf(fn, "/usr/share/fonts/truetype/ttf-sil-andika/AndikaDesRevG.ttf");
+  else if (strncmp(font_name, "DoulosSILR.ttf", FNLEN ) == 0)
+    sprintf(fn, "/usr/share/fonts/truetype/ttf-sil-doulos/DoulosSILR.ttf");
+  else if (strncmp(font_name, "lohit_hi.ttf", FNLEN ) == 0)
+    sprintf(fn, "/usr/share/fonts/truetype/ttf-devanagari-fonts/lohit_hi.ttf");
+  else if (strncmp(font_name, "Rachana_w01.ttf", FNLEN ) == 0)
+    sprintf(fn, "/usr/share/fonts/truetype/ttf-malayalam-fonts/Rachana_w01.ttf");
+
+
+
+  DEBUGCODE { fprintf(stderr, "LoadFont(): looking for %s\n in OS' font path\n", fn); }
+
+  /* try to load the font, if successful, return font*/
+  loaded_font = TTF_OpenFont(fn, font_size);
+  if (loaded_font != NULL)
+    return loaded_font;
+
+  fprintf(stderr, "LoadFont(): Error - couldn't load font: %s\n", fn);
+  return NULL;
+}
+
+/***********************
+	LoadImage : Load an image and set transparent if requested
+************************/
+SDL_Surface* LoadImage(const char* datafile, int mode)
+{
+  int oldDebug;  //so we can turn off debug output for this func only
+  SDL_Surface* tmp_pic = NULL, *final_pic = NULL;
+  char fn[FNLEN];
+
+//  oldDebug = settings.debug_on;  // suppress output for now
+//  settings.debug_on = 0;
+
+  DEBUGCODE { fprintf(stderr, "LoadImage: loading %s\n", datafile ); }
+
+  /* Look for image under theme path if desired: */
+  if (!settings.use_english && !(mode & IMG_NO_THEME))
+  {
+    sprintf(fn, "%s/images/%s", settings.theme_data_path, datafile);
+    DEBUGCODE { fprintf(stderr, "LoadImage: looking in %s\n", fn); }
+
+    tmp_pic = IMG_Load(fn);
+    if (tmp_pic != NULL)
+      DEBUGCODE { fprintf(stderr, "Graphics file %s successfully loaded\n", fn);}
+    else
+      DEBUGCODE { fprintf(stderr, "Warning: graphics file %s could not be loaded\n", fn);}
+  }
+
+  /* If we don't have a valid image yet, try the default path: */
+  if (!tmp_pic)
+  {
+    sprintf(fn, "%s/images/%s", settings.default_data_path, datafile);
+    DEBUGCODE { fprintf(stderr, "LoadImage: looking in %s\n", fn); }
+
+    tmp_pic = IMG_Load(fn);
+    if (tmp_pic != NULL)
+      DEBUGCODE { fprintf(stderr, "Graphics file %s successfully loaded\n", fn);}
+    else
+      DEBUGCODE { fprintf(stderr, "Warning: graphics file %s could not be loaded\n", fn);}
+  }
+
+  /* Couldn't load image - action depends on whether image is essential: */
+  if (!tmp_pic)
+  {
+    if (mode & IMG_NOT_REQUIRED)
+    { 
+//      settings.debug_on = oldDebug;
+      return NULL;
+    }
+
+    fprintf(stderr, "ERROR could not load required graphics file %s\n", datafile);
+    exit(1);
+  }
+
+
+  /* If we get to here, success - setup the image in the proper format: */
+
+  switch (mode & IMG_MODES)
+  {
+    case IMG_REGULAR:
+    { 
+      final_pic = SDL_DisplayFormat(tmp_pic);
+      SDL_FreeSurface(tmp_pic);
+      break;
+    }
+
+    case IMG_ALPHA:
+    {
+      final_pic = SDL_DisplayFormatAlpha(tmp_pic);
+      SDL_FreeSurface(tmp_pic);
+      break;
+    }
+
+    case IMG_COLORKEY:
+    {
+      SDL_LockSurface(tmp_pic);
+      SDL_SetColorKey(tmp_pic,
+                      (SDL_SRCCOLORKEY | SDL_RLEACCEL),
+                      SDL_MapRGB(tmp_pic->format, 255, 255, 0));
+      final_pic = SDL_DisplayFormat(tmp_pic);
+      SDL_FreeSurface(tmp_pic);
+      break;
+    }
+
+    default:
+    {
+      LOG ("Image mode not recognized\n");
+    }
+  }
+
+  LOG( "LoadImage(): Done\n" );
+
+//  settings.debug_on = oldDebug;
+
+  return (final_pic);
+}
+
+sprite* FlipSprite(sprite* in, int X, int Y ) {
+	sprite* out;
+
+	out = malloc(sizeof(sprite));
+	if (in->default_img != NULL)
+		out->default_img = flip( in->default_img, X, Y );
+	else
+		out->default_img = NULL;
+	for ( out->num_frames=0; out->num_frames<in->num_frames; out->num_frames++ )
+		out->frame[out->num_frames] = flip( in->frame[out->num_frames], X, Y );
+	out->cur = 0;
+	return out;
+}
+
+sprite* LoadSprite(const char* name, int MODE ) {
+	sprite *new_sprite;
+	char fn[FNLEN];
+	int x;
+
+	/* JA --- HACK check out what has changed with new code */
+
+	new_sprite = malloc(sizeof(sprite));
+
+	sprintf(fn, "%sd.png", name);
+	new_sprite->default_img = LoadImage( fn, MODE|IMG_NOT_REQUIRED );
+	for (x = 0; x < MAX_SPRITE_FRAMES; x++) {
+		sprintf(fn, "%s%d.png", name, x);
+		new_sprite->frame[x] = LoadImage( fn, MODE|IMG_NOT_REQUIRED );
+		if ( new_sprite->frame[x] == NULL ) {
+			new_sprite->cur = 0;
+			new_sprite->num_frames = x;
+			break;
+		}
+	}
+
+	DEBUGCODE {
+		fprintf( stderr, "loading sprite %s - contains %d frames\n",
+		        name, new_sprite->num_frames );
+	}
+
+	return new_sprite;
+}
+
+void FreeSprite(sprite* gfx )
+{
+  int x;
+
+  if (!gfx)
+    return;
+ 
+  for (x = 0; x < gfx->num_frames; x++)
+    SDL_FreeSurface(gfx->frame[x]);
+  SDL_FreeSurface(gfx->default_img);
+  free(gfx);
+}
+
+/***************************
+	LoadSound : Load a sound/music patch from a file.
+****************************/
+Mix_Chunk* LoadSound(const char* datafile )
+{ 
+  Mix_Chunk* tempChunk = NULL;
+  char fn[FNLEN];
+
+  /* First look under theme path if desired: */
+  if (!settings.use_english)
+  {
+    sprintf(fn , "%s/sounds/%s", settings.theme_data_path, datafile);
+    tempChunk = Mix_LoadWAV(fn);
+    if (tempChunk)
+      return tempChunk;
+  }
+
+  /* If nothing loaded yet, try default path: */
+  if (!tempChunk)
+  {
+    sprintf(fn , "%s/sounds/%s", settings.default_data_path, datafile);
+    tempChunk = Mix_LoadWAV(fn);
+    return tempChunk;
+  }
+}
+
+
+/************************
+	LoadMusic : Load
+	music from a datafile
+*************************/
+Mix_Music* LoadMusic(const char* datafile )
+{ 
+  Mix_Music* temp_music = NULL;
+  char fn[FNLEN];
+
+  /* First look under theme path if desired: */
+  if (!settings.use_english)
+  {
+    sprintf(fn , "%s/sounds/%s", settings.theme_data_path, datafile);
+    temp_music = Mix_LoadMUS(fn);
+    if (temp_music)
+      return temp_music;
+  }
+
+  /* If nothing loaded yet, try default path: */
+  if (!temp_music)
+  {
+    sprintf(fn , "%s/sounds/%s", settings.default_data_path, datafile);
+    temp_music = Mix_LoadMUS(fn);
+    return temp_music;
+  }
+}

Added: tuxtype/branches/tuxtype-new/src/main.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/main.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/main.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,161 @@
+/***************************************************************************
+                          main.c 
+ -  description: main tux type file
+                             -------------------
+    begin                : Tue May  2 13:25:06 MST 2000
+    copyright            : (C) 2000 by Sam Hart
+                         : (C) 2003 by Jesse Andrews
+    email                : tuxtype-dev at tux4kids.net
+ ***************************************************************************/
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+
+SDL_Surface* screen;
+
+
+SDL_Event  event;
+
+
+
+/********************
+  main : init stuff
+*********************/
+int main(int argc, char *argv[])
+{
+  Uint32 video_flags = 0,
+         lib_flags   = 0;
+  int i;
+
+  /* Initialize settings with hard-coded defaults: */ 
+  Opts_Initialize();
+
+	srand(time(NULL));
+
+	// This sets settings.default_data_path to the default theme file path:
+	SetupPaths(NULL);
+
+	LoadSettings();
+	DEBUGCODE { printf("Window setting from config file is: %d\n", settings.fullscreen);}
+
+	if (settings.fullscreen)
+        {
+	  video_flags = (SDL_FULLSCREEN | SDL_SWSURFACE | SDL_HWPALETTE);
+	} 
+        else
+        {
+	  video_flags = (SDL_SWSURFACE | SDL_HWPALETTE);
+	}
+        
+	lib_flags = SDL_INIT_VIDEO;
+	/* FIXME this could go into something like HandleCommandArgs() */
+	// check command line args
+	if (argc > 1) 
+		for (i = 1; i < argc; i++) {
+			if ((strcmp(argv[i], "-h") == 0) |
+			    (strcmp(argv[i], "--help") == 0) | 
+			    (strcmp(argv[i], "-help") == 0)) {
+				fprintf(stderr, "\nUsage:\n tuxtype [OPTION]...");
+				fprintf(stderr, "\n\nOptions:\n\n\t-h, --help, -help");
+				fprintf(stderr, "\n\t\tPrints this help message");
+				fprintf(stderr, "\n\n\t-f, --fullscreen");
+				fprintf(stderr, "\n\t\tSelects fullscreen display (default)");
+				fprintf(stderr, "\n\n\t-w, --window");
+				fprintf(stderr, "\n\t\tSelects windowed display (not fullscreen)");
+				fprintf(stderr, "\n\n\t-s, --sound");
+				fprintf(stderr, "\n\t\tAllow in-game sounds (default)");
+				fprintf(stderr, "\n\n\t-ns, --nosound");
+				fprintf(stderr, "\n\t\tDisables in-game sounds");
+				fprintf(stderr, "\n\n\t-t {THEME}, --theme {THEME}");
+				fprintf(stderr, "\n\t\tUse theme named {THEME}, if it exists");
+				fprintf(stderr, "\n\n\t-sp, --speed");
+				fprintf(stderr, "\n\t\tSpeed up gameplay (for use on slower");
+				fprintf(stderr, "\n\t\tmachines)");
+				fprintf(stderr, "\n\n\t-d, --debug");
+				fprintf(stderr, "\n\t\tEnable debug mode (output)\n");
+				fprintf(stderr, "\n\n\t-v, --version");
+				fprintf(stderr, "\n\t\tDisplay version number and exit\n");
+				exit(0);
+			}
+			if ((strcmp(argv[i], "-v") == 0) |
+			    (strcmp(argv[i], "--version") == 0)) {
+				fprintf(stderr, "\n%s, Version %s\n", PACKAGE, VERSION);
+				fprintf(stderr, "Copyright (C) Sam Hart <hart at geekcomix.com>, under the GPL\n");
+				fprintf(stderr, "-See COPYING file for more info... Thx ;)\n\n");
+				exit(0);
+			}
+			if ((strcmp(argv[i], "-f") == 0) |
+			    (strcmp(argv[i], "--fullscreen") == 0))
+				video_flags = (SDL_FULLSCREEN | SDL_HWPALETTE); // | SDL_HWSURFACE | SDL_DOUBLEBUF);
+			
+			if ((strcmp(argv[i], "-w") == 0) |
+			    (strcmp(argv[i], "--window") == 0)) 
+				video_flags = (SDL_HWPALETTE);  // | SDL_DOUBLEBUF);
+		
+			if ((strcmp(argv[i], "-sp") == 0) |
+			    (strcmp(argv[i], "--speed") == 0)) 
+				settings.speed_up = 1;
+
+			if ((strcmp(argv[i], "-d") == 0) |
+			    (strcmp(argv[i], "--debug") == 0)) 
+				settings.debug_on = 1;
+
+			if ((strcmp(argv[i], "-s") == 0) |
+				(strcmp(argv[i], "--sound") == 0)) 
+				settings.sys_sound = 1;
+			
+			if ((strcmp(argv[i], "-ns") == 0) |
+			    (strcmp(argv[i], "--nosound") == 0)) 
+				settings.sys_sound = 0;
+			
+			if ((strcmp(argv[i], "--hidden") == 0) |
+			    (strcmp(argv[i], "-hidden") == 0)) 
+				settings.hidden = 1;
+			
+			if ((strcmp(argv[i], "-t") == 0) |
+			    (strcmp(argv[i], "--theme") == 0)) 
+				SetupPaths(argv[++i]);
+		}
+
+	DEBUGCODE {
+		fprintf(stderr, "\n%s, version %s BEGIN\n", PACKAGE, VERSION);
+	}
+
+	lib_flags |= SDL_INIT_AUDIO;
+	
+	LibInit(lib_flags); /* calls SDL_Init(), TTF_Init(), some other settings */
+	GraphicsInit(video_flags); /* calls SDL_SetVideoMode(), a few others     */
+
+	if (settings.sys_sound)
+        {
+	    Mix_VolumeMusic(settings.mus_volume);
+	    Mix_Volume(-1, settings.sfx_volume);
+	}
+
+	/* Fix: we should check config files/environment variables like LANG! */
+
+	LoadLang();
+	LoadKeyboard();
+
+	/* Now actually play the game: */
+	TitleScreen();
+
+
+	SaveSettings();
+
+	/* Release heap: */
+	Cleanup();
+
+
+	LOG( "---GAME DONE, EXIT---- Thank you.\n" );
+
+	return EXIT_SUCCESS;
+}

Added: tuxtype/branches/tuxtype-new/src/options.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/options.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/options.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,48 @@
+/***************************************************************************
+ -  file: options.c
+ -  description: Functions supporting settings struct for Tux Typing
+                             -------------------
+    begin                : Wed July 11 2007
+    copyright            : (C) 2000 by David Bruce
+                           dbruce at tampabay.rr.com
+
+    project email        : tuxmath-devel at sourceforge.net
+    website              : http://tux4kids.alioth.debian.org
+
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+
+/* Local function prototypes: */
+
+/* Global (for now) settings struct: */
+game_option_type settings;
+
+/* Simply stick all the default values into the settings struct: */
+void Opts_Initialize(void)
+{
+  strncpy(settings.theme_font_name, DEFAULT_MENU_FONT, FNLEN);
+  settings.use_english = DEFAULT_USE_ENGLISH;
+  settings.fullscreen = DEFAULT_FULLSCREEN;
+  settings.sys_sound = DEFAULT_SYS_SOUND;
+  settings.sfx_volume = DEFAULT_SFX_VOLUME;
+  settings.mus_volume = DEFAULT_MUS_VOLUME;
+  settings.menu_music = DEFAULT_MENU_MUSIC;
+  settings.menu_sound = DEFAULT_MENU_SOUND;
+  settings.speed_up = DEFAULT_SPEED_UP;
+  settings.show_tux4kids = DEFAULT_SHOW_TUX4KIDS;
+  settings.debug_on = DEFAULT_DEBUG_ON;
+  settings.o_lives = DEFAULT_O_LIVES;
+  settings.sound_vol = DEFAULT_SOUND_VOL;
+  settings.hidden = DEFAULT_HIDDEN; 
+}

Added: tuxtype/branches/tuxtype-new/src/pause.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/pause.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/pause.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,400 @@
+/***************************************************************************
+pause.c 
+-  description: pause screen for the games
+-------------------
+begin                : Jan 22, 2003
+copyright            : (C) 2003 by Jesse Andrews
+email                : jdandr2 at uky.edu
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+
+static Mix_Chunk *pause_sfx = NULL;
+static SDL_Surface *up = NULL, *down = NULL, *left = NULL, *right = NULL;
+static SDL_Rect rectUp, rectDown, rectLeft, rectRight;
+static TTF_Font *f1 = NULL, *f2 = NULL;
+
+/* Local function prototypes: */
+static void darkenscreen(void);
+static void draw_vols(int sfx, int mus);
+static void pause_draw(void);
+static void pause_load_media(void);
+static void pause_unload_media(void);
+
+// QUESTION: For usability sake, should escape return to the game
+//           and the user have to choose to quit the game, or ???
+/**********************
+Pause : Pause the game
+***********************/
+int Pause(void)
+{
+	int paused = 1;
+	int sfx_volume=0;
+	int old_sfx_volume;
+	int mus_volume=0;
+	int old_mus_volume;
+	int mousePressed = 0;
+	int quit=0;
+	int tocks=0;  // used for keeping track of when a tock has happened
+	SDL_Event event;
+
+	LOG( "Entering Pause()\n" );
+
+	pause_load_media();
+	/* --- stop all sounds, play pause noise --- */
+
+	if (settings.sys_sound) {
+ 		Mix_Pause(-1);
+		Mix_PlayChannel(-1, pause_sfx, 0);
+		sfx_volume = Mix_Volume(-1, -1);  // get sfx volume w/o changing it
+		mus_volume = Mix_VolumeMusic(-1); // get mus volume w/o changing it
+	}
+
+	/* --- show the pause screen --- */
+
+	SDL_ShowCursor(1);
+
+	// Darken the screen...
+	darkenscreen(); 
+
+	pause_draw();
+
+	if (settings.sys_sound) {
+		draw_vols(sfx_volume, mus_volume);
+	}
+
+	SDL_Flip(screen);
+
+	SDL_EnableKeyRepeat( 1, 20 );
+
+	/* --- wait for space, click, or exit --- */
+
+	while (paused) {
+		old_sfx_volume = sfx_volume;
+		old_mus_volume = mus_volume;
+		while (SDL_PollEvent(&event)) 
+			switch (event.type) {
+				case SDL_QUIT: 
+					exit(0);
+					break;
+				case SDL_KEYUP:
+					if (settings.sys_sound && 
+					   ((event.key.keysym.sym == SDLK_RIGHT) ||
+					    (event.key.keysym.sym == SDLK_LEFT))) 
+					    	tocks = 0;
+					break;
+				case SDL_KEYDOWN:
+					if (event.key.keysym.sym == SDLK_SPACE) 
+						paused = 0;
+					if (event.key.keysym.sym == SDLK_ESCAPE) {
+						paused = 0;
+						quit = 1;
+					}
+					if (settings.sys_sound) { 
+						if (event.key.keysym.sym == SDLK_RIGHT) 
+							sfx_volume += 4;
+						if (event.key.keysym.sym == SDLK_LEFT) 
+							sfx_volume -= 4;
+						if (event.key.keysym.sym == SDLK_UP) 
+							mus_volume += 4;
+						if (event.key.keysym.sym == SDLK_DOWN) 
+							mus_volume -= 4;
+					}
+					break;
+				case SDL_MOUSEBUTTONDOWN:
+					mousePressed = 1;
+					tocks = 0;
+					break;
+				case SDL_MOUSEBUTTONUP:
+					mousePressed = 0;
+					break;
+
+					break;
+			}
+		if (settings.sys_sound && mousePressed) {
+			int x, y;
+
+			SDL_GetMouseState(&x, &y);
+			/* check to see if they clicked on a button */
+
+			if (inRect(rectUp, x, y)) {
+				mus_volume += 4;
+			} else if (inRect(rectDown, x, y)) {
+				mus_volume -= 4;
+			} else if (inRect(rectRight, x, y)) {
+				sfx_volume += 4;
+			} else if (inRect(rectLeft, x, y)) {
+				sfx_volume -= 4;
+			} else {
+
+				/* check to see if they clicked a bar */
+
+				if ((x > rectLeft.x + rectLeft.w) && (x < rectRight.x)) {
+					if ((y >= rectLeft.y) && (y <= rectLeft.y + rectLeft.h)) {
+						sfx_volume = 4+(int)(128.0 * ((x - rectLeft.x - rectLeft.w - 1.0) / (rectRight.x - rectLeft.x - rectLeft.w - 2.0)));
+					}
+					if ((y >= rectDown.y) && (y <= rectDown.y + rectDown.h)) {
+						mus_volume = 4+(int)(128.0 * ((x - rectLeft.x - rectLeft.w - 1.0) / (rectRight.x - rectLeft.x - rectLeft.w - 2.0)));
+					}
+
+				}
+			}
+		}
+
+		if (settings.sys_sound) {
+
+			if (sfx_volume > MIX_MAX_VOLUME)
+				sfx_volume = MIX_MAX_VOLUME;
+			if (sfx_volume < 0)
+				sfx_volume = 0;
+			if (mus_volume > MIX_MAX_VOLUME)
+				mus_volume = MIX_MAX_VOLUME;
+			if (mus_volume < 0)
+				mus_volume = 0;
+
+			if ((mus_volume != old_mus_volume) || 
+			    (sfx_volume != old_sfx_volume)) {
+
+				if (mus_volume != old_mus_volume)
+					Mix_VolumeMusic(mus_volume);
+
+				if (sfx_volume != old_sfx_volume) {
+					Mix_Volume(-1,sfx_volume);
+					if (tocks%4==0)
+						Mix_PlayChannel(-1, pause_sfx, 0);
+					tocks++;
+			    }
+
+				draw_vols(sfx_volume, mus_volume);
+				settings.mus_volume=mus_volume;
+				settings.sfx_volume=sfx_volume;
+				SDL_Flip(screen);
+			}
+		}
+
+		SDL_Delay(33);
+	}
+
+	/* --- Return to previous state --- */
+
+	SDL_EnableKeyRepeat( 0, SDL_DEFAULT_REPEAT_INTERVAL );
+
+	SDL_ShowCursor(0);
+
+	if (settings.sys_sound) {
+		Mix_PlayChannel(-1, pause_sfx, 0);
+		Mix_Resume(-1);
+	}
+
+	pause_unload_media();
+
+	LOG( "Leaving Pause()\n" );
+
+	return (quit);
+}
+
+
+static void pause_load_media(void) {
+	if (settings.sys_sound) 
+		pause_sfx = LoadSound( "tock.wav" );
+
+	up = LoadImage("up.png", IMG_ALPHA);
+	rectUp.w = up->w; rectUp.h = up->h;
+
+	down = LoadImage("down.png", IMG_ALPHA);
+	rectDown.w = down->w; rectDown.h = down->h;
+
+	left = LoadImage("left.png", IMG_ALPHA);
+	rectLeft.w = left->w; rectLeft.h = left->h;
+
+	right = LoadImage("right.png", IMG_ALPHA);
+	rectRight.w = right->w; rectRight.h = right->h;
+
+	f1 = LoadFont(settings.theme_font_name, 24);
+	f2 = LoadFont(settings.theme_font_name, 36);
+}
+
+static void pause_unload_media(void) {
+	if (settings.sys_sound)
+        {
+	  Mix_FreeChunk(pause_sfx);
+	  pause_sfx = NULL;
+        }
+	SDL_FreeSurface(up);
+	SDL_FreeSurface(down);
+	SDL_FreeSurface(left);
+	SDL_FreeSurface(right);
+        up = down = left = right = NULL;
+	TTF_CloseFont(f1);
+	TTF_CloseFont(f2);
+	f1 = f2 = NULL;
+}
+
+
+/* Slightly useful function but not sure this file is the right place for it.  */
+int inRect(SDL_Rect r, int x, int y)
+{
+  if ((x < r.x) || (y < r.y) || (x > r.x + r.w) || (y > r.y + r.h))
+   return 0;
+  return 1;
+}
+
+
+/******************************************/
+/*                                        */
+/*       Local ("private") functions      */
+/*                                        */
+/******************************************/
+
+
+
+static void pause_draw(void)
+{
+  SDL_Rect s;
+  SDL_Surface* t = NULL;
+
+  LOG("Entering pause_draw()\n");
+
+  rectLeft.y = rectRight.y = 200;
+  rectDown.y = rectUp.y = 300;
+
+  rectLeft.x = rectDown.x = 320 - (7*16) - rectLeft.w - 4;
+  rectRight.x = rectUp.x  = 320 + (7*16) + 4;
+
+  /* Avoid segfault if any needed SDL_Surfaces missing: */
+  if (settings.sys_sound
+    && left && right && down && up)
+  {
+    SDL_BlitSurface(left, NULL, screen, &rectLeft);
+    SDL_BlitSurface(right, NULL, screen, &rectRight);
+    SDL_BlitSurface(down, NULL, screen, &rectDown);
+    SDL_BlitSurface(up, NULL, screen, &rectUp);
+  }
+
+  if (settings.sys_sound)
+  {
+    t = BlackOutline(_("Sound Effects Volume"), f1, &white);
+    if (t)
+    {	
+      s.y = 160;
+      s.x = 320 - t->w/2;
+      SDL_BlitSurface(t, NULL, screen, &s);
+      SDL_FreeSurface(t);
+    }
+
+    t = BlackOutline(_("Music Volume"), f1, &white);
+    if (t)
+    {
+      s.y = 260;
+      s.x = 320 - t->w/2;
+      SDL_BlitSurface(t, NULL, screen, &s);
+      SDL_FreeSurface(t);
+    }
+  }
+  else  /* No sound: */
+  {
+    t = BlackOutline(_("Sound & Music Disabled"), f1, &white);
+    if (t)
+    {
+      s.y = 160;
+      s.x = 320 - t->w/2;
+      SDL_BlitSurface(t, NULL, screen, &s);
+      SDL_FreeSurface(t);
+    }
+  }
+
+  t = BlackOutline(_("Paused!"), f2, &white);
+  if (t)
+  {
+	s.y = 60;
+	s.x = 320 - t->w/2;
+	SDL_BlitSurface(t, NULL, screen, &s);
+	SDL_FreeSurface(t);
+  }
+
+  t = BlackOutline(_("Press escape again to return to menu"), f1, &white);
+  if (t)
+  {
+    s.y = 400;
+    s.x = 320 - t->w/2;
+    SDL_BlitSurface(t, NULL, screen, &s);
+    SDL_FreeSurface(t);
+  }
+
+  t = BlackOutline(_("Press space bar to return to game"), f1, &white);
+  if (t)
+  {
+    s.y = 440;
+    s.x = 320 - t->w/2;
+    SDL_BlitSurface(t, NULL, screen, &s);
+    SDL_FreeSurface(t);
+  }
+
+  LOG("Leaving pause_draw()\n");
+}
+
+
+/* FIXME what if rectLeft and rectDown not initialized? - should be args */
+static void draw_vols(int sfx, int mus)
+{
+  SDL_Rect s,m;
+  int i;
+
+  s.y = rectLeft.y; 
+  m.y = rectDown.y;
+  m.w = s.w = 5;
+  s.x = rectLeft.x + rectLeft.w + 5;
+  m.x = rectDown.x + rectDown.w + 5;
+  m.h = s.h = 40;
+
+  for (i = 1; i<=32; i++)
+  {
+    if (sfx >= i * 4)
+      SDL_FillRect(screen, &s, SDL_MapRGB(screen->format, 0, 0, 127 + sfx));
+    else
+      SDL_FillRect(screen, &s, SDL_MapRGB(screen->format, 0, 0, 0));
+
+    if (mus >= i * 4)
+      SDL_FillRect(screen, &m, SDL_MapRGB(screen->format, 0, 0, 127 + mus));
+    else
+      SDL_FillRect(screen, &m, SDL_MapRGB(screen->format, 0, 0, 0));
+
+    m.x = s.x += 7;
+  }
+}
+
+/* ==== fillscreen ====
+ * RESULT: it will darken the screen by a factor of 4
+ * WARNING: only works on 16bit screens right now!
+ */
+static void darkenscreen(void)
+{
+  Uint16 rm = screen->format->Rmask;
+  Uint16 gm = screen->format->Gmask;
+  Uint16 bm = screen->format->Bmask;
+  Uint16* p; 
+  int x, y;
+
+  p = screen->pixels;
+
+  for (y = 0; y < 480; y++) 
+  {
+    for (x = 0; x < 640; x++)
+    {
+      *p = (((*p&rm)>>2)&rm) | (((*p&gm)>>2)&gm) | (((*p&bm)>>2)&bm);
+      p++;
+    }
+  }
+}
+
+

Added: tuxtype/branches/tuxtype-new/src/playgame.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/playgame.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/playgame.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,1725 @@
+/***************************************************************************
+playgame.c 
+-  description: Cascade game
+-------------------
+begin                : Fri May 5 2000
+copyright            : (C) 2000 by Sam Hart
+                     : (C) 2003 by Jesse Andrews
+email                : tuxtype-dev at tux4kids.net
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+#include "playgame.h"
+#include "snow.h"
+
+//void add_words( int level );
+
+/* Should these be constants? */
+static int tux_max_width;                // the max width of the images of tux
+static int number_max_w;                 // the max width of a number image
+
+//int o_lives; // something cal is working on
+//int sound_vol;
+static TTF_Font* font = NULL;
+static SDL_Surface* background = NULL;
+static SDL_Surface* level[NUM_LEVELS] = {NULL};
+static SDL_Surface* number[NUM_NUMS] = {NULL};
+static SDL_Surface* curlev = NULL;
+static SDL_Surface* lives = NULL;
+static SDL_Surface* fish = NULL;
+static SDL_Surface* congrats[CONGRATS_FRAMES] = {NULL};
+static SDL_Surface* ohno[OH_NO_FRAMES] = {NULL};
+static Mix_Chunk* sound[NUM_WAVES];
+
+static sprite* fishy = NULL;
+static sprite* splat = NULL;
+
+/* --- Data Structure for Dirty Blitting --- */
+static SDL_Rect srcupdate[MAX_UPDATES];
+static SDL_Rect dstupdate[MAX_UPDATES];
+static int numupdates = 0; // tracks how many blits to be done
+
+struct blit {
+    SDL_Surface* src;
+    SDL_Rect* srcrect;
+    SDL_Rect* dstrect;
+    unsigned char type;
+} blits[MAX_UPDATES];
+
+
+
+/* Local function prototypes: */
+static int AddRect(SDL_Rect* src, SDL_Rect* dst);
+static void AddSplat(int* splats, struct fishypoo* f, int* curlives, int* frame);
+static void CheckCollision(int fishies, int* fish_left, int frame );
+static void CheckFishies(int* fishies, int* splats);
+static int check_word(int f);
+static void display_msg(const unsigned char* msg, int x, int y);
+static void DrawBackground(void);
+static void draw_bar(int curlevel, int diflevel, int curlives,
+              int oldlives, int fish_left, int oldfish_left);
+static void DrawFish(int which);
+static void DrawNumbers(int num, int x, int y, int places);
+static int DrawObject(SDL_Surface* surf, int x, int y);
+static int DrawSprite(sprite* gfx, int x, int y);
+static void EraseNumbers(int num, int x, int y, int places);
+static int EraseObject(SDL_Surface* sprite, int x, int y);
+static int EraseSprite(sprite* img, int x, int y);
+static float float_restrict(float a, float x, float b);
+static void FreeGame(void);
+static int int_restrict(int a, int x, int b);
+static void LoadFishies(void);
+static void LoadOthers(void);
+static void LoadTuxAnims(void);
+static void MoveFishies(int* fishies, int* splats, int* lifes, int* frame);
+static void MoveTux(int frame, int fishies);
+static void next_tux_frame(void);
+static void ResetObjects(void);
+static void SpawnFishies(int diflevel, int* fishies, int* frame);
+static void UpdateScreen(int* frame);
+static void UpdateTux(wchar_t letter_pressed, int fishies, int frame);
+static void WaitFrame(void);
+
+
+
+/************************************************************************/
+/*                                                                      */ 
+/*         "Public" functions (callable throughout program)             */
+/*                                                                      */
+/************************************************************************/
+
+/*************************************************************************
+* PlayCascade : This is the main Cascade game loop               *
+*************************************************************************/
+int PlayCascade( int diflevel ) {
+	unsigned char filename[FNLEN];
+	int still_playing = 1;
+	int playing_level = 1;
+	int setup_new_level = 1;
+	int won_level = 0;
+	int quitting = 0;
+	int curlevel = 0;
+	int i;
+	int curlives;
+	int oldlives=0, oldfish_left=0;
+	int fish_left, fishies = 0, local_max_fishies=1;
+	int frame = 0;
+	int done_frames;
+	int splats = 0;
+	SDL_Event event;
+	SDL_Surface *temp_text[CONGRATS_FRAMES + OH_NO_FRAMES];
+	SDL_Rect text_rect;
+	int text_y_end;
+	int xamp, yamp, x_not, y_not;
+	int temp_text_frames;
+	int temp_text_count;
+	Uint16 key_unicode;
+
+	DEBUGCODE {
+		fprintf(stderr, "->PlayCascade: level=%i\n", diflevel );
+	}
+
+	SDL_WarpMouse(screen->w / 2, screen->h / 2);
+	SDL_ShowCursor(0);
+
+	SNOW_init();
+
+	LoadTuxAnims(); 
+	LoadFishies();
+	LoadOthers();
+	RenderLetters(font);
+	LOG( " Done rendering letters \n ");
+
+	/* Make sure everything in the word list is "typable" according to the current */
+        /* theme's keyboard.lst:                                                       */
+	if (!CheckNeededGlyphs())
+	{
+          fprintf(stderr, "PlayCascade() - did not find all needed characters in theme's "
+                          "keyboard.lst file - returning to menu!\n\n\n");
+          FreeGame();
+          return 0;
+	}
+
+
+
+	LOG( " starting game \n ");
+	while (still_playing) {
+
+		if (setup_new_level) {
+
+			switch (diflevel) {
+				case EASY:
+				            fish_left = MAX_FISHIES_EASY;
+				            if (settings.o_lives >  LIVES_INIT_EASY){
+    				    		curlives = settings.o_lives;
+					    }else
+				    		curlives = LIVES_INIT_EASY;
+				            break;
+				case MEDIUM:
+				            fish_left = MAX_FISHIES_MEDIUM;
+				            if (settings.o_lives >  LIVES_INIT_MEDIUM){
+    				    		curlives = settings.o_lives;
+					    }else
+				            curlives =  LIVES_INIT_MEDIUM;
+				            break;
+				case HARD:
+				            fish_left = MAX_FISHIES_HARD;
+				            if (settings.o_lives >  LIVES_INIT_HARD){
+    				    		curlives = settings.o_lives;
+					    }else
+				            curlives =  LIVES_INIT_HARD;
+				            break;
+			}
+
+			local_max_fishies = fish_left;
+
+			if (curlevel != 0) {
+				SDL_FreeSurface(background);
+			}
+
+			if (diflevel == INF_PRACT)
+				sprintf(filename, "pract.png");
+			else
+				sprintf(filename, "kcas%i_%i.jpg", diflevel+1, curlevel+1);
+
+			/* ---  Special Hidden Code  --- */
+
+			if (settings.hidden && curlevel == 3)
+				sprintf(filename, "hidden.jpg");
+
+			DEBUGCODE {
+				fprintf(stderr, "->>Loading background: %s\n", filename);
+			}
+
+			background = LoadImage( filename, IMG_REGULAR );
+			SNOW_setBkg( background );
+
+			DrawBackground();
+
+			ResetObjects();
+
+			if (settings.sys_sound) {
+				sprintf(filename, "kmus%i.wav", curlevel + 1);
+				MusicLoad( filename, -1 );
+			}
+
+			LOG( "->>PLAYING THE GAME\n" );
+
+			setup_new_level = 0;
+		}
+
+		/* --- Poll input queue, get keyboard info --- */
+
+		while (playing_level) {
+
+			oldlives = curlives;
+			oldfish_left = fish_left;
+
+			EraseSprite( tux_object.spr[tux_object.state][tux_object.facing], tux_object.x, tux_object.y );
+
+			/* --- Checking input --- */
+
+			while ( SDL_PollEvent( &event ) ) 
+				if ( event.type == SDL_QUIT ) {
+					exit(0);
+				} else if (event.type == SDL_KEYDOWN) {
+	
+					if (event.key.keysym.sym == SDLK_F11) 
+						SDL_SaveBMP( screen, "screenshot.bmp" );
+					if (event.key.keysym.sym == SDLK_F6){
+						settings.o_lives=settings.o_lives-10;
+						curlives=curlives-10;
+					}
+					if (event.key.keysym.sym == SDLK_F7) {
+						settings.o_lives=settings.o_lives+10;
+						curlives=curlives+10;
+					}
+					if (event.key.keysym.sym == SDLK_F10) 
+						SwitchScreenMode();
+					if (event.key.keysym.sym == SDLK_F12) 
+						SNOW_toggle();
+					if (event.key.keysym.sym == SDLK_ESCAPE) {
+						/* Pause() returns 1 if quitting, */
+						/* 0 if returning to game:        */
+						if (Pause() == 1) {
+							playing_level = 0;
+							still_playing = 0;
+							quitting = 1;
+						} 
+						DrawBackground();
+					}
+
+					key_unicode = event.key.keysym.unicode;
+					//key_unicode = event.key.keysym.unicode & 0xff;
+					/* For now, tuxtype is case-insensitive for input, */
+                                        /* with only uppercase for answers:                */
+					DEBUGCODE
+					{
+					  fprintf(stderr,
+					    "\nkey_unicode = %d\twchar_t = %lc\t\n",
+					     key_unicode, key_unicode);
+					}
+
+                                        if (key_unicode >= 97 && key_unicode <= 122)
+                                          key_unicode -= 32;  //convert lowercase to uppercase
+                                        if (key_unicode >= 224 && key_unicode <= 255)
+                                          key_unicode -= 32; //same for non-US chars
+
+					LOG ("After checking for lower case:\n");
+					DEBUGCODE
+					{
+					  fprintf(stderr,
+					    "key_unicode = %d\twchar_t = %lc\\n\n",
+					     key_unicode, key_unicode);
+					}
+
+					/* Now update with case-folded value: */
+					UpdateTux(key_unicode, fishies, frame);
+				}
+
+			/* --- fishy updates --- */
+
+			if ((frame % 10) == 0) NEXT_FRAME( fishy );
+			
+			if (fishies < local_max_fishies)
+				SpawnFishies( diflevel, &fishies, &frame );
+
+			MoveTux( frame, fishies );
+			CheckCollision(fishies, &fish_left, frame );
+			DrawSprite( tux_object.spr[tux_object.state][tux_object.facing], tux_object.x, tux_object.y );
+			MoveFishies(&fishies, &splats, &curlives, &frame);
+			CheckFishies(&fishies, &splats);
+			SNOW_update();
+
+			/* --- update top score/info bar --- */
+
+			if (diflevel != INF_PRACT) {
+				draw_bar(curlevel, diflevel, curlives, oldlives, fish_left, oldfish_left);
+
+				if (curlives <= 0) {
+					playing_level = 0;
+					still_playing = 0;
+				}
+			} else
+				fish_left = 1; // in practice there is always 1 fish left!
+
+			if (fish_left <= 0) {
+				won_level = 1;
+				playing_level = 0;
+				curlevel++;
+				setup_new_level = 1;
+				still_playing = 1;
+			}
+
+			if (!quitting) {
+				UpdateScreen(&frame);
+
+				if (!settings.speed_up)
+					WaitFrame();
+			}
+		}
+
+		if (settings.sys_sound)
+			Mix_FadeOutMusic(MUSIC_FADE_OUT_MS);
+
+		DrawBackground();
+
+		if (quitting == 0) {
+
+			if (won_level) {
+
+				won_level = 0;
+				if (curlevel < 4) {
+
+					LOG( "--->NEXT LEVEL!\n" );
+
+					done_frames = MAX_END_FRAMES_BETWEEN_LEVELS;
+					playing_level = 1;
+					xamp = 0;
+					yamp = 0;
+
+				} else {
+
+					LOG( "--->WINNER!\n" );
+
+					done_frames = MAX_END_FRAMES_WIN_GAME;
+					still_playing = 0;
+					xamp = WIN_GAME_XAMP;
+					yamp = WIN_GAME_YAMP;
+
+					if (settings.sys_sound) 
+						Mix_PlayChannel(WINFINAL_WAV, sound[WINFINAL_WAV], 0);
+				}
+
+				if (settings.sys_sound) 
+					Mix_PlayChannel(WIN_WAV, sound[WIN_WAV], 0);
+
+				for (i = 0; i < CONGRATS_FRAMES; i++)
+					temp_text[i] = congrats[i];
+
+				temp_text_frames = CONGRATS_FRAMES;
+				tux_object.state = TUX_WINNING;
+
+			} else {
+
+				LOG( "--->LOST :(\n" );
+
+				done_frames = MAX_END_FRAMES_GAMEOVER;
+				xamp = 0;
+				yamp = 0;
+
+				if (settings.sys_sound)
+					Mix_PlayChannel(LOSE_WAV, sound[LOSE_WAV], 0);
+
+				for (i = 0; i < OH_NO_FRAMES; i++)
+					temp_text[i] = ohno[i];
+
+				temp_text_frames = OH_NO_FRAMES;
+				tux_object.state = TUX_YIPING;
+			}
+
+			/* --- draw the animation here --- */
+
+			temp_text_count = 0;
+			text_y_end = (screen->h / 2) - (temp_text[0]->h / 2);
+			text_rect.x = (screen->w / 2) - (temp_text[0]->w / 2);
+			text_rect.y = screen->h - temp_text[0]->h - 1;
+			x_not = text_rect.x;
+
+			LOG( "--->Starting Ending Animation\n" );
+			
+			for ( i=0; i<= done_frames; i++ ) {
+				temp_text_count = (temp_text_count+1) % temp_text_frames;
+
+				text_rect.y -= END_FRAME_DY;
+				y_not = text_rect.y;
+
+				if (text_rect.y < text_y_end) {
+					y_not = text_y_end + yamp * sin(i / WIN_GAME_ANGLE_MULT);
+					text_rect.y = text_y_end;
+					text_rect.x = x_not + xamp * cos(i / WIN_GAME_ANGLE_MULT);
+				}
+
+				DrawSprite( tux_object.spr[tux_object.state][tux_object.facing], tux_object.x, tux_object.y );
+				DrawObject(temp_text[temp_text_count], text_rect.x, y_not);
+				DrawObject(level[diflevel], 1, 1);
+				draw_bar(curlevel - 1, diflevel, curlives, oldlives, fish_left, oldfish_left);
+
+				next_tux_frame();
+				SNOW_update();
+				UpdateScreen(&frame);
+
+				EraseSprite( tux_object.spr[tux_object.state][tux_object.facing], tux_object.x, tux_object.y );
+				
+				EraseObject(temp_text[temp_text_count], text_rect.x, y_not);
+
+				if (!settings.speed_up)
+					WaitFrame();
+			}
+		}
+	}
+
+	SNOW_on = 0;
+
+	LOG( "->Done with level... cleaning up\n" );
+
+	FreeGame();
+
+	LOG( "->PlayCascade: END\n" );
+
+	return 1;
+}
+
+
+
+
+/***********************
+ InitEngine
+ ***********************/
+void InitEngine(void) {
+    int i;
+
+    /* --- Set up the update rectangle pointers --- */
+	
+    for (i = 0; i < MAX_UPDATES; ++i) {
+        blits[i].srcrect = &srcupdate[i];
+        blits[i].dstrect = &dstupdate[i];
+    }
+}
+
+
+
+/*************************************************/
+/* TransWipe: Performs various wipes to new bkgs */
+/*************************************************/
+/*
+ * Given a wipe request type, and any variables
+ * that wipe requires, will perform a wipe from
+ * the current screen image to a new one.
+ */
+int TransWipe(SDL_Surface* newbkg, int type, int var1, int var2)
+{
+    int i, j, x1, x2, y1, y2;
+    int step1, step2, step3, step4;
+    int frame;
+    SDL_Rect src;
+    SDL_Rect dst;
+
+    LOG("->TransWipe(): START\n");
+
+    if (!newbkg)
+    {
+      fprintf(stderr, "TransWipe() - 'newbkg' arg invalid!\n");
+      return 0;
+    }
+
+    numupdates = 0;
+    frame = 0;
+
+    if(newbkg->w == screen->w && newbkg->h == screen->h) {
+        if( type == RANDOM_WIPE )
+            type = (RANDOM_WIPE * ((float) rand()) / (RAND_MAX+1.0));
+
+        switch( type ) {
+            case WIPE_BLINDS_VERT: {
+                LOG("--+ Doing 'WIPE_BLINDS_VERT'\n");
+                /* var1 is num of divisions
+                   var2 is how many frames animation should take */
+                if( var1 < 1 ) var1 = 1;
+                if( var2 < 1 ) var2 = 1;
+                step1 = screen->w / var1;
+                step2 = step1 / var2;
+
+                for(i = 0; i <= var2; i++) {
+                    for(j = 0; j <= var1; j++) {
+                        x1 = step1 * (j - 0.5) - i * step2 + 1;
+                        x2 = step1 * (j - 0.5) + i * step2 + 1;
+                        src.x = x1;
+                        src.y = 0;
+                        src.w = step2;
+                        src.h = screen->h;
+                        dst.x = x2;
+                        dst.y = 0;
+                        dst.w = step2;
+                        dst.h = screen->h;
+                        SDL_BlitSurface(newbkg, &src, screen, &src);
+                        SDL_BlitSurface(newbkg, &dst, screen, &dst);
+                        AddRect(&src, &src);
+                        AddRect(&dst, &dst);
+                    }
+                    UpdateScreen(&frame);
+                }
+
+                src.x = 0;
+                src.y = 0;
+                src.w = screen->w;
+                src.h = screen->h;
+                SDL_BlitSurface(newbkg, NULL, screen, &src);
+                SDL_Flip(screen);
+
+                break;
+            } case WIPE_BLINDS_HORIZ: {
+                LOG("--+ Doing 'WIPE_BLINDS_HORIZ'\n");
+                /* var1 is num of divisions
+                   var2 is how many frames animation should take */
+                if( var1 < 1 ) var1 = 1;
+                if( var2 < 1 ) var2 = 1;
+                step1 = screen->h / var1;
+                step2 = step1 / var2;
+
+                for(i = 0; i <= var2; i++) {
+                    for(j = 0; j <= var1; j++) {
+                        y1 = step1 * (j - 0.5) - i * step2 + 1;
+                        y2 = step1 * (j - 0.5) + i * step2 + 1;
+                        src.x = 0;
+                        src.y = y1;
+                        src.w = screen->w;
+                        src.h = step2;
+                        dst.x = 0;
+                        dst.y = y2;
+                        dst.w = screen->w;
+                        dst.h = step2;
+                        SDL_BlitSurface(newbkg, &src, screen, &src);
+                        SDL_BlitSurface(newbkg, &dst, screen, &dst);
+                        AddRect(&src, &src);
+                        AddRect(&dst, &dst);
+                    }
+                    UpdateScreen(&frame);
+                }
+
+                src.x = 0;
+                src.y = 0;
+                src.w = screen->w;
+                src.h = screen->h;
+                SDL_BlitSurface(newbkg, NULL, screen, &src);
+                SDL_Flip(screen);
+
+                break;
+            } case WIPE_BLINDS_BOX: {
+                LOG("--+ Doing 'WIPE_BLINDS_BOX'\n");
+                /* var1 is num of divisions
+                   var2 is how many frames animation should take */
+                if( var1 < 1 ) var1 = 1;
+                if( var2 < 1 ) var2 = 1;
+                step1 = screen->w / var1;
+                step2 = step1 / var2;
+                step3 = screen->h / var1;
+                step4 = step1 / var2;
+
+                for(i = 0; i <= var2; i++) {
+                    for(j = 0; j <= var1; j++) {
+                        x1 = step1 * (j - 0.5) - i * step2 + 1;
+                        x2 = step1 * (j - 0.5) + i * step2 + 1;
+                        src.x = x1;
+                        src.y = 0;
+                        src.w = step2;
+                        src.h = screen->h;
+                        dst.x = x2;
+                        dst.y = 0;
+                        dst.w = step2;
+                        dst.h = screen->h;
+                        SDL_BlitSurface(newbkg, &src, screen, &src);
+                        SDL_BlitSurface(newbkg, &dst, screen, &dst);
+                        AddRect(&src, &src);
+                        AddRect(&dst, &dst);
+                        y1 = step3 * (j - 0.5) - i * step4 + 1;
+                        y2 = step3 * (j - 0.5) + i * step4 + 1;
+                        src.x = 0;
+                        src.y = y1;
+                        src.w = screen->w;
+                        src.h = step4;
+                        dst.x = 0;
+                        dst.y = y2;
+                        dst.w = screen->w;
+                        dst.h = step4;
+                        SDL_BlitSurface(newbkg, &src, screen, &src);
+                        SDL_BlitSurface(newbkg, &dst, screen, &dst);
+                        AddRect(&src, &src);
+                        AddRect(&dst, &dst);
+                    }
+                    UpdateScreen(&frame);
+                }
+
+                src.x = 0;
+                src.y = 0;
+                src.w = screen->w;
+                src.h = screen->h;
+                SDL_BlitSurface(newbkg, NULL, screen, &src);
+                SDL_Flip(screen);
+
+                break;
+            } default:
+                break;
+        }
+    }
+    return 1;
+}
+
+
+
+/************************************************************************/
+/*                                                                      */ 
+/*         "Private" functions (local to playgame.c)                    */
+/*                                                                      */
+/************************************************************************/
+
+
+
+static int check_word( int f ) {
+	int i;
+
+	if (wcslen(fish_object[f].word) > tux_object.wordlen) 
+		return 0;
+
+	for (i=0; i < wcslen(fish_object[f].word); i++) 
+		if (fish_object[f].word[i] != tux_object.word[tux_object.wordlen -                                           wcslen(fish_object[f].word) + i])
+			return 0;
+
+	return 1;
+}
+
+
+
+
+
+
+
+
+
+
+/***************************************
+	WaitFrame: wait for the next frame
+***************************************/
+void WaitFrame(void) {
+	static Uint32  next_tick = 0;
+	Uint32         this_tick = SDL_GetTicks();
+
+	if (this_tick < next_tick)
+		SDL_Delay(next_tick - this_tick);
+
+	next_tick = this_tick + (1000 / FRAMES_PER_SEC);
+}
+
+
+/****************************************************
+ ResetObjects : Clear and reset all objects to dead
+****************************************************/
+
+static void ResetObjects( void ) {
+	int i;
+
+	LOG( "RESETTING OBJECTS\n" );
+
+	for (i = 0; i < MAX_FISHIES_HARD + 1; i++) {
+		fish_object[i] = null_fishy;
+		splat_object[i] = null_splat;
+	}
+
+	tux_object.facing = RIGHT;
+	tux_object.x = screen->w / 2;
+	tux_object.y = screen->h - tux_object.spr[0][RIGHT]->frame[0]->h - 1;
+	tux_object.dx = 0;
+	tux_object.dy = 0;
+	tux_object.endx = tux_object.x;
+	tux_object.endy = tux_object.y;
+	tux_object.state = TUX_STANDING;
+	tux_object.word[0] = 0;
+	tux_object.wordlen = 0;
+
+	LOG( "OBJECTS RESET\n" );
+}
+
+static int DrawSprite(sprite* gfx, int x, int y)
+{
+  struct blit* update;
+
+  if (!gfx)
+  {
+    fprintf(stderr, "DrawSprite() - 'gfx' arg invalid!\n");
+    return 0;
+  }
+
+  update = &blits[numupdates++];
+
+  if(!update || !update->srcrect || !update->dstrect)
+  {
+    fprintf(stderr, "DrawSprite() - 'update' ptr invalid!\n");
+    return 0;
+  }
+
+  update->src = gfx->frame[gfx->cur];
+  update->srcrect->x = 0;
+  update->srcrect->y = 0;
+  update->srcrect->w = gfx->frame[gfx->cur]->w;
+  update->srcrect->h = gfx->frame[gfx->cur]->h;
+  update->dstrect->x = x;
+  update->dstrect->y = y;
+  update->dstrect->w = gfx->frame[gfx->cur]->w;
+  update->dstrect->h = gfx->frame[gfx->cur]->h;
+  update->type = 'D';
+
+  return 1;
+}
+
+/**********************
+DrawObject : Draw an object at the specified
+location. No respect to clipping!
+*************************/
+static int DrawObject(SDL_Surface* surf, int x, int y)
+{
+  struct blit *update;
+
+  if (!surf)
+  {
+    fprintf(stderr, "DrawObject() - invalid 'surf' arg!\n");
+    return 0;
+  }
+
+  update = &blits[numupdates++];
+
+  if(!update || !update->srcrect || !update->dstrect)
+  {
+    fprintf(stderr, "DrawObject() - 'update' ptr invalid!\n");
+    return 0;
+  }
+
+  update->src = surf;
+  update->srcrect->x = 0;
+  update->srcrect->y = 0;
+  update->srcrect->w = surf->w;
+  update->srcrect->h = surf->h;
+  update->dstrect->x = x;
+  update->dstrect->y = y;
+  update->dstrect->w = surf->w;
+  update->dstrect->h = surf->h;
+  update->type = 'D';
+
+  return 1;
+}
+
+/************************
+UpdateScreen : Update the screen and increment the frame num
+***************************/
+static void UpdateScreen(int* frame)
+{
+	int i;
+
+	/* -- First erase everything we need to -- */
+	for (i = 0; i < numupdates; i++)
+		if (blits[i].type == 'E') 
+			SDL_LowerBlit(blits[i].src, blits[i].srcrect, screen, blits[i].dstrect);
+	SNOW_erase();
+
+	/* -- then draw -- */ 
+	for (i = 0; i < numupdates; i++)
+		if (blits[i].type == 'D') 
+			SDL_BlitSurface(blits[i].src, blits[i].srcrect, screen, blits[i].dstrect);
+	SNOW_draw();
+
+	/* -- update the screen only where we need to! -- */
+	if (SNOW_on) 
+		SDL_UpdateRects(screen, SNOW_add( (SDL_Rect*)&dstupdate, numupdates ), SNOW_rects);
+	else 
+		SDL_UpdateRects(screen, numupdates, dstupdate);
+
+	numupdates = 0;
+	*frame = *frame + 1;
+}
+
+static int EraseSprite(sprite* img, int x, int y)
+{
+  struct blit* update;
+
+  if(!img)
+  {
+    fprintf(stderr, "EraseSprite() - invalid 'img' arg!\n");
+    return 0;
+  }
+
+  update = &blits[numupdates++];
+
+  if(!update || !update->srcrect || !update->dstrect)
+  {
+    fprintf(stderr, "EraseSprite() - 'update' ptr invalid!\n");
+    return 0;
+  }
+
+  update->src = background;
+  update->srcrect->x = x;
+  update->srcrect->y = y;
+  update->srcrect->w = img->frame[img->cur]->w;
+  update->srcrect->h = img->frame[img->cur]->h;
+
+  /* check to see if we are trying blit data that doesn't exist!!! */
+
+  if (update->srcrect->x + update->srcrect->w > background->w)
+    update->srcrect->w = background->w - update->srcrect->x;
+  if (update->srcrect->y + update->srcrect->h > background->h)
+    update->srcrect->h = background->h - update->srcrect->y;
+
+  update->dstrect->x = x;
+  update->dstrect->y = y;
+  update->dstrect->w = update->srcrect->w;
+  update->dstrect->h = update->srcrect->h;
+  update->type = 'E';
+
+  return 1;
+}
+
+/*************************
+EraseObject : Erase an object from the screen
+**************************/
+static int EraseObject(SDL_Surface* surf, int x, int y)
+{
+  struct blit *update;
+
+  if(!surf)
+  {
+    fprintf(stderr, "EraseObject() - invalid 'surf' arg!\n");
+    return 0;
+  }
+
+  update = &blits[numupdates++];
+
+  if(!update || !update->srcrect || !update->dstrect)
+  {
+    fprintf(stderr, "EraseObject() - 'update' ptr invalid!\n");
+    return 0;
+  }
+
+  update->src = background;
+  update->srcrect->x = x;
+  update->srcrect->y = y;
+  update->srcrect->w = surf->w;
+  update->srcrect->h = surf->h;
+
+  /* check to see if we are trying blit data that doesn't exist!!! */
+
+  if (update->srcrect->x + update->srcrect->w > background->w)
+    update->srcrect->w = background->w - update->srcrect->x;
+  if (update->srcrect->y + update->srcrect->h > background->h)
+    update->srcrect->h = background->h - update->srcrect->y;
+
+  update->dstrect->x = x;
+  update->dstrect->y = y;
+  update->dstrect->w = update->srcrect->w;
+  update->dstrect->h = update->srcrect->h; 
+  update->type = 'E';
+
+  return 1;
+}
+
+
+/******************************
+AddRect : Dont actually blit a surface,
+    but add a rect to be updated next
+    update
+*******************************/
+static int AddRect(SDL_Rect* src, SDL_Rect* dst)
+{
+
+  /*borrowed from SL's alien (and modified)*/
+  struct blit* update;
+
+  if(!src)
+  {
+    fprintf(stderr, "AddRect() - invalid 'src' arg!\n");
+    return 0;
+  }
+
+  if(!dst)
+  {
+    fprintf(stderr, "AddRect() - invalid 'dst' arg!\n");
+    return 0;
+  }
+
+  update = &blits[numupdates++];
+
+  if(!update || !update->srcrect || !update->dstrect)
+  {
+    fprintf(stderr, "AddRect() - 'update' ptr invalid!\n");
+    return 0;
+  }
+
+  update->srcrect->x = src->x;
+  update->srcrect->y = src->y;
+  update->srcrect->w = src->w;
+  update->srcrect->h = src->h;
+  update->dstrect->x = dst->x;
+  update->dstrect->y = dst->y;
+  update->dstrect->w = dst->w;
+  update->dstrect->h = dst->h;
+  update->type = 'I';
+
+  return 1;
+}
+
+/*********************
+LoadOthers : Load all other graphics
+**********************/
+static void LoadOthers(void)
+{
+	int i;
+	unsigned char filename[FNLEN];
+
+	LOG( "=LoadOthers()\n" );
+	DEBUGCODE
+	{
+	  fprintf(stderr, "settings.theme_font_name is %s\n",
+                  settings.theme_font_name);
+	}
+	font = LoadFont(settings.theme_font_name, GAME_FONT_SIZE);
+
+	curlev = BlackOutline(_("Level"), font, &white);
+	lives  = BlackOutline(_("Lives"), font, &white);
+	fish   = BlackOutline(_("Fish"), font, &white);
+
+	level[0] = BlackOutline(_("Easy"), font, &white);
+	level[1] = BlackOutline(_("Medium"), font, &white);
+	level[2] = BlackOutline(_("Hard"), font, &white);
+	level[3] = BlackOutline(_("Practice"), font, &white);
+
+	number_max_w = 0;
+	for (i = 0; i < NUM_NUMS; i++) {
+		sprintf(filename, "num_%i.png", i);
+		number[i] = LoadImage( filename, IMG_COLORKEY );
+		if (number[i]->w > number_max_w)
+			number_max_w = number[i]->w;
+	}
+
+	for (i = 0; i < CONGRATS_FRAMES; i++) {
+		congrats[i] = BlackOutline(_("Congratulations"), font, &white);
+	}
+
+	for (i = 0; i < OH_NO_FRAMES; i++) {
+		ohno[i] = BlackOutline(_("Oh No!"), font, &white);
+	}
+	
+	if (settings.sys_sound) {
+		LOG( "=Loading Sound FX\n" );
+
+		sound[WIN_WAV] = LoadSound( "win.wav" );
+		sound[WINFINAL_WAV] = LoadSound( "winfinal.wav" );
+		sound[BITE_WAV] = LoadSound( "bite.wav" );
+		sound[LOSE_WAV] = LoadSound( "lose.wav" );
+		sound[RUN_WAV] = LoadSound( "run.wav" );
+		sound[SPLAT_WAV] = LoadSound( "splat.wav" );
+		sound[EXCUSEME_WAV] = LoadSound( "excuseme.wav" );
+
+		LOG( "=Done Loading Sound FX\n" );
+	} else 
+		LOG( "=NO SOUND FX LOADED (not selected)\n" );
+
+//	PauseLoadMedia();
+
+	LOG( "=Setting NULL fish & splat & word\n" );
+
+	null_fishy.alive = 0;
+	null_fishy.can_eat = 0;
+	null_fishy.word = NULL;
+	null_fishy.x = 0;
+	null_fishy.y = 0;
+	null_fishy.dy = 0;
+
+	null_splat.x = 0;
+	null_splat.y = 0;
+	null_splat.alive = 0;
+
+	LOG( "=LoadOthers() END\n" );
+}
+
+static void display_msg(const unsigned char* msg, int x, int y)
+{
+	SDL_Surface* m;
+	m = TTF_RenderUTF8_Shaded(font, msg, white, white);
+	EraseObject(m, x, y);
+	DrawObject(m, x, y);
+	SDL_FreeSurface(m);
+}
+
+/***************************
+LoadFishies : Load the fish animations and graphics
+*****************************/
+static void LoadFishies(void)
+{
+	int i;
+
+	LOG( "=LoadFishies()\n" );
+
+	fishy = LoadSprite( "fishy", IMG_COLORKEY );
+	splat = LoadSprite( "splat", IMG_COLORKEY );
+
+	for (i = 0; i < MAX_FISHIES_HARD; i++) {
+		fish_object[i].alive = 1;
+		fish_object[i].can_eat = 0;
+		splat_object[i].alive = 0;
+	}
+
+	LOG( "=LoadFishies(): END\n" );
+}
+
+/******************************
+LoadTuxAnims : Load the Tux graphics and animations
+*******************************/
+static void LoadTuxAnims(void)
+{
+	int i;
+	int height = 0;                //temp width/height varis to determine max's
+
+	LOG( "=LoadTuxAnims(): Loading Tux Animations\n" );
+
+	for ( i=0; i < TUX_NUM_STATES; i++ ) {
+		tux_object.spr[i][RIGHT] = LoadSprite( tux_sprite_fns[i], IMG_COLORKEY ); 
+		tux_object.spr[i][LEFT] = FlipSprite( tux_object.spr[i][RIGHT], 1, 0 ); 
+	}
+
+	tux_max_width = tux_object.spr[TUX_STANDING][RIGHT]->frame[0]->w;
+	height        = tux_object.spr[TUX_STANDING][RIGHT]->frame[0]->h;
+
+	LOG( "=LoadTuxAnims(): END\n" );
+}
+
+/******************************
+DrawNumbers : Draw numbers at
+a certain x,y. See "usage"
+below
+*******************************/
+static void DrawNumbers(int num, int x, int y, int places)
+{
+//usage:
+//      num    = number to draw onscreen
+//      x, y   = coords to place number (starting upper left)
+//      places = number of places to fit it into (i.e., if
+//                                       number = 5 and places = 2, would draw "05")
+//                                       if places = 0, then will simply display as
+//                                       many as necessary
+    unsigned char numnuts[FNLEN];
+    int needed_places, i;
+    int uddernumber;
+
+    sprintf(numnuts, "%d", num);
+    i = 0;
+    needed_places = strlen(numnuts);
+
+    if (needed_places < FNLEN && needed_places <= places) {
+        if (places > 0) {
+            for (i = 1; i <= (places - needed_places); i++) {
+                DrawObject(number[0], x, y);
+                x += number[0]->w;
+            }
+        }
+    }
+    for (i = 0; i < needed_places; i++) {
+        uddernumber = numnuts[i] - '0';
+
+        DrawObject(number[uddernumber], x, y);
+        x += number[uddernumber]->w;
+    }
+}
+
+/*************************
+EraseNumbers: Erase numbers
+from the screen. See "usage"
+*****************************/
+static void EraseNumbers(int num, int x, int y, int places)
+{
+//usage:
+//      num    = number to draw onscreen
+//      x, y   = coords to place number (starting upper left)
+//      places = number of places to fit it into (i.e., if
+//                                       number = 5 and places = 2, would draw "05")
+//                                       if places = 0, then will simply display as
+//                                       many as necessary
+    unsigned char numnuts[FNLEN];
+    int needed_places, i;
+    int uddernumber;
+
+    sprintf(numnuts, "%d", num);
+    i = 0;
+    needed_places = strlen(numnuts);
+
+    if (needed_places < FNLEN && needed_places <= places) {
+        if (places > 0) {
+            for (i = 1; i <= (places - needed_places); i++) {
+                EraseObject(number[0], x, y);
+                x += number[0]->w;
+            }
+        }
+    }
+    for (i = 0; i < needed_places; i++) {
+        uddernumber = numnuts[i] - '0';
+        EraseObject(number[uddernumber], x, y);
+        x += number[uddernumber]->w;
+    }
+}
+
+/**********************
+FreeGame : Free all
+the game elements
+***********************/
+static void FreeGame(void)
+{
+	int i;
+
+	FreeLetters();
+
+	TTF_CloseFont(font);
+        font = NULL;
+
+	LOG( "FreeGame():\n-Freeing Tux Animations\n" );
+
+	for ( i=0; i < TUX_NUM_STATES; i++ ) {
+		FreeSprite(tux_object.spr[i][RIGHT]);
+		FreeSprite(tux_object.spr[i][LEFT]);
+		tux_object.spr[i][RIGHT] = NULL;
+		tux_object.spr[i][LEFT] = NULL;
+	}
+
+	LOG( "-Freeing fishies\n" );
+
+	FreeSprite( fishy );
+	FreeSprite( splat );
+        fishy = splat = NULL;
+
+	LOG( "-Freeing other game graphics\n" );
+
+	SDL_FreeSurface(background);
+	SDL_FreeSurface(curlev);
+	SDL_FreeSurface(fish);
+	SDL_FreeSurface(lives);
+        background = curlev = fish = lives = NULL;
+
+	for (i = 0; i < NUM_LEVELS; i++)
+	{
+          SDL_FreeSurface(level[i]);
+	  level[i] = NULL;
+        }
+	for (i = 0; i < NUM_NUMS; i++)
+	{
+	  SDL_FreeSurface(number[i]);
+	  number[i] = NULL;
+	}
+	for (i = 0; i < CONGRATS_FRAMES; i++)
+	{
+	  SDL_FreeSurface(congrats[i]);
+	  congrats[i] = NULL;
+	}
+	for (i = 0; i < OH_NO_FRAMES; i++)
+	{
+	  SDL_FreeSurface(ohno[i]);
+	  ohno[i] = NULL;
+	}
+	if (settings.sys_sound) {
+	  LOG( "-Freeing sound\n" );
+	  for (i = 0; i < NUM_WAVES; ++i)
+          {
+	    Mix_FreeChunk(sound[i]);
+            sound[i] = NULL;
+	  }
+	}
+
+//	PauseUnloadMedia();
+
+
+	LOG( "FreeGame(): END\n" );
+}
+
+/***************************
+DrawBackground : This
+function updates the entire
+background. Usefull when
+loading new backgrounds,
+or clearing game screen
+****************************/
+static void DrawBackground(void)
+{
+    struct blit *update;
+
+    LOG("-DrawBackground(): Updating entire background\n");
+
+    numupdates=0;  // drawing entire background writes over all other stuff, so don't draw them
+
+    update = &blits[numupdates++];
+    update->src = background;
+
+    update->srcrect->x = update->dstrect->x = 0;
+    update->srcrect->y = update->dstrect->y = 0;
+    update->srcrect->w = update->dstrect->w = background->w;
+    update->srcrect->h = update->dstrect->h = background->h;
+
+    update->type = 'D';
+}
+
+/****************************
+SpawnFishies: Spawn the fishes
+in the key cascade game
+*****************************/
+static void SpawnFishies(int diflevel, int* fishies, int* frame)
+{
+	int i, spacing;
+	wchar_t* new_word;
+
+	switch (diflevel) {
+		case INF_PRACT:
+		case EASY:   spacing = FISH_SPACING_EASY; break;
+		case MEDIUM: spacing = FISH_SPACING_MEDIUM; break;
+		case HARD:   spacing = FISH_SPACING_HARD; break;
+	}
+
+	/* --- return without spawn if there isn't room yet --- */
+
+	for (i = 0; i < *fishies; i++)
+		if (fish_object[i].y < (fishy->frame[0]->h + spacing))
+			return;
+
+	/* See if we get a valid UTF-8 word from WORDS_get before we move on: */
+	/* Now that we are using UTF-8, some characters may be more than one byte, */
+	/* so we can't just use strlen() anymore - DSB.*/		
+	LOG( "=>Spawning fishy\n" );
+
+	new_word = GetWord();
+
+	if (!new_word)
+	{
+	  fprintf(stderr, "SpawnFishies() - could not get word - returning.\n");
+          return;
+	}
+
+	/* If we get to here, it should be OK to actually spawn the fishy: */
+	fish_object[*fishies].word = new_word;
+        fish_object[*fishies].len = wcslen(new_word);
+	fish_object[*fishies].alive = 1;
+	fish_object[*fishies].can_eat = 0;
+	fish_object[*fishies].w = fishy->frame[0]->w * fish_object[*fishies].len;
+	fish_object[*fishies].x = rand() % (screen->w - fish_object[*fishies].w);
+	fish_object[*fishies].y = 0;
+
+	/* set the percentage of the speed based on length */
+	fish_object[*fishies].dy = pow(0.92,fish_object[*fishies].len-1);
+	/* ex: a 9 letter word will be roughly twice as slow! 0.92^8 */
+
+	/* give it a random variance so the fish "crunch" isn't constant */
+	fish_object[*fishies].dy *= ((75 + rand() % 25)/100.0);
+	switch (diflevel) {
+		case INF_PRACT:
+			fish_object[*fishies].dy = DEFAULT_SPEED;
+			break;
+		case EASY:
+			fish_object[*fishies].dy *= MAX_SPEED_EASY;
+			break;
+		case MEDIUM:
+			fish_object[*fishies].dy *= MAX_SPEED_MEDIUM;
+			break;
+		case HARD:
+			fish_object[*fishies].dy *= MAX_SPEED_HARD;
+			break;
+   	}
+
+	fish_object[*fishies].splat_time = *frame + (480 - fishy->frame[0]->h - tux_object.spr[TUX_STANDING][0]->frame[0]->h)/fish_object[*fishies].dy;
+
+	DEBUGCODE {
+		/* NOTE need %S rather than %s because of wide characters */
+		fprintf(stderr, "Spawn fishy with word '%S'\n", fish_object[*fishies].word);
+		fprintf(stderr, "Byte length is: %d\n", wcslen(fish_object[*fishies].word));
+		fprintf(stderr, "UTF-8 char length is: %d\n", fish_object[*fishies].len);
+	}
+
+	*fishies = *fishies + 1;
+}
+
+/***************************
+CheckFishies : Check all the fishies and splats.
+               sort the splats and fishies
+****************************/
+static void CheckFishies(int* fishies, int* splats)
+{
+	int forward, backward;
+	struct fishypoo fish_temp;
+	struct splatter splat_temp;
+
+//	LOG( "CheckFishies\n" );
+
+	/* move any fish from the rear to fill up gaps in the
+	 * front
+	 */
+	forward = 0;
+	backward = MAX_FISHIES_HARD;
+	while (forward < backward) {
+		while (backward > 0 && !fish_object[backward].alive)
+			backward--;
+		while (forward < backward && fish_object[forward].alive)
+			forward++;
+		if ((fish_object[backward].alive) && (!fish_object[forward].alive)) {
+			/* swap alive to be infront of dead */
+			fish_temp = fish_object[backward];
+			fish_object[backward] = fish_object[forward];
+			fish_object[forward] = fish_temp;
+		}
+	}
+	
+	/* same thing for splats */
+
+	forward = 0;
+	backward = MAX_FISHIES_HARD;
+	while (forward < backward) {
+		while (backward > 0 && !splat_object[backward].alive)
+			backward--;
+		while (forward < backward && splat_object[forward].alive)
+			forward++;
+		if ((splat_object[backward].alive) && (!splat_object[forward].alive)) {
+			/* swap alive to be infront of dead */
+			splat_temp = splat_object[backward];
+			splat_object[backward] = splat_object[forward];
+			splat_object[forward] = splat_temp;
+		}
+	}
+
+	/* update the count for fishies & splats */
+
+	*splats = *fishies = 0;
+
+	for (forward = 0; forward < MAX_FISHIES_HARD; forward++)
+		if (fish_object[forward].alive)
+			*fishies+=1;
+		else
+			break;
+
+	for (forward = 0; forward < MAX_FISHIES_HARD; forward++)
+		if (splat_object[forward].alive)
+			*splats+=1;
+		else
+			break;
+}
+
+// Restrict x to a value in the range from a ... b
+static int int_restrict(int a, int x, int b) {
+	if (x < a) x = a;
+	if (x > b) x = b;
+	return x;
+}
+
+static float float_restrict(float a, float x, float b)
+{
+	if (x < a) x = a;
+	if (x > b) x = b;
+	return x;
+}
+
+/***************************
+AddSplat: A fish has died, add a splat where he used to be
+****************************/
+static void AddSplat(int* splats, struct fishypoo* f, int* curlives, int* frame) {
+	int i;
+
+	for ( i = 0; i < f->len; i++ ) {
+		splat_object[*splats].x = int_restrict( 0, f->x+(fishy->frame[0]->w*i) + ((fishy->frame[fishy->cur]->w)>>1)-((splat->frame[0]->w)>>1), screen->w-splat->frame[0]->h-1 );
+		splat_object[*splats].y = screen->h - splat->frame[0]->h - 1;
+		splat_object[*splats].alive = 10; // JA tweak here! frames of live of the splat
+		*splats = *splats + 1;
+	}
+
+	f->alive = 0;
+
+	*curlives = *curlives - 1;
+	if (*curlives <= 0)
+		*curlives = 0;
+
+	if ( settings.sys_sound ) 
+		Mix_PlayChannel(SPLAT_WAV, sound[SPLAT_WAV], 0);
+}
+
+
+
+
+static void DrawFish(int which)
+{
+/*        LOG ("Entering DrawFish()\n");*/
+	int j = 0;
+	int red_letters = 0;
+	int current_letter;
+	/* 'x_inset' and 'y_inset' are where the glyph to be drawn relative        */
+	/* the fishy graphic:                                                      */
+	const int x_inset = 10;
+        const int y_inset = 10;
+	/* letter_x and letter_y are where the upper left corner of the glyph needs */
+        /* to be located - (e.g. how SDL blitting understands locations)           */
+        int letter_x = 0;
+        int letter_y = 0;
+
+        SDL_Surface* letter_surface;
+
+	/* Make sure needed pointers are valid - if not, return: */
+        if (!fishy || !fishy->frame[0])
+	{
+          fprintf(stderr, "DrawFish() - returning, needed pointer invalid\n");
+          return;
+	}
+	    
+
+
+	/* Draw the fishies: */
+	for (j = 0; j < fish_object[which].len; j++)
+        {
+	  DrawSprite( fishy,
+                      fish_object[which].x + (fishy->frame[0]->w*j),
+                      fish_object[which].y);
+        }
+
+
+	/* Now we draw the letters on top of the fish: */
+	/* we only draw the letter if tux cannot eat it yet */
+	if (!fish_object[which].can_eat)
+	{
+		red_letters = -1;
+		j = 0;
+
+		/* figure out how many letters are red: */
+		while (j < tux_object.wordlen && red_letters == -1)
+		{
+		  int k;
+		  for (k = 0; k < tux_object.wordlen - j; k++)
+                  {
+                    if (fish_object[which].word[k] != tux_object.word[j + k]) 
+                      k = 100000;
+                  }
+
+                  if (k < 100000)
+                    red_letters = tux_object.wordlen - j;	
+                  else
+                    j++;
+		}
+	
+// 		LOG ("Preparing to draw letters:\n");
+
+		/* Now draw each letter: */
+		for (j = 0; j < wcslen(fish_object[which].word); j++)
+		{
+		  current_letter = (int)fish_object[which].word[j];
+
+		  if (j < red_letters)
+                    letter_surface = GetRedGlyph(current_letter);
+                  else
+                    letter_surface = GetWhiteGlyph(current_letter);
+
+		  /* Set "letter_x" and "letter_y to where we want the letter drawn: */
+		  letter_x = fish_object[which].x + (j * fishy->frame[0]->w) + x_inset;
+		  letter_y = fish_object[which].y + y_inset;
+
+		  DrawObject(letter_surface, letter_x, letter_y);
+		}
+	}
+/*        LOG ("Leaving DrawFish()\n");*/
+}
+
+/****************************
+MoveFishies : Display and
+move the fishies according
+to their settings
+*****************************/
+static void MoveFishies(int *fishies, int *splats, int *lifes, int *frame) {
+	int i, j;
+
+//	LOG("start MoveFishies\n");
+
+	for (i = 0; i < *fishies; i++)
+		if (fish_object[i].alive) {
+			for (j=0; j < fish_object[i].len; j++)
+				EraseSprite( fishy, fish_object[i].x + (fishy->frame[0]->w*j), fish_object[i].y );
+	            
+			fish_object[i].y += fish_object[i].dy;
+	
+			if (fish_object[i].y >= (screen->h) - fishy->frame[fishy->cur]->h - 1) 
+				AddSplat( splats, &fish_object[i], lifes, frame );
+		}
+	
+	for (i = 0; i < *fishies; i++)
+		if (fish_object[i].alive && fish_object[i].can_eat) 
+			DrawFish( i );
+
+	for (i = 0; i < *fishies; i++)
+		if (fish_object[i].alive && !fish_object[i].can_eat) 
+			DrawFish( i );
+
+	for (i = 0; i < *splats; i++) 
+		if (splat_object[i].alive) {
+			splat_object[i].alive--;
+			if (splat_object[i].alive>1)
+					DrawSprite( splat, splat_object[i].x, splat_object[i].y);
+				else 
+					EraseSprite( splat, splat_object[i].x, splat_object[i].y);
+		}
+
+//	LOG("end MoveFishies\n");
+}
+
+/* UpdateTux : anytime a key is pressed, we need check to
+ * see if a fish can be eaten.  The fish that could hit
+ * the bottom of the screen first should be choosen if 
+ * two fishies match what is typed
+ */
+void UpdateTux(wchar_t letter_pressed, int fishies, int frame) {
+	int i;
+	int time_it_splats=0;
+	int which=-1;
+
+	/* --- move our word array to make room if needed --- */
+
+	if (tux_object.wordlen == MAX_WORD_SIZE) {
+		for (i = 0; i < MAX_WORD_SIZE; i++) 
+			tux_object.word[i] = tux_object.word[i + 1];
+		tux_object.wordlen--;
+	}
+
+	/* --- add letter pressed to word array --- */
+
+	tux_object.word[tux_object.wordlen] = letter_pressed;
+	tux_object.wordlen++;
+	tux_object.word[tux_object.wordlen] = 0;
+
+	/* choose the word that matchs what has been typed  */
+	/* and will hit the ground first                    */
+	for (i = 0; i < fishies; i++) 
+		if ((fish_object[i].alive && !fish_object[i].can_eat) && check_word(i) && (time_it_splats > fish_object[i].splat_time || !time_it_splats)) {
+			time_it_splats = fish_object[i].splat_time;
+			which = i;
+		}
+
+	if (which!=-1) {
+		fish_object[which].can_eat = 1;
+		tux_object.wordlen = 0;
+		tux_object.word[0] = 0;
+	}
+
+}
+
+/*************************
+CheckCollision: Check
+for collisions between Tux
+and Fishies. If collided,
+perform appropriate action
+***************************/
+static void CheckCollision(int fishies, int *fish_left, int frame ) {
+	int i, j;
+
+//	LOG( "start CheckCollision\n" );
+
+	for (i = 0; i < fishies; i++) {
+		if ((fish_object[i].y >= tux_object.y - fishy->frame[0]->h) &&
+		    (fish_object[i].x + (fish_object[i].w-fishy->frame[0]->w)/2 >= tux_object.x) &&
+		    (fish_object[i].x + (fish_object[i].w+fishy->frame[0]->w)/2 <= tux_object.x + tux_max_width)) {
+
+			if (fish_object[i].can_eat) {
+                		LOG( "**EATING A FISHY** - in CheckCollision()\n" );
+
+				fish_object[i].alive = 0;
+				fish_object[i].can_eat = 0;
+
+				for (j = 0; j < fish_object[i].len; j++) 
+					EraseSprite(fishy, (fish_object[i].x + (j * fishy->frame[0]->w)), fish_object[i].y);
+
+				*fish_left = *fish_left - 1;
+
+				tux_object.state = TUX_GULPING;
+				REWIND(tux_object.spr[TUX_GULPING][tux_object.facing]);
+				tux_object.dx = 0;
+				tux_object.endx = tux_object.x;
+
+				if (settings.sys_sound) Mix_PlayChannel(BITE_WAV, sound[BITE_WAV], 0);
+
+			} else if (tux_object.state == TUX_STANDING) {
+				LOG( "***EXCUSE ME!** - in CheckCollision()\n" );
+
+				if (settings.sys_sound && !Mix_Playing(EXCUSEME_WAV))
+					Mix_PlayChannel(EXCUSEME_WAV, sound[EXCUSEME_WAV], 0);
+			}
+		}
+	}
+//	LOG( "end CheckCollision\n" );
+}
+
+static void next_tux_frame(void) {
+
+	if ( tux_object.state != TUX_GULPING ) {
+		NEXT_FRAME(tux_object.spr[tux_object.state][tux_object.facing]);
+	} else {
+		NEXT_FRAME(tux_object.spr[TUX_GULPING][tux_object.facing]);
+		if (tux_object.spr[TUX_GULPING][tux_object.facing]->cur==0) 
+			tux_object.state = TUX_STANDING;
+	}
+}
+
+/***********************************
+MoveTux : Update Tux's location & then blit him!
+************************************/
+static void MoveTux( int frame, int fishies ) {
+	int i;
+	int which=-1, time_to_splat=0;
+
+//	LOG( "MoveTux\n" );
+
+	EraseSprite( tux_object.spr[tux_object.state][tux_object.facing], tux_object.x, tux_object.y );
+
+	if (tux_object.state != TUX_GULPING) {
+		for (i=0; i<fishies; i++) 
+			if (fish_object[i].can_eat && (!time_to_splat || fish_object[i].splat_time < time_to_splat)) {
+				time_to_splat = fish_object[i].splat_time;
+				which = i;
+			}
+		if (which != -1) {
+			int endx = int_restrict( 0, fish_object[which].x + (fish_object[which].w/2) - (tux_object.spr[TUX_GULPING][RIGHT]->frame[0]->w / 2), screen->w - tux_max_width - 1 );
+			if (endx != tux_object.endx) {
+				tux_object.endx = endx;
+
+				if (tux_object.endx >= tux_object.x)
+					tux_object.facing = RIGHT;
+				else
+					tux_object.facing = LEFT;
+
+				/* see how fast we need to go to get there... */
+				if (time_to_splat - frame > (abs(tux_object.endx - tux_object.x) / WALKING_SPEED)) {
+					tux_object.dx = WALKING_SPEED;
+					tux_object.state = TUX_WALKING;
+
+					//stop running sound (if playing)                                               
+					if (settings.sys_sound && Mix_Playing(RUN_WAV))
+						Mix_HaltChannel(RUN_WAV);
+				} else {
+					if (time_to_splat > frame) 
+						tux_object.dx = float_restrict( MIN_RUNNING_SPEED, abs(tux_object.endx - tux_object.x) / (time_to_splat-frame), MAX_RUNNING_SPEED );
+					else {
+						tux_object.dx = MAX_RUNNING_SPEED;
+						if (settings.sys_sound && !Mix_Playing(RUN_WAV))
+							if (abs(tux_object.endx - tux_object.x) > 50)
+								Mix_PlayChannel(RUN_WAV, sound[RUN_WAV], 0);
+					}
+
+					tux_object.state = TUX_RUNNING;
+				}
+			}
+		}
+	}
+
+	/* --- move tux (if moving) --- */
+	
+	tux_object.x = float_restrict(0, tux_object.x + (tux_object.facing==RIGHT ? 1.0 : -1.0)*tux_object.dx, (screen->w - tux_max_width));
+
+	/* if done with certain frames, then reset to standing */
+
+	if (tux_object.state == TUX_WALKING || tux_object.state == TUX_RUNNING) {
+		if ((tux_object.facing == RIGHT && tux_object.x >= tux_object.endx) ||
+		    (tux_object.facing == LEFT && tux_object.x <= tux_object.endx)) {
+
+			LOG( "-In MoveTux(): returning tux to standing\n" );
+			tux_object.state = TUX_STANDING;
+			tux_object.dx = 0;
+			tux_object.x = tux_object.endx;
+		}
+	}
+
+	if ((frame % 8) == 0) next_tux_frame();
+}
+
+static void draw_bar(int curlevel, int diflevel, int curlives, int oldlives, int fish_left, int oldfish_left) {
+	/* --- draw difficulty --- */
+
+	DrawObject(level[diflevel], 1, 1);
+
+	/* --- draw level --- */
+	DrawObject(curlev, 1 + GRAPHIC_SPACE + level[diflevel]->w, 1);
+	DrawNumbers(curlevel + 1, 1 + 2 * GRAPHIC_SPACE + level[diflevel]->w + curlev->w, 1, 0);
+
+	/* --- draw lives --- */
+	DrawObject(lives, (screen->w) - (1+lives->w+fish->w+((MAX_FISHIES_DIGITS+1)*2*number_max_w)+GRAPHIC_SPACE), 1);
+
+	if (oldlives != curlives) {
+		EraseNumbers(oldlives, (screen->w) - (1+fish->w+((MAX_FISHIES_DIGITS+1)*2*number_max_w)+GRAPHIC_SPACE), 1, 0);
+		oldlives = curlives;
+	}
+
+	DrawNumbers(curlives, (screen->w) - (1 + fish->w + ((MAX_FISHIES_DIGITS + 1) * 2 * number_max_w) + GRAPHIC_SPACE), 1, 0);
+
+	/* --- draw fish left --- */
+	DrawObject(fish, (screen->w) - (1 + fish->w + (MAX_FISHIES_DIGITS * number_max_w)), 1);
+	if (oldfish_left != fish_left) {
+		EraseNumbers(oldfish_left, (screen->w) - (1 + (MAX_FISHIES_DIGITS * number_max_w)), 1, MAX_FISHIES_DIGITS);
+		oldfish_left = fish_left;
+	}
+	DrawNumbers(fish_left, (screen->w) - (1 + (MAX_FISHIES_DIGITS * number[4]->w)), 1, MAX_FISHIES_DIGITS);
+}
+
+
+
+
+
+
+

Added: tuxtype/branches/tuxtype-new/src/playgame.h
===================================================================
--- tuxtype/branches/tuxtype-new/src/playgame.h	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/playgame.h	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,141 @@
+/***************************************************************************
+                          playgame.h
+  description:
+                             -------------------
+    begin                : Fri May 12 2000
+    copyright            : (C) 2000 by Sam Hart
+    email                : hart at geekcomix.com
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef __PLAYGAME_H__
+#define __PLAYGAME_H__
+
+//definitions
+#define GRAPHIC_SPACE 4 //space between each status bar element in cascade
+
+#define NUM_NUMS 10	//"Mmmmm....Num-Nums...."
+
+#define CONGRATS_FRAMES	2	//number of frames for congrats animation
+#define OH_NO_FRAMES 1	//number of frames for "oh no!" losing animation
+#define MAX_END_FRAMES_BETWEEN_LEVELS 350	//number of frames between levels
+#define MAX_END_FRAMES_WIN_GAME 750	//number of frames at ending animation
+#define MAX_END_FRAMES_GAMEOVER 400	//number of frames at game over
+#define END_FRAME_DY 2	//rise speed of ending animation text
+#define WIN_GAME_XAMP 4	//the xamplitide of winning game text circular motion
+#define WIN_GAME_YAMP 4	//the yamplitude of winning game text circular motion
+#define WIN_GAME_ANGLE_MULT 4	//the angle multiplier for winning game text circ motion
+
+//tux frame lengths (number of frames each cell of animation frames on-screen)
+#define WALK_ONSCREEN	10
+#define RUN_ONSCREEN	8
+#define STAND_ONSCREEN	15
+#define GULP_ONSCREEN	10
+//tux default walking & running speeds
+#define WALKING_SPEED	1.5
+//#define WALKING_SPEED         1
+#define MIN_RUNNING_SPEED		4 * WALKING_SPEED
+#define MAX_RUNNING_SPEED		10 * WALKING_SPEED
+/*-- These last two are for future features --*/
+#define WIN_ONSCREEN		1
+#define YIPE_ONSCREEN		2
+
+//fishy defs
+#define MAX_FISHIES_EASY	15
+#define MAX_FISHIES_MEDIUM	30
+#define MAX_FISHIES_HARD	40
+#define MAX_FISHIES_DIGITS	2
+
+#define FISHY_ONSCREEN	10
+#define SPLAT_FRAMES	1
+#define SPLAT_ONSCREEN	4
+#define DEFAULT_SPEED	.3
+
+#define MAX_SPEED_EASY       0.4
+#define MAX_SPEED_MEDIUM     0.9
+#define MAX_SPEED_HARD       1.2
+
+#define FISH_SPACING_EASY    90
+#define FISH_SPACING_MEDIUM  40
+#define FISH_SPACING_HARD    30
+
+#define LIVES_INIT_EASY      5
+#define LIVES_INIT_MEDIUM    7
+#define LIVES_INIT_HARD      9
+
+#define MAX_UPDATES	3*(20+MAX_FISHIES_HARD)	//20 to account for text updates (I hope)
+
+/* The default alpha for slow moving words,
+ note that 128 is optimized for speed! */
+#define DEFAULT_ALPHA 128
+
+typedef struct {
+    int frames;			//number of frames to display this object
+    SDL_Surface *image;
+} object;			//normal (non-RL) object
+
+struct fishypoo {
+    int alive;
+    int can_eat;
+    wchar_t* word;
+    double x, y;
+    int    w;
+    size_t len;
+    int    splat_time;
+    double dy;
+} fish_object[MAX_FISHIES_HARD + 1];
+
+struct fishypoo null_fishy;
+
+enum {
+	TUX_WALKING,
+	TUX_STANDING,
+	TUX_RUNNING,
+	TUX_GULPING,
+	TUX_WINNING,
+	TUX_YIPING,
+	TUX_NUM_STATES
+};
+
+static unsigned char* tux_sprite_fns[TUX_NUM_STATES] = {
+	"tux/walk",
+	"tux/stand",
+	"tux/run",
+	"tux/gulp",
+	"tux/win",
+	"tux/yipe"
+};
+
+#define RIGHT 0
+#define LEFT 1
+
+struct tuxguy {
+    int facing;
+    double x, y;
+    double dx, dy;
+    sprite *spr[TUX_NUM_STATES][2];
+    int endx, endy;
+    int state;
+    int wordlen;
+    wchar_t word[MAX_WORD_SIZE + 1];
+} tux_object;
+
+struct splatter {
+    double x, y;
+    int alive;
+} splat_object[MAX_FISHIES_HARD + 1];
+
+struct splatter null_splat;
+
+
+
+
+#endif

Added: tuxtype/branches/tuxtype-new/src/practice.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/practice.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/practice.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,583 @@
+/**************************************************************************
+practice.c 
+-  description: practice module
+-------------------
+begin                : Friday Jan 25, 2003
+copyright            : (C) 2003 by Jesse Andrews
+email                : jdandr2 at uky.edu
+
+Revised extensively: 2007
+David Bruce <dbruce at tampabay.rr.com>
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+
+static SDL_Surface* bg = NULL;
+static SDL_Surface* hands = NULL; 
+static SDL_Surface* hand[11] = {NULL};
+static SDL_Rect hand_loc, letter_loc;
+static TTF_Font* font = NULL;
+static wchar_t phrase[255][FNLEN];
+
+static Mix_Chunk* wrong = NULL;
+
+/*local function prototypes: */
+static int get_phrase(const wchar_t* phr);
+static int practice_load_media(void);
+static void practice_unload_media(void);
+static void print_at(const wchar_t* pphrase, int wrap, int x, int y);
+static void show(unsigned char t);
+
+
+/************************************************************************/
+/*                                                                      */ 
+/*         "Public" functions (callable throughout program)             */
+/*                                                                      */
+/************************************************************************/
+
+
+/* FIXME this is not UTF-8/Unicode compatible */
+int Phrases(wchar_t* pphrase )
+{
+
+  /* TODO 
+  * 
+  * 
+  * 
+  */
+
+  /* FIXME make variable names more descriptive */
+  Uint32 start = 0, a = 0;
+  int quit = 0,
+      i = 0,
+      c = 0,
+      wp = 0,
+      z = 0,
+      total = 0,
+      state = 0;
+  int key[100] = {0};
+  SDL_Rect dst, dst2, dst3, dst4, dst5;
+  char keytime[20],
+       totaltime[20];
+  SDL_Surface* srfc = NULL;
+
+
+  
+  if (!practice_load_media())
+  {
+    fprintf(stderr, "Phrases() - practice_load_media() failed, returning.\n");
+    return 0;
+  }
+
+  SDL_BlitSurface(bg, NULL, screen, NULL);
+  SDL_BlitSurface(hands, NULL, screen, &hand_loc);
+  SDL_Flip(screen);
+
+  wp = get_phrase(pphrase);
+
+  if (!wcsncmp(phrase[0], (wchar_t*)"", 1))
+    wcsncpy(pphrase, phrase[0], 80);
+
+  srfc = GetWhiteGlyph(65);
+
+  if (!srfc)
+  {
+    fprintf(stderr, "Phrases() - GetWhiteGlyph(65) not defined - bailing out.\n");
+    return 0;
+  }
+
+  dst.x = 320 - (srfc->w/2);
+  dst.y = 100;
+  dst.w = srfc->w;
+  dst.h = srfc->h;
+
+  dst2.x = 50;
+  dst2.y = 400;
+  dst2.w = srfc->w;
+  dst2.h = srfc->h;
+
+  dst3.x = 50;
+  dst3.y = 400;
+  dst3.w = 160;
+  dst3.h = 50;
+
+  dst4.x = 480;
+  dst4.y = 400;
+  dst4.w = 240;
+  dst4.h = 50;
+
+  dst5.x = 480;
+  dst5.y = 400;
+  dst5.w = 240;
+  dst5.h = 50;
+
+  dst.x = 40;
+
+  start = SDL_GetTicks();
+
+  do
+  {
+    switch (state)
+    {
+      case 0:
+        start = SDL_GetTicks();
+        SDL_BlitSurface(hands, NULL, screen, &hand_loc);
+        state = 1;
+        break;
+
+      case 1:
+        if (SDL_GetTicks() - start > 500)
+        {
+          /* Show finger hint, if available. Note that GetFinger() */
+          /* returns negative values on error and never returns a  */
+          /* value greater than 9.                                 */
+          int fing = GetFinger(pphrase[c]);
+          if (fing >= 0) 
+            SDL_BlitSurface(hand[fing], NULL, screen, &hand_loc);
+          state = 2;
+        }
+        break;
+
+      case 2:
+        if (state == 2 && SDL_GetTicks() - start > 750)
+        {
+          state = 3;
+        }
+        break;
+
+      case 3:
+       SDL_BlitSurface(hands, NULL, screen, &hand_loc);
+       state = 12;
+       break;  
+
+      case 4:
+        {
+          int fing = GetFinger(pphrase[c]);
+          if (fing >= 0) 
+            SDL_BlitSurface(hand[fing], NULL, screen, &hand_loc);
+          state = 11;
+          break;
+        }
+
+      default:
+        state -= 2; // this is to make the flashing slower
+    }
+
+
+    while  (SDL_PollEvent(&event))
+    {
+      if (event.type == SDL_KEYDOWN)
+      {
+        a = SDL_GetTicks();
+        key[c] = a - start;
+        total += key[c];
+        sprintf(keytime, "%.2f", (float) key[c] / 1000);
+        sprintf(totaltime, "%.2f", (float) total / 1000);
+        start = a;
+
+        if (event.key.keysym.sym == SDLK_ESCAPE)
+          quit = 1;
+
+        if (event.key.keysym.sym == SDLK_DOWN) 
+        {
+          //practice next phase in list
+          //a=a;
+        }
+        else
+        {
+          if (pphrase[c]==(char)event.key.keysym.unicode)
+          {
+            state = 0;
+            dst2.x = 40;
+            dst4.x = 480;
+            SDL_BlitSurface(bg, &dst3, screen, &dst2);
+            SDL_BlitSurface(bg, &dst5, screen, &dst4);
+            SDL_Flip(screen);
+
+            srfc = GetWhiteGlyph(event.key.keysym.unicode);
+            if (srfc)
+            { 
+              SDL_BlitSurface(srfc, NULL, screen, &dst);
+              dst.x = (dst.x + srfc->w) - 5;
+            }
+ 
+            for (z = 0; z < strlen(keytime); z++)
+            {
+              srfc = GetWhiteGlyph((int)keytime[z]);
+              if (srfc)
+              {
+                SDL_BlitSurface(srfc, NULL, screen, &dst2);
+                dst2.x = dst2.x + srfc->w - 2;
+              }
+            }
+
+            for (z = 0;z < strlen(totaltime); z++)
+            {
+              srfc = GetWhiteGlyph((int)totaltime[z]);
+              if (srfc)
+              {
+                SDL_BlitSurface(srfc, NULL, screen, &dst4);
+                dst4.x = dst4.x + srfc->w - 2;
+              }
+            }
+
+
+            if (c == (wcslen(pphrase) - 1))
+            {
+              wchar_t buf[10];
+              ConvertFromUTF8(buf, _("Great!"));
+              print_at(buf,6 ,275 ,200);
+              SDL_Flip(screen);
+              SDL_Delay(2500);
+              quit = 1;
+            }
+
+            if (c == wp)
+            {
+              c++;
+              dst.x = 40;
+              dst.y = 142;
+            }
+
+            c++;
+          }
+          else
+          {
+            if (event.key.keysym.sym != SDLK_RSHIFT
+             && event.key.keysym.sym != SDLK_LSHIFT)
+             PlaySound(wrong);
+          }
+        }
+      }
+    }
+    SDL_Flip(screen);
+    SDL_Delay(30);
+
+  }while (!quit);
+
+  practice_unload_media();
+
+  return 1;
+}
+
+
+
+/************************************************************************/
+/*                                                                      */ 
+/*       "Private" functions (local to practice.c)                      */
+/*                                                                      */
+/************************************************************************/
+
+
+static int practice_load_media(void)
+{
+  int i;	
+  unsigned char fn[FNLEN];
+  unsigned char let[5];
+  int load_failed = 0;
+
+  LOG("Loading practice media\n");
+
+
+  hands = LoadImage("hands/hands.png", IMG_ALPHA);
+  bg = LoadImage("main_bkg.png", IMG_ALPHA);
+  wrong = LoadSound("tock.wav");
+  font = LoadFont(settings.theme_font_name, 30);
+
+  for (i = 0; i < 10; i++)
+  {
+    sprintf(fn, "hands/%d.png", i);
+    hand[i] = LoadImage(fn, IMG_ALPHA);
+    if (!hand[i])
+      load_failed = 1;
+  }
+
+  /* Get out if anything failed to load: */
+  if (load_failed
+    ||!hands
+    ||!bg
+    ||!wrong
+    ||!font)
+  {
+    fprintf(stderr, "practice_load_media() - failed to load needed media \n");
+    practice_unload_media;
+    return 0;
+  }
+
+  /* Should be safe from here on out: */
+  hand_loc.x = (screen->w/2) - (hand[0]->w/2);
+  hand_loc.y = screen->h - (hand[0]->h);
+  hand_loc.w = (hand[0]->w);
+  hand_loc.h = (hand[0]->h);
+
+  /* Now render letters for glyphs in alphabet: */
+  RenderLetters(font);
+  TTF_CloseFont(font);  /* Don't need it after rendering done */
+  font = NULL;
+
+  LOG("DONE - Loading practice media\n");
+  return 1;
+}
+
+
+
+static void practice_unload_media(void)
+{
+	int i;
+	SDL_FreeSurface(bg);
+        bg = NULL;
+	SDL_FreeSurface(hands);
+        hands = NULL;
+	//TTF_CloseFont(font);
+
+	for (i=0; i<10; i++) 
+        {
+          SDL_FreeSurface(hand[i]);
+          hand[i] = NULL;
+        }
+
+	Mix_FreeChunk(wrong);
+	wrong = NULL;
+}
+
+
+/* looks like dead code: */
+static void show(unsigned char t)
+{
+	SDL_Rect dst;
+        SDL_Surface* s = NULL;
+
+        s= GetWhiteGlyph((int)t);
+        if (!s)
+          return; 
+	dst.x = 320 - (s->w/2);
+	dst.y = 100;
+	dst.w = s->w;
+	dst.h = s->h;
+	SDL_BlitSurface(s, NULL, screen, &dst);
+}
+
+
+
+static int get_phrase(const wchar_t* phr)
+{
+  int pc = 0;  // 'phrase count' (?)
+  int pw[256] = { 0 };
+  int wp = 0, i = 0, c = 0, z = 0;
+  char fn[FNLEN];
+
+  /* If we didn't receive a phrase get the first one from the file...*/
+  if (wcsncmp((wchar_t*)"", phr, 40) == 0)
+  {
+    FILE* pf; /*   "phrase file"   */
+    /* set the phrases directory/file */
+    /* FIXME I think the phrases should be under data or the theme */
+#ifdef WIN32
+    snprintf(fn, FNLEN - 1, "userdata/phrases.txt");
+#else
+    snprintf(fn, FNLEN - 1, (const char*)"%s/.tuxtype/phrases.txt", getenv("HOME"));
+#endif
+
+    DEBUGCODE { printf("get_phrases(): phrases file is '%s'\n", fn ); }
+    LOG("get_phrases(): trying to open phrases file\n");
+    pf = fopen( fn, "r" );
+    if (pf == NULL) 
+      return(wp);  /* why not just 'return 0;' ??? */
+
+    /* So now copy each line into phrases array: */
+    while (!feof(pf) && pc < 256) 
+    {
+      fscanf( pf, "%[^\n]\n", phrase[pc] );
+      pc++;
+      DEBUGCODE {printf("%s", phrase[pc]);}
+    }
+    if (pc == 256)
+      LOG("File contains more than max allowed phrases - stopping\n");
+
+    fclose(pf);
+    pc--;
+  } 
+  else
+  {
+    pc = 1;
+    wcsncpy(phrase[0], phr, 80);
+  }
+
+  /* FIXME maybe should verify that all chars in phrase are 
+//   /* Need to generate glyphs for all the needed Unicode chars: */
+// 
+//   ResetCharList();
+//   /* 'A' (i.e. 65) always has to go into list because width used for layout */
+//   /* HACK also need chars for "Great!" because of congrats message - this   */
+//   /* obviously is not a general solution. Numerals also needed for timers.  */
+//   {
+//     char* let = "AGreat!0123456789.";
+//     GenCharListFromString(let);
+//   }
+// 
+// 
+//   /* Scan through all the phrases and put needed chars into list: */
+//   for (c = 0; c <= pc; c++)
+//     GenCharListFromString(phrase[c]);
+// 
+//   /* Now render letters for glyphs in list: */
+//   font = LoadFont(settings.theme_font_name, 32 );
+//   if (!font)
+//   {
+//     fprintf(stderr, "get_phrase() - could not load font\n");
+//     return 0;
+//   }
+// 
+//   RenderLetters(font);
+// 
+//   TTF_CloseFont(font);
+//   font = NULL;
+
+
+  //Calculate and record pixel width of phrases
+  {
+    SDL_Surface* let = NULL;
+    for (c = 0; c <= pc; c++)
+    {
+      for(i = 0; i < wcslen(phrase[c]); i++)
+      {
+        let = GetWhiteGlyph((int)phrase[c][i]);
+        if (let)  
+          pw[c]+= let->w - 5;
+        else
+        {
+          fprintf(stderr, "get_phrase() - needed glyph not available\n");
+          return;
+        }
+      }
+    }
+  }
+
+  //Find wrapping point
+  for (c = 0; c <= pc; c++)
+  {
+    if (pw[c] < 598)  // If the phrase is less than 598 pixels wide
+    {
+      if (c == 0)
+      {
+        wp = wcslen(phrase[c]);
+        print_at(phrase[0], wp, 40, 10);
+      }
+    }
+    else
+    {
+      z = 0;
+      wp = 0;
+
+      for (i = 0; i < wcslen(phrase[c]); i++)
+      {
+        /* Should be safe (if no glyph, will have returned above) */
+        z += GetWhiteGlyph((int)phrase[c][i])->w-5;
+        if (wp == 0 && z > 598)
+        {
+          wp = i - 1;
+          break;
+        }
+      }
+
+      for (i = wp; i >= 0; i--)
+      {
+        if (wcsncmp((wchar_t*)" ", &phrase[c][i], 1) == 0)
+        {
+          wp = i-1;
+          break;
+        }
+      }
+
+      if (c == 0)
+      {
+        print_at(phrase[0], wp, 40, 10);
+      }
+    }
+  }
+  LOG("Leaving get_phrase()\n");
+  return(wp);
+}
+
+
+
+static void print_at(const wchar_t *pphrase, int wrap, int x, int y)
+{
+  int z = 0;
+  SDL_Surface* surf = NULL;
+  letter_loc.x = x;
+  letter_loc.y = y;
+  letter_loc.w = GetWhiteGlyph(65)->w;
+  letter_loc.h = GetWhiteGlyph(65)->h;
+
+  LOG("Entering print_at()\n");
+
+  if (wrap >= wcslen(pphrase)) // I think this means it fits on a single line
+  {
+    for (z = 0; z <wcslen(pphrase); z++)
+    {
+      surf = GetWhiteGlyph(pphrase[z]);
+      if (surf)
+      {
+        DEBUGCODE{printf("surf not NULL for %C\n", pphrase[z]);}
+        SDL_BlitSurface(surf, NULL, screen, &letter_loc);
+        letter_loc.x = (letter_loc.x + surf->w) - 5;
+      }
+      else
+      {
+        fprintf(stderr, "print_at(): needed glyph for %C not found\n",
+                pphrase[z]);
+      }
+    }
+  }
+  else  /* Another line required - code only seems to support 1 or 2 lines! */
+  {
+    for (z = 0; z <= wrap; z++) 
+    {
+      surf = GetWhiteGlyph(pphrase[z]);
+      if (surf)
+      {
+        DEBUGCODE{printf("surf not NULL for %C\n", pphrase[z]);}
+        SDL_BlitSurface(surf, NULL, screen, &letter_loc);
+        letter_loc.x = (letter_loc.x + surf->w) - 5;      }
+      else
+      {
+        fprintf(stderr, "print_at(): needed glyph for %C not found\n",
+                pphrase[z]);
+      }
+    }
+
+    /* Move 'cursor' back to left and down one line: */
+    letter_loc.x = 40;
+    // - (letter_loc.h/4) to account for free space at top and bottom of rendered letters
+    letter_loc.y = letter_loc.y + letter_loc.h - (letter_loc.h/4);
+
+    for (z = wrap + 2; z <wcslen(pphrase); z++)
+    {
+      surf = GetWhiteGlyph(pphrase[z]);
+      if (surf)
+      {
+        DEBUGCODE{printf("surf not NULL for %c\n", pphrase[z]);}
+        SDL_BlitSurface(surf, NULL, screen, &letter_loc);
+        letter_loc.x = (letter_loc.x + surf->w) - 5;
+      }
+      else
+      {
+        fprintf(stderr, "print_at(): needed glyph for %c not found",
+                pphrase[z]);
+      }
+    }
+  }
+  LOG("Leaving print_at()\n");
+}
+

Added: tuxtype/branches/tuxtype-new/src/scripting.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/scripting.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/scripting.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,1364 @@
+/***************************************************************************
+ -  file: scripting.c
+ -  description: scripting for lessons & instructions ...
+                             -------------------
+    begin                : Sun Dec 28, 2003
+    copyright            : Jesse Andrews (C) 2003
+    email                : tuxtype-dev at tux4kids.net
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************/
+
+#include "scripting.h"
+
+/* Local function prototypes: */
+static void clear_items(itemType* i);
+static void clear_pages(pageType* p);
+static void close_script(void);
+static SDL_Color* get_color(const char* in);
+static int get_int(const char* in);
+static char* get_quote(const char* in);
+static char hex2int(char b, char s);
+static int load_script(const char* fn);
+static void run_script(void);
+
+/************************************************************************/
+/*                                                                      */ 
+/*         "Public" functions (callable throughout program)             */
+/*                                                                      */
+/************************************************************************/
+
+
+void InstructCascade(void)
+{
+  char fn[FNLEN]; 
+
+  /* Try theme script first: */
+  if (!settings.use_english)
+    sprintf( fn, "%s/scripts/cascade.xml", settings.theme_data_path);
+
+  if (load_script( fn ) == 0) /* meaning successful load */
+  {
+    run_script();
+    return;
+  }
+
+  /* If unsuccessful, fall back to default (English) script: */
+  sprintf( fn, "%s/scripts/cascade.xml", settings.default_data_path);
+  if (load_script( fn ) != 0)
+    return; // bail if any errors occur
+
+  run_script();
+}
+
+
+void InstructLaser(void)
+{
+  char fn[FNLEN]; 
+  int i;
+
+  /* Try theme script first: */
+  if (!settings.use_english)
+    sprintf( fn, "%s/scripts/laser.xml", settings.theme_data_path);
+
+  if (load_script( fn ) == 0) /* meaning successful load */
+  {
+    for (i = 0; i < 20; i++)
+    {
+      run_script();
+      SDL_Delay(500);
+    }
+    return;
+  }
+
+
+  /* If unsuccessful, fall back to default (English) script: */
+  sprintf( fn, "%s/scripts/laser.xml", settings.default_data_path);
+  if (load_script( fn ) != 0)
+    return; // bail if any errors occur
+
+  for (i = 0; i < 20; i++)
+  {
+    run_script();
+    SDL_Delay(500);
+  }
+}
+
+
+void ProjectInfo(void)
+{
+  char fn[FNLEN]; 
+
+  /* Try theme script first: */
+  if (!settings.use_english)
+    sprintf( fn, "%s/scripts/projectInfo.xml", settings.theme_data_path);
+
+  if (load_script( fn ) == 0) /* meaning successful load */
+  {
+    run_script();
+    return;
+  }
+
+  /* If unsuccessful, fall back to default (English) script: */
+  sprintf( fn, "%s/scripts/projectInfo.xml", settings.default_data_path);
+  if (load_script( fn ) != 0)
+    return; // bail if any errors occur
+
+  run_script();
+}
+
+
+int TestLesson(void)
+{
+  SDL_Surface* left = NULL, *right = NULL, *pointer = NULL, *bkg = NULL;
+  SDL_Surface* filenames[200] = {NULL};
+
+  SDL_Rect spot, arrow_area;
+  SDL_Rect leftRect, rightRect;
+  SDL_Rect titleRects[8];
+
+  TTF_Font* font = NULL;
+	
+  int stop = 0;
+  int loc = 0;
+  int old_loc = 1;
+  int i;
+  int c = 0;
+  int found = 0;
+	
+  char fn[FNLEN]; 
+  unsigned char wordlistFile[200][200];
+  unsigned char script_path[FNLEN];
+
+  DIR* wordsDir = NULL;
+  struct dirent* wordsFile = NULL;
+
+  LOG("\nEnter TestLesson()\n");
+
+  pointer = LoadImage( "right.png", IMG_ALPHA );
+  bkg = LoadImage( "main_bkg.png", IMG_REGULAR );
+  left = LoadImage("left.png", IMG_ALPHA);       
+  right = LoadImage("right.png", IMG_ALPHA);
+
+  if (!pointer || !bkg || !left ||!right)
+  {
+    fprintf(stderr, "TestLesson() - needed image not found\n");
+    /* Free anything that got loaded: */
+    SDL_FreeSurface(pointer);
+    SDL_FreeSurface(left);
+    SDL_FreeSurface(right);
+    SDL_FreeSurface(bkg);
+    pointer = left = right = bkg = NULL;
+    return 0;
+  }
+
+  SDL_ShowCursor(0);
+
+  /* find the directory to load wordlists from */
+  /* First look in theme path, if desired: */
+  if (!settings.use_english)
+  {
+    sprintf( script_path, "%s/scripts", settings.theme_data_path);
+    if (CheckFile(script_path))
+    {
+      DEBUGCODE { fprintf(stderr, "Using theme script dir: %s\n", script_path); }
+      found = 1;
+    }
+  }
+
+  /* Now look in default path if desired or needed: */
+  if (!found)
+  {
+    sprintf( script_path, "%s/scripts", settings.default_data_path);
+    if (CheckFile(script_path))
+    {
+      DEBUGCODE { fprintf(stderr, "Using theme script dir: %s\n", script_path); }
+      found = 1;
+    }
+  }
+
+  if (!found)
+  {
+    fprintf(stderr, "TestLesson(): Error finding script directory!\n");
+    return 0;
+  }
+
+  /* What is this location? */
+  spot.x = 60;
+  spot.y = 20;
+
+
+  /* create a list of all the .xml files */
+
+  wordsDir = opendir( script_path );	
+  font = LoadFont(settings.theme_font_name, MENU_FONT_SIZE);
+  do
+  {
+    wordsFile = readdir(wordsDir);
+    if (!wordsFile)
+      break;
+
+    /* must have at least '.xml' at the end */
+    if (strlen(wordsFile->d_name) < 5)
+      continue;
+
+    if (strcmp(&wordsFile->d_name[strlen(wordsFile->d_name)-4],".xml"))
+      continue;
+
+    sprintf( wordlistFile[c], "%s", wordsFile->d_name );
+
+    DEBUGCODE { fprintf(stderr, "Adding XML file no. %d: %s\n", c, wordlistFile[c]); }
+
+
+    filenames[c] = TTF_RenderUTF8_Blended(font, wordsFile->d_name, white);
+    SDL_BlitSurface( filenames[c], NULL, screen, &spot );
+    SDL_FreeSurface(filenames[c]);
+    c++;
+    spot.y += MENU_FONT_SIZE;
+  } while (1); /* Leave loop when readdir() returns NULL */
+
+  TTF_CloseFont(font);
+  font = NULL;
+  closedir(wordsDir);	
+  wordsDir = NULL;
+  SDL_Flip(screen);
+
+  /* Should be safe - tested 'left' and 'right' above: */
+  leftRect.w = left->w; leftRect.h = left->h;
+  leftRect.x = 320 - 80 - (leftRect.w/2); leftRect.y = 430;
+
+  rightRect.w = right->w; rightRect.h = right->h;
+  rightRect.x = 320 + 80 - (rightRect.w/2); rightRect.y = 430;
+
+  /* set initial rect sizes */
+  titleRects[0].y = 30;
+  titleRects[0].w = titleRects[0].h = titleRects[0].x = 0;
+
+  for (i = 1; i < 8; i++)
+  { 
+    titleRects[i].y = titleRects[i-1].y + 50;
+    titleRects[i].w = titleRects[i].h = titleRects[i].x = 0;
+  }
+
+  arrow_area.x = 0;
+  arrow_area.y = 0;
+  arrow_area.w = 59;
+  arrow_area.h = 479;
+
+  while (!stop)
+  {
+    while (SDL_PollEvent(&event))
+    {
+      switch (event.type)
+      {
+        case SDL_QUIT:
+          exit(0);
+          break;
+        /* FIXME some of mouse code is wrong */
+        case SDL_MOUSEMOTION:
+          for (i=0; (i<8) && (loc-(loc%8)+i<c); i++)
+            if (inRect( titleRects[i], event.motion.x, event.motion.y ))
+            {
+              loc = loc-(loc%8)+i;
+              break;
+            }
+          break;
+
+        case SDL_MOUSEBUTTONDOWN:
+          if (inRect( leftRect, event.button.x, event.button.y ))
+            if (loc-(loc%8)-8 >= 0)
+            {
+              loc=loc-(loc%8)-8;
+              break;
+            }
+
+          if (inRect( rightRect, event.button.x, event.button.y ))
+            if (loc-(loc%8)+8 < c)
+            {
+              loc=loc-(loc%8)+8;
+              break;
+            }
+
+          for (i=0; (i<8) && (loc-(loc%8)+i<c); i++)
+            if (inRect(titleRects[i], event.button.x, event.button.y))
+            {
+//              loc = loc-(loc%8)+i;
+//              ClearWordList(); /* clear old selection */
+//               if (loc==0)
+//                 UseAlphabet(); 
+//               else
+//                 GenerateWordList(wordlistFile[loc]);
+// 
+//               stop = 1;
+//               break;
+            }
+          break;
+
+        case SDL_KEYDOWN:
+          if (event.key.keysym.sym == SDLK_ESCAPE)
+          { 
+            stop = 2;
+            break;
+          }
+
+          if (event.key.keysym.sym == SDLK_RETURN)
+          {
+            sprintf(fn, "%s/scripts/%s", settings.default_data_path, wordlistFile[loc]);
+            stop = 1;
+            break;
+          }
+
+          if ((event.key.keysym.sym == SDLK_LEFT) || (event.key.keysym.sym == SDLK_PAGEUP))
+          {
+            if (loc-(loc%8)-8 >= 0)
+              loc=loc-(loc%8)-8;
+            SDL_ShowCursor(1);
+          }
+
+          if ((event.key.keysym.sym == SDLK_RIGHT) || (event.key.keysym.sym == SDLK_PAGEDOWN))
+          {
+            if (loc-(loc%8)+8 < c)
+              loc=(loc-(loc%8)+8);
+          }
+
+          if (event.key.keysym.sym == SDLK_UP)
+          {
+            if (loc > 0)
+              loc--;
+          }
+
+          if (event.key.keysym.sym == SDLK_DOWN)
+          {
+            if (loc+1< c)
+              loc++;
+          }
+      } /* End of 'switch(event.type)' loop */
+    }  /* End of 'while(SDL_PollEvent(&event))' loop */
+
+
+
+    if (old_loc != loc)
+    {
+      int start;
+      SDL_BlitSurface( bkg, &arrow_area, screen, NULL);
+
+      start = loc;
+      for (i = start; i < c; i++)
+      {
+        spot.x = 5;
+        spot.y = (i * MENU_FONT_SIZE) + 18;
+        if (i == loc)
+          SDL_BlitSurface(pointer, NULL, screen, &spot);
+      }
+
+      SDL_Flip(screen);
+    }
+
+      SDL_Delay(40);
+      old_loc = loc;
+  }   /*   End of 'while(!stop)' loop  */
+
+  SDL_FreeSurface(pointer);
+  SDL_FreeSurface(left);
+  SDL_FreeSurface(right);
+  SDL_FreeSurface(bkg);
+  pointer = left = right = bkg = NULL;
+
+  if (stop == 2)
+  {
+    LOG("Player pressed 'Esc' - leaving TestLesson\n");
+    return 1;
+  }
+
+  /* Getting to here means "stop == 1", try to run chosen script: */
+  if (load_script(fn) != 0)
+  {
+    fprintf(stderr, "load_script() failed to load '%s'\n");
+    return 0; // bail if any errors occur
+  }
+
+  DEBUGCODE { fprintf(stderr, "Attempting to run script: %s\n", fn); }
+
+  run_script();
+
+  /* FIXME - shouldn't we show the cursor if returning in other code paths? */
+  SDL_ShowCursor(1);
+
+  LOG("Leave TestLesson()\n");
+
+  return 1; 
+}
+
+
+
+/************************************************************************/
+/*                                                                      */ 
+/*         "Private" functions (local to scripting.c)                   */
+/*                                                                      */
+/************************************************************************/
+
+
+static char* get_quote(const char* in)
+{
+    int start, finish;
+    char *out;
+
+    for (start=0; start<strlen(in) && in[start] != '"'; start++);  // find the first "
+
+    if (start >= strlen(in)) return 0; // return null string if no " found
+
+    start++; // move past the "
+    
+    for (finish=start; finish<strlen(in) && in[finish] != '"'; finish++); // find the next "
+
+    if (finish >= strlen(in)) return 0; // return null string if no " found
+    
+    out = malloc(finish-start+2);
+    
+    snprintf(out, finish-start+1, &in[start]);
+    out[finish-start]=0;
+    
+    return out;
+}
+
+
+static int get_int(const char* in)
+{
+    char *t = get_quote(in);
+    int ans=-1;
+    if (t) {
+        ans = atoi(t);
+        free(t);
+    }
+    return ans;
+}
+
+
+static char hex2int(char b, char s)
+{
+    char ans=0;
+        
+    if      ((b>='0') && (b<='9'))       ans=16*(b-'0');
+    else if ((b>='A') && (b<='F'))       ans=16*(b-'A'+10);
+    else if ((b>='a') && (b<='f'))       ans=16*(b-'a'+10);
+    
+    if      ((s>='0') && (s<='9'))       ans+=(s-'0');
+    else if ((s>='A') && (s<='F'))       ans+=(s-'A'+10);
+    else if ((s>='a') && (s<='f'))       ans+=(s-'a'+10);
+
+    return ans;
+}
+
+
+static SDL_Color* get_color(const char* in)
+{
+    char* col;
+    SDL_Color* out=malloc(sizeof(SDL_Color));
+    col = get_quote(in);
+    
+    if ((strlen(col)==7) && (col[0] == '#')) {
+        out->r = hex2int( col[1], col[2] );
+        out->g = hex2int( col[3], col[4] );
+        out->b = hex2int( col[5], col[6] );
+    }
+    
+    free(col);
+    
+    return out;
+}
+
+scriptType* curScript = NULL;
+pageType* curPage = NULL;
+itemType* curItem = NULL;
+
+static int load_script(const char* fn)
+{
+  int i;
+  char str[FNLEN];
+  FILE* f = NULL;
+    
+  DEBUGCODE
+  {
+    fprintf(stderr, "\nEnter load_script() - attempt to load '%s'\n", fn);
+  }
+
+  if (curScript)
+  {
+    LOG( "previous script in memory, removing now!\n");
+    close_script();
+  }
+    
+
+  f = fopen(fn, "r");
+
+  if (f == NULL)
+  {
+    fprintf(stderr, "error loading script %s\n", fn);
+    return -1;
+  }
+
+  do
+  {
+    fscanf(f, "%[^\n]\n", str);
+    if (strncmp("<script", str, 7) == 0)
+    {
+      /* -- allocate space for the lesson info -- */
+      curScript = (scriptType*)calloc(1, sizeof(scriptType));
+      for (i = 7; i < strlen(str) && str[i] != '>'; i++) 
+      {
+        if ((str[i] == 't') && strncmp("title", &str[i], 5) == 0)
+          curScript->title = get_quote(&str[i + 5]);
+
+        if ((str[i]=='b') && strncmp("bgcolor", &str[i], 7) == 0)
+          curScript->bgcolor = get_color(&str[i + 7]);
+
+        if ((str[i]=='b') && strncmp("background", &str[i], 10) == 0)
+          curScript->background = get_quote(&str[i + 10]);
+
+        if ((str[i]=='f') && strncmp("fgcolor", &str[i], 7) == 0) 
+          curScript->fgcolor = get_color(&str[i + 7]); 
+      }
+    }
+    else if (strncmp("<page", str,  5)==0)
+    {
+      if (curScript==NULL)
+      {
+        fprintf(stderr, "CRITICAL XML ERROR: <page> should be in a <script> in file %s line (todo)", fn); exit(1);
+      }
+
+      if (curScript->pages==NULL)
+      {
+        curPage = (pageType *)calloc(1,sizeof(pageType));
+        curPage->prev = curPage;
+        curScript->pages = curPage; 
+      }
+      else
+      {
+        curPage->next = (pageType*)calloc(1, sizeof(pageType));
+        curPage->next->prev = curPage;
+        curPage = curPage->next;
+      }
+
+      for (i = 5; i < strlen(str) && str[i]!='>'; i++)
+      {
+        if ((str[i] == 'b') && strncmp("background", &str[i], 10) == 0) 
+          curPage->background = get_quote(&str[i + 10]);
+
+        if ((str[i]== 't') && strncmp("title", &str[i], 5) == 0) 
+          curPage->title = get_quote(&str[i + 5]);
+
+        if ((str[i] == 'b') && strncmp("bgcolor", &str[i], 7) == 0) 
+          curPage->bgcolor = get_color(&str[i + 7]);
+
+        if ((str[i] == 'f') && strncmp("fgcolor", &str[i], 7) == 0) 
+          curPage->fgcolor = get_color(&str[i + 7]);
+      }
+    }
+    else if (strncmp("<text", str,  5) == 0)
+    {
+      if (curPage == NULL)
+      {
+        fprintf(stderr, "CRITICAL XML ERROR: <text> should be in a <page> in file %s line (todo)", fn); exit(1);
+      }
+
+      if (curPage->items == NULL) 
+      {
+        curItem = (itemType*)calloc(1, sizeof(itemType));
+        curPage->items = curItem;
+      }
+      else
+      {
+        curItem->next = (itemType*)calloc(1, sizeof(itemType));
+        curItem = curItem->next;
+      }
+
+      curItem->type = itemTEXT;
+      curItem->x = curItem->y = -1;
+
+      for (i = 5; i<strlen(str) && str[i]!='>'; i++)
+      {
+        if ((str[i] == 's') && strncmp("size", &str[i], 4) == 0)
+          curItem->size = (char)get_int(&str[i + 4]);
+
+        if ((str[i] == 'a') && strncmp("align", &str[i], 5) == 0)
+        {
+          char* t = get_quote(&str[i+5]);
+
+          if (strlen(t)>=1)
+          {
+            if ((t[0] == 'l') || (t[0]=='L'))
+              curItem->align='l';	// left
+            if ((t[0] == 'c') || (t[0]=='C'))
+              curItem->align='c';	// center
+            if ((t[0] == 'r') || (t[0]=='R'))
+              curItem->align='r';	// right
+            if ((t[0] == 'm') || (t[0]=='M'))
+              curItem->align='c';	// let 'm'iddle work as "center"
+          }
+          free(t);
+        }
+
+        if ((str[i] == 'c') && strncmp("color", &str[i], 5) == 0)
+           curItem->color = get_color(&str[i + 5]);
+
+        if ((str[i]== 'x') && strncmp(" x=", &str[i - 1], 3) == 0)
+           curItem->x = get_int(&str[i + 2]);
+
+        if ((str[i] == 'y') && strncmp(" y=", &str[i - 1], 3) == 0)
+           curItem->y = get_int(&str[i + 2]);
+      }
+
+      /* --- grab the text between <text> and </text> --- */
+      {
+        int start, finish;
+
+        for (start = 5; start < strlen(str) - 5 && str[start] != '>'; start++);
+
+        start++; // advance passed the '>'
+
+        for (finish = strlen(str) - 6; finish > 5; finish--)
+           if (strncmp( "</text>", &str[finish], 7) == 0)
+             break;
+
+        finish--; // advance passed the '<'
+
+        if (start <= finish)
+        {
+          curItem->data = (char*)calloc(1, finish - start + 2);
+          strncpy(curItem->data, &str[start], finish - start + 1);
+        }
+        else
+        {
+          if (start == finish + 1)
+          {
+            curItem->data = (char*)calloc(1, 2);
+            curItem->data[0]=' ';
+          }
+        }
+      }
+
+    } 
+    else if (strncmp("<img", str, 4) == 0)
+    {
+      if (curPage == NULL)
+      {
+        fprintf(stderr,
+                "CRITICAL XML ERROR: <img> should be in a <page> in file %s line (todo)",
+               fn);
+        exit(1); //FIXME should call cleanup() or maybe just return without exiting
+      }
+
+      if (curPage->items == NULL)
+      {
+        curItem = (itemType*)calloc(1, sizeof(itemType));
+        curPage->items = curItem;
+      }
+      else 
+      {
+        curItem->next = (itemType*)calloc(1, sizeof(itemType));
+        curItem = curItem->next;
+      }
+
+      curItem->type = itemIMG;
+      curItem->x = curItem->y = -1;
+
+      for (i = 5; i < strlen(str); i++) 
+      {
+        if ((str[i] == 'o') && strncmp("onclickplay", &str[i], 11) == 0)
+          curItem->onclick = get_quote(&str[i + 3]);
+
+        if ((str[i] == 'x') && strncmp(" x=", &str[i - 1], 3) == 0)
+          curItem->x = get_int(&str[i + 2]);
+
+        if ((str[i] == 'y') && strncmp(" y=", &str[i - 1], 3) == 0)
+          curItem->y = get_int(&str[i + 2]);
+
+        if ((str[i] == 's') && strncmp("src", &str[i], 3) == 0)
+          curItem->data = get_quote(&str[i + 3]);
+
+        if ((str[i] == 'a') && strncmp("align", &str[i], 5) == 0)
+        {
+          char* t = get_quote(&str[i + 5]);
+
+          if (strlen(t) >= 1)
+          {
+            if ((t[0] == 'l') || (t[0] == 'L'))
+               curItem->align='l';	// left
+
+            if ((t[0] == 'c') || (t[0]=='C'))
+               curItem->align='c';	// center
+
+            if ((t[0] == 'r') || (t[0]=='R'))
+               curItem->align='r';	// right
+
+            if ((t[0] == 'm') || (t[0]=='M'))
+               curItem->align='c';	// let 'm'iddle work as "center"
+          }
+          free(t);
+        }
+      }
+    }
+    else if (strncmp("<wav", str, 4) == 0)
+    {
+      if (curPage == NULL)
+      { 
+        fprintf(stderr,
+                "CRITICAL XML ERROR: <wav> should be in a <page> in file %s line (todo)",
+                fn);
+        exit(1);  /* FIXME call Cleanup() to exit */
+      }
+
+      if (curPage->items == NULL)
+      {
+        curItem = (itemType*)calloc(1, sizeof(itemType));
+        curPage->items = curItem;
+      } 
+      else 
+      {
+        curItem->next = (itemType*)calloc(1, sizeof(itemType));
+        curItem = curItem->next;
+      }
+
+      curItem->type = itemWAV;
+      curItem->loop = 0;
+
+      for (i =5 ; i < strlen(str); i++)
+      {
+        if ((str[i] == 's') && strncmp("src", &str[i], 3) ==0 )
+          curItem->data = get_quote(&str[i + 3]);
+
+        if ((str[i] == 'l') && strncmp("loop", &str[i], 4) == 0)
+        {
+          char* t = get_quote(&str[i + 4]);
+
+          if (strlen(t) >= 1)
+          {
+            if ((t[0] == 't') || (t[0]=='T'))
+              curItem->loop = 1;
+          } 
+          free(t);
+        }
+      }
+    }
+    else if (strncmp("<prac", str, 5) == 0)
+    {
+      if (curPage == NULL)
+      {
+        fprintf(stderr,
+                "CRITICAL XML ERROR: <prac> should be in a <page> in file %s line (todo)",
+                fn);
+        exit(1); /* FIXME call cleanup() rather than exit() */
+      }
+
+      if (curPage->items == NULL)
+      {
+        curItem = (itemType*)calloc(1, sizeof(itemType));
+        curPage->items = curItem;
+      }
+      else
+      {
+        curItem->next = (itemType*)calloc(1, sizeof(itemType));
+        curItem = curItem->next;
+      }
+
+      curItem->type = itemPRAC;
+
+      for (i = 5; i < strlen(str) && str[i] != '>'; i++)
+      {
+        if ((str[i] == 's') && strncmp("size", &str[i], 4) == 0) 
+          curItem->size = (char)get_int( &str[i + 4]);
+
+        if ((str[i] == 'g') && strncmp("goal", &str[i], 4) == 0) 
+          curItem->goal = (char)get_int(&str[i + 4]);
+
+        if ((str[i] == 'a') && strncmp("align", &str[i], 5) == 0)
+        {
+          char* t = get_quote(&str[i + 5]);
+
+          if (strlen(t) >= 1)
+          {
+            if ((t[0] == 'l') || (t[0]=='L'))
+              curItem->align = 'l';	// left
+            if ((t[0] == 'c') || (t[0]=='C'))
+              curItem->align = 'c';	// center
+            if ((t[0] == 'r') || (t[0]=='R'))
+              curItem->align = 'r';	// right
+            if ((t[0] == 'm') || (t[0]=='M'))
+              curItem->align = 'c';	// let 'm'iddle work as "center"
+          }
+                   free(t);
+        }
+
+        if ((str[i] == 'c') && strncmp("color", &str[i], 5) == 0)
+          curItem->color = get_color(&str[i + 5]);
+      }
+
+      { /* --- grab the text between <prac> and </prac> --- */
+        int start, finish;
+
+        for (start = 5; start < strlen(str) - 5 && str[start] != '>'; start++);
+
+        start++; // advance passed the '>/* --- grab the text between <prac> and </prac> --- */'
+
+        for (finish = strlen(str) - 6; finish > 5; finish--)
+          if (strncmp("</prac>", &str[finish], 7) == 0)
+            break;
+
+        finish--; // advance passed the '<'
+
+        if (start <= finish)
+        {
+          curItem->data = (char*)calloc(1, finish - start + 2);
+          strncpy(curItem->data, &str[start], finish - start + 1);
+        }
+        else
+        {
+          if (start == finish + 1)
+          {
+            curItem->data = (char*)calloc(1, 2);
+            curItem->data[0]=' ';
+          }
+        }
+      }
+    }
+    else if (strncmp("<waitforinput", str, 13) == 0)
+    { 
+      if (curPage == NULL)
+      {
+        fprintf(stderr,
+               "CRITICAL XML ERROR: <waitforinput> should be in a <page> in file %s line (todo)",
+                fn);
+        exit(1);
+      }
+
+      if (curPage->items == NULL)
+      {
+        curItem = (itemType*)calloc(1, sizeof(itemType));
+        curPage->items = curItem;
+      } 
+      else
+      {
+        curItem->next = (itemType*)calloc(1, sizeof(itemType));
+        curItem = curItem->next;
+      }
+
+      curItem->type = itemWFIN;
+
+    }
+    else if (strncmp("<waitforchar",  str, 12) == 0)
+    { 
+      if (curPage == NULL)
+      {
+        fprintf(stderr,
+               "CRITICAL XML ERROR: <waitforchar> should be in a <page> in file %s line (todo)",
+               fn);
+        exit(1);
+      }
+
+      if (curPage->items == NULL)
+      {
+        curItem = (itemType*)calloc(1, sizeof(itemType));
+        curPage->items = curItem;
+      }
+      else
+      {
+        curItem->next = (itemType*)calloc(1, sizeof(itemType));
+        curItem = curItem->next;
+      }
+
+      curItem->type = itemWFCH;
+    }
+    else if (strncmp("</",str, 2) == 0)
+    {
+      /* do nothing */
+    }
+    else
+      fprintf(stderr, "not recognized: %s\n", str); 
+
+  } while(!feof(f));
+
+  fclose(f);
+
+  LOG("Leave load_script()\n");
+
+  return 0;
+}
+
+
+static void run_script(void)
+{
+  /* FIXME FNLEN doesn't make sense for size of these arrays */
+  Mix_Chunk* sounds[FNLEN] = {NULL};
+
+  /* --- for on mouse click on an image --- */
+  Mix_Chunk* clickWavs[FNLEN] = {NULL};
+  SDL_Rect   clickRects[FNLEN];
+
+  LOG("\nEnter run_script()\n");
+
+  if (!curScript)
+  {
+    fprintf(stderr, "run_script() - Error: curScript is NULL\n");
+    return;
+  }
+
+  curPage = curScript->pages;
+
+  while (curPage)
+  {
+    int y = 0;
+    int skip = 0;
+    int numWavs = 0;
+    int numClicks = 0;
+
+    curItem = curPage->items;
+
+    /* --- setup background color --- */
+    if (curPage->bgcolor)
+      SDL_FillRect( screen, NULL, COL2RGB(curPage->bgcolor));
+    else if (curScript->bgcolor)
+      SDL_FillRect(screen, NULL, COL2RGB(curScript->bgcolor));
+
+    /* --- setup background image --- */
+    if (curPage->background)
+    {
+      SDL_Surface* img = LoadImage(curPage->background, IMG_ALPHA|IMG_NOT_REQUIRED);
+      SDL_BlitSurface(img, NULL, screen, NULL);
+      SDL_FreeSurface(img);
+    }
+    else if (curScript->background)
+    {
+      SDL_Surface* img = LoadImage(curScript->background, IMG_ALPHA|IMG_NOT_REQUIRED);
+      SDL_BlitSurface(img, NULL, screen, NULL);
+      SDL_FreeSurface(img);
+    }
+
+    /* --- go through all the items in the page --- */
+    while (curItem)
+    {
+      switch (curItem->type)
+      {
+        case itemIMG:
+        {
+          SDL_Surface* img = LoadImage(curItem->data, IMG_ALPHA|IMG_NOT_REQUIRED);
+          if (img)
+          {
+            /* --- figure out where to put it! --- */
+            SDL_Rect loc;
+            loc.w = img->w;
+            loc.h = img->h;
+
+            /* --- if user specifies y location, use it --- */
+            if (curItem->y >= 0)
+            {
+              loc.y = curItem->y;
+            }
+            else
+            {
+              loc.y = y;
+              y += loc.h;
+            }
+
+            /* --- if user specifies x location, use it --- */
+            if (curItem->x >= 0)
+            {
+              loc.x = curItem->x;
+            }
+            else
+            {
+              switch (curItem->align)
+              {
+                case 'r':
+                  loc.x = (screen->w) - (loc.w);
+                  break;
+                case 'c':
+                  loc.x = ((screen->w) - (loc.w))/2;
+                  break;
+                default:
+                  loc.x = 0;
+                  break;
+              }
+            }
+
+            /* --- and blit! --- */
+            SDL_BlitSurface(img, NULL, screen, &loc);
+
+            /* --- does it do click and play --- */
+            if (curItem->onclick)
+            {
+              if (settings.sys_sound)
+                clickWavs[numClicks] = LoadSound(curItem->onclick);
+              clickRects[numClicks].x = loc.x;
+              clickRects[numClicks].y = loc.y;
+              clickRects[numClicks].w = loc.w;
+              clickRects[numClicks].h = loc.h;
+              numClicks++;
+            }
+          }
+          SDL_FreeSurface(img);
+          break;
+        }
+
+        case itemTEXT:
+        {
+          TTF_Font* myFont;
+          SDL_Surface* img;
+          SDL_Color* col;
+
+          int shown, toshow, w, h; // used to wrap text
+          char tmp[FNLEN];   // used to hold temp text for wrapping
+
+          /* --- create font & render text --- */
+          if (curItem->size > 0)
+            myFont = LoadFont(settings.theme_font_name, (int)curItem->size);
+          else
+            myFont = LoadFont(settings.theme_font_name, 24); // default size is 24
+
+          if (curItem->color)
+            col = curItem->color;
+          else if (curPage->fgcolor)
+            col = curPage->fgcolor;
+          else if (curScript->fgcolor)
+            col = curScript->fgcolor;
+          else 
+            col = &white;
+
+          shown = 0;
+
+
+          do 
+          {
+            int ok = 0;
+
+            if ((shown > 0) && (curItem->data[shown] == ' '))
+              shown++;
+            strncpy(tmp, &curItem->data[shown], FNLEN - 1);
+            tmp[FNLEN - 1] = 0;
+            tmp[strlen(curItem->data) - shown] = 0;
+
+            for (toshow = strlen(&curItem->data[shown]); !ok; toshow--)
+            {
+              if (toshow + 1 > FNLEN)
+                continue;
+
+              tmp[toshow] = 0;
+              TTF_SizeText(myFont, tmp, &w, &h);
+
+              if (w + 20 < screen->w)
+                ok = 1;
+            }
+
+            shown += toshow + 1;
+
+            img = TTF_RenderUTF8_Blended(myFont, tmp, *col);
+
+            if (img)
+            {
+              SDL_Rect loc;
+              /* --- figure out where to put it! --- */
+              loc.w = img->w;
+              loc.h = img->h;
+
+              /* --- if user specifies y location, use it --- */
+              if (curItem->y >= 0)
+                loc.y = curItem->y;
+              else 
+                loc.y=y; y+=loc.h;
+
+              /* --- if user specifies x location, use it --- */
+              if (curItem->x >= 0)
+                loc.x = curItem->x;
+              else 
+              {
+                switch (curItem->align)
+                {
+                  case 'r':
+                    loc.x = (screen->w) - (loc.w);
+                    break;
+                  case 'c':
+                    loc.x = ((screen->w) - (loc.w))/2;
+                    break;
+                  default:
+                    loc.x = 0;
+                  break;
+                }
+              }
+
+              /* --- and blit! --- */
+              SDL_BlitSurface( img, NULL, screen, &loc );
+              SDL_FreeSurface( img );
+            }
+                    
+          } while (shown + 1 < strlen(curItem->data));
+
+          TTF_CloseFont(myFont);
+          break;
+        }
+
+
+        case itemWAV:
+        {
+          // HACK, we need to make sure no more than 8 sounds or so..
+          sounds[numWavs] = LoadSound( curItem->data );
+          Mix_PlayChannel( numWavs, sounds[numWavs], -curItem->loop );
+          numWavs++;
+          break;
+        }
+
+
+        case itemWFIN:
+        {
+          int done = 0;
+
+          // Make sure everything is on screen 
+          SDL_Flip(screen);
+
+          while (!done)
+          {
+            SDL_Delay(100);
+
+            while (SDL_PollEvent(&event))
+            {
+              switch (event.type)
+              {
+                case SDL_MOUSEBUTTONDOWN:
+                {
+                  int j;
+
+                  for (j=0; j<numClicks; j++) 
+                  {
+                    if (inRect(clickRects[j], event.button.x, event.button.y))
+                     Mix_PlayChannel(numWavs + j, clickWavs[j], 0);
+                  }
+                  break;
+                }
+
+                case SDL_QUIT:
+                {
+                  curPage = NULL;
+                  done = 1;
+                  break;
+                }
+
+                case SDL_KEYDOWN: 
+                {
+                  switch (event.key.keysym.sym)
+                  {
+                    case SDLK_ESCAPE: 
+                      curPage = NULL;
+                      done = 1;
+                      break;  // quit
+                    case SDLK_LEFT: 
+                      curPage = curPage->prev;
+                      done = 1;
+                      break;
+                    case SDLK_RIGHT:
+                    case SDLK_SPACE:
+                    case SDLK_RETURN:
+                      curPage = curPage->next;
+                      skip = 1;
+                      done = 1;
+                      break;
+                    default:
+                      break;
+                  };
+
+                  break;
+                }
+              }
+            }
+          }
+        }
+        break;
+
+
+        case itemWFCH:
+        {
+          int done = 0;
+          // Make sure everything is on screen 
+          SDL_Flip(screen);
+
+          while (!done)
+          {
+            SDL_Delay(100);
+            while (SDL_PollEvent(&event))
+            {
+              switch (event.type)
+              {
+                case SDL_QUIT:
+                {
+                  curPage = NULL;
+                  done = 1;
+                  break;
+                }
+
+                case SDL_KEYDOWN: 
+                {
+                  switch (event.key.keysym.sym)
+                  {
+                    case SDLK_ESCAPE: 
+                    {
+                      curPage = NULL;
+                      done = 1;
+                      break;  // quit
+                    }
+                    case SDLK_p:
+                    {
+                      curPage = curPage->next;
+                      done = 1;
+                      break;
+                    }
+                    default:
+                      break;
+                  };
+                  break;
+                }
+              }
+            }
+          }
+        }
+        break;
+
+        case itemPRAC:
+        {
+          wchar_t wide_buf[FNLEN];
+          ConvertFromUTF8(wide_buf, curItem->data);
+          if (curItem->goal > 0)
+          {
+            //printf( "goal is %d\n", curItem->goal );
+            Phrases(wide_buf);
+          }
+          else
+          {
+            //printf( "No goal \n" );
+            Phrases(wide_buf);
+          }
+          break;
+        }
+
+        default:
+        {
+          /* do nothing */
+        }
+      }
+
+      if (curItem->next == NULL && curPage != NULL)
+      {
+        if (!skip)
+        {
+          curPage = curPage->next;
+          skip = 0;
+        }
+        break;
+      }
+      else
+        curItem = curItem->next;
+    }
+    SDL_Flip(screen);
+    SDL_Delay(30);
+        
+        
+    /* --- cleanup memory --- changing pages --- */
+    { 
+      int i;
+
+      if (settings.sys_sound)
+      {
+        for (i=0; i<numWavs; i++)
+        {
+          Mix_HaltChannel(i);
+          Mix_FreeChunk(sounds[i]);
+        }
+
+        for (i = 0; i < numClicks; i++)
+        {
+          Mix_HaltChannel(i + numWavs);
+          Mix_FreeChunk(clickWavs[i]);
+        }
+      }
+    }
+
+  } /* --- End of "while (curPage)" loop ----*/
+
+  LOG("Leave run_script()\n");
+}
+
+
+static void clear_items(itemType* i)
+{
+    itemType* n;
+
+    /* if i is null, will return harmlessly: */
+    while (i) {
+        n = i->next;  // remember the next guy
+
+        /* -- remove any data we are pointing to -- */
+        free(i->data);
+        free(i->onclick);
+        free(i->color);
+
+        /* -- remove ourselves --*/
+        free(i);
+
+        /* -- on to the next guy! -- */
+        i = n;
+    }
+}
+
+static void clear_pages(pageType* p)
+{
+    pageType* n;
+
+    /* if p is null, will return harmlessly: */
+    while (p) {
+        n = p->next;  // remember the next guy
+
+        /* -- remove all of our sub elements -- */
+        clear_items(p->items);
+
+        /* -- free anything we are pointing to --- */
+        free(p->background);
+        free(p->title);
+        free(p->bgcolor);
+        free(p->fgcolor);
+
+        /* -- free ourselves -- */
+        free(p);
+
+        /* -- on to the next --*/
+        p = n;
+    }
+}
+
+
+static void close_script(void)
+{
+  if (curScript)
+  {
+    /* -- remove all the pages we have --*/
+    clear_pages(curScript->pages);
+
+    /* -- remove attributes we are pointing to -- */
+    free(curScript->title);
+    free(curScript->bgcolor);
+    free(curScript->fgcolor);
+    free(curScript->background);
+
+    /* -- free yourself -- */
+    free(curScript); 
+
+    /* -- and remember you did -- */
+    curScript = NULL;
+  }
+}
+
+
+
+

Added: tuxtype/branches/tuxtype-new/src/scripting.h
===================================================================
--- tuxtype/branches/tuxtype-new/src/scripting.h	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/scripting.h	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,64 @@
+/***************************************************************************
+ -  file: scripting.h
+ -  description: types for scripting 
+-------------------
+    begin                : Sun Dec 28, 2003
+    copyright            : Jesse Andrews (C) 2003
+    email                : tuxtype-dev at tux4kids.net
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+
+enum { itemTEXT, itemIMG, itemWAV, itemPRAC, itemWFIN, itemWFCH };
+
+/* linked list of elements for a page */
+struct item {
+        char type;		// text or img or wav enum type?
+        char *data;		// holds text/location for file (sound/image)
+        char *onclick;		// holds additional data
+        char size;		// holds font size if applicable
+        char align;             // holds 'L'eft, 'R'ight, 'C'enter for alignment
+        char loop;		// holds if sound files loop
+        int  goal;		// goal for practice session
+	int  x,y;		// for absolute positioning
+        SDL_Color *color;       // holds text color
+        
+        struct item *next; // the linked list part ... 
+};
+
+typedef struct item itemType;
+
+/* linked list of pages for a lesson */
+struct page {
+    itemType *items;	// linked list of elements
+    char *background;		// background image
+    char *title;		// title of the page
+    SDL_Color *bgcolor;		// background color
+    SDL_Color *fgcolor;		// default text color
+    
+    struct page *next;         // the linked list part ...
+    struct page *prev;         // the doubly-linked list part ...
+};
+
+typedef struct page pageType;
+
+struct script {
+    pageType *pages;		// linked list of pages
+    char *title;		// title of lesson
+    SDL_Color *bgcolor;         // default background color for all pages
+    SDL_Color *fgcolor;         // default foreground color for all text
+    char *background;		// default background image for all pages
+}; 
+
+typedef struct script scriptType;
+

Added: tuxtype/branches/tuxtype-new/src/setup.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/setup.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/setup.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,450 @@
+/***************************************************************************
+                          setup.c 
+ -  description: Init SDL
+                             -------------------
+    begin                : Thu May 4 2000
+    copyright            : (C) 2000 by Sam Hart
+                         : (C) 2003 by Jesse Andrews
+    email                : tuxtype-dev at tux4kids.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+
+#define NUM_PATHS 4
+
+
+/* FIXME this is a hack that can have unintended results */
+/* if the program is run from a path that has 'data' as a */
+/* subdir */
+const char PATHS[NUM_PATHS][FNLEN] = 
+{
+  DATA_PREFIX"/share/"PACKAGE"/data",
+  "/usr/share/"PACKAGE"/data",
+  "/usr/local/share/"PACKAGE"/data",
+  "./data"
+};
+
+
+/* Local function prototypes: */
+static int load_settings_fp(FILE* fp);
+static int load_settings_filename(const char* fn);
+
+/***************************
+	GraphicsInit: Initializes the graphic system
+****************************/
+void GraphicsInit(Uint32 video_flags)
+{
+	LOG( "GraphicsInit - Initialize graphic system\n" );
+
+	DEBUGCODE {
+		fprintf(stderr, "-SDL Setting VidMode to %ix%ix%i\n", RES_X, RES_Y, BPP);
+	}
+
+	/* NOTE fullscreen vs. windowed is indicated by video_flags */
+	screen = SDL_SetVideoMode(RES_X, RES_Y, BPP, video_flags);
+
+	if (screen == NULL) {
+		fprintf(stderr, "Couldn't set %ix%i video mode: %s\n", RES_X, RES_Y, SDL_GetError());
+		exit(2);
+	}
+
+
+	LOG( "SDL_SetClipRect(screen, NULL):\n" );
+
+	SDL_SetClipRect(screen, NULL); // Let's set the appropriate clip rect  -- JA: is neccessary???  
+
+	LOG( "SDL_ShowCursor(0):\n" );
+
+	SDL_ShowCursor(0); // no cursor please
+
+	LOG( "SDL_WM_SetCaption(\"Tux Typing\", PACKAGE);\n" );
+
+	SDL_WM_SetCaption("Tux Typing", "tuxtype"); // Set window manager stuff
+
+	/* --- setup color we use --- */
+	black.r       = 0x00; black.g       = 0x00; black.b       = 0x00;
+        gray.r        = 0x80; gray.g        = 0x80; gray.b        = 0x80;
+	dark_blue.r   = 0x00; dark_blue.g   = 0x00; dark_blue.b   = 0x60; 
+	red.r         = 0xff; red.g         = 0x00; red.b         = 0x00;
+	white.r       = 0xff; white.g       = 0xff; white.b       = 0xff;
+	yellow.r      = 0xff; yellow.g      = 0xff; yellow.b      = 0x00; 
+
+	InitEngine();
+
+	DEBUGCODE {
+		fprintf(stderr, "-SDL VidMode successfully set to %ix%ix%i\n", RES_X, RES_Y, BPP);
+	}
+
+	LOG( "GraphicsInit():END\n" );
+}
+
+/****************************
+	LibInit : Init the SDL
+	library
+*****************************/
+void LibInit(Uint32 lib_flags)
+{
+	LOG( "LibInit():\n-About to init SDL Library\n" );
+
+	if (SDL_Init(lib_flags) < 0) 
+		/* FIXME this looks wrong - if no sys_sound, we don't init video??? */
+		if (settings.sys_sound) {
+			if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+				fprintf(stderr, "Couldn't initialize SDL: %s\n",
+				SDL_GetError());
+				exit(2);
+			} else {
+				LOG( "Couldn't initialize SDL Sound\n" );
+				settings.sys_sound = 0;
+			}
+		}
+
+
+//	atexit(SDL_Quit); // fire and forget... 
+
+	LOG( "-SDL Library init'd successfully\n" );
+
+	/* FIXME should read settings before we do this: */ 
+	if (settings.sys_sound)
+        { 
+          if (Mix_OpenAudio(22050, AUDIO_S16, 1, 2048) == -1)
+          {
+            fprintf( stderr, "Warning: couldn't set 22050 Hz 8-bit audio\n - Reasons: %s\n", SDL_GetError());
+            settings.sys_sound=0;
+          }
+          else
+            LOG("Mix_OpenAudio() successful\n");
+        }
+
+	LOG( "-about to init SDL_ttf\n" );
+
+	if (TTF_Init() < 0) {
+		fprintf( stderr, "Couldn't initialize SDL_ttf\n" );
+		exit(2);
+	}
+
+//	atexit(TTF_Quit);
+
+	SDL_EnableKeyRepeat( 0, SDL_DEFAULT_REPEAT_INTERVAL );
+	/* Need this to get Unicode values from keysyms: */
+	SDL_EnableUNICODE(1);
+
+	LOG( "LibInit():END\n" );
+}
+
+/* Load the settings from a file... make sure to update SaveSettings if you change
+ *  what can be saved/loaded 
+ */
+void LoadSettings(void)
+{
+  char fn[FNLEN];
+// 	char setting[FNLEN];
+// 	char value[FNLEN];
+//	FILE *settingsFile;
+	
+  /* set the settings directory/file */
+
+#ifdef WIN32
+  snprintf(fn, FNLEN - 1, "userdata/settings.txt");
+  LOG("WIN32 defined\n");
+#else
+  snprintf(fn, FNLEN - 1, (const char*)"%s/.tuxtype/settings.txt", getenv("HOME"));
+  LOG("WIN32 not defined\n");
+#endif
+
+  DEBUGCODE { printf("LoadSettings: settings file is '%s'\n", fn ); }
+
+  LOG("LoadSettings: trying to open settings file\n");
+
+  load_settings_filename(fn);
+}
+
+
+
+/* Load the settings if given the complete pathname to the settings file.  Returns 1 if
+   able to call load_settings_fp() successfully on named file.
+ */
+static int load_settings_filename(const char* fn)
+{
+  FILE* fp = fopen(fn, "r");
+
+  if (!fp)
+  {
+    fprintf(stderr, "load_settings_filename(): no theme-specific settings found\n");
+    return;
+  }
+	
+  if (!load_settings_fp(fp))
+  {
+    fprintf(stderr, "No settings in settings file.\n");
+    fclose(fp); /* still need to close fp */
+    return 0;
+  }
+
+  /* Success! */
+  fclose(fp);
+  return 1;
+}
+
+
+/* Load the settings if given an open FILE* pointer to the settings file.  Returns 1 if
+   at least one setting value found, 0 otherwise. It does not close the FILE*.
+ */
+static int load_settings_fp(FILE* fp)
+{
+  char setting[FNLEN]; /* these don't really need to be 'FNLEN' long */
+  char value[FNLEN];
+  int setting_found = 0;
+
+  if (!fp)
+  {
+    fprintf(stderr, "load_settings_fp() - FILE* parameter NULL\n");
+    return 0;
+  }
+
+  /* we load all the settings here */
+  while (!feof(fp))
+  {
+    fscanf(fp, "%[^=]=%[^\n]\n", setting, value );
+
+    DEBUGCODE {fprintf(stderr, "%s = %s", setting, value );}
+
+    if (strncmp( setting, "lang", FNLEN ) == 0 )
+    {
+      DEBUGCODE {fprintf(stderr, "LoadSettings: Setting language to %s", value);}
+      strncpy(settings.lang, value, FNLEN - 1);
+      setting_found = 1;
+      SetupPaths(value); /* Does this really belong here? */ 
+    }
+    else if (strncmp( setting, "o_lives", FNLEN ) == 0 )
+    {
+      DEBUGCODE {fprintf(stderr, "LoadSettings: Setting lives to %s", value);}
+      settings.o_lives = atoi(value);
+      setting_found = 1;
+   }
+    else if (strncmp( setting, "mus_volume", FNLEN ) == 0 )
+    {
+      DEBUGCODE {fprintf(stderr, "LoadSettings: Setting music volume to %s", value);}
+      settings.mus_volume = atoi(value);
+      setting_found = 1;
+    }
+    else if (strncmp(setting, "sfx_volume", FNLEN) == 0)
+    {
+      DEBUGCODE {fprintf(stderr, "LoadSettings: Setting effects volume to %s", value);}
+      settings.sfx_volume = atoi(value);
+      setting_found = 1;
+    }
+    else if (strncmp(setting, "menu_music", FNLEN) == 0)
+    {
+      DEBUGCODE {fprintf(stderr, "LoadSettings: Setting menu music to %s", value);}
+      settings.menu_music = atoi(value);
+      setting_found = 1;
+    }
+    else if (strncmp( setting, "fullscreen", FNLEN ) == 0 )
+    {
+      settings.fullscreen = atoi(value);
+      setting_found = 1;
+    }
+    else if (strncmp( setting, "theme_font_name", FNLEN ) == 0 )
+    {
+      DEBUGCODE {fprintf(stderr, "load_settings_fp(): Setting theme font to %s", value);}
+      strncpy(settings.theme_font_name, value, FNLEN - 1);
+      setting_found = 1;
+    }
+    else
+      DEBUGCODE {fprintf(stderr, "load_settings_fp(): unrecognized string: %s", value);}
+
+  }
+
+
+  if (setting_found)
+    return 1;
+  else
+  {
+    fprintf(stderr, "load_settings_fp() - no settings in file - empty or corrupt?\n");
+    return 0;
+  }
+}
+
+
+
+/* Save the settings from a file... make sure to update LoadSettings if you change
+ *  what can be saved/loaded 
+ */
+void SaveSettings(void)
+{
+	char fn[FNLEN];
+	FILE* settingsFile;
+	
+	/* set the settings directory/file */
+
+	#ifdef WIN32
+		_mkdir( "userdata" );  // just in case try to create save location
+		snprintf( fn, FNLEN-1, "userdata/settings.txt" );
+	#else
+		snprintf( fn, FNLEN-1, (const char*)"%s/.tuxtype", getenv("HOME") );
+		mkdir( fn, 0755 ); // just in case try to create save location
+		snprintf( fn, FNLEN-1, (const char*)"%s/.tuxtype/settings.txt", getenv("HOME") );
+	#endif
+
+
+	DEBUGCODE { printf("SaveSettings: settings file is '%s'\n", fn ); }
+	
+	LOG("SaveSettings: trying to open settings file\n");
+	
+	settingsFile = fopen( fn, "w" );
+
+	if (settingsFile == NULL) {
+		printf("SaveSettings: Settings file cannot be created!\n");
+		return;
+	}
+	
+	/* Save all the settings here! */
+	if (strncmp(settings.theme_name, "", FNLEN) != 0)
+		fprintf( settingsFile, "lang=%s\n", settings.theme_name );
+	if (settings.o_lives > 9)
+		fprintf( settingsFile, "o_lives=%d\n", settings.o_lives );
+
+	fprintf( settingsFile, "mus_volume=%d\n", settings.mus_volume );
+	fprintf( settingsFile, "sfx_volume=%d\n", settings.sfx_volume );
+	fprintf( settingsFile, "menu_music=%d\n", settings.menu_music );
+	fprintf( settingsFile, "fullscreen=%d\n", settings.fullscreen);
+
+
+// 	if (screen->flags & SDL_FULLSCREEN){
+// 		fprintf( settingsFile, "fullscreen=%s\n", "1");
+// 	} else {
+// 		fprintf( settingsFile, "fullscreen=%s\n", "0");
+// 	}
+	fclose(settingsFile);
+}
+
+
+/* Check for default (English) and theme data paths and update settings struct. */
+/* Returns 0 if default data path not found, 1 if successfully located.         */
+/* If theme not found, still returns 1 but settings changed to use English.     */
+/* TODO should have this function set up the user and global settings paths.    */
+/* TODO settings should be re-loaded when theme changes.                        */
+
+int SetupPaths(const char* theme_dir)
+{
+  int i;
+  settings.use_english = 1; // default is to use English if we cannot find theme
+
+  /* First find default data path: */
+  for (i = 0; i < NUM_PATHS; i++)
+  {
+
+    DEBUGCODE
+    {
+      fprintf(stderr, "SetupPaths(): checking for '%s' as default data path\n", PATHS[i]);
+    }
+
+    if (CheckFile(PATHS[i]))
+    {
+      strncpy(settings.default_data_path, PATHS[i], FNLEN - 1);
+
+      DEBUGCODE
+      {
+        fprintf(stderr, "path '%s' found, copy to settings.default_data_path\n", PATHS[i]);
+      }
+      break;
+    }
+    else
+    {
+      DEBUGCODE
+      {
+        fprintf(stderr, "path '%s' not found.\n", PATHS[i]);
+      }
+    }
+  }
+
+  /* If we didn't find a data path, print error msg and get out: */
+  if (i >= NUM_PATHS) /* (shouldn't actually ever be > NUM_PATHS) */
+  {
+    fprintf(stderr, "SetupPaths(): Error - could not find data path.\n");
+    return 0;
+  }
+
+
+  /* Now look for theme directory: */
+  if (theme_dir != NULL)
+  {
+    char full_theme_path[FNLEN];
+    char theme_settings_path[FNLEN];
+
+    sprintf(full_theme_path, "%s/themes/%s", settings.default_data_path, theme_dir);
+
+    DEBUGCODE
+    {
+      fprintf(stderr, "SetupPaths(): checking for '%s' as theme path\n", full_theme_path);
+    }
+
+    if (CheckFile(full_theme_path)) /* Theme found - set it up! */
+    {
+      settings.use_english = 0;
+      strncpy(settings.theme_data_path, full_theme_path, FNLEN - 1);
+      DEBUGCODE
+      {
+        fprintf(stderr, "settings.theme_data_path is: %s\n", settings.theme_data_path);
+      }
+ 
+      strncpy(settings.theme_name, theme_dir, FNLEN - 1);
+      /* (Need to do this in case we are changing from a theme with */
+      /* a special font to a theme that uses the default, but lacks */
+      /* an explicit statement to use the default(                  */
+      strncpy(settings.theme_font_name, DEFAULT_MENU_FONT, FNLEN);
+
+      /* Load fontname or any other theme-specific settings: */
+      sprintf(theme_settings_path, "%s/settings.txt", full_theme_path);
+
+      DEBUGCODE
+      {
+        fprintf(stderr, "theme_settings_path is: %s\n", theme_settings_path);
+      }
+
+      load_settings_filename(theme_settings_path);
+    }
+    else /* Theme not found! */
+    {
+      settings.use_english = 1; // default is to use English if we cannot find theme
+      strcpy(settings.theme_name, "");
+      strncpy(settings.theme_font_name, DEFAULT_MENU_FONT, FNLEN);
+      fprintf(stderr, "SetupPaths(): could not find '%s'\n", full_theme_path);
+    }
+  }
+  else /* No theme name passed as arg so just use English: */
+  {
+    settings.use_english = 1; // default is to use English if we cannot find theme
+    strcpy(settings.theme_name, "");
+  }
+
+
+  DEBUGCODE
+  {
+    fprintf(stderr, "Leaving SetupPaths():\n");
+    fprintf(stderr, "default_data_path: '%s'\n", settings.default_data_path);
+    fprintf(stderr, "theme_data_path: '%s'\n\n", settings.theme_data_path);
+  }
+  return 1;	
+}
+
+
+void Cleanup(void)
+{
+  SDL_FreeSurface(screen);
+  screen = NULL;
+
+  SDL_Quit();
+  TTF_Quit();
+}

Added: tuxtype/branches/tuxtype-new/src/snow.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/snow.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/snow.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,272 @@
+/***************************************************************************
+ -  file: snow.c
+ -  description: this file contains snow for the cascade game
+-------------------
+begin                : March 12, 2003
+copyright            : (C) 2003 Jesse Andrews
+email                : tuxtype-dev at tux4kids.net
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************/
+
+#include <stdlib.h>
+#include "SDL.h"
+
+/* while it looks like you can just
+ * change the number of planes, flakes,
+ * etc and it will work all right, it is not
+ * true.  Do not fiddle with number unless you
+ * change the rest of the code to be the same!
+ */
+
+#define NUM_PLANES 3
+
+extern SDL_Surface *screen;
+SDL_Surface* bkg;
+
+Uint16 snow_color;
+
+int wind = 0;
+int SNOW_on = 0;
+
+int NUM_FLAKES = 300;
+int PER_PLANE = 100; // should equal NUM_FLAKES/NUM_PLANES
+
+/* to get the real x location divide by 8 (>>3)
+ */
+struct {
+	int x;
+	int y;
+} flake[300];
+
+/* used for the SDL_UpdateRects */
+SDL_Rect SNOW_rects[1000];
+
+/* pass add_wind +/- 1 --- it just adds a fraction in that direction! */
+void add_wind( int dir ) {
+
+	/* don't let the wind blow too hard */
+	if ( wind * dir > 16 )
+		return;
+	
+	if (dir > 0)
+		wind++;
+	else
+		wind--;
+}
+
+/* ### INTERNAL FUNCTION ### 
+ * move_snow: updates the location of the flakes
+ * based upon the wind and different "planes"
+ * of the flakes
+ */
+void move_snow(void) {
+	int i;
+	static int slowframe=1;
+	int ws=wind;
+
+	slowframe = !slowframe;
+	/* even though we only move the "slowest" every other frame,
+	 * the code is still updating them every single frame!!!
+	 * the SNOW_Rect data structure will need to be updated to fix this!
+	 * slowframe just cycles between updating the slowest and not!
+	 */
+	if (slowframe) {
+		for (i = 0; i<PER_PLANE; i++) {
+			flake[i].x += ws;
+			flake[i].y ++;
+		}
+	}
+
+	for (i = PER_PLANE; i<PER_PLANE<<1; i++) {
+		flake[i].x += ws;
+		flake[i].y += 1;
+	}
+
+	ws<<=1;
+	for (i = PER_PLANE<<1; i<NUM_FLAKES; i++) {
+		flake[i].x += ws;
+		flake[i].y += 2;
+	} 
+
+	for (i = 0; i<NUM_FLAKES; i++) {
+		/* if a flake hits the bottom, move to top randomly */
+		if (flake[i].y >= 478) {
+			flake[i].y = 0;
+			flake[i].x = (int)(8*639.0*rand()/(RAND_MAX+1.0));
+		}
+
+		/* if a flake hists the edge, move to the other edge randomly */
+		if (flake[i].x >= 638<<3) {
+			flake[i].x = 0;
+			flake[i].y = (int)(478.0*rand()/(RAND_MAX+1.0));
+		} else if (flake[i].x < 0) {
+			flake[i].x = 8*637;
+			flake[i].y = (int)(478.0*rand()/(RAND_MAX+1.0));
+		}
+
+		/* the first NUM_FLAKES are for erasing the last frame's FLAKES */
+		SNOW_rects[i].x = SNOW_rects[NUM_FLAKES+i].x;
+		SNOW_rects[i].y = SNOW_rects[NUM_FLAKES+i].y;
+		/* the next NUM_FLAKES are for bliting the new positions this frame */
+		SNOW_rects[NUM_FLAKES+i].x = flake[i].x>>3;
+		SNOW_rects[NUM_FLAKES+i].y = flake[i].y;
+	}
+}
+
+/* SNOW_draw: updates the screen surface
+ * with the new flake pixels
+ * note: y<<9 + y<<7 is short for y*640
+ */
+void SNOW_draw(void) {
+	int i;
+	Uint16 *to;
+
+	/* we only draw if we are on and haven't toggled (see SNOW_Erase for more info */
+	if (SNOW_on!=1)
+		return;
+
+	for (i=0; i<NUM_FLAKES; i++) {
+		to = screen->pixels;
+		to += (SNOW_rects[NUM_FLAKES+i].y<<9) + (SNOW_rects[NUM_FLAKES+i].y<<7) + SNOW_rects[NUM_FLAKES+i].x;
+		*to = snow_color;
+		to += 1;
+		*to = snow_color;
+		to += 640;
+		*to = snow_color;
+		to -= 1;
+		*to = snow_color;
+	}
+}
+
+/* SNOW_erase: updates the screen surface
+ * by replacing the previous flakes with
+ * the background image (set via SNOW_setBkg).
+ * This should be run before bliting any
+ * graphics to the screen so you don't over-
+ * write good images with background!
+ *
+ * note: y<<9 + y<<7 is short for y*640
+ */
+void SNOW_erase(void) {
+	int i;
+	Uint16 *from, *to;
+
+	if (!SNOW_on)
+		return;
+
+	/* SNOW_on isn't a boolean variable, it is really
+	 * holding the state:
+	 *  0 means no snow
+	 *  1 means snow
+	 *  2 means the user has requested snowing to stop
+	 *          we cannot just stop snowing since we
+	 *          need to erase the previous frames snow
+	 *  3 means have erased the snow during the previous
+	 *          frame and can go back to waiting for
+	 *          snow to be turned on
+	 */
+	if (SNOW_on>1) {
+		if (SNOW_on == 3)
+			SNOW_on = 0;
+		else
+			SNOW_on++;
+	}
+
+	for (i=0; i<NUM_FLAKES; i++) {
+		to = screen->pixels;
+		from = bkg->pixels;
+		to += (SNOW_rects[i].y<<9) + (SNOW_rects[i].y<<7) + SNOW_rects[i].x;
+		from += (SNOW_rects[i].y<<9) + (SNOW_rects[i].y<<7) + SNOW_rects[i].x;
+		*to = *from;
+		to += 1;
+		from += 1;
+		*to = *from;
+		to += 640;
+		from += 640;
+		*to = *from;
+		to -= 1;
+		from -= 1;
+		*to = *from;
+	}
+}
+
+/* SNOW_setBkg: we need to have the  background
+ * to erase snow flakes every frame
+ */
+void SNOW_setBkg( SDL_Surface *img ) {
+	bkg = img;
+}
+
+/* SNOW_add: this adds the other rectangles that we need 
+ * to update on the screen to the list and returns
+ * the total number of items on the complete list
+ * (flakes & regular stuff)
+ */
+int SNOW_add( SDL_Rect *rs, int num ){
+	int i;
+	for (i=0; i<num; i++) {
+		SNOW_rects[(NUM_FLAKES<<1)+i].x = rs[i].x;
+		SNOW_rects[(NUM_FLAKES<<1)+i].y = rs[i].y;
+		SNOW_rects[(NUM_FLAKES<<1)+i].w = rs[i].w;
+		SNOW_rects[(NUM_FLAKES<<1)+i].h = rs[i].h;
+	}
+	return num + (NUM_FLAKES<<1);
+}
+
+/* SNOW_init: initing the snow "library" envoles
+ * seting up the color for the snow, the inital
+ * locations for the flakes and the size of the
+ * snow rectangles
+ */
+void SNOW_init( void ) {
+
+	int i;
+
+	snow_color = SDL_MapRGB( screen->format, 255, 255, 255 );
+	for (i=0; i<NUM_FLAKES; i++) {
+		flake[i].x = (int)(8*638.0*rand()/(RAND_MAX+1.0));
+		flake[i].y = (int)(480.0*rand()/(RAND_MAX+1.0));
+	}
+	for (i=0; i<2*NUM_FLAKES; i++) {
+		SNOW_rects[i].w = 2;
+		SNOW_rects[i].h = 2;
+	}
+}
+
+/* SNOW_toggle: toggles the snow on and off.
+ * see SNOW_erase for a discription of what
+ * SNOW_on means
+ */
+void SNOW_toggle( void ) {
+	SNOW_on ++;
+}
+
+/* SNOW_update: update the wind with
+ * a 10% prob of blowing further left
+ * a 10% prob of blowing further right
+ * and 80% of not changing.
+ * AFTER updating the wind, we move all
+ * the snow
+ */
+void SNOW_update( void ) {
+	int rand_tmp = (int)(10.0*rand()/(RAND_MAX+1.0));
+
+	if (!SNOW_on)
+		return;
+
+	if (rand_tmp == 0)
+		add_wind(-1);
+	else if (rand_tmp == 1)
+		add_wind(+1);
+	
+	move_snow();
+}
+

Added: tuxtype/branches/tuxtype-new/src/snow.h
===================================================================
--- tuxtype/branches/tuxtype-new/src/snow.h	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/snow.h	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,9 @@
+extern int SNOW_on;
+extern SDL_Rect SNOW_rects[2000];
+extern int SNOW_add( SDL_Rect *rs, int num );
+extern void SNOW_toggle( void );
+extern void SNOW_draw( void );
+extern void SNOW_erase( void );
+extern void SNOW_setBkg( SDL_Surface *img );
+extern void SNOW_init( void );
+extern void SNOW_update( void );

Added: tuxtype/branches/tuxtype-new/src/theme.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/theme.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/theme.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,287 @@
+/***************************************************************************
+                          theme.c 
+ -  description: theme related code
+                             -------------------
+    begin                : Jan 6 2003
+    copyright            : (C) 2003 by Jesse Andrews et al
+    email                : jdandr2 at tux4kids.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+
+
+SDL_Surface* letters[255] = {NULL}; //get rid of this
+wchar_t ALPHABET[256];
+int ALPHABET_SIZE;
+
+
+#define MAX_LANGUAGES 100
+
+
+
+void ChooseTheme(void)
+{
+  SDL_Surface* titles[MAX_LANGUAGES] = {NULL};
+  SDL_Surface* select[MAX_LANGUAGES] = {NULL};
+  SDL_Surface* left = NULL, *right = NULL;
+  SDL_Rect leftRect, rightRect;
+  SDL_Surface* world = NULL, *map = NULL, *photo = NULL;
+  SDL_Surface* bkg = NULL;
+  TTF_Font* font = NULL;
+  SDL_Rect worldRect, photoRect;
+  SDL_Rect titleRects[8];
+  int stop = 0;
+  int loc = 0;
+  int old_loc = 1;
+
+  int themes = 1;
+  int i;
+  unsigned char fn[FNLEN];
+  unsigned char themeNames[MAX_LANGUAGES][FNLEN];
+  unsigned char themePaths[MAX_LANGUAGES][FNLEN];
+
+  int old_use_english;
+  char old_theme_path[FNLEN];
+
+  DIR* themesDir = NULL;
+  struct dirent* themesFile = NULL;
+
+  /* save previous settings in case we back out: */
+  old_use_english = settings.use_english;
+  strncpy(old_theme_path, settings.theme_data_path, FNLEN - 1);
+
+  sprintf(fn, "%s/themes/", settings.default_data_path);
+  themesDir = opendir(fn);
+
+  if (!themesDir)
+  {
+    fprintf(stderr, "ChooseTheme() - cannot open themes directory!");
+    return;
+  }
+
+  do
+  {
+    themesFile = readdir(themesDir);
+    if (!themesFile)
+			break;
+
+		/* we ignore any hidden file and CVS */
+
+		if (themesFile->d_name[0] == '.') 
+			continue;
+
+		if (strcmp("CVS", themesFile->d_name)==0)
+			continue;
+
+		/* check to see if it is a directory */
+		sprintf(fn, "%s/themes/%s", settings.default_data_path, themesFile->d_name);
+
+
+		/* CheckFile() returns 2 if dir, 1 if file, 0 if neither: */
+		if (CheckFile(fn) == 2) {
+		    /* HACK: we should get the names from file :) */
+		    strncpy( themeNames[themes], themesFile->d_name, FNLEN-1);
+		    /* Make sure theme name is capitalized: */
+                    themeNames[themes][0] = toupper(themeNames[themes][0]);
+		    strncpy( themePaths[themes++], themesFile->d_name, FNLEN-1 );
+		}
+	} while (1);
+
+	closedir(themesDir);
+
+	settings.use_english = 1;
+        // HACK: is font empty now???
+	font = LoadFont(settings.theme_font_name, MENU_FONT_SIZE);
+
+	titles[0] = BlackOutline( "English", font, &white );
+	select[0] = BlackOutline( "English", font, &yellow);
+	for (i = 1; i<themes; i++) {
+		titles[i] = BlackOutline( themeNames[i], font, &white );
+		select[i] = BlackOutline( themeNames[i], font, &yellow);
+	}
+
+	world = LoadImage("world.png", IMG_ALPHA);
+	worldRect.x = 480 - (world->w/2);
+	worldRect.w = world->w;
+	worldRect.y = 10;
+	worldRect.h = world->h;
+
+	
+
+	TTF_CloseFont(font);
+        font = NULL;
+
+	settings.use_english = old_use_english;
+
+	bkg = LoadImage("main_bkg.png", IMG_REGULAR);
+
+	left = LoadImage("left.png", IMG_ALPHA);
+	leftRect.w = left->w; leftRect.h = left->h;
+	leftRect.x = 160 - 80 - (leftRect.w/2); leftRect.y = 430;
+
+	right = LoadImage("right.png", IMG_ALPHA);
+	rightRect.w = right->w; rightRect.h = right->h;
+	rightRect.x = 160 + 80 - (rightRect.w/2); rightRect.y = 430;
+
+	/* set initial rect sizes */
+	titleRects[0].y = 30;
+	titleRects[0].w = titleRects[0].h = titleRects[0].x = 0;
+	for (i = 1; i<8; i++) {
+		titleRects[i].y = titleRects[i-1].y + 50;
+		titleRects[i].w = titleRects[i].h = titleRects[i].x = 0;
+	}
+	
+
+	while (!stop) {
+		while (SDL_PollEvent(&event)) 
+			switch (event.type) {
+				case SDL_QUIT:
+					exit(0);
+					break;
+				case SDL_MOUSEMOTION: 
+					for (i=0; (i<8) && (loc-(loc%8)+i<themes); i++)
+						if (inRect( titleRects[i], event.motion.x, event.motion.y )) {
+							loc = loc-(loc%8)+i;
+							break;
+						}
+					
+					break;
+				case SDL_MOUSEBUTTONDOWN: 
+					if (inRect( leftRect, event.button.x, event.button.y )) 
+						if (loc-(loc%8)-8 >= 0) {
+							loc=loc-(loc%8)-8;
+							break;
+						}
+					if (inRect( rightRect, event.button.x, event.button.y )) 
+						if (loc-(loc%8)+8 < themes) {
+							loc=loc-(loc%8)+8;
+							break;
+						}
+					for (i=0; (i<8) && (loc-(loc%8)+i<themes); i++) 
+						if (inRect(titleRects[i], event.button.x, event.button.y)) {
+							loc = loc-(loc%8)+i;
+							if (loc) {
+								/* --- set theme --- */
+								SetupPaths(themePaths[loc]);
+							} else {
+								/* --- english --- */
+								SetupPaths(NULL);
+							}
+							stop = 1;
+							break;
+						}
+					break;
+				case SDL_KEYDOWN:
+					if (event.key.keysym.sym == SDLK_ESCAPE) { 
+						settings.use_english = old_use_english;
+						strncpy(settings.theme_data_path, old_theme_path, FNLEN - 1);
+						stop = 1; 
+						break; 
+					}
+					if (event.key.keysym.sym == SDLK_RETURN) { 
+						if (loc) {
+							/* --- set theme --- */
+							SetupPaths(themePaths[loc]);
+						} else {
+							/* --- english --- */
+							SetupPaths(NULL);
+						}
+						stop = 1;
+						break;
+					}
+
+					if ((event.key.keysym.sym == SDLK_LEFT) || (event.key.keysym.sym == SDLK_PAGEUP)) {
+						if (loc-(loc%8)-8 >= 0) 
+							loc=loc-(loc%8)-8;
+					}
+
+					if ((event.key.keysym.sym == SDLK_RIGHT) || (event.key.keysym.sym == SDLK_PAGEDOWN)) {
+						if (loc-(loc%8)+8 < themes)
+							loc=(loc-(loc%8)+8);
+					}
+
+
+					if (event.key.keysym.sym == SDLK_UP) {
+						if (loc > 0)
+							loc--;
+					}
+
+					if (event.key.keysym.sym == SDLK_DOWN) {
+						if (loc+1<themes)
+							loc++;
+					}
+			}
+
+		if (old_loc != loc) {
+			int start;
+
+			SDL_BlitSurface( bkg, NULL, screen, NULL );
+
+			SDL_BlitSurface( world, NULL, screen, &worldRect );
+
+		        if (loc) SetupPaths(themePaths[loc]); else SetupPaths(NULL);
+
+			map = LoadImage( "map.png", IMG_ALPHA|IMG_NOT_REQUIRED );
+			if (map) {
+				SDL_BlitSurface( map, NULL, screen, &worldRect );
+				SDL_FreeSurface( map );
+			}
+
+			photo = LoadImage( "photo.png", IMG_ALPHA|IMG_NOT_REQUIRED );
+			if (photo) {
+				photoRect.x = 480 - (photo->w/2);
+				photoRect.y = 250;
+				photoRect.w = photo->w;
+				photoRect.h = photo->h;
+				SDL_BlitSurface( photo, NULL, screen, &photoRect );
+				SDL_FreeSurface( photo );
+			}
+
+			start = loc - (loc % 8);
+			for (i = start; i<MIN(start+8,themes); i++) {
+				titleRects[i%8].x = 160 - (titles[i]->w/2);
+				if (i == loc)
+					SDL_BlitSurface(select[loc], NULL, screen, &titleRects[i%8]);
+				else
+					SDL_BlitSurface(titles[i], NULL, screen, &titleRects[i%8]);
+			}
+
+			/* --- draw buttons --- */
+
+			if (start>0) 
+				SDL_BlitSurface( left, NULL, screen, &leftRect );
+
+			if (start+8<themes) 
+				SDL_BlitSurface( right, NULL, screen, &rightRect );
+
+			SDL_UpdateRect(screen, 0, 0, 0 ,0);
+		}
+		SDL_Delay(40);
+		old_loc = loc;
+  }
+
+  /* --- clear graphics before quitting --- */ 
+
+  for (i = 0; i<themes; i++)
+  {
+    SDL_FreeSurface(titles[i]);
+    SDL_FreeSurface(select[i]);
+  }
+
+  SDL_FreeSurface(world);
+  SDL_FreeSurface(bkg);
+  SDL_FreeSurface(left);
+  SDL_FreeSurface(right);
+  bkg = NULL;  /* the other pointers are going out of scope so we don't */
+               /* have to worry about setting them to NULL              */
+}

Added: tuxtype/branches/tuxtype-new/src/titlescreen.c
===================================================================
--- tuxtype/branches/tuxtype-new/src/titlescreen.c	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/titlescreen.c	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,1505 @@
+/***************************************************************************
+ -  file: titlescreen.c
+ -  description: splash, title and menu screen functionality 
+                            ------------------
+    begin                : Thur May 4 2000
+    copyright            : (C) 2000 by Sam Hart
+                         : (C) 2003 by Jesse Andrews
+    email                : tuxtype-dev at tux4kids.net
+***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "globals.h"
+#include "funcs.h"
+#include "titlescreen.h"
+
+/* --- media for menus --- */
+
+/* images of regular and selected text of menu items: */
+static SDL_Surface* reg_text[TITLE_MENU_ITEMS + 1][TITLE_MENU_DEPTH + 1] = {NULL};
+static SDL_Surface* sel_text[TITLE_MENU_ITEMS + 1][TITLE_MENU_DEPTH + 1] = {NULL};
+static sprite* reg = NULL;
+static sprite* sel = NULL;
+/* this will contain pointers to all of the menu 'icons' */
+static sprite* menu_gfx[TITLE_MENU_ITEMS + 1][TITLE_MENU_DEPTH + 1] = {NULL};
+/* keep track of the width of each menu: */
+static int menu_width[TITLE_MENU_DEPTH + 1];
+
+/* NOTE for 'depth', think pages like a restaurant menu, */
+/* not heirarchical depth - choice of term is misleading */
+static int menu_depth; // how deep we are in the menu
+//int menu_sound; // status of menu sound effects
+//int menu_music; // status of menu sound effects
+
+/* --- other media --- */
+static SDL_Surface* bkg = NULL;
+static SDL_Surface* title = NULL;
+static SDL_Surface* speaker = NULL;
+static SDL_Surface* speakeroff = NULL;
+static sprite* Tux = NULL;
+static Mix_Chunk* snd_move = NULL;
+static Mix_Chunk* snd_select = NULL;
+static TTF_Font* font = NULL;
+
+/* --- locations we need --- */
+static SDL_Rect text_dst[TITLE_MENU_ITEMS + 1];     // location of text for menu
+static SDL_Rect menu_gfxdest[TITLE_MENU_ITEMS + 1]; // location of animated icon
+/* These are the rectangular mouse event "buttons" for each menu item */
+static SDL_Rect menu_button[TITLE_MENU_ITEMS + 1];  // size of "button"
+
+
+/* Local function prototypes: */
+static int chooseWordlist(void);
+static void draw_button(int id, sprite* s);
+static void not_implemented(void);
+static int load_media(void);
+static void load_menu(void);
+static void unload_media(void);
+static void unload_menu(void);
+
+/************************************************************************/
+/*                                                                      */ 
+/*         "Public" functions (callable throughout program)             */
+/*                                                                      */
+/************************************************************************/
+
+
+
+/****************************************
+* TitleScreen: Display the title screen *
+*****************************************
+* display title screen, get input
+*/
+void TitleScreen(void)
+{
+
+  SDL_Rect dest,
+	 Tuxdest,
+	 Titledest,
+	 spkrdest,
+	 cursor;
+
+  Uint32 frame = 0;
+  Uint32 start = 0;
+
+  int i, j, tux_frame = 0;
+  int done = 0;
+  int firstloop = 1;
+  int menu_opt = NONE;
+  int sub_menu = NONE;
+  int update_locs = 1;
+  int redraw = 0;
+  int key_menu = 1;
+  int old_key_menu = 5;
+  wchar_t phrase[128];
+
+
+  if (settings.sys_sound)
+  {
+    settings.menu_sound = 1;
+    settings.menu_music = 1;
+  }
+
+
+  /* FIXME phrase(s) should come from file */
+
+  ConvertFromUTF8(phrase, "Now is the time for all good men to come to the aid of their country.");
+//  ConvertFromUTF8(phrase, "To all that believe in his name he gave power to become children of God");
+
+//  wcscpy(phrase, "Now is the time for all good men to come to the aid of their country.");
+  start = SDL_GetTicks();
+
+
+  /*
+  * StandbyScreen: Display the Standby screen.... 
+  */
+
+  if (settings.show_tux4kids)
+  {
+    SDL_Surface* standby = NULL;
+    standby = LoadImage("standby.png", IMG_REGULAR|IMG_NO_THEME);
+
+    if (standby) /* Avoid segfault */
+    { 
+      dest.x = ((screen->w) / 2) - (standby->w) / 2;  // Center horizontally
+      dest.y = ((screen->h) / 2) - (standby->h) / 2;  // Center vertically
+      dest.w = standby->w;
+      dest.h = standby->h;
+
+      SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
+      SDL_BlitSurface(standby, NULL, screen, &dest);
+      SDL_UpdateRect(screen, 0, 0, 0, 0);
+      SDL_FreeSurface(standby);  // Unload image
+    }
+  }
+
+
+  /* Load media and menu data: */
+  if (!load_media())
+  {
+    fprintf(stderr, "TitleScreen - load_media() failed!");
+    return;
+  }
+
+  SDL_WM_GrabInput(SDL_GRAB_ON); // User input goes to TuxType, not window manager
+
+
+  /***************************
+  * Tux and Title animations *
+  ***************************/
+
+  LOG( "->Now Animating Tux and Title onto the screen\n" );
+
+  Tuxdest.x = 0;
+  Tuxdest.y = screen->h;
+  Tuxdest.w = Tux->frame[0]->w;
+  Tuxdest.h = Tux->frame[0]->h;
+
+  Titledest.x = screen->w;
+  Titledest.y = 10;
+  Titledest.w = title->w;
+  Titledest.h = title->h;
+
+  spkrdest.x = 520;
+  spkrdest.y = 420;
+  spkrdest.w = speaker->w;
+  spkrdest.h = speaker->h;
+
+  /* --- wait if the first time in the game --- */
+
+  if (settings.show_tux4kids)
+  {
+    while ((SDL_GetTicks() - start) < 2000)
+    {
+      SDL_Delay(50);
+    }
+    settings.show_tux4kids = 0;
+  }
+
+  SDL_ShowCursor(1);    
+  /* FIXME not sure the next line works in Windows: */
+  TransWipe(bkg, RANDOM_WIPE, 10, 20);
+  /* Make sure background gets drawn (since TransWipe() doesn't */
+  /* seem to work reliably as of yet):                          */
+  SDL_BlitSurface(bkg, NULL, screen, NULL);
+  SDL_UpdateRect(screen, 0, 0, 0, 0);
+
+  /* --- Pull tux & logo onscreen --- */
+  for (i = 0; i < (PRE_ANIM_FRAMES * PRE_FRAME_MULT); i++)
+  {
+    start = SDL_GetTicks();
+    SDL_BlitSurface(bkg, &Tuxdest, screen, &Tuxdest);
+    SDL_BlitSurface(bkg, &Titledest, screen, &Titledest);
+
+    Tuxdest.y -= Tux->frame[0]->h / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
+    Titledest.x -= (screen->w) / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
+
+    SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
+    SDL_BlitSurface(title, NULL, screen, &Titledest);
+
+    SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
+    SDL_UpdateRect(screen, Titledest.x, Titledest.y, Titledest.w+40, Titledest.h);
+
+    while ((SDL_GetTicks() - start) < 33) 
+    {
+      SDL_Delay(2);
+    }
+  }
+
+  SDL_BlitSurface(title, NULL, screen, &Titledest);
+
+  /* Pick speaker graphic according to whether music is on: */
+  if ( settings.menu_music )
+    SDL_BlitSurface(speaker, NULL, screen, &spkrdest);
+  else
+    SDL_BlitSurface(speakeroff, NULL, screen, &spkrdest);
+
+  /* Start playing menu music if desired: */
+  if (settings.menu_music)
+    MusicLoad( "tuxi.ogg", -1 );
+
+  LOG( "Tux and Title are in place now\n" );
+
+  /* Move mouse to top button: */
+  cursor.x = menu_button[1].x + (menu_button[1].w / 2);
+  cursor.y = menu_button[1].y + (3 * menu_button[1].h / 4);
+  SDL_WarpMouse(cursor.x, cursor.y);
+  SDL_WM_GrabInput(SDL_GRAB_OFF);
+
+
+
+  /****************************
+  * Main Loop Starts Here ... *
+  ****************************/
+
+
+  menu_depth = 1;
+  firstloop = 1;
+  Tuxdest.y = screen->h - Tux->frame[0]->h;
+
+
+  while (!done) 
+  {
+
+    start=SDL_GetTicks();
+
+    /* ---process input queue --- */
+
+    menu_opt = NONE; // clear the option so we don't change twice!
+
+    old_key_menu = key_menu;
+
+    /* Retrieve any user interface events: */
+    while (SDL_PollEvent(&event))
+    {
+      switch (event.type)
+      {
+
+        case SDL_MOUSEMOTION:
+        {
+          cursor.x = event.motion.x;
+          cursor.y = event.motion.y;
+          break;
+        }
+
+
+        /* Handle mouse clicks based on mouse location: */
+        case SDL_MOUSEBUTTONDOWN:
+        {
+          cursor.x = event.motion.x;
+          cursor.y = event.motion.y;
+
+          for (j = 1; j <= TITLE_MENU_ITEMS; j++)
+          {
+            if ((cursor.x >= menu_button[j].x && cursor.x <= (menu_button[j].x + menu_button[j].w)) && 
+                (cursor.y >= menu_button[j].y && cursor.y <= (menu_button[j].y + menu_button[j].h)))
+            {
+              menu_opt = menu_item[j][menu_depth];
+              if (settings.menu_sound)
+              {
+                PlaySound(snd_select);
+              }
+              DEBUGCODE
+              {
+                fprintf(stderr, "->>BUTTON CLICK menu_opt = %d\n", menu_opt);
+                fprintf(stderr, "->J = %d menu_depth=%d\n", j, menu_depth);
+              }
+            }
+          }
+
+          /* If mouse over speaker, toggle menu music off or on: */
+          if ((cursor.x >= spkrdest.x && cursor.x <= (spkrdest.x + spkrdest.w)) && 
+              (cursor.y >= spkrdest.y && cursor.y <= (spkrdest.y + spkrdest.h)))
+          {
+            if (settings.menu_music)
+            {
+              MusicUnload();
+              settings.menu_music = 0;
+            }
+            else
+            {
+              settings.menu_music = 1;
+              MusicLoad("tuxi.ogg", -1);
+            }
+            redraw = 1;
+          }
+          break;
+        }
+
+
+
+        case SDL_QUIT:
+        {
+          menu_opt = QUIT_GAME;
+          break;
+        }
+
+
+        /* Handle key press events based on key value: */
+        case SDL_KEYDOWN:
+        {
+          switch (event.key.keysym.sym)
+          {
+            case SDLK_ESCAPE:
+            {
+              /* Go to main menu (if in submenu) or quit: */
+              if (menu_depth != 1) 
+                menu_opt = MAIN;
+              else
+                menu_opt = QUIT_GAME;
+
+              if (settings.menu_sound)
+                PlaySound(snd_select);
+              break;
+            }
+
+
+            /* Toggle screen mode: */
+            case SDLK_F10:
+            {
+              SwitchScreenMode();
+              redraw = 1;
+              break;
+            }
+
+
+            /* Toggle menu music: */
+            case SDLK_F11:
+            {
+              if (settings.menu_music)
+              {
+                MusicUnload( );
+                settings.menu_music=0;
+              }
+              else
+              {
+                settings.menu_music=1;
+                MusicLoad("tuxi.ogg", -1);
+              }
+              redraw = 1;
+              break;
+            }
+
+
+            /* --- reload translation/graphics/media: for themers/translaters --- */
+            case SDLK_F12:
+            {
+              unload_media();
+              LoadLang();
+              load_media();
+              redraw = 1;
+              break;
+            }
+
+
+            case SDLK_UP:
+            {
+              if (settings.menu_sound)
+                PlaySound(snd_move);
+              key_menu--;
+              if (key_menu < 1)
+                key_menu = 5;
+              break;
+            }
+
+
+            case SDLK_DOWN:
+            {
+              key_menu++;
+              if (settings.menu_sound)
+                PlaySound(snd_move);
+              if (key_menu > 5)
+                key_menu = 1;
+              break;
+            }
+
+
+            case SDLK_RETURN:
+            {
+              if (key_menu)
+              {
+                menu_opt = menu_item[key_menu][menu_depth];
+                if (settings.menu_sound)
+                  PlaySound(snd_select);
+              }
+              break;
+            }
+
+
+            default:     /* Some other key pressed - do nothing: */
+            {
+              break;
+            }
+          }             /* End of switch(event.key.keysym.sym) statement */
+        }               /* End of case: SDL_KEYDOWN: */
+
+
+        default:        /* Some other type of SDL event - do nothing;    */
+        {
+          break;
+        }
+      }                 /* End of switch(event.type) statement           */
+    }	              /* End of while (SDL_PollEvent(&event)) loop     */
+
+
+
+    /* --- warp mouse to follow keyboard input --- */
+
+    if (old_key_menu != key_menu)
+    {
+      cursor.x = menu_button[key_menu].x + (menu_button[key_menu].w / 2);
+      cursor.y = menu_button[key_menu].y + (3 * menu_button[key_menu].h / 4);
+      SDL_WarpMouse(cursor.x, cursor.y);
+    }
+
+
+
+    /* --- do menu processing --- */
+
+
+    if (menu_opt == QUIT_GAME)
+      done = 1;
+
+
+    if (menu_opt == LASER)
+    {
+      menu_depth = LASER_SUBMENU;
+      sub_menu = LASER;
+      update_locs = 1;
+      redraw = 1;
+    }
+
+
+    if (menu_opt == CASCADE)
+    {
+      menu_depth = CASCADE_SUBMENU;
+      sub_menu = CASCADE;
+      update_locs = 1;
+      redraw=1;
+    }
+
+
+    if (menu_opt == OPTIONS)
+    {
+      menu_depth = OPTIONS_SUBMENU;
+      sub_menu = OPTIONS;
+      update_locs = 1;
+      redraw = 1;
+    }
+
+
+    if (menu_opt == MAIN)
+    {
+      menu_depth = ROOTMENU;
+      update_locs = 1;
+      redraw = 1;
+    }
+
+
+    if (menu_opt == NOT_CODED)
+    {
+      not_implemented();
+      redraw = 1;
+    }
+
+
+    if (menu_opt == PROJECT_INFO)
+    {
+      ProjectInfo();
+      redraw = 1;
+    }
+
+
+    if (menu_opt == LESSONS)
+    {
+      SDL_BlitSurface(bkg, NULL, screen, NULL);
+      SDL_Flip( screen );
+      unload_media();
+
+      if (settings.menu_music)
+        MusicUnload( );
+
+      TestLesson();
+
+      load_media();
+      redraw = 1;
+
+      if (settings.menu_music)
+        MusicLoad( "tuxi.ogg", -1 );
+    }
+
+
+    if (menu_opt == SET_LANGUAGE)
+    {
+      unload_media();
+      ChooseTheme();
+      LoadLang();
+      LoadKeyboard();
+      load_media();
+      redraw = 1;
+
+      if (settings.menu_music)
+        MusicLoad( "tuxi.ogg", -1 );
+    }
+
+
+    if (menu_opt == LEVEL1)
+    {  
+      if (chooseWordlist()) 
+      {
+        unload_media();
+
+        switch (sub_menu)
+        {
+          case CASCADE: PlayCascade( EASY ); break;
+          case LASER:   PlayLaserGame(  EASY ); break;
+        }
+      }
+
+      load_media();
+
+      if (settings.menu_music)
+        MusicLoad("tuxi.ogg", -1);
+
+      redraw = 1;
+    }
+
+
+    if (menu_opt == LEVEL2)
+    {
+      if (chooseWordlist())
+      {
+        unload_media();
+
+        switch (sub_menu)
+        {
+          case CASCADE: PlayCascade( MEDIUM ); break;
+          case LASER:   PlayLaserGame(  MEDIUM ); break;
+        }
+
+
+        if (settings.menu_music)
+          MusicLoad( "tuxi.ogg", -1 );
+      }
+
+      load_media();
+      redraw = 1;
+    }
+
+
+
+    if (menu_opt == LEVEL3)
+    {
+      if (chooseWordlist())
+      {
+        unload_media();
+
+        switch (sub_menu)
+        {
+          case CASCADE: PlayCascade( HARD ); break;
+          case LASER:   PlayLaserGame(  HARD ); break;
+        }
+
+
+        if (settings.menu_music)
+          MusicLoad( "tuxi.ogg", -1 );
+      }
+
+      load_media();
+      redraw = 1;
+    }
+
+
+
+    if (menu_opt == LEVEL4)
+    {
+      if (chooseWordlist())
+      {
+        unload_media();
+
+        switch (sub_menu)
+        {
+          case CASCADE: PlayCascade( INSANE ); break;
+          case LASER:   PlayLaserGame(  INSANE ); break;
+        }
+
+        if (settings.menu_music)
+          MusicLoad( "tuxi.ogg", -1 );
+      }
+
+      load_media();
+      redraw = 1;
+    }
+
+
+
+    if (menu_opt == INSTRUCT)
+    {
+      unload_media();
+
+      switch (sub_menu)
+      {
+        case CASCADE: InstructCascade(); break;
+        case LASER:   InstructLaser();   break;
+      }
+
+      load_media();
+
+      if (settings.menu_music)
+        MusicLoad( "tuxi.ogg", -1 );
+
+      redraw = 1;
+    }
+
+
+
+    if (menu_opt == FREETYPE)
+    {
+      unload_media();
+      Phrases( phrase );
+      //Practice();
+      load_media();
+      redraw = 1;
+    }
+
+    /* ------ End menu_opt processing ----------- */
+
+
+
+    if (redraw)
+    {
+      LOG("TitleScreen() - redraw requested\n");
+
+      SDL_BlitSurface(bkg, NULL, screen, NULL); 
+      SDL_BlitSurface(title, NULL, screen, &Titledest);
+
+      if ( settings.menu_music )
+        SDL_BlitSurface(speaker, NULL, screen, &spkrdest);
+      else
+        SDL_BlitSurface(speakeroff, NULL, screen, &spkrdest);
+
+      /* Screen will be updated due to update_locs - see ~30 lines down: */
+//      SDL_UpdateRect(screen, 0, 0, 0, 0);
+      frame = redraw = 0;   // so we redraw tux
+      update_locs = 1;      // so we redraw menu
+      firstloop = 1;
+    }
+
+
+
+    /* --- create new menu screen when needed --- */
+
+    if (update_locs)
+    {
+      LOG("TitleScreen() - update_locs requested\n");
+
+      /* --- erase the last menu --- */
+      for (i = 1; i <= TITLE_MENU_ITEMS; i++)
+      {
+        text_dst[i].x = 290;
+        text_dst[i].w = reg_text[i][menu_depth]->w;
+        text_dst[i].h = reg_text[i][menu_depth]->h;
+        SDL_BlitSurface(bkg, &menu_button[i], screen, &menu_button[i]);
+        menu_button[i].w = menu_width[menu_depth] + (2*reg->frame[2]->w);
+      }
+
+
+      update_locs = 0;
+
+      /* --- draw the full menu --- */
+
+      for (j = 1; j <= TITLE_MENU_ITEMS; j++)
+      {
+        DOUT(j);
+        draw_button(j, reg);
+        if (reg_text[j][menu_depth] != NULL)
+          SDL_BlitSurface(reg_text[j][menu_depth], NULL, screen, &text_dst[j]);
+        if (menu_gfx[j][menu_depth] != NULL)
+          SDL_BlitSurface(menu_gfx[j][menu_depth]->default_img, NULL, screen, &menu_gfxdest[j]);
+      }
+
+      SDL_UpdateRect(screen, 0, 0, 0, 0);
+
+      LOG("TitleScreen() - update_locs completed\n");
+    }
+
+
+
+    /* --- make tux blink --- */
+
+    switch (frame % TUX6)
+    {
+      case 0:    tux_frame = 1; break;
+      case TUX1: tux_frame = 2; break;
+      case TUX2: tux_frame = 3; break;
+      case TUX3: tux_frame = 4; break;			
+      case TUX4: tux_frame = 3; break;
+      case TUX5: tux_frame = 2; break;
+      default: tux_frame = 0;
+    }
+
+    if (tux_frame)
+    {
+      SDL_BlitSurface(bkg, &Tuxdest, screen, &Tuxdest);
+      SDL_BlitSurface(Tux->frame[tux_frame - 1], NULL, screen, &Tuxdest);
+    }
+
+
+    /* --- check if mouse is in a menu option --- */
+
+    key_menu = 0;
+
+    for (j = 1; j <= TITLE_MENU_ITEMS; j++)
+    {
+      if ((cursor.x >= menu_button[j].x && cursor.x <= (menu_button[j].x + menu_button[j].w)) &&
+          (cursor.y >= menu_button[j].y && cursor.y <= (menu_button[j].y + menu_button[j].h)))
+      {
+        key_menu = j; // update menu to point
+        break;        // Don't need to check rest of menu
+      }
+    }
+
+
+    /* --- return old selection to unselected state --- */
+
+    if (old_key_menu && (key_menu != old_key_menu))
+    {
+      SDL_BlitSurface(bkg, &menu_button[old_key_menu], screen, &menu_button[old_key_menu]);
+      draw_button( old_key_menu, reg );
+      SDL_BlitSurface(reg_text[old_key_menu][menu_depth], NULL, screen, &text_dst[old_key_menu]);
+      SDL_BlitSurface(menu_gfx[old_key_menu][menu_depth]->default_img, NULL, screen, &menu_gfxdest[old_key_menu]);
+    }
+
+
+    /* --- draw current selection --- */
+
+    if ((key_menu != 0) &&
+       ((old_key_menu != key_menu) || (frame % 5 == 0))) // Redraw every fifth frame?
+    {
+      if (key_menu != old_key_menu)
+      {
+        REWIND(menu_gfx[key_menu][menu_depth]);
+        PlaySound(snd_move);
+      }
+
+      SDL_BlitSurface(bkg, &menu_button[key_menu], screen, &menu_button[key_menu]);
+      draw_button( key_menu, sel );
+      SDL_BlitSurface(sel_text[key_menu][menu_depth], NULL, screen, &text_dst[key_menu]);
+      SDL_BlitSurface(menu_gfx[key_menu][menu_depth]->frame[menu_gfx[key_menu][menu_depth]->cur], NULL, screen, &menu_gfxdest[key_menu]);
+
+      NEXT_FRAME(menu_gfx[key_menu][menu_depth]);
+    }
+
+
+    // HACK This is still more than we need to update every frame but
+    // it cuts cpu on my machine %60 so it seems better...
+    if ( settings.menu_music )
+      SDL_BlitSurface(speaker, NULL, screen, &spkrdest);
+    else
+      SDL_BlitSurface(speakeroff, NULL, screen, &spkrdest);
+
+    SDL_UpdateRect(screen, spkrdest.x, spkrdest.y, spkrdest.w, spkrdest.h);
+
+    for ( i=1; i<6; i++ )
+    {
+      SDL_UpdateRect(screen, menu_button[i].x, menu_button[i].y, menu_button[i].w, menu_button[i].h);
+    }
+
+    if (tux_frame)
+      SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
+
+    if (firstloop)
+      SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
+
+    firstloop = 0;
+
+    /* Wait so we keep frame rate constant: */
+    while ((SDL_GetTicks() - start) < 33)
+    {
+      SDL_Delay(20);
+    }
+
+    frame++;
+  } /* ----------- End of 'while(!done)' loop ------------  */
+
+
+
+  LOG( "->>Freeing title screen images\n" );
+
+  unload_media();
+
+  LOG( "->TitleScreen():END \n" );
+}
+
+
+void SwitchScreenMode(void)
+{
+  SDL_Surface *tmp;
+  SDL_Rect src, dst;
+  int window=0;
+  src.x = 0; src.y = 0;
+  src.w = RES_X; src.h = RES_Y;
+  dst.x = 0; dst.y = 0;
+
+  tmp = SDL_CreateRGBSurface(
+      SDL_SWSURFACE,
+      RES_X,
+      RES_Y,
+      BPP,
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+      0xff000000,
+      0x00ff0000,
+      0x0000ff00,
+      0x000000ff
+#else
+      0x000000ff,
+      0x0000ff00,
+      0x00ff0000,
+      0xff000000
+#endif
+      );
+  if (screen->flags & SDL_FULLSCREEN)
+	window=1;
+  SDL_BlitSurface(screen,&src,tmp,&dst);
+  SDL_UpdateRect(tmp,0,0,RES_X,RES_Y);
+  SDL_FreeSurface(screen);
+  screen = NULL;
+
+  if ( window ){
+	screen = SDL_SetVideoMode(RES_X,RES_Y,BPP, SDL_SWSURFACE|SDL_HWPALETTE);
+  } else {
+	screen = SDL_SetVideoMode(RES_X,RES_Y,BPP, SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN);
+  }
+  SDL_BlitSurface(tmp,&src,screen,&dst);
+  SDL_UpdateRect(tmp,0,0,RES_X,RES_Y);
+  SDL_FreeSurface(tmp);
+
+  /* FIXME maybe settings.fullscreen should be updated by the */
+  /* calling function rather than here? */
+  settings.fullscreen = !settings.fullscreen;
+}
+
+
+/************************************************************************/
+/*                                                                      */ 
+/*       "Private" functions (local to titlescreen.c)                   */
+/*                                                                      */
+/************************************************************************/
+
+
+static void draw_button(int id, sprite* s) {
+	SDL_Rect button;
+
+	button.x = menu_button[id].x;
+	button.y = menu_button[id].y;
+	button.w = s->frame[0]->w;
+	button.h = s->frame[0]->h;
+	SDL_BlitSurface(s->frame[0], NULL, screen, &button);
+	button.w = s->frame[1]->w;
+	for (button.x += s->frame[0]->w; button.x < (menu_button[id].x + menu_width[menu_depth]); button.x += s->frame[1]->w) 
+		SDL_BlitSurface(s->frame[1], NULL, screen, &button);
+	button.w = s->frame[2]->w;
+	SDL_BlitSurface(s->frame[2], NULL, screen, &button);
+}
+
+static void load_menu(void)
+{
+  unsigned char fn[FNLEN];
+  int max, i, j;
+
+  SDL_ShowCursor(1);
+
+  LOG("loading & parsing menu\n");
+
+  for (j = 1; j <= TITLE_MENU_DEPTH; j++)  /* Each 'depth' is a different menu */
+  {
+    max = 0;
+    for (i = 1; i <= TITLE_MENU_ITEMS; i++)
+    {
+      DEBUGCODE
+      {
+        fprintf(stderr, "i = '%d'\tj = '%d'\ttext = '%s'\n",
+                i, j,  _((unsigned char*)menu_text[i][j]));
+      }
+
+      /* --- create text surfaces --- */
+      reg_text[i][j] = BlackOutline( _((unsigned char*)menu_text[i][j]), font, &white);
+      sel_text[i][j] = BlackOutline( _((unsigned char*)menu_text[i][j]), font, &yellow);
+
+      /* (first make sure ptr valid to avoid segfault) */
+      if (sel_text[i][j] && sel_text[i][j]->w > max)
+        max = sel_text[i][j]->w;
+
+      /* --- load animated icon for menu item --- */
+      sprintf(fn, "menu/%s", menu_icon[i][j]);
+      menu_gfx[i][j] = LoadSprite(fn, IMG_ALPHA);
+    }
+    menu_width[j] = max + 20 + 40; // Not clear where '20' and '40' are coming from
+  }
+
+  LOG("done creating graphics, now setting positions\n");
+
+  /* --- setup menu item destinations --- */
+  menu_button[1].x = 240;
+  menu_button[1].y = 100;
+  menu_button[1].w = menu_width[1];  //calc from width of widest menu item
+  /* we should only get to here after we know 'sel' successfully loaded, so safe: */
+  menu_button[1].h = sel->frame[1]->h; //height of sprite image
+
+  menu_gfxdest[1].x = menu_button[1].x + 6; // inset graphic by (6, 4) */
+  menu_gfxdest[1].y = menu_button[1].y + 4;
+  menu_gfxdest[1].w = 40;
+  menu_gfxdest[1].h = 50;
+
+  text_dst[1].y = menu_button[1].y + 15;
+
+  /* FIXME each menu item drawn hardcoded 60 pixels below last - */
+  /* perhaps increment should be "menu_button[j-1].h + MENU_ITEM_GAP" */
+  for (j = 2; j < 6; j++) 
+  {
+    /* --- setup vertical location of button text --- */
+    text_dst[j].y = text_dst[j-1].y + 60;
+
+    /* --- setup location of button background --- */
+    menu_button[j].x = menu_button[j-1].x;
+    menu_button[j].y = menu_button[j-1].y + 60;
+    menu_button[j].w = menu_button[j-1].w;
+    menu_button[j].h = menu_button[j-1].h;
+
+    /* --- setup location of animated icon --- */
+    menu_gfxdest[j].x = menu_gfxdest[j-1].x;
+    menu_gfxdest[j].y = menu_gfxdest[j-1].y + 60;
+    menu_gfxdest[j].w = menu_gfxdest[j-1].w;
+    menu_gfxdest[j].h = menu_gfxdest[j-1].h;
+  }
+}
+
+
+static void unload_menu(void)
+{
+  int i,j;
+  printf("enter unload_menu()\n");
+
+  for (i = 1; i <= TITLE_MENU_ITEMS; i++)
+  {
+    for (j = 1; j <= TITLE_MENU_DEPTH; j++)
+    {
+      if (reg_text[i][j])
+        SDL_FreeSurface(reg_text[i][j]);
+      if (sel_text[i][j])
+        SDL_FreeSurface(sel_text[i][j]);
+      if (menu_gfx[i][j])
+        FreeSprite(menu_gfx[i][j]);
+      reg_text[i][j] = sel_text[i][j] = NULL;
+      menu_gfx[i][j] = NULL;
+    }
+  }
+}
+
+
+static int load_media(void)
+{
+  DEBUGCODE
+  {
+    fprintf(stderr, "Entering load_media():\n");
+    fprintf(stderr, "default_data_path = %s\n", settings.default_data_path);
+    fprintf(stderr, "theme_data_path = %s\n", settings.theme_data_path);
+  }
+
+  /* Make sure everything is unloaded before we start: */
+  /* FIXME have not been to do this to run without crashing: */
+  //unload_media();
+
+  /* --- load sounds --- */
+  if (settings.menu_sound)
+  {
+    snd_move = LoadSound("tock.wav");
+    snd_select = LoadSound("pop.wav");
+    if (!snd_move || !snd_select)
+    {
+      fprintf(stderr, "Could not load menu sounds - turning menu_sound off\n");
+      settings.menu_sound = 0;
+    }
+  }
+ 
+  /* --- load graphics --- */
+  title = LoadImage( "title1.png", IMG_ALPHA );
+  speaker = LoadImage( "sound.png", IMG_ALPHA );
+  speakeroff = LoadImage( "nosound.png", IMG_ALPHA );
+  bkg = LoadImage( "main_bkg.png", IMG_REGULAR );
+  sel = LoadSprite("menu/sel", IMG_ALPHA);
+  reg = LoadSprite("menu/reg", IMG_ALPHA);
+  Tux = LoadSprite("tux", IMG_ALPHA);
+
+  DEBUGCODE
+  {
+    fprintf(stderr, "titlescreen.c load_media(): settings.theme_font_name is %s\n",
+            settings.theme_font_name);
+  }
+  font = LoadFont(settings.theme_font_name, MENU_FONT_SIZE);
+
+  /* Make sure we were successful: */
+  if (!title
+   || !speaker
+   || !speakeroff
+   || !bkg
+   || !sel
+   || !reg
+   || !Tux
+   || !font)
+  {
+    fprintf(stderr, "load_media() - could not load all needed files\n");
+    unload_media();
+    return 0;
+  }
+
+  /* Should probably call this directly from TitleScreen() */
+  load_menu();
+  return 1;
+}
+
+
+
+static void unload_media(void)
+{
+  LOG("Entering unload_media():\n");
+
+  /* --- unload sounds --- */
+  if (settings.menu_sound){
+ 
+    if (snd_move)
+    { 
+      Mix_FreeChunk(snd_move);
+      snd_move = NULL;
+    }
+    if (snd_select)
+    { 
+      Mix_FreeChunk(snd_select);
+      snd_select = NULL;
+    }
+  }
+
+  /* --- unload graphics --- */
+  if (title)
+  {
+    SDL_FreeSurface(title);
+    title = NULL;
+  }
+  if (speaker)
+  {
+    SDL_FreeSurface(speaker);
+    speaker = NULL;
+  }
+  if (speakeroff)
+  {
+    SDL_FreeSurface(speakeroff);
+    speakeroff = NULL;
+  }
+
+  if (bkg)
+  {
+    SDL_FreeSurface(bkg);
+    bkg = NULL;
+  }
+
+  if (sel)
+  {
+    FreeSprite(sel);
+    sel = NULL;
+  }
+  if (reg)
+  {
+    FreeSprite(reg);
+    reg = NULL;
+  }
+  if (Tux)
+  {
+    FreeSprite(Tux);
+    Tux = NULL;
+  }
+
+  if (font)
+  {
+    TTF_CloseFont(font);
+    font = NULL;
+  }
+
+  LOG("Leaving load_media():\n");
+
+  unload_menu();
+}
+
+
+static void not_implemented(void)
+{
+  SDL_Surface* bk = NULL;
+  SDL_Surface *s1 = NULL, *s2 = NULL, *s3 = NULL, *s4 = NULL;
+  sprite* tux = NULL;
+  SDL_Rect loc;
+  int finished = 0, i;
+
+  LOG( "NotImplemented() - creating text\n" );
+
+  s1 = BlackOutline( _("Work In Progress!"), font, &white);
+  s2 = BlackOutline( _("This feature is not ready yet"), font, &white);
+  s3 = BlackOutline( _("Discuss the future of TuxTyping at"), font, &white);
+
+  /* we always want the URL in english */
+  /* NOTE: all fonts are almost certain to include glyphs for ASCII, */
+  /* so the following "english_font" hackery is probably unnecessary: */
+  if (!settings.use_english)
+  {
+    TTF_Font *english_font;
+    settings.use_english = 1;
+    english_font = LoadFont(DEFAULT_MENU_FONT, MENU_FONT_SIZE);
+    s4 = BlackOutline( "http://tuxtype.sf.net/forums", english_font, &white);
+    TTF_CloseFont(english_font);
+    settings.use_english = 0;
+  }
+  else 
+    s4 = BlackOutline( "http://tuxtype.sf.net/forums", font, &white);
+
+  tux = LoadSprite("tux/tux-egypt", IMG_ALPHA);
+  bk = LoadImage("main_bkg.png", IMG_REGULAR);
+
+  if (s1 && s2 && s3 && s4 && tux && bk)
+  {
+    LOG( "NotImplemented() - drawing screen\n" );
+
+    SDL_BlitSurface(bk, NULL, screen, NULL);
+    loc.x = 320-(s1->w/2); loc.y = 10;
+    SDL_BlitSurface( s1, NULL, screen, &loc);
+    loc.x = 320-(s2->w/2); loc.y = 60;
+    SDL_BlitSurface( s2, NULL, screen, &loc);
+    loc.x = 320-(s3->w/2); loc.y = 400;
+    SDL_BlitSurface( s3, NULL, screen, &loc);
+    loc.x = 320-(s4->w/2); loc.y = 440;
+    SDL_BlitSurface( s4, NULL, screen, &loc);
+
+    loc.x = 320-(tux->frame[0]->w/2);
+    loc.y = 200;
+    loc.w = tux->frame[0]->w;
+    loc.h = tux->frame[0]->h;
+    SDL_BlitSurface( tux->frame[tux->cur], NULL, screen, &loc);
+
+    SDL_UpdateRect(screen, 0, 0, 0, 0);
+
+    i = 0;
+
+    while (!finished)
+    {
+      while (SDL_PollEvent(&event)) 
+      {
+        switch (event.type)
+        {
+          case SDL_QUIT:
+            exit(0);
+          case SDL_MOUSEBUTTONDOWN:
+          case SDL_KEYDOWN:
+            finished = 1;
+        }
+      }
+
+      i++;
+
+      if (i %5 == 0)
+      {
+        NEXT_FRAME(tux);
+        SDL_BlitSurface(bk, &loc, screen, &loc);
+        SDL_BlitSurface(tux->frame[tux->cur], NULL, screen, &loc);
+        SDL_UpdateRect(screen, loc.x, loc.y, loc.w, loc.h);
+      }
+
+      SDL_Delay(40);
+    }
+  }
+  else
+    fprintf(stderr, "NotImplemented() - could not load needed graphic\n");
+
+  SDL_FreeSurface(s1);
+  SDL_FreeSurface(s2);
+  SDL_FreeSurface(s3);
+  SDL_FreeSurface(s4);
+  SDL_FreeSurface(bk);
+  s1 = s2 = s3 = s4 = bk = NULL;
+  FreeSprite(tux);
+  tux = NULL;
+}
+
+
+
+
+#define MAX_WORD_LISTS 100
+
+/* returns 0 if user pressed escape ...
+ *         1 if word list was set correctly
+ */
+static int chooseWordlist(void)
+{
+  SDL_Surface* titles[MAX_WORD_LISTS] = {NULL};
+  SDL_Surface* select[MAX_WORD_LISTS] = {NULL};
+  SDL_Surface* left = NULL, *right = NULL;
+  SDL_Surface* backg = NULL;
+  SDL_Rect leftRect, rightRect;
+  SDL_Rect titleRects[8];
+  int stop = 0;
+  int loc = 0;
+  int old_loc = 1;
+  int lists = 0;
+  int i;
+  unsigned char wordPath[FNLEN];
+  unsigned char wordlistFile[MAX_WORD_LISTS][200];
+  unsigned char wordlistName[MAX_WORD_LISTS][200];
+
+  DIR* wordsDir = NULL;
+  struct dirent* wordsFile = NULL;
+  FILE* tempFile = NULL;
+
+  LOG("Entering chooseWordlist():\n");
+
+  /* find the directory to load wordlists from */
+
+  /* Check under theme directory first, if theme selected: */
+  if (!settings.use_english)  /* Using theme: */
+  {
+    sprintf(wordPath,"%s/words", settings.theme_data_path);
+    if (!CheckFile(wordPath))
+    {
+      fprintf(stderr, "chooseWordList() - theme contains no wordlist dir \n");
+      return 0;
+    }
+  }
+  else  /* No theme selected - using English: */
+  {
+    sprintf(wordPath,"%s/words", settings.default_data_path);
+    if (!CheckFile(wordPath))
+    {
+      fprintf(stderr, "chooseWordList() - data path contains no wordlist dir \n");
+      return 0;
+    }
+  }
+
+  /* If we get to here, we know there is at least a wordlist directory */
+  /* but not necessarily any valid files.                              */
+
+  DEBUGCODE { fprintf(stderr, "wordPath is: %s\n", wordPath); }
+
+
+  /* FIXME looks like a place for scandir() - or our own w32_scandir() */
+  /* create a list of all the .txt files */
+
+  wordsDir = opendir( wordPath );	
+
+  do
+  {
+    wordsFile = readdir(wordsDir);
+    if (!wordsFile)
+      break; /* Loop continues until break occurs */
+
+    /* must have at least .txt at the end */
+    if (strlen(wordsFile->d_name) < 5)
+      continue;
+
+    if (strcmp(&wordsFile->d_name[strlen(wordsFile->d_name)-4],".txt"))
+      continue;
+
+    sprintf(wordlistFile[lists], "%s/%s", wordPath, wordsFile->d_name);
+
+    /* load the name for the wordlist from the file ... (1st line) */
+    tempFile = fopen( wordlistFile[lists], "r" );
+    if (!tempFile)
+      continue;
+
+    fscanf(tempFile, "%[^\n]\n", wordlistName[lists]);
+
+    /* check to see if it has a \r at the end of it (dos format!) */
+    if (wordlistName[lists][strlen(wordlistName[lists]) - 1] == '\r')
+      wordlistName[lists][strlen(wordlistName[lists]) - 1] = '\0';
+
+    lists++;
+
+    fclose(tempFile);
+  } while (1); /* Loop continues until break occurs */
+
+  closedir(wordsDir);	
+ 
+ DEBUGCODE { fprintf(stderr, "Found %d .txt file(s) in words dir\n", lists); }
+
+
+
+  /* let the user pick the list */
+
+  /* Render SDL_Surfaces for list entries: */
+//  titles[0] = BlackOutline( _("Alphabet"), font, &white );
+//  select[0] = BlackOutline( _("Alphabet"), font, &yellow);
+
+  /* NOTE - no longer hard-coding titles[0] to be alphabet - themes  */
+  /* should include a regular word list file called "alphabet.txt"   */
+  /* Should sort the list and always put the alphabet file first, if */
+  /* present.                                                        */
+  for (i = 0; i < lists; i++)
+  {
+    titles[i] = BlackOutline( wordlistName[i], font, &white );
+    select[i] = BlackOutline( wordlistName[i], font, &yellow);
+  }
+
+  backg = LoadImage("main_bkg.png", IMG_REGULAR);
+  left = LoadImage("left.png", IMG_ALPHA);
+  right = LoadImage("right.png", IMG_ALPHA);
+
+  /* Get out if needed surface not loaded successfully: */
+  if (!backg || !left || !right)
+  {
+    fprintf(stderr, "chooseWordList(): needed image not available\n");
+  
+    for (i = 0; i < lists; i++)
+    {
+      SDL_FreeSurface(titles[i]);
+      SDL_FreeSurface(select[i]);
+      titles[i] = select[i] = NULL;
+    }
+
+    SDL_FreeSurface(backg);
+    SDL_FreeSurface(left);
+    SDL_FreeSurface(right);
+    backg = left = right = NULL;
+
+    return 0;
+  }
+  
+
+
+  leftRect.w = left->w; leftRect.h = left->h;
+  leftRect.x = 320 - 80 - (leftRect.w/2); leftRect.y = 430;
+
+  rightRect.w = right->w; rightRect.h = right->h;
+  rightRect.x = 320 + 80 - (rightRect.w/2); rightRect.y = 430;
+
+  /* set initial rect sizes */
+  titleRects[0].y = 30;
+  titleRects[0].w = titleRects[0].h = titleRects[0].x = 0;
+
+  for (i = 1; i < 8; i++)
+  { 
+    titleRects[i].y = titleRects[i - 1].y + 50;
+    titleRects[i].w = titleRects[i].h = titleRects[i].x = 0;
+  }
+
+  /* Main event loop for this screen: */
+  while (!stop)
+  {
+    while (SDL_PollEvent(&event))
+    {
+      switch (event.type)
+      {
+        case SDL_QUIT:
+          exit(0); /* FIXME may need to cleanup memory and exit more cleanly */
+          break;
+
+        case SDL_MOUSEMOTION:
+          for (i=0; (i<8) && (loc-(loc%8)+i<lists); i++)
+            if (inRect( titleRects[i], event.motion.x, event.motion.y ))
+            {
+              loc = loc-(loc%8)+i;
+              break;
+            }
+          break;
+
+        case SDL_MOUSEBUTTONDOWN:
+                                        if (inRect( leftRect, event.button.x, event.button.y ))
+                                                if (loc-(loc%8)-8 >= 0) {
+                                                        loc=loc-(loc%8)-8;
+                                                        break;
+                                                }
+                                        if (inRect( rightRect, event.button.x, event.button.y ))
+                                                if (loc-(loc%8)+8 < lists) {
+                                                        loc=loc-(loc%8)+8;
+                                                        break;
+                                                }
+                                        for (i=0; (i<8) && (loc-(loc%8)+i<lists); i++)
+                                                if (inRect(titleRects[i], event.button.x, event.button.y)) {
+                                                        loc = loc-(loc%8)+i;
+							ClearWordList(); /* clear old selection */
+							//if (loc==0)
+							//  UseAlphabet(); 
+							//else
+							GenerateWordList(wordlistFile[loc]); 
+                                                        stop = 1;
+                                                        break;
+                                                }
+                                        break;
+                                case SDL_KEYDOWN:
+                                        if (event.key.keysym.sym == SDLK_ESCAPE) { stop = 2; break; }
+                                        if (event.key.keysym.sym == SDLK_RETURN) {
+						ClearWordList(); /* clear old selection */
+						//if (loc==0)
+						//  UseAlphabet(); 
+						//else
+						GenerateWordList(wordlistFile[loc]); 
+                                                stop = 1;
+                                                break;
+                                        }
+
+                                        if ((event.key.keysym.sym == SDLK_LEFT) || (event.key.keysym.sym == SDLK_PAGEUP)) {
+                                                if (loc-(loc%8)-8 >= 0)
+                                                        loc=loc-(loc%8)-8;
+                                        }
+
+                                        if ((event.key.keysym.sym == SDLK_RIGHT) || (event.key.keysym.sym == SDLK_PAGEDOWN)) {
+                                                if (loc-(loc%8)+8 < lists)
+                                                        loc=(loc-(loc%8)+8);
+                                        }
+
+                                        if (event.key.keysym.sym == SDLK_UP) {
+                                                if (loc > 0)
+                                                        loc--;
+                                        }
+
+                                        if (event.key.keysym.sym == SDLK_DOWN) {
+                                                if (loc+1<lists)
+                                                        loc++;
+                                        }
+      }
+    }
+
+    if (old_loc != loc) {
+                        int start;
+
+                        SDL_BlitSurface(backg, NULL, screen, NULL );
+
+                        start = loc - (loc % 8);
+                        for (i = start; i<MIN(start+8,lists); i++) {
+                                titleRects[i%8].x = 320 - (titles[i]->w/2);
+                                if (i == loc)
+                                        SDL_BlitSurface(select[loc], NULL, screen, &titleRects[i%8]);
+                                else
+                                        SDL_BlitSurface(titles[i], NULL, screen, &titleRects[i%8]);
+                        }
+
+                        /* --- draw buttons --- */
+
+                        if (start>0)
+                                SDL_BlitSurface( left, NULL, screen, &leftRect );
+
+                        if (start+8<lists)
+                                SDL_BlitSurface( right, NULL, screen, &rightRect );
+
+                        SDL_UpdateRect(screen, 0, 0, 0 ,0);
+                }
+                SDL_Delay(40);
+                old_loc = loc;
+  }
+
+  /* --- clear graphics before leaving function --- */ 
+  for (i = 0; i<lists; i++)
+  {
+    SDL_FreeSurface(titles[i]);
+    SDL_FreeSurface(select[i]);
+    titles[i] = select[i] = NULL;
+  }
+
+  SDL_FreeSurface(backg);
+  SDL_FreeSurface(left);
+  SDL_FreeSurface(right);
+  backg = left = right = NULL; /* Maybe overkill - about to be destroyed anyway */
+
+  DEBUGCODE { fprintf( stderr, "Leaving chooseWordlist();\n" ); }
+
+  if (stop == 2)
+    return 0;
+
+  return 1;
+}
+
+
+
+
+

Added: tuxtype/branches/tuxtype-new/src/titlescreen.h
===================================================================
--- tuxtype/branches/tuxtype-new/src/titlescreen.h	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/src/titlescreen.h	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,45 @@
+
+/* --- SETUP MENU OPTIONS --- */
+
+#define TITLE_MENU_ITEMS                5
+#define TITLE_MENU_DEPTH                4
+
+#define OPTIONS_SUBMENU                 4
+#define LASER_SUBMENU	        	3
+#define CASCADE_SUBMENU	        	2
+#define ROOTMENU		        1
+
+/* --- define menu structure --- */
+/* (these values are all in the Game_Type enum in globals.h) */
+const int menu_item[][6]= {{0, 0,         0,         0,          0},
+			   {0, CASCADE,   LEVEL1,    LEVEL1,  NOT_CODED },
+			   {0, LASER,     LEVEL2,    LEVEL2,  FREETYPE   },
+			   {0, LESSONS,  LEVEL3,    LEVEL3,  PROJECT_INFO },
+			   {0, OPTIONS,   INSTRUCT,  LEVEL4,  SET_LANGUAGE},
+			   {0, QUIT_GAME, MAIN,      MAIN,    MAIN}};
+
+/* --- menu text --- */
+const unsigned char *menu_text[][6]= 
+{{"", "",            "",             "",            ""    },
+ {"", gettext_noop("Fish Cascade"), gettext_noop("Easy"),         gettext_noop("Space Cadet"), gettext_noop("Edit Word Lists")},
+ {"", gettext_noop("Comet Zap"),    gettext_noop("Medium"),       gettext_noop("Pilot"),       gettext_noop("Practice")},
+ {"", gettext_noop("Lessons"),     gettext_noop("Hard"),         gettext_noop("Ace"),         gettext_noop("Project Info")},
+ {"", gettext_noop("Options"),      gettext_noop("Instructions"), gettext_noop("Commander"),   gettext_noop("Setup Language")},
+ {"", gettext_noop("Quit"),         gettext_noop("Main Menu"),    gettext_noop("Main Menu"),   gettext_noop("Main Menu")}};
+
+/* --- menu icons --- */
+const unsigned char *menu_icon[][6]= 
+{{"", "", "", "", ""},
+ {"", "cascade", "easy",   "grade1_", "list"   },
+ {"", "comet",   "medium", "grade2_", "practice" },
+ {"", "lesson","hard",   "grade3_", "keyboard"   },
+ {"", "tux_config",  "tutor",  "grade4_", "lang" },
+ {"", "quit",    "main",   "main",    "main"   }};
+
+/* --- timings for tux blinking --- */
+#define TUX1                            115
+#define TUX2                            118
+#define TUX3                            121
+#define TUX4                            124
+#define TUX5                            127
+#define TUX6                            130

Added: tuxtype/branches/tuxtype-new/stamp-h1
===================================================================
--- tuxtype/branches/tuxtype-new/stamp-h1	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/stamp-h1	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1 @@
+timestamp for config.h

Added: tuxtype/branches/tuxtype-new/tuxtype.ico
===================================================================
(Binary files differ)


Property changes on: tuxtype/branches/tuxtype-new/tuxtype.ico
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: tuxtype/branches/tuxtype-new/tuxtype.lsm
===================================================================
--- tuxtype/branches/tuxtype-new/tuxtype.lsm	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/tuxtype.lsm	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,14 @@
+Begin3
+Title:          Tuxtype 
+Version:        1.0
+Entered-date:   
+Description:    Educational Typing Tutor Game Starring Tux
+Keywords:        
+Author:         Sam Hart <hart at geekcomix.com> 
+Maintained-by:  Sam Hart <hart at geekcomix.com> 
+Primary-site:   	        
+Home-page:      http://www.geekcomix.com/dm/tuxtype/
+Original-site:  
+Platforms:       Linux and other Unices
+Copying-policy: GNU Public License
+End

Added: tuxtype/branches/tuxtype-new/tuxtype.spec.in
===================================================================
--- tuxtype/branches/tuxtype-new/tuxtype.spec.in	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/tuxtype.spec.in	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,101 @@
+# Spec-file for TuxType version @VERSION@
+
+%define name  @PACKAGE@
+%define version @VERSION@
+%define release 1
+
+Summary: An educational typing tutor game starring Tux
+Name: %{name}
+Version: %{version}
+Release: %{release}
+Source: http://www.geekcomix.com/dm/tuxtype/%{name}-%{version}.tar.gz
+URL: http://www.geekcomix.com/dm/tuxtype/
+License: GPL 
+Group: Games/Educational
+Distribution: Digital Monkey Software <http://www.geekcomix.com/dm/>
+Vendor: Digital Monkey Software <http://www.geekcomix.com/dm/>
+Packager: Calvin Arndt <calarndt at yahoo.com>
+BuildRoot: %{tmp}
+Prefix: $prefix
+
+%description 
+Tux Typing is an educational typing tutor game starring Tux, the Linux
+penguin. It is graphical and requires SDL to run. This is a stable
+release.
+
+%prep
+
+%setup -q -n %{name}-%{version}
+
+%build
+
+if test x%{prefix} = x; then
+./configure --prefix="/usr/local"
+else
+./configure --prefix=%{prefix}
+fi
+   
+make
+
+%install
+
+if test x%{prefix} = x; then
+
+make prefix=$RPM_BUILD_ROOT/usr/local install
+
+else
+
+make prefix=$RPM_BUILD_ROOT%{prefix} install
+
+fi
+
+
+%files
+%docdir  %{prefix}/doc/tuxtype
+/*
+
+%clean
+
+rm -rf $RPM_BUILD_DIR/%{name}-%{version}
+rm -rf $RPM_BUILD_ROOT%{prefix}
+
+%changelog
+* Wed Aug 01 2001 Sam "Criswell" Hart <criswell at geekcomix.com>
+Tweaked gameplay & menu speeds. Prep for 1.0 release
+
+* Fri Jul 27 2001 Sam "Criswell" Hart <criswell at geekcomix.com>
+Fixed word cascade LinuxPPC/Win32 crashing bug
+
+* Sun Jul 15 2001 Sam "Criswell" Hart <criswell at geekcomix.com>
+Added alpha blit option for fast word emphasis. Prepping for 1.0pre1 rel.
+
+* Fri Jul 13 2001 Jesse Andrews <jdandr2 at pop.uky.edu>
+Fixed clipping blit bug as well as menu glitches
+
+* Sat Jul 07 2001 Sam "Criswell" Hart <criswell at geekcomix.com>
+Added preliminary theme support
+
+* Tue Jun 20 2001 Sam "Criswell" Hart <criswell at geekcomix.com>
+Added keyboard support to main menu
+
+* Sat Jun 16 2001 Sam "Criswell" Hart <criswell at geekcomix.com>
+Fixed tutorial screen crashing bug. Other minor work. Prepping for 0.9 rel.
+
+* Fri Jun 15 2001 Sam "Criswell" Hart <criswell at geekcomix.com>
+Better Kdevelop/SDL integration to fix non-POSIX OS support (first Win32 release).
+
+* Tue Jun 12 2001 Sam "Criswell" Hart <criswell at geekcomix.com>
+Further Tutorial stabilization work.
+
+* Sat Jun 09 2001 Jesse Andrews <jdandr2 at sheffield.cslab.uky.edu>
+Fixed several small problems with Tutorial/Main screen bug.
+
+* Sat May 19 2001 Sam "Criswell" Hart <criswell at geekcomix.com>
+Fixed GIF->PNG and "yellow outline" in gameplay bugs.
+
+* Mon May 14 2001 Sam "Criswell" Hart <criswell at geekcomix.com>
+Packaged up the 0.8 release.
+
+* Fri May 04 2001 Sam "Criswell" Hart <criswell at geekcomix.com>
+RPM ChangeLog began. For previous changes, see ChangeLog.old
+

Added: tuxtype/branches/tuxtype-new/tuxtypereorg.kdevelop
===================================================================
--- tuxtype/branches/tuxtype-new/tuxtypereorg.kdevelop	                        (rev 0)
+++ tuxtype/branches/tuxtype-new/tuxtypereorg.kdevelop	2008-03-29 14:52:14 UTC (rev 446)
@@ -0,0 +1,95 @@
+<?xml version = '1.0'?>
+<kdevelop>
+  <general>
+    <author>David Bruce</author>
+    <email>dbruce at tampabay.rr.com</email>
+    <version>[1.5.16]</version>
+    <projectmanagement>KDevAutoProject</projectmanagement>
+    <primarylanguage>C</primarylanguage>
+    <ignoreparts/>
+    <projectname>tuxtypereorg</projectname>
+  </general>
+  <kdevautoproject>
+    <general>
+      <useconfiguration>debug</useconfiguration>
+    </general>
+    <run/>
+    <configurations>
+      <optimized>
+        <builddir>optimized</builddir>
+        <ccompiler>GccOptions</ccompiler>
+        <cxxcompiler>GppOptions</cxxcompiler>
+        <f77compiler>G77Options</f77compiler>
+        <cflags>-O2 -g0</cflags>
+      </optimized>
+      <debug>
+        <configargs>--enable-debug=full</configargs>
+        <builddir>debug</builddir>
+        <ccompiler>GccOptions</ccompiler>
+        <cxxcompiler>GppOptions</cxxcompiler>
+        <f77compiler>G77Options</f77compiler>
+        <cflags>-O0 -g3</cflags>
+      </debug>
+    </configurations>
+  </kdevautoproject>
+  <kdevdebugger>
+    <general>
+      <dbgshell>libtool</dbgshell>
+    </general>
+  </kdevdebugger>
+  <kdevdoctreeview>
+    <ignoretocs>
+      <toc>ada</toc>
+      <toc>ada_bugs_gcc</toc>
+      <toc>bash</toc>
+      <toc>bash_bugs</toc>
+      <toc>clanlib</toc>
+      <toc>fortran_bugs_gcc</toc>
+      <toc>gnome1</toc>
+      <toc>gnustep</toc>
+      <toc>gtk</toc>
+      <toc>gtk_bugs</toc>
+      <toc>haskell</toc>
+      <toc>haskell_bugs_ghc</toc>
+      <toc>java_bugs_gcc</toc>
+      <toc>java_bugs_sun</toc>
+      <toc>kde2book</toc>
+      <toc>libstdc++</toc>
+      <toc>opengl</toc>
+      <toc>pascal_bugs_fp</toc>
+      <toc>php</toc>
+      <toc>php_bugs</toc>
+      <toc>perl</toc>
+      <toc>perl_bugs</toc>
+      <toc>python</toc>
+      <toc>python_bugs</toc>
+      <toc>qt-kdev3</toc>
+      <toc>ruby</toc>
+      <toc>ruby_bugs</toc>
+      <toc>sdl</toc>
+      <toc>stl</toc>
+      <toc>sw</toc>
+      <toc>w3c-dom-level2-html</toc>
+      <toc>w3c-svg</toc>
+      <toc>w3c-uaag10</toc>
+      <toc>wxwidgets_bugs</toc>
+    </ignoretocs>
+    <ignoreqt_xml>
+      <toc>Guide to the Qt Translation Tools</toc>
+      <toc>Qt Assistant Manual</toc>
+      <toc>Qt Designer Manual</toc>
+      <toc>Qt Reference Documentation</toc>
+      <toc>qmake User Guide</toc>
+    </ignoreqt_xml>
+    <ignoredoxygen>
+      <toc>KDE Libraries (Doxygen)</toc>
+    </ignoredoxygen>
+  </kdevdoctreeview>
+  <kdevfilecreate>
+    <filetypes/>
+    <useglobaltypes>
+      <type ext="c" />
+      <type ext="h" />
+    </useglobaltypes>
+  </kdevfilecreate>
+</kdevelop>




More information about the Tux4kids-commits mailing list