diff -r -C 3 -N blib-1.1.7/modules/Makefile.am blib-1.1.7-ba20070811/modules/Makefile.am
*** blib-1.1.7/modules/Makefile.am	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/Makefile.am	Sat Aug 11 22:18:43 2007
***************
*** 16,31 ****
--- 16,36 ----
  	libbbreakout.la		\
  	libbclock.la		\
  	libbcountdown.la	\
+ 	libbcreatefile.la	\
  	libbdebug.la		\
  	libbdropout.la		\
  	libbfire.la		\
+ 	libbfireworks.la	\
  	libbmatrix.la		\
  	libbpacman.la		\
  	libbpong.la		\
+ 	libbpongmulti.la	\
+ 	libbpongv.la		\
  	libbproxy.la		\
  	libbpushline.la 	\
  	libbqix.la		\
  	libbretris.la	 	\
+ 	libbsitris4.la	 	\
  	libbsnake.la		\
  	libbtetris.la		\
  	libbtext.la		\
***************
*** 41,54 ****
  libbcountdown_la_SOURCES = bcountdown.c digits.h
  libbcountdown_la_LDFLAGS = -avoid-version -module
  
  libbdebug_la_SOURCES = bdebug.c digits.h
  libbdebug_la_LDFLAGS = -avoid-version -module
  
  libbfire_la_SOURCES = bfire.c
  libbfire_la_LDFLAGS = -avoid-version -module
  
! libbdropout_la_SOURCES = bdropout.c
! libbdropout_la_LDFLAGS = -avoid-version -module
  
  libbmatrix_la_SOURCES = bmatrix.c
  libbmatrix_la_LDFLAGS = -avoid-version -module
--- 46,65 ----
  libbcountdown_la_SOURCES = bcountdown.c digits.h
  libbcountdown_la_LDFLAGS = -avoid-version -module
  
+ libbcreatefile_la_SOURCES = bcreatefile.c
+ libbcreatefile_la_LDFLAGS = -avoid-version -module
+ 
  libbdebug_la_SOURCES = bdebug.c digits.h
  libbdebug_la_LDFLAGS = -avoid-version -module
  
+ libbdropout_la_SOURCES = bdropout.c
+ libbdropout_la_LDFLAGS = -avoid-version -module
+ 
  libbfire_la_SOURCES = bfire.c
  libbfire_la_LDFLAGS = -avoid-version -module
  
! libbfireworks_la_SOURCES = bfireworks.c
! libbfireworks_la_LDFLAGS = -avoid-version -module
  
  libbmatrix_la_SOURCES = bmatrix.c
  libbmatrix_la_LDFLAGS = -avoid-version -module
***************
*** 59,64 ****
--- 70,81 ----
  libbpong_la_SOURCES = bpong.c digits.h
  libbpong_la_LDFLAGS = -avoid-version -module
  
+ libbpongmulti_la_SOURCES = bpongmulti.c digits.h
+ libbpongmulti_la_LDFLAGS = -avoid-version -module
+ 
+ libbpongv_la_SOURCES = bpongv.c digits.h
+ libbpongv_la_LDFLAGS = -avoid-version -module
+ 
  libbproxy_la_SOURCES = bproxy.c
  libbproxy_la_LDFLAGS = -avoid-version -module
  
***************
*** 71,83 ****
  libbretris_la_SOURCES = bretris.c
  libbretris_la_LDFLAGS = -avoid-version -module
  
  libbsnake_la_SOURCES = bsnake.c
  libbsnake_la_LDFLAGS = -avoid-version -module
  
  libbtetris_la_SOURCES = btetris.c
  libbtetris_la_LDFLAGS = -avoid-version -module
  
! libbtext_la_SOURCES = btext.c
  libbtext_la_LDFLAGS = -avoid-version -module
  
  libbxxo_la_SOURCES = bxxo.c
--- 88,103 ----
  libbretris_la_SOURCES = bretris.c
  libbretris_la_LDFLAGS = -avoid-version -module
  
+ libbsitris4_la_SOURCES = bsitris4.c
+ libbsitris4_la_LDFLAGS = -avoid-version -module
+ 
  libbsnake_la_SOURCES = bsnake.c
  libbsnake_la_LDFLAGS = -avoid-version -module
  
  libbtetris_la_SOURCES = btetris.c
  libbtetris_la_LDFLAGS = -avoid-version -module
  
! libbtext_la_SOURCES = btext.c characters.c characters.h
  libbtext_la_LDFLAGS = -avoid-version -module
  
  libbxxo_la_SOURCES = bxxo.c
diff -r -C 3 -N blib-1.1.7/modules/Makefile.in blib-1.1.7-ba20070811/modules/Makefile.in
*** blib-1.1.7/modules/Makefile.in	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/Makefile.in	Sat Aug 11 22:18:43 2007
***************
*** 1,8 ****
! # Makefile.in generated by automake 1.7.9 from Makefile.am.
! # @configure_input@
  
! # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
! # 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.
--- 1,6 ----
! # Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
  
! # Copyright (C) 1994, 1995-8, 1999, 2001 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.
***************
*** 12,51 ****
  # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  # PARTICULAR PURPOSE.
  
! @SET_MAKE@
  
  srcdir = @srcdir@
  top_srcdir = @top_srcdir@
  VPATH = @srcdir@
  pkgdatadir = $(datadir)/@PACKAGE@
  pkglibdir = $(libdir)/@PACKAGE@
  pkgincludedir = $(includedir)/@PACKAGE@
  top_builddir = ..
  
! am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
  INSTALL = @INSTALL@
! 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 = :
  host_triplet = @host@
  AA_LIBS = @AA_LIBS@
  AA_VIEW_TYPE = @AA_VIEW_TYPE@
! ACLOCAL = @ACLOCAL@
! AMDEP_FALSE = @AMDEP_FALSE@
! AMDEP_TRUE = @AMDEP_TRUE@
  AMTAR = @AMTAR@
  AR = @AR@
! AUTOCONF = @AUTOCONF@
! AUTOHEADER = @AUTOHEADER@
! AUTOMAKE = @AUTOMAKE@
  AWK = @AWK@
  BLIB_BINARY_AGE = @BLIB_BINARY_AGE@
  BLIB_INTERFACE_AGE = @BLIB_INTERFACE_AGE@
--- 10,69 ----
  # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  # PARTICULAR PURPOSE.
  
! 
! SHELL = @SHELL@
  
  srcdir = @srcdir@
  top_srcdir = @top_srcdir@
  VPATH = @srcdir@
+ prefix = @prefix@
+ exec_prefix = @exec_prefix@
+ 
+ bindir = @bindir@
+ sbindir = @sbindir@
+ libexecdir = @libexecdir@
+ datadir = @datadir@
+ sysconfdir = @sysconfdir@
+ sharedstatedir = @sharedstatedir@
+ localstatedir = @localstatedir@
+ infodir = @infodir@
+ mandir = @mandir@
+ includedir = @includedir@
+ oldincludedir = /usr/include
+ 
+ DESTDIR =
+ 
  pkgdatadir = $(datadir)/@PACKAGE@
  pkglibdir = $(libdir)/@PACKAGE@
  pkgincludedir = $(includedir)/@PACKAGE@
+ 
  top_builddir = ..
  
! ACLOCAL = @ACLOCAL@
! AUTOCONF = @AUTOCONF@
! AUTOMAKE = @AUTOMAKE@
! AUTOHEADER = @AUTOHEADER@
! 
  INSTALL = @INSTALL@
! INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
! INSTALL_DATA = @INSTALL_DATA@
! INSTALL_SCRIPT = @INSTALL_SCRIPT@
! transform = @program_transform_name@
! 
  NORMAL_INSTALL = :
  PRE_INSTALL = :
  POST_INSTALL = :
  NORMAL_UNINSTALL = :
  PRE_UNINSTALL = :
  POST_UNINSTALL = :
+ host_alias = @host_alias@
  host_triplet = @host@
  AA_LIBS = @AA_LIBS@
  AA_VIEW_TYPE = @AA_VIEW_TYPE@
! AMDEPBACKSLASH = @AMDEPBACKSLASH@
  AMTAR = @AMTAR@
  AR = @AR@
! AS = @AS@
  AWK = @AWK@
  BLIB_BINARY_AGE = @BLIB_BINARY_AGE@
  BLIB_INTERFACE_AGE = @BLIB_INTERFACE_AGE@
***************
*** 53,224 ****
  BLIB_MICRO_VERSION = @BLIB_MICRO_VERSION@
  BLIB_MINOR_VERSION = @BLIB_MINOR_VERSION@
  BLIB_VERSION = @BLIB_VERSION@
- BUILD_MODULES_FALSE = @BUILD_MODULES_FALSE@
- BUILD_MODULES_TRUE = @BUILD_MODULES_TRUE@
  CC = @CC@
- CCDEPMODE = @CCDEPMODE@
  CFLAGS = @CFLAGS@
- CPP = @CPP@
- CPPFLAGS = @CPPFLAGS@
  CXX = @CXX@
  CXXCPP = @CXXCPP@
- CXXDEPMODE = @CXXDEPMODE@
- CXXFLAGS = @CXXFLAGS@
  CYGPATH_W = @CYGPATH_W@
  DATADIR = @DATADIR@
  DB2HTML = @DB2HTML@
- DEFS = @DEFS@
  DEPDIR = @DEPDIR@
- DIRECTFB_CFLAGS = @DIRECTFB_CFLAGS@
- DIRECTFB_LIBS = @DIRECTFB_LIBS@
  DIRECTFB_VIEW_TYPE = @DIRECTFB_VIEW_TYPE@
  ECHO = @ECHO@
- ECHO_C = @ECHO_C@
- ECHO_N = @ECHO_N@
- ECHO_T = @ECHO_T@
  EGREP = @EGREP@
- ENABLE_GTK_DOC_FALSE = @ENABLE_GTK_DOC_FALSE@
- ENABLE_GTK_DOC_TRUE = @ENABLE_GTK_DOC_TRUE@
  EXEEXT = @EXEEXT@
  F77 = @F77@
! FFLAGS = @FFLAGS@
! GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@
! GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@
  GLIB_CFLAGS = @GLIB_CFLAGS@
  GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
  GLIB_LIBS = @GLIB_LIBS@
  GLIB_MKENUMS = @GLIB_MKENUMS@
  GOBJECT_QUERY = @GOBJECT_QUERY@
  GTKDOC = @GTKDOC@
- GTK_CFLAGS = @GTK_CFLAGS@
- GTK_LIBS = @GTK_LIBS@
  GTK_VIEW_TYPE = @GTK_VIEW_TYPE@
- HAVE_AA_FALSE = @HAVE_AA_FALSE@
- HAVE_AA_TRUE = @HAVE_AA_TRUE@
- HAVE_DIRECTFB_FALSE = @HAVE_DIRECTFB_FALSE@
- HAVE_DIRECTFB_TRUE = @HAVE_DIRECTFB_TRUE@
- HAVE_DOCBOOK_FALSE = @HAVE_DOCBOOK_FALSE@
- HAVE_DOCBOOK_TRUE = @HAVE_DOCBOOK_TRUE@
  HAVE_GTK_DOC = @HAVE_GTK_DOC@
- HAVE_GTK_DOC_FALSE = @HAVE_GTK_DOC_FALSE@
- HAVE_GTK_DOC_TRUE = @HAVE_GTK_DOC_TRUE@
- HAVE_GTK_FALSE = @HAVE_GTK_FALSE@
- HAVE_GTK_TRUE = @HAVE_GTK_TRUE@
- HAVE_PIXBUF_FALSE = @HAVE_PIXBUF_FALSE@
- HAVE_PIXBUF_TRUE = @HAVE_PIXBUF_TRUE@
  HTML_DIR = @HTML_DIR@
  INCLUDEDIR = @INCLUDEDIR@
- INSTALL_DATA = @INSTALL_DATA@
- INSTALL_PROGRAM = @INSTALL_PROGRAM@
- INSTALL_SCRIPT = @INSTALL_SCRIPT@
  INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
- LDFLAGS = @LDFLAGS@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
  LIBTOOL = @LIBTOOL@
  LN_S = @LN_S@
- LTLIBOBJS = @LTLIBOBJS@
  LT_AGE = @LT_AGE@
  LT_CURRENT = @LT_CURRENT@
  LT_RELEASE = @LT_RELEASE@
  LT_REVISION = @LT_REVISION@
  MAINT = @MAINT@
- MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
- MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
  MAKEINFO = @MAKEINFO@
  MODULEPATH = @MODULEPATH@
  OBJEXT = @OBJEXT@
- OS_WIN32_FALSE = @OS_WIN32_FALSE@
- OS_WIN32_TRUE = @OS_WIN32_TRUE@
  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@
  PIXBUF_VIEW_TYPE = @PIXBUF_VIEW_TYPE@
  PKG_CONFIG = @PKG_CONFIG@
  RANLIB = @RANLIB@
! SET_MAKE = @SET_MAKE@
! SHELL = @SHELL@
  STRIP = @STRIP@
  THEMEPATH = @THEMEPATH@
  VERSION = @VERSION@
  WIN32_CFLAGS = @WIN32_CFLAGS@
  WIN32_LIBS = @WIN32_LIBS@
- ac_ct_AR = @ac_ct_AR@
- ac_ct_CC = @ac_ct_CC@
- ac_ct_CXX = @ac_ct_CXX@
- ac_ct_F77 = @ac_ct_F77@
- ac_ct_RANLIB = @ac_ct_RANLIB@
- ac_ct_STRIP = @ac_ct_STRIP@
- am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
- am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
- am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
- am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
  am__include = @am__include@
  am__leading_dot = @am__leading_dot@
  am__quote = @am__quote@
- bindir = @bindir@
- build = @build@
- build_alias = @build_alias@
- build_cpu = @build_cpu@
- build_os = @build_os@
- build_vendor = @build_vendor@
- datadir = @datadir@
- exec_prefix = @exec_prefix@
- host = @host@
- host_alias = @host_alias@
- host_cpu = @host_cpu@
- host_os = @host_os@
- host_vendor = @host_vendor@
- includedir = @includedir@
- infodir = @infodir@
  install_sh = @install_sh@
  
  libdir = @MODULEPATH@
- libexecdir = @libexecdir@
- localstatedir = @localstatedir@
- mandir = @mandir@
- oldincludedir = @oldincludedir@
- prefix = @prefix@
- program_transform_name = @program_transform_name@
- sbindir = @sbindir@
- sharedstatedir = @sharedstatedir@
- sysconfdir = @sysconfdir@
- target_alias = @target_alias@
  
! AM_CPPFLAGS = \
! 	$(CFLAGS)		\
! 	 -DG_DISABLE_DEPRECATED
! 
! 
! INCLUDES = \
! 	-I$(top_srcdir)		\
! 	@GLIB_CFLAGS@
! 
! 
! @BUILD_MODULES_TRUE@lib_LTLIBRARIES = \
! @BUILD_MODULES_TRUE@	libbbreakout.la		\
! @BUILD_MODULES_TRUE@	libbclock.la		\
! @BUILD_MODULES_TRUE@	libbcountdown.la	\
! @BUILD_MODULES_TRUE@	libbdebug.la		\
! @BUILD_MODULES_TRUE@	libbdropout.la		\
! @BUILD_MODULES_TRUE@	libbfire.la		\
! @BUILD_MODULES_TRUE@	libbmatrix.la		\
! @BUILD_MODULES_TRUE@	libbpacman.la		\
! @BUILD_MODULES_TRUE@	libbpong.la		\
! @BUILD_MODULES_TRUE@	libbproxy.la		\
! @BUILD_MODULES_TRUE@	libbpushline.la 	\
! @BUILD_MODULES_TRUE@	libbqix.la		\
! @BUILD_MODULES_TRUE@	libbretris.la	 	\
! @BUILD_MODULES_TRUE@	libbsnake.la		\
! @BUILD_MODULES_TRUE@	libbtetris.la		\
! @BUILD_MODULES_TRUE@	libbtext.la		\
! @BUILD_MODULES_TRUE@	libbxxo.la
  
  
  libbbreakout_la_SOURCES = bbreakout.c
  libbbreakout_la_LDFLAGS = -avoid-version -module
  
--- 71,139 ----
  BLIB_MICRO_VERSION = @BLIB_MICRO_VERSION@
  BLIB_MINOR_VERSION = @BLIB_MINOR_VERSION@
  BLIB_VERSION = @BLIB_VERSION@
  CC = @CC@
  CFLAGS = @CFLAGS@
  CXX = @CXX@
  CXXCPP = @CXXCPP@
  CYGPATH_W = @CYGPATH_W@
  DATADIR = @DATADIR@
  DB2HTML = @DB2HTML@
  DEPDIR = @DEPDIR@
  DIRECTFB_VIEW_TYPE = @DIRECTFB_VIEW_TYPE@
+ DLLTOOL = @DLLTOOL@
  ECHO = @ECHO@
  EGREP = @EGREP@
  EXEEXT = @EXEEXT@
  F77 = @F77@
! GCJ = @GCJ@
! GCJFLAGS = @GCJFLAGS@
  GLIB_CFLAGS = @GLIB_CFLAGS@
  GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
  GLIB_LIBS = @GLIB_LIBS@
  GLIB_MKENUMS = @GLIB_MKENUMS@
  GOBJECT_QUERY = @GOBJECT_QUERY@
  GTKDOC = @GTKDOC@
  GTK_VIEW_TYPE = @GTK_VIEW_TYPE@
  HAVE_GTK_DOC = @HAVE_GTK_DOC@
  HTML_DIR = @HTML_DIR@
  INCLUDEDIR = @INCLUDEDIR@
  INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
  LIBTOOL = @LIBTOOL@
  LN_S = @LN_S@
  LT_AGE = @LT_AGE@
  LT_CURRENT = @LT_CURRENT@
  LT_RELEASE = @LT_RELEASE@
  LT_REVISION = @LT_REVISION@
  MAINT = @MAINT@
  MAKEINFO = @MAKEINFO@
  MODULEPATH = @MODULEPATH@
+ OBJDUMP = @OBJDUMP@
  OBJEXT = @OBJEXT@
  PACKAGE = @PACKAGE@
  PIXBUF_VIEW_TYPE = @PIXBUF_VIEW_TYPE@
  PKG_CONFIG = @PKG_CONFIG@
  RANLIB = @RANLIB@
! RC = @RC@
  STRIP = @STRIP@
  THEMEPATH = @THEMEPATH@
  VERSION = @VERSION@
  WIN32_CFLAGS = @WIN32_CFLAGS@
  WIN32_LIBS = @WIN32_LIBS@
  am__include = @am__include@
  am__leading_dot = @am__leading_dot@
  am__quote = @am__quote@
  install_sh = @install_sh@
  
  libdir = @MODULEPATH@
  
! AM_CPPFLAGS =  	$(CFLAGS)			 -DG_DISABLE_DEPRECATED
! 
! 
! INCLUDES =  	-I$(top_srcdir)			@GLIB_CFLAGS@
  
  
+ @BUILD_MODULES_TRUE@lib_LTLIBRARIES = 	libbbreakout.la			libbclock.la			libbcountdown.la		libbcreatefile.la		libbdebug.la			libbdropout.la			libbfire.la			libbfireworks.la		libbmatrix.la			libbpacman.la			libbpong.la			libbpongmulti.la			libbpongv.la		libbproxy.la			libbpushline.la 		libbqix.la			libbretris.la	 		libbsitris4.la	 		libbsnake.la			libbtetris.la			libbtext.la			libbxxo.la
+ 
  libbbreakout_la_SOURCES = bbreakout.c
  libbbreakout_la_LDFLAGS = -avoid-version -module
  
***************
*** 228,241 ****
  libbcountdown_la_SOURCES = bcountdown.c digits.h
  libbcountdown_la_LDFLAGS = -avoid-version -module
  
  libbdebug_la_SOURCES = bdebug.c digits.h
  libbdebug_la_LDFLAGS = -avoid-version -module
  
  libbfire_la_SOURCES = bfire.c
  libbfire_la_LDFLAGS = -avoid-version -module
  
! libbdropout_la_SOURCES = bdropout.c
! libbdropout_la_LDFLAGS = -avoid-version -module
  
  libbmatrix_la_SOURCES = bmatrix.c
  libbmatrix_la_LDFLAGS = -avoid-version -module
--- 143,162 ----
  libbcountdown_la_SOURCES = bcountdown.c digits.h
  libbcountdown_la_LDFLAGS = -avoid-version -module
  
+ libbcreatefile_la_SOURCES = bcreatefile.c
+ libbcreatefile_la_LDFLAGS = -avoid-version -module
+ 
  libbdebug_la_SOURCES = bdebug.c digits.h
  libbdebug_la_LDFLAGS = -avoid-version -module
  
+ libbdropout_la_SOURCES = bdropout.c
+ libbdropout_la_LDFLAGS = -avoid-version -module
+ 
  libbfire_la_SOURCES = bfire.c
  libbfire_la_LDFLAGS = -avoid-version -module
  
! libbfireworks_la_SOURCES = bfireworks.c
! libbfireworks_la_LDFLAGS = -avoid-version -module
  
  libbmatrix_la_SOURCES = bmatrix.c
  libbmatrix_la_LDFLAGS = -avoid-version -module
***************
*** 246,251 ****
--- 167,178 ----
  libbpong_la_SOURCES = bpong.c digits.h
  libbpong_la_LDFLAGS = -avoid-version -module
  
+ libbpongmulti_la_SOURCES = bpongmulti.c digits.h
+ libbpongmulti_la_LDFLAGS = -avoid-version -module
+ 
+ libbpongv_la_SOURCES = bpongv.c digits.h
+ libbpongv_la_LDFLAGS = -avoid-version -module
+ 
  libbproxy_la_SOURCES = bproxy.c
  libbproxy_la_LDFLAGS = -avoid-version -module
  
***************
*** 258,679 ****
  libbretris_la_SOURCES = bretris.c
  libbretris_la_LDFLAGS = -avoid-version -module
  
  libbsnake_la_SOURCES = bsnake.c
  libbsnake_la_LDFLAGS = -avoid-version -module
  
  libbtetris_la_SOURCES = btetris.c
  libbtetris_la_LDFLAGS = -avoid-version -module
  
! libbtext_la_SOURCES = btext.c
  libbtext_la_LDFLAGS = -avoid-version -module
  
  libbxxo_la_SOURCES = bxxo.c
  libbxxo_la_LDFLAGS = -avoid-version -module
- subdir = modules
- ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
  mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
! CONFIG_HEADER = $(top_builddir)/config.h
! CONFIG_CLEAN_FILES =
! LTLIBRARIES = $(lib_LTLIBRARIES)
! 
! libbbreakout_la_LIBADD =
! am_libbbreakout_la_OBJECTS = bbreakout.lo
! libbbreakout_la_OBJECTS = $(am_libbbreakout_la_OBJECTS)
! libbclock_la_LIBADD =
! am_libbclock_la_OBJECTS = bclock.lo
! libbclock_la_OBJECTS = $(am_libbclock_la_OBJECTS)
! libbcountdown_la_LIBADD =
! am_libbcountdown_la_OBJECTS = bcountdown.lo
! libbcountdown_la_OBJECTS = $(am_libbcountdown_la_OBJECTS)
! libbdebug_la_LIBADD =
! am_libbdebug_la_OBJECTS = bdebug.lo
! libbdebug_la_OBJECTS = $(am_libbdebug_la_OBJECTS)
! libbdropout_la_LIBADD =
! am_libbdropout_la_OBJECTS = bdropout.lo
! libbdropout_la_OBJECTS = $(am_libbdropout_la_OBJECTS)
! libbfire_la_LIBADD =
! am_libbfire_la_OBJECTS = bfire.lo
! libbfire_la_OBJECTS = $(am_libbfire_la_OBJECTS)
! libbmatrix_la_LIBADD =
! am_libbmatrix_la_OBJECTS = bmatrix.lo
! libbmatrix_la_OBJECTS = $(am_libbmatrix_la_OBJECTS)
! libbpacman_la_LIBADD =
! am_libbpacman_la_OBJECTS = bpacman.lo
! libbpacman_la_OBJECTS = $(am_libbpacman_la_OBJECTS)
! libbpong_la_LIBADD =
! am_libbpong_la_OBJECTS = bpong.lo
! libbpong_la_OBJECTS = $(am_libbpong_la_OBJECTS)
! libbproxy_la_LIBADD =
! am_libbproxy_la_OBJECTS = bproxy.lo
! libbproxy_la_OBJECTS = $(am_libbproxy_la_OBJECTS)
! libbpushline_la_LIBADD =
! am_libbpushline_la_OBJECTS = bpushline.lo
! libbpushline_la_OBJECTS = $(am_libbpushline_la_OBJECTS)
! libbqix_la_LIBADD =
! am_libbqix_la_OBJECTS = bqix.lo
! libbqix_la_OBJECTS = $(am_libbqix_la_OBJECTS)
! libbretris_la_LIBADD =
! am_libbretris_la_OBJECTS = bretris.lo
! libbretris_la_OBJECTS = $(am_libbretris_la_OBJECTS)
! libbsnake_la_LIBADD =
! am_libbsnake_la_OBJECTS = bsnake.lo
! libbsnake_la_OBJECTS = $(am_libbsnake_la_OBJECTS)
! libbtetris_la_LIBADD =
! am_libbtetris_la_OBJECTS = btetris.lo
! libbtetris_la_OBJECTS = $(am_libbtetris_la_OBJECTS)
! libbtext_la_LIBADD =
! am_libbtext_la_OBJECTS = btext.lo
! libbtext_la_OBJECTS = $(am_libbtext_la_OBJECTS)
! libbxxo_la_LIBADD =
! am_libbxxo_la_OBJECTS = bxxo.lo
! libbxxo_la_OBJECTS = $(am_libbxxo_la_OBJECTS)
! 
! DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
! depcomp = $(SHELL) $(top_srcdir)/depcomp
! am__depfiles_maybe = depfiles
! @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/bbreakout.Plo ./$(DEPDIR)/bclock.Plo \
! @AMDEP_TRUE@	./$(DEPDIR)/bcountdown.Plo ./$(DEPDIR)/bdebug.Plo \
! @AMDEP_TRUE@	./$(DEPDIR)/bdropout.Plo ./$(DEPDIR)/bfire.Plo \
! @AMDEP_TRUE@	./$(DEPDIR)/bmatrix.Plo ./$(DEPDIR)/bpacman.Plo \
! @AMDEP_TRUE@	./$(DEPDIR)/bpong.Plo ./$(DEPDIR)/bproxy.Plo \
! @AMDEP_TRUE@	./$(DEPDIR)/bpushline.Plo ./$(DEPDIR)/bqix.Plo \
! @AMDEP_TRUE@	./$(DEPDIR)/bretris.Plo ./$(DEPDIR)/bsnake.Plo \
! @AMDEP_TRUE@	./$(DEPDIR)/btetris.Plo ./$(DEPDIR)/btext.Plo \
! @AMDEP_TRUE@	./$(DEPDIR)/bxxo.Plo
! COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
! 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
! LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
! 	$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
  CCLD = $(CC)
! LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
! 	$(AM_LDFLAGS) $(LDFLAGS) -o $@
! DIST_SOURCES = $(libbbreakout_la_SOURCES) $(libbclock_la_SOURCES) \
! 	$(libbcountdown_la_SOURCES) $(libbdebug_la_SOURCES) \
! 	$(libbdropout_la_SOURCES) $(libbfire_la_SOURCES) \
! 	$(libbmatrix_la_SOURCES) $(libbpacman_la_SOURCES) \
! 	$(libbpong_la_SOURCES) $(libbproxy_la_SOURCES) \
! 	$(libbpushline_la_SOURCES) $(libbqix_la_SOURCES) \
! 	$(libbretris_la_SOURCES) $(libbsnake_la_SOURCES) \
! 	$(libbtetris_la_SOURCES) $(libbtext_la_SOURCES) \
! 	$(libbxxo_la_SOURCES)
! DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
! SOURCES = $(libbbreakout_la_SOURCES) $(libbclock_la_SOURCES) $(libbcountdown_la_SOURCES) $(libbdebug_la_SOURCES) $(libbdropout_la_SOURCES) $(libbfire_la_SOURCES) $(libbmatrix_la_SOURCES) $(libbpacman_la_SOURCES) $(libbpong_la_SOURCES) $(libbproxy_la_SOURCES) $(libbpushline_la_SOURCES) $(libbqix_la_SOURCES) $(libbretris_la_SOURCES) $(libbsnake_la_SOURCES) $(libbtetris_la_SOURCES) $(libbtext_la_SOURCES) $(libbxxo_la_SOURCES)
  
! all: all-am
  
  .SUFFIXES:
! .SUFFIXES: .c .lo .o .obj
! $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
! 	cd $(top_srcdir) && \
! 	  $(AUTOMAKE) --gnu  modules/Makefile
! Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in  $(top_builddir)/config.status
! 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
! libLTLIBRARIES_INSTALL = $(INSTALL)
  install-libLTLIBRARIES: $(lib_LTLIBRARIES)
  	@$(NORMAL_INSTALL)
  	$(mkinstalldirs) $(DESTDIR)$(libdir)
  	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
  	  if test -f $$p; then \
! 	    f="`echo $$p | sed -e 's|^.*/||'`"; \
! 	    echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
! 	    $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
  	  else :; fi; \
  	done
  
  uninstall-libLTLIBRARIES:
  	@$(NORMAL_UNINSTALL)
! 	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
! 	    p="`echo $$p | sed -e 's|^.*/||'`"; \
! 	  echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
! 	  $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
  	done
  
! clean-libLTLIBRARIES:
! 	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
! 	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
! 	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
! 	  test "$$dir" = "$$p" && dir=.; \
! 	  echo "rm -f \"$${dir}/so_locations\""; \
! 	  rm -f "$${dir}/so_locations"; \
! 	done
! libbbreakout.la: $(libbbreakout_la_OBJECTS) $(libbbreakout_la_DEPENDENCIES) 
  	$(LINK) -rpath $(libdir) $(libbbreakout_la_LDFLAGS) $(libbbreakout_la_OBJECTS) $(libbbreakout_la_LIBADD) $(LIBS)
! libbclock.la: $(libbclock_la_OBJECTS) $(libbclock_la_DEPENDENCIES) 
  	$(LINK) -rpath $(libdir) $(libbclock_la_LDFLAGS) $(libbclock_la_OBJECTS) $(libbclock_la_LIBADD) $(LIBS)
! libbcountdown.la: $(libbcountdown_la_OBJECTS) $(libbcountdown_la_DEPENDENCIES) 
  	$(LINK) -rpath $(libdir) $(libbcountdown_la_LDFLAGS) $(libbcountdown_la_OBJECTS) $(libbcountdown_la_LIBADD) $(LIBS)
! libbdebug.la: $(libbdebug_la_OBJECTS) $(libbdebug_la_DEPENDENCIES) 
  	$(LINK) -rpath $(libdir) $(libbdebug_la_LDFLAGS) $(libbdebug_la_OBJECTS) $(libbdebug_la_LIBADD) $(LIBS)
! libbdropout.la: $(libbdropout_la_OBJECTS) $(libbdropout_la_DEPENDENCIES) 
  	$(LINK) -rpath $(libdir) $(libbdropout_la_LDFLAGS) $(libbdropout_la_OBJECTS) $(libbdropout_la_LIBADD) $(LIBS)
! libbfire.la: $(libbfire_la_OBJECTS) $(libbfire_la_DEPENDENCIES) 
  	$(LINK) -rpath $(libdir) $(libbfire_la_LDFLAGS) $(libbfire_la_OBJECTS) $(libbfire_la_LIBADD) $(LIBS)
! libbmatrix.la: $(libbmatrix_la_OBJECTS) $(libbmatrix_la_DEPENDENCIES) 
  	$(LINK) -rpath $(libdir) $(libbmatrix_la_LDFLAGS) $(libbmatrix_la_OBJECTS) $(libbmatrix_la_LIBADD) $(LIBS)
! libbpacman.la: $(libbpacman_la_OBJECTS) $(libbpacman_la_DEPENDENCIES) 
  	$(LINK) -rpath $(libdir) $(libbpacman_la_LDFLAGS) $(libbpacman_la_OBJECTS) $(libbpacman_la_LIBADD) $(LIBS)
! libbpong.la: $(libbpong_la_OBJECTS) $(libbpong_la_DEPENDENCIES) 
  	$(LINK) -rpath $(libdir) $(libbpong_la_LDFLAGS) $(libbpong_la_OBJECTS) $(libbpong_la_LIBADD) $(LIBS)
- libbproxy.la: $(libbproxy_la_OBJECTS) $(libbproxy_la_DEPENDENCIES) 
- 	$(LINK) -rpath $(libdir) $(libbproxy_la_LDFLAGS) $(libbproxy_la_OBJECTS) $(libbproxy_la_LIBADD) $(LIBS)
- libbpushline.la: $(libbpushline_la_OBJECTS) $(libbpushline_la_DEPENDENCIES) 
- 	$(LINK) -rpath $(libdir) $(libbpushline_la_LDFLAGS) $(libbpushline_la_OBJECTS) $(libbpushline_la_LIBADD) $(LIBS)
- libbqix.la: $(libbqix_la_OBJECTS) $(libbqix_la_DEPENDENCIES) 
- 	$(LINK) -rpath $(libdir) $(libbqix_la_LDFLAGS) $(libbqix_la_OBJECTS) $(libbqix_la_LIBADD) $(LIBS)
- libbretris.la: $(libbretris_la_OBJECTS) $(libbretris_la_DEPENDENCIES) 
- 	$(LINK) -rpath $(libdir) $(libbretris_la_LDFLAGS) $(libbretris_la_OBJECTS) $(libbretris_la_LIBADD) $(LIBS)
- libbsnake.la: $(libbsnake_la_OBJECTS) $(libbsnake_la_DEPENDENCIES) 
- 	$(LINK) -rpath $(libdir) $(libbsnake_la_LDFLAGS) $(libbsnake_la_OBJECTS) $(libbsnake_la_LIBADD) $(LIBS)
- libbtetris.la: $(libbtetris_la_OBJECTS) $(libbtetris_la_DEPENDENCIES) 
- 	$(LINK) -rpath $(libdir) $(libbtetris_la_LDFLAGS) $(libbtetris_la_OBJECTS) $(libbtetris_la_LIBADD) $(LIBS)
- libbtext.la: $(libbtext_la_OBJECTS) $(libbtext_la_DEPENDENCIES) 
- 	$(LINK) -rpath $(libdir) $(libbtext_la_LDFLAGS) $(libbtext_la_OBJECTS) $(libbtext_la_LIBADD) $(LIBS)
- libbxxo.la: $(libbxxo_la_OBJECTS) $(libbxxo_la_DEPENDENCIES) 
- 	$(LINK) -rpath $(libdir) $(libbxxo_la_LDFLAGS) $(libbxxo_la_OBJECTS) $(libbxxo_la_LIBADD) $(LIBS)
  
! mostlyclean-compile:
! 	-rm -f *.$(OBJEXT) core *.core
  
! distclean-compile:
! 	-rm -f *.tab.c
  
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bbreakout.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bclock.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bcountdown.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bdebug.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bdropout.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bfire.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmatrix.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bpacman.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bpong.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bproxy.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bpushline.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bqix.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bretris.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsnake.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btetris.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btext.Plo@am__quote@
! @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bxxo.Plo@am__quote@
! 
! .c.o:
! @am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
! @am__fastdepCC_TRUE@	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
! @am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
! @am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
! @am__fastdepCC_TRUE@	fi
! @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
! @AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
! @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
! @am__fastdepCC_FALSE@	$(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
  
! .c.obj:
! @am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
! @am__fastdepCC_TRUE@	  -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
! @am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
! @am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
! @am__fastdepCC_TRUE@	fi
! @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
! @AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
! @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
! @am__fastdepCC_FALSE@	$(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
! 
! .c.lo:
! @am__fastdepCC_TRUE@	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
! @am__fastdepCC_TRUE@	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
! @am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
! @am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
! @am__fastdepCC_TRUE@	fi
! @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
! @AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
! @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
! @am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
  
! mostlyclean-libtool:
! 	-rm -f *.lo
  
! clean-libtool:
! 	-rm -rf .libs _libs
  
! distclean-libtool:
! 	-rm -f libtool
! uninstall-info-am:
  
! ETAGS = etags
! ETAGSFLAGS =
  
! CTAGS = ctags
! CTAGSFLAGS =
  
  tags: TAGS
  
! 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; } \
  	       END { for (i in files) print i; }'`; \
! 	mkid -fID $$unique
  
! 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; } \
! 	       END { for (i in files) print i; }'`; \
! 	test -z "$(ETAGS_ARGS)$$tags$$unique" \
! 	  || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
! 	     $$tags $$unique
! 
! ctags: CTAGS
! CTAGS:  $(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; } \
  	       END { 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
! DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
  
! top_distdir = ..
! distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
  
  distdir: $(DISTFILES)
! 	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
! 	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
! 	list='$(DISTFILES)'; for file in $$list; do \
! 	  case $$file in \
! 	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
! 	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
! 	  esac; \
! 	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
! 	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
! 	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
! 	    dir="/$$dir"; \
! 	    $(mkinstalldirs) "$(distdir)$$dir"; \
! 	  else \
! 	    dir=''; \
! 	  fi; \
  	  if test -d $$d/$$file; then \
! 	    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 $(LTLIBRARIES)
! 
! installdirs:
! 	$(mkinstalldirs) $(DESTDIR)$(libdir)
! 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:
! 	-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 clean-libLTLIBRARIES clean-libtool \
! 	mostlyclean-am
! 
! distclean: distclean-am
! 	-rm -rf ./$(DEPDIR)
! 	-rm -f Makefile
! distclean-am: clean-am distclean-compile distclean-generic \
! 	distclean-libtool distclean-tags
! 
! dvi: dvi-am
  
! dvi-am:
! 
! info: info-am
  
! info-am:
  
! install-data-am:
! 
! install-exec-am: install-libLTLIBRARIES
  
! install-info: install-info-am
  
! install-man:
  
! 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 \
- 	mostlyclean-libtool
- 
- pdf: pdf-am
- 
- pdf-am:
  
! ps: ps-am
  
- ps-am:
- 
- uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
- 
- .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- 	clean-libLTLIBRARIES clean-libtool ctags distclean \
- 	distclean-compile distclean-generic distclean-libtool \
- 	distclean-tags distdir dvi dvi-am info info-am install \
- 	install-am install-data install-data-am install-exec \
- 	install-exec-am install-info install-info-am \
- 	install-libLTLIBRARIES install-man install-strip installcheck \
- 	installcheck-am installdirs maintainer-clean \
- 	maintainer-clean-generic mostlyclean mostlyclean-compile \
- 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- 	tags uninstall uninstall-am uninstall-info-am \
- 	uninstall-libLTLIBRARIES
  
  # 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.
--- 185,576 ----
  libbretris_la_SOURCES = bretris.c
  libbretris_la_LDFLAGS = -avoid-version -module
  
+ libbsitris4_la_SOURCES = bsitris4.c
+ libbsitris4_la_LDFLAGS = -avoid-version -module
+ 
  libbsnake_la_SOURCES = bsnake.c
  libbsnake_la_LDFLAGS = -avoid-version -module
  
  libbtetris_la_SOURCES = btetris.c
  libbtetris_la_LDFLAGS = -avoid-version -module
  
! libbtext_la_SOURCES = btext.c characters.c characters.h
  libbtext_la_LDFLAGS = -avoid-version -module
  
  libbxxo_la_SOURCES = bxxo.c
  libbxxo_la_LDFLAGS = -avoid-version -module
  mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
! CONFIG_HEADER = ../config.h ../$@)]
! CONFIG_CLEAN_FILES = 
! LTLIBRARIES =  $(lib_LTLIBRARIES)
! 
! 
! DEFS = @DEFS@ -I. -I$(srcdir) -I.. -I..
! CPPFLAGS = @CPPFLAGS@
! LDFLAGS = @LDFLAGS@
! LIBS = @LIBS@
! libbbreakout_la_LIBADD = 
! libbbreakout_la_OBJECTS =  bbreakout.lo
! libbclock_la_LIBADD = 
! libbclock_la_OBJECTS =  bclock.lo
! libbcountdown_la_LIBADD = 
! libbcountdown_la_OBJECTS =  bcountdown.lo
! libbcreatefile_la_LIBADD = 
! libbcreatefile_la_OBJECTS =  bcreatefile.lo
! libbdebug_la_LIBADD = 
! libbdebug_la_OBJECTS =  bdebug.lo
! libbdropout_la_LIBADD = 
! libbdropout_la_OBJECTS =  bdropout.lo
! libbfire_la_LIBADD = 
! libbfire_la_OBJECTS =  bfire.lo
! libbfireworks_la_LIBADD = 
! libbfireworks_la_OBJECTS =  bfireworks.lo
! libbmatrix_la_LIBADD = 
! libbmatrix_la_OBJECTS =  bmatrix.lo
! libbpacman_la_LIBADD = 
! libbpacman_la_OBJECTS =  bpacman.lo
! libbpong_la_LIBADD = 
! libbpong_la_OBJECTS =  bpong.lo
! libbpongmulti_la_LIBADD = 
! libbpongmulti_la_OBJECTS =  bpongmulti.lo
! libbpongv_la_LIBADD = 
! libbpongv_la_OBJECTS =  bpongv.lo
! libbproxy_la_LIBADD = 
! libbproxy_la_OBJECTS =  bproxy.lo
! libbpushline_la_LIBADD = 
! libbpushline_la_OBJECTS =  bpushline.lo
! libbqix_la_LIBADD = 
! libbqix_la_OBJECTS =  bqix.lo
! libbretris_la_LIBADD = 
! libbretris_la_OBJECTS =  bretris.lo
! libbsitris4_la_LIBADD = 
! libbsitris4_la_OBJECTS =  bsitris4.lo
! libbsnake_la_LIBADD = 
! libbsnake_la_OBJECTS =  bsnake.lo
! libbtetris_la_LIBADD = 
! libbtetris_la_OBJECTS =  btetris.lo
! libbtext_la_LIBADD = 
! libbtext_la_OBJECTS =  btext.lo characters.lo
! libbxxo_la_LIBADD = 
! libbxxo_la_OBJECTS =  bxxo.lo
! COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
! LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
  CCLD = $(CC)
! LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
! DIST_COMMON =  Makefile.am Makefile.in
! 
  
! DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
  
+ TAR = tar
+ GZIP_ENV = --best
+ DEP_FILES =  .deps/bbreakout.P .deps/bclock.P .deps/bcountdown.P \
+ .deps/bcreatefile.P .deps/bdebug.P .deps/bdropout.P .deps/bfire.P \
+ .deps/bfireworks.P .deps/bmatrix.P .deps/bpacman.P .deps/bpong.P \
+ .deps/bpongmulti.P .deps/bpongv.P .deps/bproxy.P .deps/bpushline.P \
+ .deps/bqix.P .deps/bretris.P .deps/bsitris4.P .deps/bsnake.P \
+ .deps/btetris.P .deps/btext.P .deps/bxxo.P .deps/characters.P
+ SOURCES = $(libbbreakout_la_SOURCES) $(libbclock_la_SOURCES) $(libbcountdown_la_SOURCES) $(libbcreatefile_la_SOURCES) $(libbdebug_la_SOURCES) $(libbdropout_la_SOURCES) $(libbfire_la_SOURCES) $(libbfireworks_la_SOURCES) $(libbmatrix_la_SOURCES) $(libbpacman_la_SOURCES) $(libbpong_la_SOURCES) $(libbpongmulti_la_SOURCES) $(libbpongv_la_SOURCES) $(libbproxy_la_SOURCES) $(libbpushline_la_SOURCES) $(libbqix_la_SOURCES) $(libbretris_la_SOURCES) $(libbsitris4_la_SOURCES) $(libbsnake_la_SOURCES) $(libbtetris_la_SOURCES) $(libbtext_la_SOURCES) $(libbxxo_la_SOURCES)
+ OBJECTS = $(libbbreakout_la_OBJECTS) $(libbclock_la_OBJECTS) $(libbcountdown_la_OBJECTS) $(libbcreatefile_la_OBJECTS) $(libbdebug_la_OBJECTS) $(libbdropout_la_OBJECTS) $(libbfire_la_OBJECTS) $(libbfireworks_la_OBJECTS) $(libbmatrix_la_OBJECTS) $(libbpacman_la_OBJECTS) $(libbpong_la_OBJECTS) $(libbpongmulti_la_OBJECTS) $(libbpongv_la_OBJECTS) $(libbproxy_la_OBJECTS) $(libbpushline_la_OBJECTS) $(libbqix_la_OBJECTS) $(libbretris_la_OBJECTS) $(libbsitris4_la_OBJECTS) $(libbsnake_la_OBJECTS) $(libbtetris_la_OBJECTS) $(libbtext_la_OBJECTS) $(libbxxo_la_OBJECTS)
+ 
+ all: all-redirect
  .SUFFIXES:
! .SUFFIXES: .S .c .lo .o .obj .s
! $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
! 	cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/Makefile
! 
! Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
! 	cd $(top_builddir) \
! 	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
! 
! 
! mostlyclean-libLTLIBRARIES:
! 
! clean-libLTLIBRARIES:
! 	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
! 
! distclean-libLTLIBRARIES:
! 
! maintainer-clean-libLTLIBRARIES:
! 
  install-libLTLIBRARIES: $(lib_LTLIBRARIES)
  	@$(NORMAL_INSTALL)
  	$(mkinstalldirs) $(DESTDIR)$(libdir)
  	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
  	  if test -f $$p; then \
! 	    echo "$(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
! 	    $(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
  	  else :; fi; \
  	done
  
  uninstall-libLTLIBRARIES:
  	@$(NORMAL_UNINSTALL)
! 	list='$(lib_LTLIBRARIES)'; for p in $$list; do \
! 	  $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
  	done
  
! # FIXME: We should only use cygpath when building on Windows,
! # and only if it is available.
! .c.obj:
! 	$(COMPILE) -c `cygpath -w $<`
! 
! .s.o:
! 	$(COMPILE) -c $<
! 
! .S.o:
! 	$(COMPILE) -c $<
! 
! mostlyclean-compile:
! 	-rm -f *.o core *.core
! 	-rm -f *.$(OBJEXT)
! 
! clean-compile:
! 
! distclean-compile:
! 	-rm -f *.tab.c
! 
! maintainer-clean-compile:
! 
! .s.lo:
! 	$(LIBTOOL) --mode=compile $(COMPILE) -c $<
! 
! .S.lo:
! 	$(LIBTOOL) --mode=compile $(COMPILE) -c $<
! 
! mostlyclean-libtool:
! 	-rm -f *.lo
! 
! clean-libtool:
! 	-rm -rf .libs _libs
! 
! distclean-libtool:
! 
! maintainer-clean-libtool:
! 
! libbbreakout.la: $(libbbreakout_la_OBJECTS) $(libbbreakout_la_DEPENDENCIES)
  	$(LINK) -rpath $(libdir) $(libbbreakout_la_LDFLAGS) $(libbbreakout_la_OBJECTS) $(libbbreakout_la_LIBADD) $(LIBS)
! 
! libbclock.la: $(libbclock_la_OBJECTS) $(libbclock_la_DEPENDENCIES)
  	$(LINK) -rpath $(libdir) $(libbclock_la_LDFLAGS) $(libbclock_la_OBJECTS) $(libbclock_la_LIBADD) $(LIBS)
! 
! libbcountdown.la: $(libbcountdown_la_OBJECTS) $(libbcountdown_la_DEPENDENCIES)
  	$(LINK) -rpath $(libdir) $(libbcountdown_la_LDFLAGS) $(libbcountdown_la_OBJECTS) $(libbcountdown_la_LIBADD) $(LIBS)
! 
! libbcreatefile.la: $(libbcreatefile_la_OBJECTS) $(libbcreatefile_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbcreatefile_la_LDFLAGS) $(libbcreatefile_la_OBJECTS) $(libbcreatefile_la_LIBADD) $(LIBS)
! 
! libbdebug.la: $(libbdebug_la_OBJECTS) $(libbdebug_la_DEPENDENCIES)
  	$(LINK) -rpath $(libdir) $(libbdebug_la_LDFLAGS) $(libbdebug_la_OBJECTS) $(libbdebug_la_LIBADD) $(LIBS)
! 
! libbdropout.la: $(libbdropout_la_OBJECTS) $(libbdropout_la_DEPENDENCIES)
  	$(LINK) -rpath $(libdir) $(libbdropout_la_LDFLAGS) $(libbdropout_la_OBJECTS) $(libbdropout_la_LIBADD) $(LIBS)
! 
! libbfire.la: $(libbfire_la_OBJECTS) $(libbfire_la_DEPENDENCIES)
  	$(LINK) -rpath $(libdir) $(libbfire_la_LDFLAGS) $(libbfire_la_OBJECTS) $(libbfire_la_LIBADD) $(LIBS)
! 
! libbfireworks.la: $(libbfireworks_la_OBJECTS) $(libbfireworks_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbfireworks_la_LDFLAGS) $(libbfireworks_la_OBJECTS) $(libbfireworks_la_LIBADD) $(LIBS)
! 
! libbmatrix.la: $(libbmatrix_la_OBJECTS) $(libbmatrix_la_DEPENDENCIES)
  	$(LINK) -rpath $(libdir) $(libbmatrix_la_LDFLAGS) $(libbmatrix_la_OBJECTS) $(libbmatrix_la_LIBADD) $(LIBS)
! 
! libbpacman.la: $(libbpacman_la_OBJECTS) $(libbpacman_la_DEPENDENCIES)
  	$(LINK) -rpath $(libdir) $(libbpacman_la_LDFLAGS) $(libbpacman_la_OBJECTS) $(libbpacman_la_LIBADD) $(LIBS)
! 
! libbpong.la: $(libbpong_la_OBJECTS) $(libbpong_la_DEPENDENCIES)
  	$(LINK) -rpath $(libdir) $(libbpong_la_LDFLAGS) $(libbpong_la_OBJECTS) $(libbpong_la_LIBADD) $(LIBS)
  
! libbpongmulti.la: $(libbpongmulti_la_OBJECTS) $(libbpongmulti_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbpongmulti_la_LDFLAGS) $(libbpongmulti_la_OBJECTS) $(libbpongmulti_la_LIBADD) $(LIBS)
  
! libbpongv.la: $(libbpongv_la_OBJECTS) $(libbpongv_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbpongv_la_LDFLAGS) $(libbpongv_la_OBJECTS) $(libbpongv_la_LIBADD) $(LIBS)
  
! libbproxy.la: $(libbproxy_la_OBJECTS) $(libbproxy_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbproxy_la_LDFLAGS) $(libbproxy_la_OBJECTS) $(libbproxy_la_LIBADD) $(LIBS)
  
! libbpushline.la: $(libbpushline_la_OBJECTS) $(libbpushline_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbpushline_la_LDFLAGS) $(libbpushline_la_OBJECTS) $(libbpushline_la_LIBADD) $(LIBS)
  
! libbqix.la: $(libbqix_la_OBJECTS) $(libbqix_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbqix_la_LDFLAGS) $(libbqix_la_OBJECTS) $(libbqix_la_LIBADD) $(LIBS)
  
! libbretris.la: $(libbretris_la_OBJECTS) $(libbretris_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbretris_la_LDFLAGS) $(libbretris_la_OBJECTS) $(libbretris_la_LIBADD) $(LIBS)
  
! libbsitris4.la: $(libbsitris4_la_OBJECTS) $(libbsitris4_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbsitris4_la_LDFLAGS) $(libbsitris4_la_OBJECTS) $(libbsitris4_la_LIBADD) $(LIBS)
! 
! libbsnake.la: $(libbsnake_la_OBJECTS) $(libbsnake_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbsnake_la_LDFLAGS) $(libbsnake_la_OBJECTS) $(libbsnake_la_LIBADD) $(LIBS)
  
! libbtetris.la: $(libbtetris_la_OBJECTS) $(libbtetris_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbtetris_la_LDFLAGS) $(libbtetris_la_OBJECTS) $(libbtetris_la_LIBADD) $(LIBS)
! 
! libbtext.la: $(libbtext_la_OBJECTS) $(libbtext_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbtext_la_LDFLAGS) $(libbtext_la_OBJECTS) $(libbtext_la_LIBADD) $(LIBS)
  
! libbxxo.la: $(libbxxo_la_OBJECTS) $(libbxxo_la_DEPENDENCIES)
! 	$(LINK) -rpath $(libdir) $(libbxxo_la_LDFLAGS) $(libbxxo_la_OBJECTS) $(libbxxo_la_LIBADD) $(LIBS)
  
  tags: TAGS
  
! ID: $(HEADERS) $(SOURCES) $(LISP)
! 	list='$(SOURCES) $(HEADERS)'; \
! 	unique=`for i in $$list; do echo $$i; done | \
! 	  awk '    { files[$$0] = 1; } \
  	       END { for (i in files) print i; }'`; \
! 	here=`pwd` && cd $(srcdir) \
! 	  && mkid -f$$here/ID $$unique $(LISP)
  
! TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
  	tags=; \
  	here=`pwd`; \
! 	list='$(SOURCES) $(HEADERS)'; \
! 	unique=`for i in $$list; do echo $$i; done | \
! 	  awk '    { files[$$0] = 1; } \
  	       END { for (i in files) print i; }'`; \
! 	test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
! 	  || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags  $$unique $(LISP))
! 
! mostlyclean-tags:
! 
! clean-tags:
  
  distclean-tags:
! 	-rm -f TAGS ID
! 
! maintainer-clean-tags:
  
! distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
! 
! subdir = modules
  
  distdir: $(DISTFILES)
! 	here=`cd $(top_builddir) && pwd`; \
! 	top_distdir=`cd $(top_distdir) && pwd`; \
! 	distdir=`cd $(distdir) && pwd`; \
! 	cd $(top_srcdir) \
! 	  && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu modules/Makefile
! 	@for file in $(DISTFILES); do \
! 	  d=$(srcdir); \
  	  if test -d $$d/$$file; then \
! 	    cp -pr $$d/$$file $(distdir)/$$file; \
  	  else \
  	    test -f $(distdir)/$$file \
! 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
! 	    || cp -p $$d/$$file $(distdir)/$$file || :; \
  	  fi; \
  	done
+ 
+ DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+ 
+ -include $(DEP_FILES)
+ 
+ mostlyclean-depend:
+ 
+ clean-depend:
+ 
+ distclean-depend:
+ 	-rm -rf .deps
+ 
+ maintainer-clean-depend:
+ 
+ %.o: %.c
+ 	@echo '$(COMPILE) -c $<'; \
+ 	$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ 	@-cp .deps/$(*F).pp .deps/$(*F).P; \
+ 	tr ' ' '\012' < .deps/$(*F).pp \
+ 	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ 	    >> .deps/$(*F).P; \
+ 	rm .deps/$(*F).pp
+ 
+ %.lo: %.c
+ 	@echo '$(LTCOMPILE) -c $<'; \
+ 	$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ 	@-sed -e 's/^\([^:]*\)\.o[ 	]*:/\1.lo \1.o :/' \
+ 	  < .deps/$(*F).pp > .deps/$(*F).P; \
+ 	tr ' ' '\012' < .deps/$(*F).pp \
+ 	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ 	    >> .deps/$(*F).P; \
+ 	rm -f .deps/$(*F).pp
+ info-am:
+ info: info-am
+ dvi-am:
+ dvi: dvi-am
  check-am: all-am
  check: check-am
! installcheck-am:
! installcheck: installcheck-am
! install-exec-am: install-libLTLIBRARIES
  install-exec: install-exec-am
+ 
+ install-data-am:
  install-data: install-data-am
  
  install-am: all-am
  	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
! install: install-am
! uninstall-am: uninstall-libLTLIBRARIES
! uninstall: uninstall-am
! all-am: Makefile $(LTLIBRARIES)
! all-redirect: all-am
  install-strip:
! 	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
! installdirs:
! 	$(mkinstalldirs)  $(DESTDIR)$(libdir)
! 
! 
  mostlyclean-generic:
  
  clean-generic:
  
  distclean-generic:
! 	-rm -f Makefile $(CONFIG_CLEAN_FILES)
! 	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
  
  maintainer-clean-generic:
! mostlyclean-am:  mostlyclean-libLTLIBRARIES mostlyclean-compile \
! 		mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
! 		mostlyclean-generic
  
! mostlyclean: mostlyclean-am
  
! clean-am:  clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \
! 		clean-depend clean-generic mostlyclean-am
  
! clean: clean-am
  
! distclean-am:  distclean-libLTLIBRARIES distclean-compile \
! 		distclean-libtool distclean-tags distclean-depend \
! 		distclean-generic clean-am
! 	-rm -f libtool
  
! distclean: distclean-am
  
! maintainer-clean-am:  maintainer-clean-libLTLIBRARIES \
! 		maintainer-clean-compile maintainer-clean-libtool \
! 		maintainer-clean-tags maintainer-clean-depend \
! 		maintainer-clean-generic distclean-am
! 	@echo "This command is intended for maintainers to use;"
! 	@echo "it deletes files that may require special tools to rebuild."
  
  maintainer-clean: maintainer-clean-am
  
! .PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
! clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
! uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
! distclean-compile clean-compile maintainer-clean-compile \
! mostlyclean-libtool distclean-libtool clean-libtool \
! maintainer-clean-libtool tags mostlyclean-tags distclean-tags \
! clean-tags maintainer-clean-tags distdir mostlyclean-depend \
! distclean-depend clean-depend maintainer-clean-depend info-am info \
! dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
! install-exec install-data-am install-data install-am install \
! uninstall-am uninstall all-redirect all-am all installdirs \
! mostlyclean-generic distclean-generic clean-generic \
! maintainer-clean-generic clean mostlyclean distclean maintainer-clean
  
  
  # 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.
diff -r -C 3 -N blib-1.1.7/modules/bbreakout.c blib-1.1.7-ba20070811/modules/bbreakout.c
*** blib-1.1.7/modules/bbreakout.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bbreakout.c	Sat Aug 11 22:18:43 2007
***************
*** 3,9 ****
   * Copyright (c) 2002  1stein <1stein@1stein.no-ip.com>
   *
   * based on Test implementation for a BModule by the Blinkenlights Crew
!  * 
   * 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
--- 3,9 ----
   * Copyright (c) 2002  1stein <1stein@1stein.no-ip.com>
   *
   * based on Test implementation for a BModule by the Blinkenlights Crew
!  *
   * 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
***************
*** 33,71 ****
  #define BBreakoutVerMin 0
  #define BBreakoutVerRev 0
  
! //minimum size and color count of display
  #define BBreakoutSizeXMin 18
  #define BBreakoutSizeYMin 15
  #define BBreakoutColorCntMin 4
! //minimum number of free pixel rows over player
  #define BBreakoutFreeRowsMin 3
! //size of stones
  #define BBreakoutStoneSizeX 3
  #define BBreakoutStoneSizeY 1
! //number of lives for player
  #define BBreakoutLives 5
! //speed of game
  #define BBreakoutTicks 120
! //number of ticks player is dead after missing a ball
  #define BBreakoutDeadTime 10
  
  #define BBreakoutAutoStart TRUE
  
! //the colors
! #define BBreakoutColorEmpty( MaxColor ) (0)
! #define BBreakoutColorStone1( MaxColor ) ((MaxColor) / 2)
! #define BBreakoutColorStone2( MaxColor ) ((MaxColor) * 3 / 4)
! #define BBreakoutColorStone3( MaxColor ) (MaxColor)
! #define BBreakoutColorBall( MaxColor ) (MaxColor)
! #define BBreakoutColorPlayerDead( MaxColor ) ((MaxColor) / 2)
! #define BBreakoutColorPlayerDeadBlink( MaxColor ) ((MaxColor) / 4)
! #define BBreakoutColorPlayerAlive( MaxColor ) ((MaxColor) * 3 / 4)
  
  #ifdef BREAKOUT_DEBUG
  #define dbg_print g_print
  #else
  static inline void
! dbg_print (char * Fmt, ...)
  {
  }
  #endif
--- 33,71 ----
  #define BBreakoutVerMin 0
  #define BBreakoutVerRev 0
  
! /* minimum size and color count of display */
  #define BBreakoutSizeXMin 18
  #define BBreakoutSizeYMin 15
  #define BBreakoutColorCntMin 4
! /* minimum number of free pixel rows over player */
  #define BBreakoutFreeRowsMin 3
! /* size of stones */
  #define BBreakoutStoneSizeX 3
  #define BBreakoutStoneSizeY 1
! /* number of lives for player */
  #define BBreakoutLives 5
! /* speed of game */
  #define BBreakoutTicks 120
! /* number of ticks player is dead after missing a ball */
  #define BBreakoutDeadTime 10
  
  #define BBreakoutAutoStart TRUE
  
! /* the colors */
! #define BBreakoutColorEmpty(MaxColor)           (0)
! #define BBreakoutColorStone1(MaxColor)          ((MaxColor) / 2)
! #define BBreakoutColorStone2(MaxColor)          ((MaxColor) * 3 / 4)
! #define BBreakoutColorStone3(MaxColor)          (MaxColor)
! #define BBreakoutColorBall(MaxColor)            (MaxColor)
! #define BBreakoutColorPlayerDead(MaxColor)      ((MaxColor) / 2)
! #define BBreakoutColorPlayerDeadBlink(MaxColor) ((MaxColor) / 4)
! #define BBreakoutColorPlayerAlive(MaxColor)     ((MaxColor) * 3 / 4)
  
  #ifdef BREAKOUT_DEBUG
  #define dbg_print g_print
  #else
  static inline void
! dbg_print (gchar * Fmt, ...)
  {
  }
  #endif
***************
*** 75,105 ****
  #define B_BREAKOUT_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_BREAKOUT_MODULE, BBreakoutModuleClass))
  #define B_IS_BREAKOUT_MODULE(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_BREAKOUT_MODULE))
  
! typedef struct _BBreakoutModule BBreakoutModule;
  typedef struct _BBreakoutModuleClass BBreakoutModuleClass;
  
  struct _BBreakoutModule
  {
    BModule parent_instance;
  
!   int MaxColor;                   //maximum color value
!   int FreeRows;                   //number of free pixel rows over player
!   int StoneCntX, StoneCntY;       //number of stones in field
!   int StoneSizeX, StoneSizeY;     //size of stone area of game-field
!   int SizeX, SizeY;               //size of game-field
!   int OfsX, OfsY;                 //offset of top left corner of game-field
!   int PlayerSizeX, PlayerPosY;    //x-size and y-position of player
!   int PlayerPosXMax, PlayerStepX; //maximum x-position and x-step-size of player
!   int * * ppStones;               //two-dimensional array with stones
!   int StoneCnt;                   //number of stones left in game
!   int Lives;                      //rest of player's lives
!   int DeadCnt;                    //number of ticks player is dead, 0 if player is alive
!   int PlayerPosX;                 //x-position of (left corner of) player
!   int BallActive;                 //!0 if ball is flying, 0 if ball is at player
!   int BallPosX, BallPosY;         //position of ball (if ball is flying)
!   int BallDirX, BallDirY;         //direction of ball (if ball is flying)
! 
!   int player_device_id;
  };
  
  struct _BBreakoutModuleClass
--- 75,105 ----
  #define B_BREAKOUT_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_BREAKOUT_MODULE, BBreakoutModuleClass))
  #define B_IS_BREAKOUT_MODULE(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_BREAKOUT_MODULE))
  
! typedef struct _BBreakoutModule      BBreakoutModule;
  typedef struct _BBreakoutModuleClass BBreakoutModuleClass;
  
  struct _BBreakoutModule
  {
    BModule parent_instance;
  
!   gint    MaxColor;                   /* maximum color value */
!   gint    FreeRows;                   /* number of free pixel rows over player */
!   gint    StoneCntX, StoneCntY;       /* number of stones in field */
!   gint    StoneSizeX, StoneSizeY;     /* size of stone area of game-field */
!   gint    SizeX, SizeY;               /* size of game-field */
!   gint    OfsX, OfsY;                 /* offset of top left corner of game-field */
!   gint    PlayerSizeX, PlayerPosY;    /* x-size and y-position of player */
!   gint    PlayerPosXMax, PlayerStepX; /* maximum x-position and x-step-size of player */
!   gint  **ppStones;                   /* two-dimensional array with stones */
!   gint    StoneCnt;                   /* number of stones left in game */
!   gint    Lives;                      /* rest of player's lives */
!   gint    DeadCnt;                    /* number of ticks player is dead, 0 if player is alive */
!   gint    PlayerPosX;                 /* x-position of (left corner of) player */
!   gint    BallActive;                 /* !0 if ball is flying, 0 if ball is at player */
!   gint    BallPosX, BallPosY;         /* position of ball (if ball is flying) */
!   gint    BallDirX, BallDirY;         /* direction of ball (if ball is flying) */
!  
!   gint    player_device_id;
  };
  
  struct _BBreakoutModuleClass
***************
*** 167,206 ****
    return b_type_breakout_module;
  }
  
! //output current picture
  void
  BBreakoutOutput (BBreakoutModule *pBreakoutModule)
  {
!   int OfsX, OfsY, X, Y, X1, Y1, Y2, Color;
  
!   //empty the screen
    b_module_fill ((BModule *) pBreakoutModule,
  		 BBreakoutColorEmpty (pBreakoutModule->MaxColor));
  
!   //get offset
    OfsX = pBreakoutModule->OfsX;
    OfsY = pBreakoutModule->OfsY;
  
!   //draw stones
    for (Y = 0; Y < pBreakoutModule->StoneCntY; Y++)
    {
      for (X = 0; X < pBreakoutModule->StoneCntX; X++)
      {
!       //stone there
        if (pBreakoutModule->ppStones[Y][X] > 0)
        {
!         //get position of stone
          X1 = OfsX + X * BBreakoutStoneSizeX;
          Y1 = OfsY + Y * BBreakoutStoneSizeY;
!         //get color
          if (pBreakoutModule->ppStones[Y][X] == 1)
            Color = BBreakoutColorStone1 (pBreakoutModule->MaxColor);
          else if (pBreakoutModule->ppStones[Y][X] == 2)
            Color = BBreakoutColorStone2 (pBreakoutModule->MaxColor);
          else
            Color = BBreakoutColorStone3 (pBreakoutModule->MaxColor);
!         //draw stone
!         for( Y2 = 0; Y2 < BBreakoutStoneSizeY; Y2++ )
            b_module_draw_line ((BModule *) pBreakoutModule,
                                X1, Y1 + Y2,
                                X1 + BBreakoutStoneSizeX - 1, Y1 + Y2,
--- 167,206 ----
    return b_type_breakout_module;
  }
  
! /* output current picture */
  void
  BBreakoutOutput (BBreakoutModule *pBreakoutModule)
  {
!   gint OfsX, OfsY, X, Y, X1, Y1, Y2, Color;
  
!   /* empty the screen */
    b_module_fill ((BModule *) pBreakoutModule,
  		 BBreakoutColorEmpty (pBreakoutModule->MaxColor));
  
!   /* get offset */
    OfsX = pBreakoutModule->OfsX;
    OfsY = pBreakoutModule->OfsY;
  
!   /* draw stones */
    for (Y = 0; Y < pBreakoutModule->StoneCntY; Y++)
    {
      for (X = 0; X < pBreakoutModule->StoneCntX; X++)
      {
!       /* stone there */
        if (pBreakoutModule->ppStones[Y][X] > 0)
        {
!         /* get position of stone */
          X1 = OfsX + X * BBreakoutStoneSizeX;
          Y1 = OfsY + Y * BBreakoutStoneSizeY;
!         /* get color */
          if (pBreakoutModule->ppStones[Y][X] == 1)
            Color = BBreakoutColorStone1 (pBreakoutModule->MaxColor);
          else if (pBreakoutModule->ppStones[Y][X] == 2)
            Color = BBreakoutColorStone2 (pBreakoutModule->MaxColor);
          else
            Color = BBreakoutColorStone3 (pBreakoutModule->MaxColor);
!         /* draw stone */
!         for (Y2 = 0; Y2 < BBreakoutStoneSizeY; Y2++)
            b_module_draw_line ((BModule *) pBreakoutModule,
                                X1, Y1 + Y2,
                                X1 + BBreakoutStoneSizeX - 1, Y1 + Y2,
***************
*** 209,231 ****
      }
    }
  
!   //get player color (dead or alive)
    if (pBreakoutModule->DeadCnt > 0)
    {
!     if (pBreakoutModule->DeadCnt & 1 )
        Color = BBreakoutColorPlayerDead (pBreakoutModule->MaxColor);
      else
        Color = BBreakoutColorPlayerDeadBlink (pBreakoutModule->MaxColor);
    }
    else
      Color = BBreakoutColorPlayerAlive (pBreakoutModule->MaxColor);
!   //draw player
    b_module_draw_line ((BModule *) pBreakoutModule,
!                       OfsX + pBreakoutModule->PlayerPosX, OfsY + pBreakoutModule->PlayerPosY,
!                       OfsX + pBreakoutModule->PlayerPosX + pBreakoutModule->PlayerSizeX - 1, OfsY + pBreakoutModule->PlayerPosY,
                        Color);
  
!   //draw active ball
    if (pBreakoutModule->BallActive)
    {
      b_module_draw_point ((BModule *) pBreakoutModule,
--- 209,234 ----
      }
    }
  
!   /* get player color (dead or alive) */
    if (pBreakoutModule->DeadCnt > 0)
    {
!     if (pBreakoutModule->DeadCnt & 1)
        Color = BBreakoutColorPlayerDead (pBreakoutModule->MaxColor);
      else
        Color = BBreakoutColorPlayerDeadBlink (pBreakoutModule->MaxColor);
    }
    else
      Color = BBreakoutColorPlayerAlive (pBreakoutModule->MaxColor);
!   /* draw player */
    b_module_draw_line ((BModule *) pBreakoutModule,
!                       OfsX + pBreakoutModule->PlayerPosX,
!                       OfsY + pBreakoutModule->PlayerPosY,
!                       OfsX + pBreakoutModule->PlayerPosX
!                            + pBreakoutModule->PlayerSizeX - 1,
!                       OfsY + pBreakoutModule->PlayerPosY,
                        Color);
  
!   /* draw active ball */
    if (pBreakoutModule->BallActive)
    {
      b_module_draw_point ((BModule *) pBreakoutModule,
***************
*** 233,290 ****
  			 OfsY + pBreakoutModule->BallPosY,
  			 BBreakoutColorBall (pBreakoutModule->MaxColor));
    }
!   //draw ball at player
    else
    {
      b_module_draw_point ((BModule *) pBreakoutModule,
!                          OfsX + pBreakoutModule->PlayerPosX + pBreakoutModule->PlayerSizeX / 2,
  			 OfsY + pBreakoutModule->PlayerPosY - 1,
  			 BBreakoutColorBall (pBreakoutModule->MaxColor));
    }
  
!   //update screen
    b_module_paint ((BModule *) pBreakoutModule);
  }
  
! //initialize player
  void
  BBreakoutPlayerInit (BBreakoutModule *pBreakoutModule)
  {
!   //player is alive
    pBreakoutModule->DeadCnt = 0;
!   //set start position of player
!   pBreakoutModule->PlayerPosX = (pBreakoutModule->SizeX - pBreakoutModule->PlayerSizeX) / 2;
  
    if (BBreakoutAutoStart)
      {
!       //set ball to active, set position and direction
        pBreakoutModule->BallActive = 1;
!       pBreakoutModule->BallPosX = pBreakoutModule->PlayerPosX + pBreakoutModule->PlayerSizeX / 2;
        pBreakoutModule->BallPosY = pBreakoutModule->PlayerPosY - 1;
        pBreakoutModule->BallDirX = rand() % 1 ? -1 : 1;
        pBreakoutModule->BallDirY = -1;
      }
    else
      {
!       //ball is at player
        pBreakoutModule->BallActive = 0;
      }
  }
  
! //start a new game
  void
  BBreakoutNewGame (BBreakoutModule *pBreakoutModule)
  {
!   int X, Y;
  
!   //set stones to 2 or 3 hits in checkerboard-style
    for (Y = 0; Y < pBreakoutModule->StoneCntY; Y++)
      for (X = 0; X < pBreakoutModule->StoneCntX; X++)
        if ((X + Y) & 1)
          pBreakoutModule->ppStones[Y][X] = 2;
        else
          pBreakoutModule->ppStones[Y][X] = 3;
!   //make a free way around the field
    for (Y = 2; Y < pBreakoutModule->StoneCntY - 1; Y++)
    {
      pBreakoutModule->ppStones[Y][0] = 0;
--- 236,296 ----
  			 OfsY + pBreakoutModule->BallPosY,
  			 BBreakoutColorBall (pBreakoutModule->MaxColor));
    }
!   /* draw ball at player */
    else
    {
      b_module_draw_point ((BModule *) pBreakoutModule,
!                          OfsX + pBreakoutModule->PlayerPosX
!                               + pBreakoutModule->PlayerSizeX / 2,
  			 OfsY + pBreakoutModule->PlayerPosY - 1,
  			 BBreakoutColorBall (pBreakoutModule->MaxColor));
    }
  
!   /* update screen */
    b_module_paint ((BModule *) pBreakoutModule);
  }
  
! /* initialize player */
  void
  BBreakoutPlayerInit (BBreakoutModule *pBreakoutModule)
  {
!   /* player is alive */
    pBreakoutModule->DeadCnt = 0;
!   /* set start position of player */
!   pBreakoutModule->PlayerPosX =
!     (pBreakoutModule->SizeX - pBreakoutModule->PlayerSizeX) / 2;
  
    if (BBreakoutAutoStart)
      {
!       /* set ball to active, set position and direction */
        pBreakoutModule->BallActive = 1;
!       pBreakoutModule->BallPosX = pBreakoutModule->PlayerPosX
!                                 + pBreakoutModule->PlayerSizeX / 2;
        pBreakoutModule->BallPosY = pBreakoutModule->PlayerPosY - 1;
        pBreakoutModule->BallDirX = rand() % 1 ? -1 : 1;
        pBreakoutModule->BallDirY = -1;
      }
    else
      {
!       /* ball is at player */
        pBreakoutModule->BallActive = 0;
      }
  }
  
! /* start a new game */
  void
  BBreakoutNewGame (BBreakoutModule *pBreakoutModule)
  {
!   gint X, Y;
  
!   /* set stones to 2 or 3 hits in checkerboard-style */
    for (Y = 0; Y < pBreakoutModule->StoneCntY; Y++)
      for (X = 0; X < pBreakoutModule->StoneCntX; X++)
        if ((X + Y) & 1)
          pBreakoutModule->ppStones[Y][X] = 2;
        else
          pBreakoutModule->ppStones[Y][X] = 3;
!   /* make a free way around the field */
    for (Y = 2; Y < pBreakoutModule->StoneCntY - 1; Y++)
    {
      pBreakoutModule->ppStones[Y][0] = 0;
***************
*** 295,308 ****
      pBreakoutModule->ppStones[0][X] = 0;
      pBreakoutModule->ppStones[1][X] = 0;
    }
!   //put a hole into the upper center
    for (Y = 4; Y < pBreakoutModule->StoneCntY * 2 / 3; Y++)
    {
      pBreakoutModule->ppStones[Y][(pBreakoutModule->StoneCntX - 1) / 2] = 0;
      pBreakoutModule->ppStones[Y][(pBreakoutModule->StoneCntX) / 2] = 0;
    }
  
!   //count stones
    pBreakoutModule->StoneCnt = 0;
    for (Y = 0; Y < pBreakoutModule->StoneCntY; Y++)
      for (X = 0; X < pBreakoutModule->StoneCntX; X++)
--- 301,314 ----
      pBreakoutModule->ppStones[0][X] = 0;
      pBreakoutModule->ppStones[1][X] = 0;
    }
!   /* put a hole into the upper center */
    for (Y = 4; Y < pBreakoutModule->StoneCntY * 2 / 3; Y++)
    {
      pBreakoutModule->ppStones[Y][(pBreakoutModule->StoneCntX - 1) / 2] = 0;
      pBreakoutModule->ppStones[Y][(pBreakoutModule->StoneCntX) / 2] = 0;
    }
  
!   /* count stones */
    pBreakoutModule->StoneCnt = 0;
    for (Y = 0; Y < pBreakoutModule->StoneCntY; Y++)
      for (X = 0; X < pBreakoutModule->StoneCntX; X++)
***************
*** 311,378 ****
  
    dbg_print ("BBreakout: new game\n");
  
!   //initialize player
    BBreakoutPlayerInit (pBreakoutModule);
  
!   //output current picture
    BBreakoutOutput (pBreakoutModule);
  }
  
! //key-procedure
  void
  BBreakoutKey (BBreakoutModule *pBreakoutModule,
                BModuleKey     Key)
  {
!   //don't do anything if player is dead
    if (pBreakoutModule->DeadCnt > 0)
  	  return;
  
    switch (Key)
      {
      case B_KEY_1:
!       //shoot ball to the left
        if (!pBreakoutModule->BallActive)
        {
!         //set ball to active, set position and direction
          pBreakoutModule->BallActive = 1;
!         pBreakoutModule->BallPosX = pBreakoutModule->PlayerPosX + pBreakoutModule->PlayerSizeX / 2;
!         pBreakoutModule->BallPosY = pBreakoutModule->PlayerPosY - 1;
!         pBreakoutModule->BallDirX = -1;
!         pBreakoutModule->BallDirY = -1;
        }
        break;
      case B_KEY_3:
!       //shoot ball to the right
        if (!pBreakoutModule->BallActive)
        {
!         //set ball to active, set position and direction
          pBreakoutModule->BallActive = 1;
!         pBreakoutModule->BallPosX = pBreakoutModule->PlayerPosX + pBreakoutModule->PlayerSizeX / 2;
!         pBreakoutModule->BallPosY = pBreakoutModule->PlayerPosY - 1;
!         pBreakoutModule->BallDirX = 1;
!         pBreakoutModule->BallDirY = -1;
        }
        break;
      case B_KEY_4:
!       //move player one step left
        pBreakoutModule->PlayerPosX -= pBreakoutModule->PlayerStepX;
        if (pBreakoutModule->PlayerPosX < 0)
          pBreakoutModule->PlayerPosX = 0;
        break;
      case B_KEY_6:
!       //move player one step right
        pBreakoutModule->PlayerPosX += pBreakoutModule->PlayerStepX;
        if (pBreakoutModule->PlayerPosX > pBreakoutModule->PlayerPosXMax)
          pBreakoutModule->PlayerPosX = pBreakoutModule->PlayerPosXMax;
        break;
      case B_KEY_7:
!       //move player one pixel left
        pBreakoutModule->PlayerPosX--;;
        if (pBreakoutModule->PlayerPosX < 0)
          pBreakoutModule->PlayerPosX = 0;
        break;
      case B_KEY_9:
!       //move player one pixel right
        pBreakoutModule->PlayerPosX++;
        if (pBreakoutModule->PlayerPosX > pBreakoutModule->PlayerPosXMax)
          pBreakoutModule->PlayerPosX = pBreakoutModule->PlayerPosXMax;
--- 317,386 ----
  
    dbg_print ("BBreakout: new game\n");
  
!   /* initialize player */
    BBreakoutPlayerInit (pBreakoutModule);
  
!   /* output current picture */
    BBreakoutOutput (pBreakoutModule);
  }
  
! /* key-procedure */
  void
  BBreakoutKey (BBreakoutModule *pBreakoutModule,
                BModuleKey     Key)
  {
!   /* don't do anything if player is dead */
    if (pBreakoutModule->DeadCnt > 0)
  	  return;
  
    switch (Key)
      {
      case B_KEY_1:
!       /* shoot ball to the left */
        if (!pBreakoutModule->BallActive)
        {
!         /* set ball to active, set position and direction */
          pBreakoutModule->BallActive = 1;
!         pBreakoutModule->BallPosX   = pBreakoutModule->PlayerPosX
!                                     + pBreakoutModule->PlayerSizeX / 2;
!         pBreakoutModule->BallPosY   = pBreakoutModule->PlayerPosY - 1;
!         pBreakoutModule->BallDirX   = -1;
!         pBreakoutModule->BallDirY   = -1;
        }
        break;
      case B_KEY_3:
!       /* shoot ball to the right */
        if (!pBreakoutModule->BallActive)
        {
!         /* set ball to active, set position and direction */
          pBreakoutModule->BallActive = 1;
!         pBreakoutModule->BallPosX   = pBreakoutModule->PlayerPosX
!                                     + pBreakoutModule->PlayerSizeX / 2;
!         pBreakoutModule->BallPosY   = pBreakoutModule->PlayerPosY - 1;
!         pBreakoutModule->BallDirX   = 1;
!         pBreakoutModule->BallDirY   = -1;
        }
        break;
      case B_KEY_4:
!       /* move player one step left */
        pBreakoutModule->PlayerPosX -= pBreakoutModule->PlayerStepX;
        if (pBreakoutModule->PlayerPosX < 0)
          pBreakoutModule->PlayerPosX = 0;
        break;
      case B_KEY_6:
!       /* move player one step right */
        pBreakoutModule->PlayerPosX += pBreakoutModule->PlayerStepX;
        if (pBreakoutModule->PlayerPosX > pBreakoutModule->PlayerPosXMax)
          pBreakoutModule->PlayerPosX = pBreakoutModule->PlayerPosXMax;
        break;
      case B_KEY_7:
!       /* move player one pixel left */
        pBreakoutModule->PlayerPosX--;;
        if (pBreakoutModule->PlayerPosX < 0)
          pBreakoutModule->PlayerPosX = 0;
        break;
      case B_KEY_9:
!       /* move player one pixel right */
        pBreakoutModule->PlayerPosX++;
        if (pBreakoutModule->PlayerPosX > pBreakoutModule->PlayerPosXMax)
          pBreakoutModule->PlayerPosX = pBreakoutModule->PlayerPosXMax;
***************
*** 382,587 ****
        break;
      }
  
!   //output current picture
    BBreakoutOutput (pBreakoutModule);
  }
  
! //tick-procedure
! //returns 1 if game over or 0 if game not over
! int
  BBreakoutTick (BBreakoutModule *pBreakoutModule)
  {
!   int X, Y, X1, Y1, X2, Y2;
  
!   //player is dead
    if (pBreakoutModule->DeadCnt >= 0)
    {
!     //decrement dead counter
      pBreakoutModule->DeadCnt--;
      if (pBreakoutModule->DeadCnt == 0)
      {
!       //player has life left
        if (pBreakoutModule->Lives > 0)
        {
!         dbg_print( "BBreakout: player is alive again - %d live(s) left\n", pBreakoutModule->Lives);
!         //initialize player
          BBreakoutPlayerInit (pBreakoutModule);
        }
  
!       //game over
        else
        {
!         dbg_print( "BBreakout: player has no more lives left - game over\n");
! 	//request end of game
  	b_module_request_stop ((BModule *) pBreakoutModule);
!         //return game over
          return 1;
        }
      }
  
!     //output current picture
      BBreakoutOutput (pBreakoutModule);
  
!     //return game not over
      return 0;
!   } //if (pBreakoutModule->DeadCnt >= 0)
  
!   //ball ist active
    if (pBreakoutModule->BallActive)
    {
!     //bounce ball at left of game-field
      if (pBreakoutModule->BallPosX <= 0
       && pBreakoutModule->BallDirX == -1)
        pBreakoutModule->BallDirX = 1;
!     //bounce ball at right of game-field
      if (pBreakoutModule->BallPosX >= pBreakoutModule->SizeX - 1
       && pBreakoutModule->BallDirX == 1)
        pBreakoutModule->BallDirX = -1;
!     //bounce ball at top of game-field
      if (pBreakoutModule->BallPosY <= 0
       && pBreakoutModule->BallDirY == -1)
        pBreakoutModule->BallDirY = 1;
!     //bounce ball at bottom of game-field
      if (pBreakoutModule->BallPosY >= pBreakoutModule->SizeY - 1
       && pBreakoutModule->BallDirY == 1)
        pBreakoutModule->BallDirY = -1;
  
!     //bounce ball at edges of stones
      for (Y = 0; Y < pBreakoutModule->StoneCntY; Y++)
      {
        for (X = 0; X < pBreakoutModule->StoneCntX; X++)
        {
!         //stone there
          if (pBreakoutModule->ppStones[Y][X] > 0)
          {
!           //get position (all 4 corners) of stone
            X1 = X * BBreakoutStoneSizeX;
            Y1 = Y * BBreakoutStoneSizeY;
            X2 = X1 + BBreakoutStoneSizeX - 1;
            Y2 = Y1 + BBreakoutStoneSizeY - 1;
!           //bounce ball at left edge of stone
            if (pBreakoutModule->BallPosX == X1 - 1
             && pBreakoutModule->BallDirX == 1
             && pBreakoutModule->BallPosY >= Y1
             && pBreakoutModule->BallPosY <= Y2)
            {
!             pBreakoutModule->BallDirX = -1; //bounce ball
!             pBreakoutModule->ppStones[Y][X]--; //stone has one hit less
!             if (pBreakoutModule->ppStones[Y][X] == 0) //stone is gone
!               pBreakoutModule->StoneCnt--; //one stone less
            }
!           //bounce ball at right edge of stone
            if (pBreakoutModule->BallPosX == X2 + 1
             && pBreakoutModule->BallDirX == -1
             && pBreakoutModule->BallPosY >= Y1
             && pBreakoutModule->BallPosY <= Y2)
            {
!             pBreakoutModule->BallDirX = 1; //bounce ball
!             pBreakoutModule->ppStones[Y][X]--; //stone has one hit less
!             if (pBreakoutModule->ppStones[Y][X] == 0) //stone is gone
!               pBreakoutModule->StoneCnt--; //one stone less
            }
!           //bounce ball at top edge of stone
            if (pBreakoutModule->BallPosY == Y1 - 1
             && pBreakoutModule->BallDirY == 1
             && pBreakoutModule->BallPosX >= X1
             && pBreakoutModule->BallPosX <= X2)
            {
!             pBreakoutModule->BallDirY = -1; //bounce ball
!             pBreakoutModule->ppStones[Y][X]--; //stone has one hit less
!             if (pBreakoutModule->ppStones[Y][X] == 0) //stone is gone
!               pBreakoutModule->StoneCnt--; //one stone less
            }
!           //bounce ball at bottom edge of stone
            if (pBreakoutModule->BallPosY == Y2 + 1
             && pBreakoutModule->BallDirY == -1
             && pBreakoutModule->BallPosX >= X1
             && pBreakoutModule->BallPosX <= X2)
            {
!             pBreakoutModule->BallDirY = 1; //bounce ball
!             pBreakoutModule->ppStones[Y][X]--; //stone has one hit less
!             if (pBreakoutModule->ppStones[Y][X] == 0) //stone is gone
!               pBreakoutModule->StoneCnt--; //one stone less
            }
          }
!       } //for (X ...
!     } //for (Y ...
  
!     //bounce ball at corners of stones
!     //(it is important to bounce at all stone edges first)
      for (Y = 0; Y < pBreakoutModule->StoneCntY; Y++)
      {
        for (X = 0; X < pBreakoutModule->StoneCntX; X++)
        {
!         //stone there
          if (pBreakoutModule->ppStones[Y][X] > 0)
          {
!           //get position (all 4 corners) of stone
            X1 = X * BBreakoutStoneSizeX;
            Y1 = Y * BBreakoutStoneSizeY;
            X2 = X1 + BBreakoutStoneSizeX - 1;
            Y2 = Y1 + BBreakoutStoneSizeY - 1;
!           //bounce ball at top-left corner of stone
            if (pBreakoutModule->BallPosX == X1 - 1
             && pBreakoutModule->BallPosY == Y1 - 1
             && pBreakoutModule->BallDirX == 1
             && pBreakoutModule->BallDirY == 1)
            {
!             pBreakoutModule->BallDirX = -1; //bounce ball
!             pBreakoutModule->BallDirY = -1; //bounce ball
!             pBreakoutModule->ppStones[Y][X]--; //stone has one hit less
!             if (pBreakoutModule->ppStones[Y][X] == 0) //stone is gone
!               pBreakoutModule->StoneCnt--; //one stone less
            }
!           //bounce ball at top-right corner of stone
            if (pBreakoutModule->BallPosX == X2 + 1
             && pBreakoutModule->BallPosY == Y1 - 1
             && pBreakoutModule->BallDirX == -1
             && pBreakoutModule->BallDirY == 1)
            {
!             pBreakoutModule->BallDirX = 1; //bounce ball
!             pBreakoutModule->BallDirY = -1; //bounce ball
!             pBreakoutModule->ppStones[Y][X]--; //stone has one hit less
!             if (pBreakoutModule->ppStones[Y][X] == 0) //stone is gone
!               pBreakoutModule->StoneCnt--; //one stone less
            }
!           //bounce ball at bottom-left corner of stone
            if (pBreakoutModule->BallPosX == X1 - 1
             && pBreakoutModule->BallPosY == Y2 + 1
             && pBreakoutModule->BallDirX == 1
             && pBreakoutModule->BallDirY == -1)
            {
!             pBreakoutModule->BallDirX = -1; //bounce ball
!             pBreakoutModule->BallDirY = 1; //bounce ball
!             pBreakoutModule->ppStones[Y][X]--; //stone has one hit less
!             if (pBreakoutModule->ppStones[Y][X] == 0) //stone is gone
!               pBreakoutModule->StoneCnt--; //one stone less
            }
!           //bounce ball at bottom-right corner of stone
            if (pBreakoutModule->BallPosX == X2 + 1
             && pBreakoutModule->BallPosY == Y2 + 1
             && pBreakoutModule->BallDirX == -1
             && pBreakoutModule->BallDirY == -1)
            {
!             pBreakoutModule->BallDirX = 1; //bounce ball
!             pBreakoutModule->BallDirY = 1; //bounce ball
!             pBreakoutModule->ppStones[Y][X]--; //stone has one hit less
!             if (pBreakoutModule->ppStones[Y][X] == 0) //stone is gone
!               pBreakoutModule->StoneCnt--; //one stone less
            }
  	}
!       } //for (X ...
!     } //for (Y ...
  
!     //bounce ball at top edge of player
      if (pBreakoutModule->BallPosY == pBreakoutModule->PlayerPosY - 1
       && pBreakoutModule->BallPosX >= pBreakoutModule->PlayerPosX
!      && pBreakoutModule->BallPosX <= pBreakoutModule->PlayerPosX + pBreakoutModule->PlayerSizeX - 1
       && pBreakoutModule->BallDirY == 1)
      {
        pBreakoutModule->BallDirY = -1;
      }
!     //bounce ball at left corner of player
      if (pBreakoutModule->BallPosX == pBreakoutModule->PlayerPosX - 1
       && pBreakoutModule->BallPosY == pBreakoutModule->PlayerPosY - 1
       && pBreakoutModule->BallDirX == 1
--- 390,597 ----
        break;
      }
  
!   /* output current picture */
    BBreakoutOutput (pBreakoutModule);
  }
  
! /* tick-procedure */
! /* returns 1 if game over or 0 if game not over */
! gint
  BBreakoutTick (BBreakoutModule *pBreakoutModule)
  {
!   gint X, Y, X1, Y1, X2, Y2;
  
!   /* player is dead */
    if (pBreakoutModule->DeadCnt >= 0)
    {
!     /* decrement dead counter */
      pBreakoutModule->DeadCnt--;
      if (pBreakoutModule->DeadCnt == 0)
      {
!       /* player has life left */
        if (pBreakoutModule->Lives > 0)
        {
!         dbg_print ("BBreakout: player is alive again - %d live(s) left\n",
!                    pBreakoutModule->Lives);
!         /* initialize player */
          BBreakoutPlayerInit (pBreakoutModule);
        }
  
!       /* game over */
        else
        {
!         dbg_print ("BBreakout: player has no more lives left - game over\n");
! 	/* request end of game */
  	b_module_request_stop ((BModule *) pBreakoutModule);
!         /* return game over */
          return 1;
        }
      }
  
!     /* output current picture */
      BBreakoutOutput (pBreakoutModule);
  
!     /* return game not over */
      return 0;
!   } /* if (pBreakoutModule->DeadCnt >= 0) */
  
!   /* ball ist active */
    if (pBreakoutModule->BallActive)
    {
!     /* bounce ball at left of game-field */
      if (pBreakoutModule->BallPosX <= 0
       && pBreakoutModule->BallDirX == -1)
        pBreakoutModule->BallDirX = 1;
!     /* bounce ball at right of game-field */
      if (pBreakoutModule->BallPosX >= pBreakoutModule->SizeX - 1
       && pBreakoutModule->BallDirX == 1)
        pBreakoutModule->BallDirX = -1;
!     /* bounce ball at top of game-field */
      if (pBreakoutModule->BallPosY <= 0
       && pBreakoutModule->BallDirY == -1)
        pBreakoutModule->BallDirY = 1;
!     /* bounce ball at bottom of game-field */
      if (pBreakoutModule->BallPosY >= pBreakoutModule->SizeY - 1
       && pBreakoutModule->BallDirY == 1)
        pBreakoutModule->BallDirY = -1;
  
!     /* bounce ball at edges of stones */
      for (Y = 0; Y < pBreakoutModule->StoneCntY; Y++)
      {
        for (X = 0; X < pBreakoutModule->StoneCntX; X++)
        {
!         /* stone there */
          if (pBreakoutModule->ppStones[Y][X] > 0)
          {
!           /* get position (all 4 corners) of stone */
            X1 = X * BBreakoutStoneSizeX;
            Y1 = Y * BBreakoutStoneSizeY;
            X2 = X1 + BBreakoutStoneSizeX - 1;
            Y2 = Y1 + BBreakoutStoneSizeY - 1;
!           /* bounce ball at left edge of stone */
            if (pBreakoutModule->BallPosX == X1 - 1
             && pBreakoutModule->BallDirX == 1
             && pBreakoutModule->BallPosY >= Y1
             && pBreakoutModule->BallPosY <= Y2)
            {
!             pBreakoutModule->BallDirX = -1; /* bounce ball */
!             pBreakoutModule->ppStones[Y][X]--; /* stone has one hit less */
!             if (pBreakoutModule->ppStones[Y][X] == 0) /* stone is gone */
!               pBreakoutModule->StoneCnt--; /* one stone less */
            }
!           /* bounce ball at right edge of stone */
            if (pBreakoutModule->BallPosX == X2 + 1
             && pBreakoutModule->BallDirX == -1
             && pBreakoutModule->BallPosY >= Y1
             && pBreakoutModule->BallPosY <= Y2)
            {
!             pBreakoutModule->BallDirX = 1; /* bounce ball */
!             pBreakoutModule->ppStones[Y][X]--; /* stone has one hit less */
!             if (pBreakoutModule->ppStones[Y][X] == 0) /* stone is gone */
!               pBreakoutModule->StoneCnt--; /* one stone less */
            }
!           /* bounce ball at top edge of stone */
            if (pBreakoutModule->BallPosY == Y1 - 1
             && pBreakoutModule->BallDirY == 1
             && pBreakoutModule->BallPosX >= X1
             && pBreakoutModule->BallPosX <= X2)
            {
!             pBreakoutModule->BallDirY = -1; /* bounce ball */
!             pBreakoutModule->ppStones[Y][X]--; /* stone has one hit less */
!             if (pBreakoutModule->ppStones[Y][X] == 0) /* stone is gone */
!               pBreakoutModule->StoneCnt--; /* one stone less */
            }
!           /* bounce ball at bottom edge of stone */
            if (pBreakoutModule->BallPosY == Y2 + 1
             && pBreakoutModule->BallDirY == -1
             && pBreakoutModule->BallPosX >= X1
             && pBreakoutModule->BallPosX <= X2)
            {
!             pBreakoutModule->BallDirY = 1; /* bounce ball */
!             pBreakoutModule->ppStones[Y][X]--; /* stone has one hit less */
!             if (pBreakoutModule->ppStones[Y][X] == 0) /* stone is gone */
!               pBreakoutModule->StoneCnt--; /* one stone less */
            }
          }
!       } /* for (X ... */
!     } /* for (Y ... */
  
!     /* bounce ball at corners of stones */
!     /* (it is important to bounce at all stone edges first) */
      for (Y = 0; Y < pBreakoutModule->StoneCntY; Y++)
      {
        for (X = 0; X < pBreakoutModule->StoneCntX; X++)
        {
!         /* stone there */
          if (pBreakoutModule->ppStones[Y][X] > 0)
          {
!           /* get position (all 4 corners) of stone */
            X1 = X * BBreakoutStoneSizeX;
            Y1 = Y * BBreakoutStoneSizeY;
            X2 = X1 + BBreakoutStoneSizeX - 1;
            Y2 = Y1 + BBreakoutStoneSizeY - 1;
!           /* bounce ball at top-left corner of stone */
            if (pBreakoutModule->BallPosX == X1 - 1
             && pBreakoutModule->BallPosY == Y1 - 1
             && pBreakoutModule->BallDirX == 1
             && pBreakoutModule->BallDirY == 1)
            {
!             pBreakoutModule->BallDirX = -1; /* bounce ball */
!             pBreakoutModule->BallDirY = -1; /* bounce ball */
!             pBreakoutModule->ppStones[Y][X]--; /* stone has one hit less */
!             if (pBreakoutModule->ppStones[Y][X] == 0) /* stone is gone */
!               pBreakoutModule->StoneCnt--; /* one stone less */
            }
!           /* bounce ball at top-right corner of stone */
            if (pBreakoutModule->BallPosX == X2 + 1
             && pBreakoutModule->BallPosY == Y1 - 1
             && pBreakoutModule->BallDirX == -1
             && pBreakoutModule->BallDirY == 1)
            {
!             pBreakoutModule->BallDirX = 1; /* bounce ball */
!             pBreakoutModule->BallDirY = -1; /* bounce ball */
!             pBreakoutModule->ppStones[Y][X]--; /* stone has one hit less */
!             if (pBreakoutModule->ppStones[Y][X] == 0) /* stone is gone */
!               pBreakoutModule->StoneCnt--; /* one stone less */
            }
!           /* bounce ball at bottom-left corner of stone */
            if (pBreakoutModule->BallPosX == X1 - 1
             && pBreakoutModule->BallPosY == Y2 + 1
             && pBreakoutModule->BallDirX == 1
             && pBreakoutModule->BallDirY == -1)
            {
!             pBreakoutModule->BallDirX = -1; /* bounce ball */
!             pBreakoutModule->BallDirY = 1; /* bounce ball */
!             pBreakoutModule->ppStones[Y][X]--; /* stone has one hit less */
!             if (pBreakoutModule->ppStones[Y][X] == 0) /* stone is gone */
!               pBreakoutModule->StoneCnt--; /* one stone less */
            }
!           /* bounce ball at bottom-right corner of stone */
            if (pBreakoutModule->BallPosX == X2 + 1
             && pBreakoutModule->BallPosY == Y2 + 1
             && pBreakoutModule->BallDirX == -1
             && pBreakoutModule->BallDirY == -1)
            {
!             pBreakoutModule->BallDirX = 1; /* bounce ball */
!             pBreakoutModule->BallDirY = 1; /* bounce ball */
!             pBreakoutModule->ppStones[Y][X]--; /* stone has one hit less */
!             if (pBreakoutModule->ppStones[Y][X] == 0) /* stone is gone */
!               pBreakoutModule->StoneCnt--; /* one stone less */
            }
  	}
!       } /* for (X ... */
!     } /* for (Y ... */
  
!     /* bounce ball at top edge of player */
      if (pBreakoutModule->BallPosY == pBreakoutModule->PlayerPosY - 1
       && pBreakoutModule->BallPosX >= pBreakoutModule->PlayerPosX
!      && pBreakoutModule->BallPosX <= pBreakoutModule->PlayerPosX
!                                    + pBreakoutModule->PlayerSizeX - 1
       && pBreakoutModule->BallDirY == 1)
      {
        pBreakoutModule->BallDirY = -1;
      }
!     /* bounce ball at left corner of player */
      if (pBreakoutModule->BallPosX == pBreakoutModule->PlayerPosX - 1
       && pBreakoutModule->BallPosY == pBreakoutModule->PlayerPosY - 1
       && pBreakoutModule->BallDirX == 1
***************
*** 590,597 ****
        pBreakoutModule->BallDirX = -1;
        pBreakoutModule->BallDirY = -1;
      }
!     //bounce ball at right corner of player
!     if (pBreakoutModule->BallPosX == pBreakoutModule->PlayerPosX + pBreakoutModule->PlayerSizeX
       && pBreakoutModule->BallPosY == pBreakoutModule->PlayerPosY - 1
       && pBreakoutModule->BallDirX == -1
       && pBreakoutModule->BallDirY == 1)
--- 600,608 ----
        pBreakoutModule->BallDirX = -1;
        pBreakoutModule->BallDirY = -1;
      }
!     /* bounce ball at right corner of player */
!     if (pBreakoutModule->BallPosX == pBreakoutModule->PlayerPosX
!                                    + pBreakoutModule->PlayerSizeX
       && pBreakoutModule->BallPosY == pBreakoutModule->PlayerPosY - 1
       && pBreakoutModule->BallDirX == -1
       && pBreakoutModule->BallDirY == 1)
***************
*** 600,636 ****
        pBreakoutModule->BallDirY = -1;
      }
  
!     //move ball
      pBreakoutModule->BallPosX += pBreakoutModule->BallDirX;
      pBreakoutModule->BallPosY += pBreakoutModule->BallDirY;
  
!     //all stones gone
      if (pBreakoutModule->StoneCnt == 0)
      {
!         dbg_print( "BBreakout: player has destroyed all stones - game over\n");
!         //output current picture
          BBreakoutOutput (pBreakoutModule);
! 	//request end of game
  	b_module_request_stop ((BModule *) pBreakoutModule);
!         //return game over
          return 1;
      }
  
!     //player missed ball
!     if( pBreakoutModule->BallPosY >= pBreakoutModule->PlayerPosY )
      {
!       //decrement player's lives
        pBreakoutModule->Lives--;
        dbg_print ("BBreakout: player missed the ball and died\n");
!       //player is dead now
        pBreakoutModule->DeadCnt = BBreakoutDeadTime;
      }
!   } //if (pBreakoutModule->BallActive)
  
!   //output current picture
    BBreakoutOutput (pBreakoutModule);
  
!   //return game not over
    return 0;
  }
  
--- 611,647 ----
        pBreakoutModule->BallDirY = -1;
      }
  
!     /* move ball */
      pBreakoutModule->BallPosX += pBreakoutModule->BallDirX;
      pBreakoutModule->BallPosY += pBreakoutModule->BallDirY;
  
!     /* all stones gone */
      if (pBreakoutModule->StoneCnt == 0)
      {
!         dbg_print ("BBreakout: player has destroyed all stones - game over\n");
!         /* output current picture */
          BBreakoutOutput (pBreakoutModule);
! 	/* request end of game */
  	b_module_request_stop ((BModule *) pBreakoutModule);
!         /* return game over */
          return 1;
      }
  
!     /* player missed ball */
!     if (pBreakoutModule->BallPosY >= pBreakoutModule->PlayerPosY)
      {
!       /* decrement player's lives */
        pBreakoutModule->Lives--;
        dbg_print ("BBreakout: player missed the ball and died\n");
!       /* player is dead now */
        pBreakoutModule->DeadCnt = BBreakoutDeadTime;
      }
!   } /* if (pBreakoutModule->BallActive) */
  
!   /* output current picture */
    BBreakoutOutput (pBreakoutModule);
  
!   /* return game not over */
    return 0;
  }
  
***************
*** 672,708 ****
  b_breakout_module_prepare (BModule  *module,
                             GError  **error)
  {
!   int SizePtrs, SizeRow, Size, Y;
!   char * Ptr;
  
    BBreakoutModule *breakout_module = B_BREAKOUT_MODULE (module);
  
!   //initialize the module values that depend on the output device
!   breakout_module->MaxColor = module->maxval; //maximum color value
!   breakout_module->FreeRows = module->height * 2 / 5; //number of free rows over player
    if (breakout_module->FreeRows < BBreakoutFreeRowsMin)
!     breakout_module->FreeRows = BBreakoutFreeRowsMin;
!   breakout_module->StoneCntX = module->width / BBreakoutStoneSizeX; //number of stones in field
!   breakout_module->StoneCntY = (module->height - breakout_module->FreeRows - 1) / BBreakoutStoneSizeY;
!   breakout_module->StoneSizeX = breakout_module->StoneCntX * BBreakoutStoneSizeX; //size of stone area of game-field
!   breakout_module->StoneSizeY = breakout_module->StoneCntY * BBreakoutStoneSizeY;
!   breakout_module->SizeX = breakout_module->StoneSizeX; //size of game field
!   breakout_module->SizeY = breakout_module->StoneSizeY + breakout_module->FreeRows + 1;
!   breakout_module->OfsX = (module->width - breakout_module->SizeX) / 2; //offset of top left corner of game-field
!   breakout_module->OfsY = (module->height - breakout_module->SizeY) / 2;
!   breakout_module->PlayerSizeX = breakout_module->SizeX / 3; //x-size and y-position of player
!   breakout_module->PlayerPosY = breakout_module->SizeY - 1;
!   breakout_module->PlayerPosXMax = breakout_module->SizeX - breakout_module->PlayerSizeX; //maximum x-position of player
!   breakout_module->PlayerStepX = breakout_module->PlayerSizeX / 2; //x-step-size of player
! 
!   //allocate needed memory
!   SizePtrs = breakout_module->StoneCntY * sizeof( int * ); //get needed size
!   SizeRow = breakout_module->StoneCntX * sizeof( int );
    Size = SizePtrs + breakout_module->StoneCntY * SizeRow;
    Ptr = g_new (gchar, Size);
  
!   breakout_module->ppStones = (int * *)Ptr; //remember pointer
!   for( Y = 0; Y < breakout_module->StoneCntY; Y++ ) //generate pointers to rows
      breakout_module->ppStones[Y] = (int *)(Ptr + SizePtrs + Y * SizeRow);
  
    return TRUE;
--- 683,727 ----
  b_breakout_module_prepare (BModule  *module,
                             GError  **error)
  {
!   gint SizePtrs, SizeRow, Size, Y;
!   gchar *Ptr;
  
    BBreakoutModule *breakout_module = B_BREAKOUT_MODULE (module);
  
!   /* initialize the module values that depend on the output device */
!   breakout_module->MaxColor = module->maxval;                           /* maximum color value */
!   breakout_module->FreeRows = module->height * 2 / 5;                   /* number of free rows over player */
    if (breakout_module->FreeRows < BBreakoutFreeRowsMin)
!     breakout_module->FreeRows    = BBreakoutFreeRowsMin;
!   breakout_module->StoneCntX     = module->width / BBreakoutStoneSizeX; /* number of stones in field */
!   breakout_module->StoneCntY     = (module->height
!                                     - breakout_module->FreeRows - 1)
!                                    / BBreakoutStoneSizeY;
!   breakout_module->StoneSizeX    = breakout_module->StoneCntX           /* size of stone area of game-field */
!                                    * BBreakoutStoneSizeX;
!   breakout_module->StoneSizeY    = breakout_module->StoneCntY
!                                    * BBreakoutStoneSizeY;
!   breakout_module->SizeX         = breakout_module->StoneSizeX;         /* size of game field */
!   breakout_module->SizeY         = breakout_module->StoneSizeY
!                                    + breakout_module->FreeRows + 1;
!   breakout_module->OfsX          = (module->width                       /* offset of top left corner of game-field */
!                                      - breakout_module->SizeX) / 2;
!   breakout_module->OfsY          = (module->height
!                                     - breakout_module->SizeY) / 2;
!   breakout_module->PlayerSizeX   = breakout_module->SizeX / 3;          /* x-size and y-position of player */
!   breakout_module->PlayerPosY    = breakout_module->SizeY - 1;
!   breakout_module->PlayerPosXMax = breakout_module->SizeX               /* maximum x-position of player */
!                                    - breakout_module->PlayerSizeX;
!   breakout_module->PlayerStepX   = breakout_module->PlayerSizeX / 2;    /* x-step-size of player */
! 
!   /* allocate needed memory */
!   SizePtrs = breakout_module->StoneCntY * sizeof (int *); /* get needed size */
!   SizeRow = breakout_module->StoneCntX * sizeof (int);
    Size = SizePtrs + breakout_module->StoneCntY * SizeRow;
    Ptr = g_new (gchar, Size);
  
!   breakout_module->ppStones = (int * *)Ptr; /* remember pointer */
!   for (Y = 0; Y < breakout_module->StoneCntY; Y++)  /* generate pointers to rows */
      breakout_module->ppStones[Y] = (int *)(Ptr + SizePtrs + Y * SizeRow);
  
    return TRUE;
***************
*** 713,732 ****
  {
    BBreakoutModule *breakout_module = B_BREAKOUT_MODULE (module);
  
!   g_free( breakout_module->ppStones );
    breakout_module->ppStones = NULL;
  }
  
  static void
  b_breakout_module_start (BModule *module)
  {
!   //set player's lives
    ((BBreakoutModule *)module)->Lives = BBreakoutLives;
  
!   //start new game
    BBreakoutNewGame ((BBreakoutModule *) module);
  
!   //start the tick machinery
    b_module_ticker_start (module, BBreakoutTicks);
  }
  
--- 732,751 ----
  {
    BBreakoutModule *breakout_module = B_BREAKOUT_MODULE (module);
  
!   g_free (breakout_module->ppStones);
    breakout_module->ppStones = NULL;
  }
  
  static void
  b_breakout_module_start (BModule *module)
  {
!   /* set player's lives */
    ((BBreakoutModule *)module)->Lives = BBreakoutLives;
  
!   /* start new game */
    BBreakoutNewGame ((BBreakoutModule *) module);
  
!   /* start the tick machinery */
    b_module_ticker_start (module, BBreakoutTicks);
  }
  
***************
*** 771,783 ****
  static gint
  b_breakout_module_tick (BModule *module)
  {
!   int GameOver;
  
!   //call tick-procedure
    GameOver = BBreakoutTick ((BBreakoutModule *) module);
  
!   //we want to be called again in some milliseconds, if game is not over
!   if( GameOver )
      return 0;
    else
      return BBreakoutTicks;
--- 790,802 ----
  static gint
  b_breakout_module_tick (BModule *module)
  {
!   gint GameOver;
  
!   /* call tick-procedure */
    GameOver = BBreakoutTick ((BBreakoutModule *) module);
  
!   /* we want to be called again in some milliseconds, if game is not over */
!   if (GameOver)
      return 0;
    else
      return BBreakoutTicks;
diff -r -C 3 -N blib-1.1.7/modules/bclock.c blib-1.1.7-ba20070811/modules/bclock.c
*** blib-1.1.7/modules/bclock.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bclock.c	Sat Aug 11 22:18:43 2007
***************
*** 64,74 ****
  
  struct _BClock
  {
!   BModule   parent_instance;
  
!   guint     epoche;
!   gint      mode;
!   gboolean  colon;
  };
  
  struct _BClockClass
--- 64,78 ----
  
  struct _BClock
  {
!   BModule      parent_instance;
  
!   gint         with_secs;
!   gint         num_digits;
!   const BFont  *digits;
! 
!   guint        epoche;
!   gint         mode;
!   gboolean     colon;
  };
  
  struct _BClockClass
***************
*** 224,230 ****
  static void
  b_clock_start (BModule *module)
  {
!   b_clock_gettime (B_CLOCK (module));
    b_module_ticker_start (module, b_clock_tick (module));
  }
  
--- 228,258 ----
  static void
  b_clock_start (BModule *module)
  {
!   BClock * clock = (BClock *)module;
! 
!   gint f;
!   const BFont *fonts[] = { &b_digits_3x5,
!                            &b_digits_5x7,
!                            &b_digits_8x7,
!                            &b_digits_8x7wide };
! 
!   clock->with_secs = module->width >= MIN (25, 2 * module->height);
!   clock->num_digits = clock->with_secs ? 8 : 5;
! 
!   for (f = (sizeof (fonts) / sizeof (fonts[0])) - 1;
!        module->width - ((clock->num_digits - 1) * fonts[f]->advance + fonts[f]->width) < 0
!        || module->width - fonts[f]->height < 0;
!        f--)
!     {
!       if (f < 0)
!         {
!           b_module_request_stop (module);
!           return;
!         }
!     }
!   clock->digits = fonts[f];
! 
!   b_clock_gettime (clock);
    b_module_ticker_start (module, b_clock_tick (module));
  }
  
***************
*** 249,255 ****
  {
    gint h, m, s;
    BClock *clock = B_CLOCK (module);
-   const BFont *digits = &b_digits_3x5;
    struct tm *tm;
  
    if (!b_clock_gettime (clock))
--- 277,282 ----
***************
*** 271,277 ****
  	gchar *text;
  	gint   len, i, n, x, y, x0, y0;
  
!         if (module->width > 20)
  	  {
              text = g_strdup_printf ("%02d:%02d:%02d", h, m, s);
            }
--- 298,304 ----
  	gchar *text;
  	gint   len, i, n, x, y, x0, y0;
  
!         if (clock->with_secs)
  	  {
              text = g_strdup_printf ("%02d:%02d:%02d", h, m, s);
            }
***************
*** 284,297 ****
  
  	len = strlen (text);
  
! 	x0 = 0;
! 	y0 = module->height / 4;
  
  	for (n = 0; n < len; n++)
  	  {
! 	    for (i = 0; i < digits->num_digits && digits->digits_str[i] != text[n]; i++);
  
! 	    if (len * digits->advance > module->width)
                {
                if (text[n-1] == ':' || text[n-1] == ' ')
                    x0--;
--- 311,324 ----
  
  	len = strlen (text);
  
!         x0 = (module->width - (clock->num_digits - 1) * clock->digits->advance - clock->digits->width) / 2;
! 	y0 = (module->height - clock->digits->height) / 2;
  
  	for (n = 0; n < len; n++)
  	  {
! 	    for (i = 0; i < clock->digits->num_digits && clock->digits->digits_str[i] != text[n]; i++);
  
! 	    if (len * clock->digits->advance > module->width)
                {
                if (text[n-1] == ':' || text[n-1] == ' ')
                    x0--;
***************
*** 300,313 ****
                    x0--;
                }
  
! 	    if (i < digits->num_digits)
! 	      for (x = 0; x < digits->width; x++)
! 		for (y = 0; y < digits->height; y++)
! 		  if (digits->data[i][y * digits->width + x] != '0')
  		    b_module_draw_point (module,
                                           x0 + x, y0 + y, module->maxval);
  
! 	    x0 += digits->advance;
  	  }
  	g_free (text);
        }
--- 327,340 ----
                    x0--;
                }
  
! 	    if (i < clock->digits->num_digits)
! 	      for (x = 0; x < clock->digits->width; x++)
! 		for (y = 0; y < clock->digits->height; y++)
! 		  if (clock->digits->data[i][y * clock->digits->width + x] != '0')
  		    b_module_draw_point (module,
                                           x0 + x, y0 + y, module->maxval);
  
! 	    x0 += clock->digits->advance;
  	  }
  	g_free (text);
        }
diff -r -C 3 -N blib-1.1.7/modules/bcountdown.c blib-1.1.7-ba20070811/modules/bcountdown.c
*** blib-1.1.7/modules/bcountdown.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bcountdown.c	Sat Aug 11 22:18:43 2007
***************
*** 38,44 ****
  #define B_COUNTDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_COUNTDOWN, BCountdownClass))
  #define B_IS_COUNTDOWN(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_COUNTDOWN))
  
! #define MAX_DIGITS 4
  
  typedef struct _BCountdown      BCountdown;
  typedef struct _BCountdownClass BCountdownClass;
--- 38,44 ----
  #define B_COUNTDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_COUNTDOWN, BCountdownClass))
  #define B_IS_COUNTDOWN(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_COUNTDOWN))
  
! #define MAX_DIGITS 8
  
  typedef struct _BCountdown      BCountdown;
  typedef struct _BCountdownClass BCountdownClass;
***************
*** 46,57 ****
  struct _BCountdown
  {
    BModule   parent_instance;
!  
    gchar last_digits[MAX_DIGITS];
    gchar last_font;
    gchar last_number_of_digits;
  
    gint      end;
  };
  
  struct _BCountdownClass
--- 46,58 ----
  struct _BCountdown
  {
    BModule   parent_instance;
! 
    gchar last_digits[MAX_DIGITS];
    gchar last_font;
    gchar last_number_of_digits;
  
    gint      end;
+   gint      duration;
  };
  
  struct _BCountdownClass
***************
*** 62,68 ****
  enum
  {
    PROP_0,
!   PROP_END
  };
  
  
--- 63,70 ----
  enum
  {
    PROP_0,
!   PROP_END,
!   PROP_DURATION
  };
  
  
***************
*** 144,149 ****
--- 146,157 ----
  				 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
    g_object_class_install_property (object_class, PROP_END, param_spec);
  
+   param_spec = g_param_spec_int ("duration", NULL,
+ 				 "How long to run the countdown.",
+ 				 3, 999999, 999,
+ 				 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_DURATION, param_spec);
+ 
    module_class->query    = b_countdown_query;
    module_class->prepare  = b_countdown_prepare;
    module_class->start    = b_countdown_start;
***************
*** 165,170 ****
--- 173,182 ----
        countdown->end = g_value_get_int (value);
        break;
  
+     case PROP_DURATION:
+       countdown->duration = g_value_get_int (value);
+       break;
+ 
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
        break;
***************
*** 177,183 ****
  		   gint  channels,
  		   gint  maxval)
  {
!   return (width > 17 && height > 7 && channels == 1 && maxval > 0);
  }
  
  static gboolean
--- 189,195 ----
  		   gint  channels,
  		   gint  maxval)
  {
!   return (width >= 12 && height >= 7 && channels == 1 && maxval > 0);
  }
  
  static gboolean
***************
*** 199,205 ****
  b_countdown_start (BModule *module)
  {
    gint x;
!   
    BCountdown     *countdown = B_COUNTDOWN (module);
    countdown->last_font = -1;
    countdown->last_number_of_digits = -1;
--- 211,217 ----
  b_countdown_start (BModule *module)
  {
    gint x;
!  
    BCountdown     *countdown = B_COUNTDOWN (module);
    countdown->last_font = -1;
    countdown->last_number_of_digits = -1;
***************
*** 207,214 ****
    for (x = 0; x < MAX_DIGITS; x++)
      {
        countdown->last_digits[x] = -1;
!     }  
!   
    b_module_ticker_start (module, 1);
  }
  
--- 219,226 ----
    for (x = 0; x < MAX_DIGITS; x++)
      {
        countdown->last_digits[x] = -1;
!     } 
!  
    b_module_ticker_start (module, 1);
  }
  
***************
*** 225,231 ****
    gint            new_digits[MAX_DIGITS];
    const BFont    *fonts[] = { &b_digits_3x5,
                                &b_digits_5x7,
!                               &b_digits_8x7 };
  
    gettimeofday (&tv, NULL);
  
--- 237,244 ----
    gint            new_digits[MAX_DIGITS];
    const BFont    *fonts[] = { &b_digits_3x5,
                                &b_digits_5x7,
!                               &b_digits_8x7,
!                               &b_digits_8x7wide };
  
    gettimeofday (&tv, NULL);
  
***************
*** 233,239 ****
  
    g_print ("BCountdown: %d\n", n);
  
!   if (n <= 0 || n > 999)
      {
        b_module_request_stop (module);
        return -1;
--- 246,252 ----
  
    g_print ("BCountdown: %d\n", n);
  
!   if (n <= 0 || n > countdown->duration)
      {
        b_module_request_stop (module);
        return -1;
***************
*** 241,249 ****
  
    for (d = 1, i = n; i > 9; d++)
      i /= 10;
!   
!   for (f = (sizeof (fonts) / sizeof (fonts[0])) - 1; 
!        module->width - ((d - 1) * fonts[f]->advance + fonts[f]->width) < 0;
         f--)
      {
        if (f < 0)
--- 254,263 ----
  
    for (d = 1, i = n; i > 9; d++)
      i /= 10;
!  
!   for (f = (sizeof (fonts) / sizeof (fonts[0])) - 1;
!        module->width - ((d - 1) * fonts[f]->advance + fonts[f]->width) < 0
!        || module->width - fonts[f]->height < 0;
         f--)
      {
        if (f < 0)
***************
*** 251,285 ****
            b_module_request_stop (module);
            return -1;
          }
!     } 
!  
    for (i = 0; i < MAX_DIGITS; i++)
      new_digits[i] = ' ';
!   
!   g_print ("using font #%d, w: %d h: %d a: %d\n", 
             f, fonts[f]->width, fonts[f]->height, fonts[f]->advance);
  
!   if (countdown->last_font != f || 
        countdown->last_number_of_digits != d)
      b_module_fill (module, 0);
  
    for (i = d; i > 0; i--)
      {
        new_digits[i] = n % 10;
!       scroll[i] = (countdown->last_digits[i] == -1) 
                  || (countdown->last_digits[i] != new_digits[i]);
        n /= 10;
      }
  
    for (scrollstep = 0; scrollstep < module->height; scrollstep++)
      {
!       x0 = module->width - fonts[f]->width;
!       y0 = module->height - fonts[f]->height;
  
-       /* i'm too tired to think about a smart algorithm... */
-       if (d == 1)
-         x0 = 4;
-   
        for (i = d; i > 0; i--)
          {
            if (scroll[i])
--- 265,295 ----
            b_module_request_stop (module);
            return -1;
          }
!     }
! 
    for (i = 0; i < MAX_DIGITS; i++)
      new_digits[i] = ' ';
!  
!   g_print ("using font #%d, w: %d h: %d a: %d\n",
             f, fonts[f]->width, fonts[f]->height, fonts[f]->advance);
  
!   if (countdown->last_font != f ||
        countdown->last_number_of_digits != d)
      b_module_fill (module, 0);
  
    for (i = d; i > 0; i--)
      {
        new_digits[i] = n % 10;
!       scroll[i] = (countdown->last_digits[i] == -1)
                  || (countdown->last_digits[i] != new_digits[i]);
        n /= 10;
      }
  
    for (scrollstep = 0; scrollstep < module->height; scrollstep++)
      {
!       x0 = (module->width + (d - 1) * fonts[f]->advance - fonts[f]->width) / 2;
!       y0 = (module->height - fonts[f]->height) / 2;
  
        for (i = d; i > 0; i--)
          {
            if (scroll[i])
***************
*** 293,303 ****
                          (module->maxval/2):0;
                      }
                    module->buffer[x + x0] = 0;
!                   
                    for (y = 0; y < fonts[f]->height; y++)
                      {
                        if (y + y0 <= scrollstep + 1)
!                         b_module_draw_point (module, x0 + x, y0 + y + (scrollstep - module->height),
                                               (fonts[f]->data[new_digits[i]][y * fonts[f]->width + x] != '0')?
                                               module->maxval:0);
                      }
--- 303,313 ----
                          (module->maxval/2):0;
                      }
                    module->buffer[x + x0] = 0;
!                  
                    for (y = 0; y < fonts[f]->height; y++)
                      {
                        if (y + y0 <= scrollstep + 1)
!                         b_module_draw_point (module, x0 + x, y0 + y + (scrollstep - module->height + 1),
                                               (fonts[f]->data[new_digits[i]][y * fonts[f]->width + x] != '0')?
                                               module->maxval:0);
                      }
***************
*** 308,324 ****
        b_module_paint (module);
        usleep (33 * 1000);
      }
!  
    for (x = 0; x < MAX_DIGITS; x++)
      {
        countdown->last_digits[x] = new_digits[x];
      }
!   
    b_module_paint (module);
  
    countdown->last_font = f;
    countdown->last_number_of_digits = d;
!   
    gettimeofday (&tv, NULL);
    return 1000 - (tv.tv_usec / 1000);
  
--- 318,334 ----
        b_module_paint (module);
        usleep (33 * 1000);
      }
! 
    for (x = 0; x < MAX_DIGITS; x++)
      {
        countdown->last_digits[x] = new_digits[x];
      }
!  
    b_module_paint (module);
  
    countdown->last_font = f;
    countdown->last_number_of_digits = d;
!  
    gettimeofday (&tv, NULL);
    return 1000 - (tv.tv_usec / 1000);
  
diff -r -C 3 -N blib-1.1.7/modules/bcreatefile.c blib-1.1.7-ba20070811/modules/bcreatefile.c
*** blib-1.1.7/modules/bcreatefile.c	Thu Jan  1 01:00:00 1970
--- blib-1.1.7-ba20070811/modules/bcreatefile.c	Sat Aug 11 22:18:43 2007
***************
*** 0 ****
--- 1,248 ----
+ /* blib - Library of useful things to hack the Blinkenlights
+  *
+  * Copyright (c) 2001-2002  The Blinkenlights Crew
+  *                          Michael Natterer <mitch@gimp.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.
+  *
+  * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #include <stdlib.h>
+ #include <string.h>
+ 
+ #include <glib-object.h>
+ 
+ #include <blib/blib.h>
+ 
+ #define CREATE_FILE_DIR "/var/blink/createfile"
+ 
+ typedef struct _BChar BChar;
+ 
+ #define B_TYPE_CREATEFILE            (b_type_createfile)
+ #define B_CREATEFILE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_CREATEFILE, BCreateFile))
+ #define B_CREATEFILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_CREATEFILE, BCreateFileClass))
+ #define B_IS_CREATEFILE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_CREATEFILE))
+ #define B_IS_CREATEFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_CREATEFILE))
+ 
+ typedef struct _BCreateFile      BCreateFile;
+ typedef struct _BCreateFileClass BCreateFileClass;
+ 
+ struct _BCreateFile
+ {
+   BModule       parent_instance;
+ };
+ 
+ struct _BCreateFileClass
+ {
+   BModuleClass  parent_class;
+ };
+ 
+ 
+ static GType      b_createfile_get_type      (GTypeModule   *module);
+ 
+ static void       b_createfile_class_init    (BCreateFileClass    *klass);
+ static void       b_createfile_init          (BCreateFile         *text);
+ 
+ static void       b_createfile_finalize      (GObject       *object);
+ static gboolean   b_createfile_query         (gint           width,
+                                         gint           height,
+                                         gint           channels,
+                                         gint           maxval);
+ static gboolean   b_createfile_prepare       (BModule       *module,
+                                         GError       **error);
+ static void       b_createfile_relax         (BModule       *module);
+ static void       b_createfile_start         (BModule       *module);
+ static void       b_createfile_stop          (BModule       *module);
+ static void       b_createfile_event         (BModule       *module,
+                                         BModuleEvent  *event);
+ static void       b_createfile_describe      (BModule       *module,
+                                         const gchar  **title,
+                                         const gchar  **description,
+                                         const gchar  **author);
+ 
+ 
+ static BModuleClass * parent_class = NULL;
+ static GType          b_type_createfile  = 0;
+ 
+ 
+ G_MODULE_EXPORT gboolean
+ b_module_register (GTypeModule *module)
+ {
+   b_createfile_get_type (module);
+   return TRUE;
+ }
+ 
+ static GType
+ b_createfile_get_type (GTypeModule *module)
+ {
+   if (! b_type_createfile)
+     {
+       static const GTypeInfo text_info =
+       {
+         sizeof (BCreateFileClass),
+         NULL,           /* base_init */
+         NULL,           /* base_finalize */
+         (GClassInitFunc) b_createfile_class_init,
+         NULL,           /* class_finalize */
+         NULL,           /* class_data */
+         sizeof (BCreateFile),
+         0,              /* n_preallocs */
+         (GInstanceInitFunc) b_createfile_init,
+       };
+ 
+       b_type_createfile = g_type_module_register_type (module,
+                                                  B_TYPE_MODULE, "BCreateFile",
+                                                  &text_info, 0);
+     }
+ 
+   return b_type_createfile;
+ }
+ 
+ static void
+ b_createfile_class_init (BCreateFileClass *klass)
+ {
+   GObjectClass *object_class;
+   BModuleClass *module_class;
+ 
+   object_class = G_OBJECT_CLASS (klass);
+   module_class = B_MODULE_CLASS (klass);
+ 
+   parent_class = g_type_class_peek_parent (klass);
+ 
+   object_class->finalize     = b_createfile_finalize;
+ 
+   module_class->max_players = 1;
+ 
+   module_class->query    = b_createfile_query;
+   module_class->prepare  = b_createfile_prepare;
+   module_class->relax    = b_createfile_relax;
+   module_class->start    = b_createfile_start;
+   module_class->stop     = b_createfile_stop;
+   module_class->event    = b_createfile_event;
+   module_class->describe = b_createfile_describe;
+ }
+ 
+ static void
+ b_createfile_init (BCreateFile *text)
+ {
+ }
+ 
+ static void
+ b_createfile_finalize (GObject *object)
+ {
+   BCreateFile *text;
+ 
+   text = B_CREATEFILE (object);
+ 
+   G_OBJECT_CLASS (parent_class)->finalize (object);
+ }
+ 
+ static gboolean
+ b_createfile_query (gint     width,
+               gint     height,
+               gint     channels,
+               gint     maxval)
+ {
+   return (width  >= 1 &&
+           height >= 1 &&
+           channels >= 1 &&
+           maxval >= 1);
+ }
+ 
+ static gboolean
+ b_createfile_prepare (BModule  *module,
+                 GError  **error)
+ {
+   BCreateFile *text;
+ 
+   text = B_CREATEFILE (module);
+ 
+   return TRUE;
+ }
+ 
+ static void
+ b_createfile_relax (BModule *module)
+ {
+ }
+ 
+ static void
+ b_createfile_start (BModule *module)
+ {
+   b_module_fill (module, 0);
+   b_module_paint (module);
+ }
+ 
+ static void
+ b_createfile_stop (BModule *module)
+ {
+ }
+ 
+ static void
+ b_createfile_event (BModule      *module,
+               BModuleEvent *event)
+ {
+   switch (event->type)
+     {
+     case B_EVENT_TYPE_KEY:
+       switch (event->key)
+         {
+         default:
+           case B_KEY_1:
+             fclose (fopen (CREATE_FILE_DIR"/1", "wt"));
+             break;
+           case B_KEY_2:
+             fclose (fopen (CREATE_FILE_DIR"/2", "wt"));
+             break;
+           case B_KEY_3:
+             fclose (fopen (CREATE_FILE_DIR"/3", "wt"));
+             break;
+           case B_KEY_4:
+             fclose (fopen (CREATE_FILE_DIR"/4", "wt"));
+             break;
+           case B_KEY_5:
+             fclose (fopen (CREATE_FILE_DIR"/5", "wt"));
+             break;
+           case B_KEY_6:
+             fclose (fopen (CREATE_FILE_DIR"/6", "wt"));
+             break;
+           case B_KEY_7:
+             fclose (fopen (CREATE_FILE_DIR"/7", "wt"));
+             break;
+           case B_KEY_8:
+             fclose (fopen (CREATE_FILE_DIR"/8", "wt"));
+             break;
+           case B_KEY_9:
+             fclose (fopen (CREATE_FILE_DIR"/9", "wt"));
+             break;
+           case B_KEY_0:
+             fclose (fopen (CREATE_FILE_DIR"/0", "wt"));
+             break;
+         }
+       break;
+ 
+     default:
+       break;
+     }
+ }
+ 
+ static void
+ b_createfile_describe (BModule      *module,
+                  const gchar **title,
+                  const gchar **description,
+                  const gchar **author)
+ {
+   *title       = "BCreateFile";
+   *description = "create a file";
+   *author      = "1stein";
+ }
diff -r -C 3 -N blib-1.1.7/modules/bdebug.c blib-1.1.7-ba20070811/modules/bdebug.c
*** blib-1.1.7/modules/bdebug.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bdebug.c	Sat Aug 11 22:18:43 2007
***************
*** 85,91 ****
  b_module_register (GTypeModule *module)
  {
    b_debug_get_type (module);
!   
    return TRUE;
  }
  
--- 85,91 ----
  b_module_register (GTypeModule *module)
  {
    b_debug_get_type (module);
!  
    return TRUE;
  }
  
***************
*** 244,250 ****
            switch (event->key)
              {
              case B_KEY_1:
! 	      debug->x--;	 
              case B_KEY_2:
  	      debug->y--;	
                break;
--- 244,250 ----
            switch (event->key)
              {
              case B_KEY_1:
! 	      debug->x--;	
              case B_KEY_2:
  	      debug->y--;	
                break;
***************
*** 252,258 ****
              case B_KEY_7:
  	      debug->y++;
              case B_KEY_4:
! 	      debug->x--;	 
                break;
  
              case B_KEY_3:
--- 252,258 ----
              case B_KEY_7:
  	      debug->y++;
              case B_KEY_4:
! 	      debug->x--;	
                break;
  
              case B_KEY_3:
***************
*** 282,288 ****
  		  b_module_ticker_start (module, 1000);
  		}
  	      break;
! 		  
  	    case B_KEY_5:
  	      debug->val += module->maxval/8;
  	      if (debug->val > module->maxval)
--- 282,288 ----
  		  b_module_ticker_start (module, 1000);
  		}
  	      break;
! 		 
  	    case B_KEY_5:
  	      debug->val += module->maxval/8;
  	      if (debug->val > module->maxval)
***************
*** 309,315 ****
  		  b_module_ticker_start (module, 250);
  		}
  	      break;
! 	     
  	    case B_KEY_ASTERISK:
  	      debug->val = module->maxval;
  	      break;
--- 309,315 ----
  		  b_module_ticker_start (module, 250);
  		}
  	      break;
! 	    
  	    case B_KEY_ASTERISK:
  	      debug->val = module->maxval;
  	      break;
diff -r -C 3 -N blib-1.1.7/modules/bdropout.c blib-1.1.7-ba20070811/modules/bdropout.c
*** blib-1.1.7/modules/bdropout.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bdropout.c	Sat Aug 11 22:18:43 2007
***************
*** 97,108 ****
  	  0,              /* n_preallocs */
  	  (GInstanceInitFunc) b_dropout_init,
  	};
!       
        b_type_dropout = g_type_module_register_type (module,
  						    B_TYPE_MODULE, "BDropout",
  						    &dropout_info, 0);
      }
!   
    return b_type_dropout;
  }
  
--- 97,108 ----
  	  0,              /* n_preallocs */
  	  (GInstanceInitFunc) b_dropout_init,
  	};
!      
        b_type_dropout = g_type_module_register_type (module,
  						    B_TYPE_MODULE, "BDropout",
  						    &dropout_info, 0);
      }
!  
    return b_type_dropout;
  }
  
***************
*** 114,120 ****
  
    object_class = G_OBJECT_CLASS (klass);
    module_class = B_MODULE_CLASS (klass);
!   
    module_class->query    = b_dropout_query;
    module_class->prepare  = b_dropout_prepare;
    module_class->relax    = b_dropout_relax;
--- 114,120 ----
  
    object_class = G_OBJECT_CLASS (klass);
    module_class = B_MODULE_CLASS (klass);
!  
    module_class->query    = b_dropout_query;
    module_class->prepare  = b_dropout_prepare;
    module_class->relax    = b_dropout_relax;
***************
*** 155,161 ****
  
    dropout->dropmap = g_new0 (gboolean, module->width * module->height);
    dropout->n = 0;
!   
    return TRUE;
  }
  
--- 155,161 ----
  
    dropout->dropmap = g_new0 (gboolean, module->width * module->height);
    dropout->n = 0;
!  
    return TRUE;
  }
  
***************
*** 163,169 ****
  b_dropout_relax (BModule *module)
  {
    BDropout *dropout = B_DROPOUT (module);
!   
    if (dropout->dropmap)
      {
        g_free (dropout->dropmap);
--- 163,169 ----
  b_dropout_relax (BModule *module)
  {
    BDropout *dropout = B_DROPOUT (module);
!  
    if (dropout->dropmap)
      {
        g_free (dropout->dropmap);
***************
*** 192,211 ****
  	  b_module_request_stop (module);
  	  return 0;
  	}
!       
!       do 
  	{
  	  x = random () % module->width;
  	  y = random () % module->height;
  	}
        while (dropout->dropmap[(y * module->width) + x]);
!       
        dropout->dropmap[(y * module->width) + x] = TRUE;
        b_module_draw_point (module, x, y, 0);
      }
!   
    b_module_paint (module);
!   
    return TIMEOUT;
  }
  
--- 192,211 ----
  	  b_module_request_stop (module);
  	  return 0;
  	}
!      
!       do
  	{
  	  x = random () % module->width;
  	  y = random () % module->height;
  	}
        while (dropout->dropmap[(y * module->width) + x]);
!      
        dropout->dropmap[(y * module->width) + x] = TRUE;
        b_module_draw_point (module, x, y, 0);
      }
!  
    b_module_paint (module);
!  
    return TIMEOUT;
  }
  
diff -r -C 3 -N blib-1.1.7/modules/bfire.c blib-1.1.7-ba20070811/modules/bfire.c
*** blib-1.1.7/modules/bfire.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bfire.c	Sat Aug 11 22:18:43 2007
***************
*** 4,10 ****
   *                     Sven Neumann <sven@gimp.org>
   *
   * Fire algorithm is based upon aafire which is distributed with aalib.
!  * 
   *                              dT8  8Tb
   *                             dT 8  8 Tb
   *                            dT  8  8  Tb
--- 4,10 ----
   *                     Sven Neumann <sven@gimp.org>
   *
   * Fire algorithm is based upon aafire which is distributed with aalib.
!  *
   *                              dT8  8Tb
   *                             dT 8  8 Tb
   *                            dT  8  8  Tb
***************
*** 208,214 ****
        else
  	fire->table[i] = 0;
      }
!   
    return TRUE;
  }
  
--- 208,214 ----
        else
  	fire->table[i] = 0;
      }
!  
    return TRUE;
  }
  
***************
*** 260,274 ****
      *d = fire->table[(d[width - 1] + d[width + 1] + d[width] +
                        d[2 * width - 1] + d[2 * width + 1])];
  
!   for ( ; i > width + 1; d++, i--)
      *d = fire->table[(d[width - 1] + d[width + 1] + d[width] +
                        2 * d[0])];
  
!   for ( ; i > 1; d++, i--)
      *d = fire->table[d[- 1] + 3 * d[0] + d[1]];
  
    *d = fire->table[2 * d[- 1] + 3 * d[0]];
!   
    b_module_paint (module);
  
    return TIMEOUT;
--- 260,274 ----
      *d = fire->table[(d[width - 1] + d[width + 1] + d[width] +
                        d[2 * width - 1] + d[2 * width + 1])];
  
!   for  (; i > width + 1; d++, i--)
      *d = fire->table[(d[width - 1] + d[width + 1] + d[width] +
                        2 * d[0])];
  
!   for  (; i > 1; d++, i--)
      *d = fire->table[d[- 1] + 3 * d[0] + d[1]];
  
    *d = fire->table[2 * d[- 1] + 3 * d[0]];
!  
    b_module_paint (module);
  
    return TIMEOUT;
diff -r -C 3 -N blib-1.1.7/modules/bfireworks.c blib-1.1.7-ba20070811/modules/bfireworks.c
*** blib-1.1.7/modules/bfireworks.c	Thu Jan  1 01:00:00 1970
--- blib-1.1.7-ba20070811/modules/bfireworks.c	Sat Aug 11 22:18:43 2007
***************
*** 0 ****
--- 1,298 ----
+ /* blib - Library of useful things to hack the Blinkenlights
+  *
+  * Copyright (c) 2006  The Blinkenlights Crew
+  *                     Stefan Schuermans <1stein@blinkenarea.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.
+  *
+  * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #include <stdlib.h>
+ 
+ #include <glib.h>
+ #include <gmodule.h>
+ 
+ #include <math.h>
+ #include <string.h>
+ 
+ #include <blib/blib.h>
+ 
+ #define TIMEOUT  100
+ #define MAX_FIREWORKS 16
+ #define MIN_OBJECTS 3
+ #define MAX_OBJECTS 8
+ #define NEW_FIREWORKS_STEPS 30 /* 1/probability that an inactive firework is created in a step */
+ #define RISE_STEP 0.07
+ #define SPREAD_STEP 0.03
+ #define FADE16 25 /* 16 for no fading, greater for more fading */
+ 
+ #define B_TYPE_FIREWORKS         (b_type_fireworks)
+ #define B_FIREWORKS(obj)         (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_FIREWORKS, BFireworks))
+ #define B_FIREWORKS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_FIREWORKS, BFireworksClass))
+ #define B_IS_FIREWORKS(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_FIREWORKS))
+ 
+ typedef struct _tFirework {
+   gint active; /* if firework is active */
+   gint center_x, center_y; /* center of firework */
+   gint max_radius; /* maximum radius to reach */
+   gint num_objects; /* number of objects */
+   double base_angle; /* angle of first object */
+   float rise; /* 0..1, increased during rise phase */
+   float spread; /* 0..1, increased during explosion phase */
+ } tFirework;
+ 
+ typedef struct _BFireworks BFireworks;
+ typedef struct _BFireworksClass BFireworksClass;
+ 
+ struct _BFireworks
+ {
+   BModule parent_instance;
+ 
+   guchar * data;
+   guchar * data2;
+ 
+   guint n_fireworks;
+   tFirework fireworks[MAX_FIREWORKS];
+ };
+ 
+ struct _BFireworksClass
+ {
+   BModuleClass parent_class;
+ };
+ 
+ 
+ static GType b_fireworks_get_type (GTypeModule * module);
+ 
+ static void b_fireworks_class_init (BFireworksClass * klass);
+ static void b_fireworks_init (BFireworks * fireworks);
+ 
+ static gboolean b_fireworks_query (gint width,
+ 				   gint height, gint channels, gint maxval);
+ static gboolean b_fireworks_prepare (BModule * module, GError ** error);
+ static void b_fireworks_start (BModule * module);
+ static void b_fireworks_relax (BModule * module);
+ static gint b_fireworks_tick (BModule * module);
+ static void b_fireworks_describe (BModule * module,
+ 				  const gchar ** title,
+ 				  const gchar ** description,
+ 				  const gchar ** author);
+ 
+ 
+ static GType b_type_fireworks = 0;
+ 
+ 
+ G_MODULE_EXPORT gboolean
+ b_module_register (GTypeModule * module)
+ {
+   b_fireworks_get_type (module);
+   return TRUE;
+ }
+ 
+ GType
+ b_fireworks_get_type (GTypeModule * module)
+ {
+   if (!b_type_fireworks)
+     {
+       static const GTypeInfo fireworks_info = {
+ 	sizeof (BFireworksClass),
+ 	NULL,			/* base_init */
+ 	NULL,			/* base_finalize */
+ 	(GClassInitFunc) b_fireworks_class_init,
+ 	NULL,			/* class_finalize */
+ 	NULL,			/* class_data */
+ 	sizeof (BFireworks),
+ 	0,			/* n_preallocs */
+ 	(GInstanceInitFunc) b_fireworks_init,
+       };
+ 
+       b_type_fireworks = g_type_module_register_type (module,
+ 						      B_TYPE_MODULE,
+ 						      "BFireworks",
+ 						      &fireworks_info, 0);
+     }
+ 
+   return b_type_fireworks;
+ }
+ 
+ static void
+ b_fireworks_class_init (BFireworksClass * klass)
+ {
+   GObjectClass *object_class;
+   BModuleClass *module_class;
+ 
+   object_class = G_OBJECT_CLASS (klass);
+   module_class = B_MODULE_CLASS (klass);
+ 
+   module_class->query = b_fireworks_query;
+   module_class->prepare = b_fireworks_prepare;
+   module_class->relax = b_fireworks_relax;
+   module_class->start = b_fireworks_start;
+   module_class->tick = b_fireworks_tick;
+   module_class->describe = b_fireworks_describe;
+ }
+ 
+ static void
+ b_fireworks_init (BFireworks * fireworks)
+ {
+ }
+ 
+ static gboolean
+ b_fireworks_query (gint width, gint height, gint channels, gint maxval)
+ {
+   return (width > 3 && height > 3 && channels == 1 && maxval == 255);
+ }
+ 
+ static gboolean
+ b_fireworks_prepare (BModule * module, GError ** error)
+ {
+   BFireworks *fireworks = B_FIREWORKS (module);
+   gint width = module->width;
+   gint height = module->height;
+ 
+   fireworks->data = (guchar *)g_malloc (width * height);
+   memset (fireworks->data, 0, width * height);
+   fireworks->data2 = (guchar *)g_malloc (width * height);
+   memset (fireworks->data2, 0, width * height);
+ 
+   fireworks->n_fireworks = MAX (width / height, height / width);
+   if (fireworks->n_fireworks > MAX_FIREWORKS)
+     fireworks->n_fireworks = MAX_FIREWORKS;
+ 
+   return TRUE;
+ }
+ 
+ static void
+ b_fireworks_relax (BModule * module)
+ {
+   BFireworks *fireworks = B_FIREWORKS (module);
+ 
+   g_free (fireworks->data);
+   fireworks->data = NULL;
+   g_free (fireworks->data2);
+   fireworks->data2 = NULL;
+ }
+ 
+ static void
+ b_fireworks_start (BModule * module)
+ {
+   BFireworks *fireworks = B_FIREWORKS (module);
+   gint i;
+ 
+   for (i = 0; i < fireworks->n_fireworks; i++)
+     fireworks->fireworks[i].active = 0;
+ 
+   b_module_ticker_start (module, b_fireworks_tick (module));
+ }
+ 
+ static gint
+ b_fireworks_tick (BModule * module)
+ {
+   BFireworks *fireworks = B_FIREWORKS (module);
+   gint width = module->width;
+   gint height = module->height;
+   float aspect = module->aspect;
+   gint maxval = module->maxval;
+   float base_radius = MIN ((float)height, (float)width * aspect)  * 0.3;
+   gint min_radius = (gint)(base_radius);
+   gint max_radius = (gint)(base_radius * 2);
+   guchar * data = fireworks->data;
+   guchar * data2 = fireworks->data2;
+   gint x, y, i;
+ 
+   /* create new fireworks */
+   for (i = 0; i < fireworks->n_fireworks; i++)  {
+     tFirework * fw = &fireworks->fireworks[i];
+     if (! fw->active && rand () < RAND_MAX / NEW_FIREWORKS_STEPS)  {
+       fw->active = 1;
+       fw->center_x = rand () % width;
+       fw->center_y = rand () % height;
+       fw->max_radius = min_radius + rand () % (max_radius - min_radius + 1);
+       fw->num_objects = MIN_OBJECTS + rand () % (MAX_OBJECTS - MIN_OBJECTS + 1);
+       fw->base_angle = 6.28 * (double)rand () / (double)RAND_MAX;
+       fw->rise = 0.0;
+       fw->spread = 0.0;
+     }
+   }
+   /* blur and fade out */
+   memcpy (data2, data, width * height);
+   for (y = 0, i = 0; y < height; y++)  {
+     for (x = 0; x < width; x++, i++)  {
+       gint l = x > 0 ? x - 1 : 0, r = x < width - 1 ? x + 1 : width - 1;
+       gint t = y > 0 ? y - 1 : 0, b = y < height - 1 ? y + 1 : height - 1;
+       gint c = 1 * ((gint)data2[t * width + l] + (gint)data2[t * width + r]
+                   + (gint)data2[b * width + l] + (gint)data2[b * width + r])
+              + 2 * ((gint)data2[y * width + l] + (gint)data2[y * width + r]
+                   + (gint)data2[t * width + x] + (gint)data2[b * width + x])
+              + 4 * (gint)data2[y * width + x];
+       data[i] = (guchar)(c / FADE16);
+     }
+   }
+ 
+   /* draw fireworks */
+   for (i = 0; i < fireworks->n_fireworks; i++)  {
+     tFirework * fw = &fireworks->fireworks[i];
+     if (fw->active)  {
+       /* rise phase */
+       if (fw->rise < 1.0)  {
+         guchar c;
+         fw->rise += RISE_STEP;
+         c = (guchar)(fw->rise * (float)0xFF + 0.5);
+         x = fw->center_x;
+         y = fw->center_y;
+         if (x >= 0 && x < width && y >= 0 && y < height)  {
+           guchar * ptr = &data[y * width + x];
+           *ptr = MAX (*ptr, c);
+         }
+       /* spread phase */
+       } else if (fw->spread < 1.0)  {
+         guchar c;
+         gint j;
+         fw->spread += SPREAD_STEP;
+         c = (guchar)((1.0 - 0.5 * fw->spread) * (float)module->maxval + 0.5);
+         for (j = 0; j < fw->num_objects; j++)  {
+           double radius = fw->spread * fw->max_radius;
+           double angle = fw->base_angle + 6.28 * (double)j / (double)fw->num_objects;
+           x = (gint)((double)fw->center_x + radius / (double)aspect * (double)cos (angle)  + 0.5);
+           y = (gint)((double)fw->center_y + radius * (double)sin (angle)  + 0.5);
+           if (x >= 0 && x < width && y >= 0 && y < height)  {
+             guchar * ptr = &data[y * width + x];
+             *ptr = MAX (*ptr, c);
+           }
+         }
+       /* done */
+       } else
+         fw->active = 0;
+     }
+   }
+ 
+   /* draw data to display */
+   for (y = 0, i = 0; y < height; y++)  {
+     for (x = 0; x < width; x++, i++)  {
+       b_module_draw_point (module, x, y, (gint)data[i] * maxval / 0xFF);
+     }
+   }
+   b_module_paint (module);
+ 
+   return TIMEOUT;
+ }
+ 
+ static void
+ b_fireworks_describe (BModule * module,
+ 		      const gchar ** title,
+ 		      const gchar ** description, const gchar ** author)
+ {
+   *title = "BFireworks";
+   *description = "Fireworks hack";
+   *author = "Stefan Schuermans";
+ }
diff -r -C 3 -N blib-1.1.7/modules/bmatrix.c blib-1.1.7-ba20070811/modules/bmatrix.c
*** blib-1.1.7/modules/bmatrix.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bmatrix.c	Sat Aug 11 22:18:43 2007
***************
*** 13,19 ****
   * the above copyright notice appear in all copies and that both that
   * copyright notice and this permission notice appear in supporting
   * documentation.  No representations are made about the suitability of this
!  * software for any purpose.  It is provided "as is" without express or 
   * implied warranty.
   *
   * Matrix -- simulate the text scrolls from the movie "The Matrix".
--- 13,19 ----
   * the above copyright notice appear in all copies and that both that
   * copyright notice and this permission notice appear in supporting
   * documentation.  No representations are made about the suitability of this
!  * software for any purpose.  It is provided "as is" without express or
   * implied warranty.
   *
   * Matrix -- simulate the text scrolls from the movie "The Matrix".
***************
*** 81,87 ****
    gint insert_top_p, insert_bottom_p;
    gint density;
    gint density_param;
!   
    gint image_width, image_height;
    gint nglyphs;
  };
--- 81,87 ----
    gint insert_top_p, insert_bottom_p;
    gint density;
    gint density_param;
!  
    gint image_width, image_height;
    gint nglyphs;
  };
***************
*** 366,372 ****
    to->changed = 1;
  
    if (!to->glyph)
!     ;
    else if (bottom_feeder_p)
      to->glow = 1 + (rand() % 2);
    else
--- 366,372 ----
    to->changed = 1;
  
    if (!to->glyph)
!    ;
    else if (bottom_feeder_p)
      to->glow = 1 + (rand() % 2);
    else
***************
*** 536,542 ****
  
            x = (rand() % state->grid_width);
  
!           for (i = -w; i <= w ; i++)
              {
                if (x+i >= 0 &&
                    x+i < state->grid_width &&
--- 536,542 ----
  
            x = (rand() % state->grid_width);
  
!           for (i = -w; i <= w; i++)
              {
                if (x+i >= 0 &&
                    x+i < state->grid_width &&
diff -r -C 3 -N blib-1.1.7/modules/bpacman.c blib-1.1.7-ba20070811/modules/bpacman.c
*** blib-1.1.7/modules/bpacman.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bpacman.c	Sat Aug 11 22:18:43 2007
***************
*** 1,6 ****
! /* BPacman: Pacman module for Blinkenlights
   *
!  * Copyright (c) 2002  1stein <1stein@1stein.no-ip.com>
   *
   * based on Test implementation for a BModule by the Blinkenlights Crew
   *
--- 1,6 ----
! /* BPacman: Pacman bluebox module for Blinkenlights
   *
!  * Copyright (c) 2006 1stein <1stein@blinkenare.org>
   *
   * based on Test implementation for a BModule by the Blinkenlights Crew
   *
***************
*** 19,24 ****
--- 19,26 ----
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   */
  
+ /* #define PACMAN_DEBUG */
+ 
  #include "config.h"
  
  #include <string.h>
***************
*** 29,139 ****
  
  #include <blib/blib.h>
  
! #define BPacmanVerMaj 1
! #define BPacmanVerMin 0
! #define BPacmanVerRev 3
! 
! //minimum size and color count of display
! #define BPacmanSizeXMin 25
! #define BPacmanSizeYMin 19
  #define BPacmanColorCntMin 4
! //number of lives for pacman
  #define BPacmanLives 3
! //speed of game
  #define BPacmanTicks 150
! //number of ticks pacman is dead after contact with monster
  #define BPacmanDeadTime 10
! //position of eaten monsters
  #define BPacmanMonsterNirvana -100
! //the colors
! #define BPacmanColorEmpty( MaxColor ) (0)
! #define BPacmanColorWall( MaxColor ) ((MaxColor) * 2 / 3)
! #define BPacmanColorPoint( MaxColor ) ((MaxColor) / 3)
! #define BPacmanColorPacmanDead( MaxColor ) ((MaxColor) / 2)
! #define BPacmanColorPacmanAlive( MaxColor ) (MaxColor)
! #define BPacmanColorMonsterDead( MaxColor ) ((MaxColor) / 2)
! #define BPacmanColorMonsterAlive( MaxColor ) (MaxColor)
! //start position and direction of pacman
! #define BPacmanStartPosX -1
! #define BPacmanStartPosY 8
! #define BPacmanStartDirX 1
! #define BPacmanStartDirY 0
! //start positions and directions of monsters
! #define BPacmanMonsterCnt 2
! #define BPacmanMonster0StartPosX 12
! #define BPacmanMonster0StartPosY -1
! #define BPacmanMonster0StartDirX 0
! #define BPacmanMonster0StartDirY 1
! #define BPacmanMonster1StartPosX 12
! #define BPacmanMonster1StartPosY 19
! #define BPacmanMonster1StartDirX 0
! #define BPacmanMonster1StartDirY -1
! //the walls of the game-field
! int BPacmanWalls[BPacmanSizeYMin][BPacmanSizeXMin] = {
!   {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
!   {1, 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, 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, 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, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1},
!   {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1},
!   {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1},
!   {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0},
!   {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
!   {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1},
!   {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1},
!   {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1},
!   {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1},
!   {1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1},
!   {1, 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, 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, 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, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
! };
! //the positions where changing direction is allowed
! int BPacmanChDir[BPacmanSizeYMin][BPacmanSizeXMin] = {
!   {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, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 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, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 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, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 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, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 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, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 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, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 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}
! };
! //the points of the game-field
! int BPacmanPoints[BPacmanSizeYMin][BPacmanSizeXMin] = {
!   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 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, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 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, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 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, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
!   {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, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 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, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 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, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 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, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
! };
  
  #ifdef PACMAN_DEBUG
  #define dbg_print g_print
--- 31,185 ----
  
  #include <blib/blib.h>
  
! /* color count of display */
  #define BPacmanColorCntMin 4
! /* number of lives for pacman */
  #define BPacmanLives 3
! /* speed of game */
  #define BPacmanTicks 150
! /* number of ticks pacman is dead after contact with monster */
  #define BPacmanDeadTime 10
! /* position of eaten monsters */
  #define BPacmanMonsterNirvana -100
! /* the colors */
! #define BPacmanColorEmpty(MaxColor)        (0)
! #define BPacmanColorWall(MaxColor)         ((MaxColor) * 2 / 3)
! #define BPacmanColorPoint(MaxColor)        ((MaxColor) / 3)
! #define BPacmanColorPacmanDead(MaxColor)   ((MaxColor) / 2)
! #define BPacmanColorPacmanAlive(MaxColor)  (MaxColor)
! #define BPacmanColorMonsterDead(MaxColor)  ((MaxColor) / 2)
! #define BPacmanColorMonsterAlive(MaxColor) (MaxColor)
! /* number of monsters */
! #define BPacmanMonsterCntMax 5
! 
! /* meaning of game field data */
! #define BPacmanFieldWall 1
! #define BPacmanFieldChDir 2
! #define BPacmanFieldPoint 4
! 
! /* the pacman game fields */
! typedef struct BPacmanPosDirInfo
!   {
!     gint xPos, yPos; /* start position */
!     gint xDir, yDir; /* start direction */
!   } BPacmanPosDirInfo;
! typedef struct BPacmanField
!   {
!     guint             xTotal, yTotal;                      /* total size of game filed */
!     guint             xOffset, yOffset;                    /* offset of the visible part of the game field */
!     guint             xVisible, yVisible;                  /* size of the visible part of the game field */
!     gchar            *fieldData;                           /* the game field data */
!     BPacmanPosDirInfo pacmanStart;                         /* start information of pacman */
!     guint             monsterCnt;                          /* number of monsters */
!     BPacmanPosDirInfo monsterStarts[BPacmanMonsterCntMax]; /* start information of monsters */
!   } BPacmanField;
! guchar BPacmanFieldDataArcade[] =
!   {
!     1,1,1,1,1,1,1,1,1,1,1,0,4,0,1,1,1,1,1,1,1,1,1,1,1,
!     1,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,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,1,
!     1,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,0,6,0,1,0,6,0,1,1,1,1,1,1,1,1,1,0,6,0,1,0,6,0,1,
!     1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,
!     1,0,6,0,1,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,1,0,6,0,1,
!     0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
!     4,0,6,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,6,0,4,
!     0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,
!     1,0,6,0,1,0,6,0,6,0,6,0,1,0,6,0,6,0,6,0,1,0,6,0,1,
!     1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,
!     1,0,6,0,1,0,6,0,1,0,6,0,6,0,6,0,1,0,6,0,1,0,6,0,1,
!     1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,
!     1,0,6,0,1,0,6,0,1,1,1,1,1,1,1,1,1,0,6,0,1,0,6,0,1,
!     1,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,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,1,
!     1,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,0,4,0,1,1,1,1,1,1,1,1,1,1,1,
!   };
! guchar BPacmanFieldDataBluebox[] =
!   {
!     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,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,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,1,
!     1,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,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,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,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,1,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,1,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,1,
!     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,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,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,
!     4,0,6,0,1,1,1,1,1,1,1,0,6,0,1,1,1,1,1,1,1,1,1,1,1,0,6,0,1,0,6,0,1,1,1,1,1,1,1,1,1,0,6,0,1,1,1,1,1,1,1,1,1,0,6,0,1,1,1,1,1,1,1,1,1,0,6,0,1,0,6,0,1,1,1,1,1,1,1,1,1,1,1,0,6,0,1,1,1,1,1,1,1,0,6,0,4,
!     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,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,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,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,1,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,1,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,1,
!     1,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,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,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,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,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,1,1,
!   };
! BPacmanField BPacmanFields[] =
!   {
!     {
!       .xTotal = 25, .yTotal = 19,
!       .xOffset = 0, .yOffset = 0,
!       .xVisible = 25, .yVisible = 19,
!       .fieldData = BPacmanFieldDataArcade,
!       .pacmanStart =
!         {
!           .xPos = -1, .yPos = 8,
!           .xDir = 1, .yDir = 0,
!         },
!       .monsterCnt = 2,
!       .monsterStarts =
!         {
!           {
!             .xPos = 12, .yPos = -1,
!             .xDir = 0, .yDir = 1,
!           },
!           {
!             .xPos = 12, .yPos = 19,
!             .xDir = 0, .yDir = -1,
!           },
!           {
!             .xPos = -100, .yPos = -100,
!             .xDir = -100, .yDir = -100,
!           },
!           {
!             .xPos = -100, .yPos = -100,
!             .xDir = -100, .yDir = -100,
!           },
!           {
!             .xPos = -100, .yPos = -100,
!             .xDir = -100, .yDir = -100,
!           },
!         },
!     },
!     {
!       .xTotal = 97, .yTotal = 9,
!       .xOffset = 0, .yOffset = 1,
!       .xVisible = 97, .yVisible = 7,
!       .fieldData = BPacmanFieldDataBluebox,
!       .pacmanStart =
!         {
!           .xPos = -1, .yPos = 4,
!           .xDir = 1, .yDir = 0,
!         },
!       .monsterCnt = 2,
!       .monsterStarts =
!         {
!           {
!             .xPos = 76, .yPos = 2,
!             .xDir = -1, .yDir = 0,
!           },
!           {
!             .xPos = 20, .yPos = 6,
!             .xDir = -1, .yDir = 0,
!           },
!           {
!             .xPos = -100, .yPos = -100,
!             .xDir = -100, .yDir = -100,
!           },
!           {
!             .xPos = -100, .yPos = -100,
!             .xDir = -100, .yDir = -100,
!           },
!           {
!             .xPos = -100, .yPos = -100,
!             .xDir = -100, .yDir = -100,
!           },
!         },
!     },
!   };
  
  #ifdef PACMAN_DEBUG
  #define dbg_print g_print
***************
*** 156,173 ****
  {
    BModule parent_instance;
  
!   int OfsX, OfsY;		//offset of top left corner of game-field
!   int MaxColor;			//maximum color value
!   int Points[BPacmanSizeYMin][BPacmanSizeXMin];	//points in game field
!   int PointsLeft;		//numer of points left
!   int PosX, PosY, CurDirX, CurDirY, NextDirX, NextDirY;	//position, current direction and next direction of pacman
!   int MouthOpen;		//pacman's mouth state
!   int DeadCnt;			//counter how long pacman is dead, 0 if not dead
!   int MonsterPosX[BPacmanMonsterCnt], MonsterPosY[BPacmanMonsterCnt];	//position of monsters
!   int MonsterDirX[BPacmanMonsterCnt], MonsterDirY[BPacmanMonsterCnt];	//direction of monsters
!   int MonstersDead;		//!0 if monsters are dead
!   int Lives;                    //rest of pacman's lives
!   int player_device_id;
  };
  
  struct _BPacmanModuleClass
--- 202,220 ----
  {
    BModule parent_instance;
  
!   BPacmanField * field; 	                        /* pointer to information about the game field */
!   gint OfsX, OfsY;					/* offset of top left corner of game-field */
!   gint MaxColor;					/* maximum color value */
!   gint * Points;					/* points in game field */
!   gint PointsLeft;					/* numer of points left */
!   BPacmanPosDirInfo pacman;				/* position and current direction of pacman */
!   BPacmanPosDirInfo nextPacman;				/* next direction of pacman (ignore position in this structure) */
!   gint MouthOpen;					/* pacman's mouth state */
!   gint DeadCnt;						/* counter how long pacman is dead, 0 if not dead */
!   BPacmanPosDirInfo monsters[BPacmanMonsterCntMax];	/* position and direction of monsters */
!   gint MonstersDead;					/* !0 if monsters are dead */
!   gint Lives;						/* rest of pacman's lives */
!   gint player_device_id;
  };
  
  struct _BPacmanModuleClass
***************
*** 185,190 ****
--- 232,238 ----
  static gboolean b_pacman_module_prepare    (BModule             *module,
                                              GError             **error);
  static void     b_pacman_module_start      (BModule             *module);
+ static void     b_pacman_module_stop       (BModule             *module);
  static void     b_pacman_module_event      (BModule             *module,
                                              BModuleEvent        *event);
  static gint     b_pacman_module_tick       (BModule             *module);
***************
*** 234,295 ****
    return b_type_pacman_module;
  }
  
! //check a picel
! //returns 1 if pixel in game field or 0 if it is not in game field
! static inline int
! BPacmanCheckPixel (int X, int Y)
  {
!   return (X >= 0 && X < BPacmanSizeXMin && Y >= 0 && Y < BPacmanSizeYMin);
  }
  
! //check a position (for pacman or monster)
! //returns 1 if position is free of walls or 0 if there is a wall at this position
! int
! BPacmanCheckPos (int X, int Y)
  {
!   int XX, YY;
  
    for (YY = -1; YY <= 1; YY++)
!     for (XX = -1; XX <= 1; XX++)
!       if (BPacmanCheckPixel (X + XX, Y + YY))
! 	if (BPacmanWalls[Y + YY][X + XX])
  	  return 0;
    return 1;
  }
  
! //output a pixel
! void
! BPacmanOutputPixel (BPacmanModule *pPacmanModule, int X, int Y, int Color)
  {
!   if (BPacmanCheckPixel (X, Y))
      b_module_draw_point ((BModule *) pPacmanModule,
! 			 X + pPacmanModule->OfsX, Y + pPacmanModule->OfsY,
  			 Color);
  }
  
! //output current picture
! void
  BPacmanOutput (BPacmanModule *pPacmanModule)
  {
!   int X, Y, I, Color;
  
!   //empty the screen
    b_module_fill ((BModule *) pPacmanModule,
  		 BPacmanColorEmpty (pPacmanModule->MaxColor));
  
!   //put walls and points onto screen
!   for (Y = 0; Y < BPacmanSizeYMin; Y++)
      {
!       for (X = 0; X < BPacmanSizeXMin; X++)
  	{
! 	  //wall
! 	  if (BPacmanWalls[Y][X])
  	    b_module_draw_point ((BModule *) pPacmanModule,
  				 X + pPacmanModule->OfsX,
  				 Y + pPacmanModule->OfsY,
  				 BPacmanColorWall (pPacmanModule->MaxColor));
! 	  //point
! 	  if (pPacmanModule->Points[Y][X])
  	    b_module_draw_point ((BModule *) pPacmanModule,
  				 X + pPacmanModule->OfsX,
  				 Y + pPacmanModule->OfsY,
--- 282,373 ----
    return b_type_pacman_module;
  }
  
! /* select a game field based on the display size */
! /* returns pointer to game field descriptor or NULL if no field has been found */
! static BPacmanField * b_pacman_module_select_field (gint width, gint height)
! {
!   gint i;
! 
!   /* return pointer to descriptor of first game field that fits on the display */
!   for (i = 0; i < sizeof (BPacmanFields)  / sizeof (BPacmanFields[0]); i++)
!     if (width >= BPacmanFields[i].xVisible && height >= BPacmanFields[i].yVisible)
!       return &BPacmanFields[i];
! 
!   /* no game fields fits on the display */
!   return NULL;
! }
! 
! /* check a pixel */
! /* returns 1 if pixel in game field or 0 if it is not in game field */
! static inline gint
! BPacmanCheckPixel (BPacmanModule * pPacmanModule, gint X, gint Y)
  {
!   return (X >= 0 && X < pPacmanModule->field->xTotal
!           && Y >= 0 && Y < pPacmanModule->field->yTotal);
  }
  
! /* check a position (for pacman or monster) */
! /* returns 1 if position is free of walls or 0 if there is a wall at this position */
! static gint
! BPacmanCheckPos (BPacmanModule * pPacmanModule, gint X, gint Y)
  {
!   gint xTotal, XX, YY, iX, iY;
  
+   xTotal = pPacmanModule->field->xTotal;
    for (YY = -1; YY <= 1; YY++)
!     for (XX = -1; XX <= 1; XX++) {
!       iX = X + XX;
!       iY = Y + YY;
!       if (BPacmanCheckPixel (pPacmanModule, iX, iY))
! 	if (pPacmanModule->field->fieldData[iY * xTotal + iX] & BPacmanFieldWall)
  	  return 0;
+     }
    return 1;
  }
  
! /* output a pixel */
! static void
! BPacmanOutputPixel (BPacmanModule *pPacmanModule, gint X, gint Y, gint Color)
  {
!   X -= pPacmanModule->field->xOffset;
!   Y -= pPacmanModule->field->yOffset;
!   if (X >= 0 && Y >= 0
!       && X < pPacmanModule->field->xVisible
!       && Y < pPacmanModule->field->yVisible)
      b_module_draw_point ((BModule *) pPacmanModule,
! 			 X + pPacmanModule->OfsX,
!                          Y + pPacmanModule->OfsY,
  			 Color);
  }
  
! /* output current picture */
! static void
  BPacmanOutput (BPacmanModule *pPacmanModule)
  {
!   gint xTotal, xOffset, yOffset, X, Y, I, Color;
! 
!   xTotal = pPacmanModule->field->xTotal;
!   xOffset = pPacmanModule->field->xOffset;
!   yOffset = pPacmanModule->field->yOffset;
  
!   /* empty the screen */
    b_module_fill ((BModule *) pPacmanModule,
  		 BPacmanColorEmpty (pPacmanModule->MaxColor));
  
!   /* put walls and points onto screen */
!   for (Y = 0; Y < pPacmanModule->field->yVisible; Y++)
      {
!       for (X = 0; X < pPacmanModule->field->xVisible; X++)
  	{
!           gint i = (yOffset + Y) * xTotal + xOffset + X;
! 	  /* wall */
! 	  if (pPacmanModule->field->fieldData[i] & BPacmanFieldWall)
  	    b_module_draw_point ((BModule *) pPacmanModule,
  				 X + pPacmanModule->OfsX,
  				 Y + pPacmanModule->OfsY,
  				 BPacmanColorWall (pPacmanModule->MaxColor));
! 	  /* point */
! 	  if (pPacmanModule->Points[i])
  	    b_module_draw_point ((BModule *) pPacmanModule,
  				 X + pPacmanModule->OfsX,
  				 Y + pPacmanModule->OfsY,
***************
*** 297,516 ****
  	}
      }
  
!   //get pacman color (dead or alive)
    if (pPacmanModule->DeadCnt > 0)
      Color = BPacmanColorPacmanDead (pPacmanModule->MaxColor);
    else
      Color = BPacmanColorPacmanAlive (pPacmanModule->MaxColor);
!   //draw pacman
    if (!pPacmanModule->MouthOpen)
!     BPacmanOutputPixel (pPacmanModule, pPacmanModule->PosX,
! 			pPacmanModule->PosY, Color);
!   if (!pPacmanModule->MouthOpen || pPacmanModule->CurDirX != -1)
!     BPacmanOutputPixel (pPacmanModule, pPacmanModule->PosX - 1,
! 			pPacmanModule->PosY, Color);
!   if (!pPacmanModule->MouthOpen || pPacmanModule->CurDirX != 1)
!     BPacmanOutputPixel (pPacmanModule, pPacmanModule->PosX + 1,
! 			pPacmanModule->PosY, Color);
!   if (!pPacmanModule->MouthOpen || pPacmanModule->CurDirY != -1)
!     BPacmanOutputPixel (pPacmanModule, pPacmanModule->PosX,
! 			pPacmanModule->PosY - 1, Color);
!   if (!pPacmanModule->MouthOpen || pPacmanModule->CurDirY != 1)
!     BPacmanOutputPixel (pPacmanModule, pPacmanModule->PosX,
! 			pPacmanModule->PosY + 1, Color);
  
!   //get monster color (dead or alive)
    if (pPacmanModule->MonstersDead)
      Color = BPacmanColorMonsterDead (pPacmanModule->MaxColor);
    else
      Color = BPacmanColorMonsterAlive (pPacmanModule->MaxColor);
!   //draw monsters
!   for (I = 0; I < BPacmanMonsterCnt; I++)
      {
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->MonsterPosX[I],
! 			  pPacmanModule->MonsterPosY[I] - 1, Color);
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->MonsterPosX[I] - 1,
! 			  pPacmanModule->MonsterPosY[I], Color);
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->MonsterPosX[I],
! 			  pPacmanModule->MonsterPosY[I], Color);
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->MonsterPosX[I] + 1,
! 			  pPacmanModule->MonsterPosY[I], Color);
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->MonsterPosX[I] - 1,
! 			  pPacmanModule->MonsterPosY[I] + 1, Color);
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->MonsterPosX[I] + 1,
! 			  pPacmanModule->MonsterPosY[I] + 1, Color);
      }
  
!   //update screen
    b_module_paint ((BModule *) pPacmanModule);
  }
  
! //start a new game
! void
  BPacmanNewGame (BPacmanModule *pPacmanModule)
  {
!   int X, Y;
  
!   //copy points into local points array and count them
    pPacmanModule->PointsLeft = 0;
!   for (Y = 0; Y < BPacmanSizeYMin; Y++)
      {
!       for (X = 0; X < BPacmanSizeXMin; X++)
  	{
! 	  pPacmanModule->Points[Y][X] = BPacmanPoints[Y][X];
! 	  if (BPacmanPoints[Y][X])
  	    pPacmanModule->PointsLeft++;
  	}
      }
  
!   //set start position and direction of pacman
!   pPacmanModule->PosX = BPacmanStartPosX;
!   pPacmanModule->PosY = BPacmanStartPosY;
!   pPacmanModule->CurDirX = BPacmanStartDirX;
!   pPacmanModule->CurDirY = BPacmanStartDirY;
!   pPacmanModule->NextDirX = BPacmanStartDirX;
!   pPacmanModule->NextDirY = BPacmanStartDirY;
    pPacmanModule->MouthOpen = 0;
    pPacmanModule->DeadCnt = 0;
!   //set start position and direction of monsters
!   pPacmanModule->MonsterPosX[0] = BPacmanMonster0StartPosX;
!   pPacmanModule->MonsterPosY[0] = BPacmanMonster0StartPosY;
!   pPacmanModule->MonsterDirX[0] = BPacmanMonster0StartDirX;
!   pPacmanModule->MonsterDirY[0] = BPacmanMonster0StartDirY;
!   pPacmanModule->MonsterPosX[1] = BPacmanMonster1StartPosX;
!   pPacmanModule->MonsterPosY[1] = BPacmanMonster1StartPosY;
!   pPacmanModule->MonsterDirX[1] = BPacmanMonster1StartDirX;
!   pPacmanModule->MonsterDirY[1] = BPacmanMonster1StartDirY;
    pPacmanModule->MonstersDead = 0;
  
    dbg_print ("BPacman: new game\n");
  
!   //output current picture
    BPacmanOutput (pPacmanModule);
  }
  
! //key-procedure
! void
  BPacmanKey (BPacmanModule *pPacmanModule,
              BModuleKey     Key)
  {
    switch (Key)
      {
      case B_KEY_2:
!       //set pacman's next direction to upwards
!       pPacmanModule->NextDirX = 0;
!       pPacmanModule->NextDirY = -1;
        break;
      case B_KEY_4:
!       //set pacman's next direction to leftwards
!       pPacmanModule->NextDirX = -1;
!       pPacmanModule->NextDirY = 0;
        break;
      case B_KEY_6:
!       //set pacman's next direction to rightwards
!       pPacmanModule->NextDirX = 1;
!       pPacmanModule->NextDirY = 0;
        break;
      case B_KEY_8:
!       //set pacman's next direction to downwards
!       pPacmanModule->NextDirX = 0;
!       pPacmanModule->NextDirY = 1;
        break;
  
      default:
        break;
      }
  
!   //output current picture
    BPacmanOutput (pPacmanModule);
  }
  
! //tick-procedure
! //returns 1 if game over or 0 if game not over
! int
  BPacmanTick (BPacmanModule *pPacmanModule)
  {
!   int X, Y, I, J, Left, Right, Up, Down, Cnt, DirX[4], DirY[4];
  
!   //toggle mouth state
    pPacmanModule->MouthOpen = !pPacmanModule->MouthOpen;
  
!   //mouth now open
    if (pPacmanModule->MouthOpen)
      {
!       //pacman is dead
        if (pPacmanModule->DeadCnt > 0)
  	{
! 	  //decrement dead count
  	  pPacmanModule->DeadCnt--;
  	  if (pPacmanModule->DeadCnt == 0)
            {
!             //another life
!             if( pPacmanModule->Lives > 0 )
              {
!               dbg_print( "BPacman: Pacman is alive again - %d live(s) left\n", pPacmanModule->Lives );
              }
!             //game over
              else
              {
!               dbg_print( "BPacman: Pacman has no lives left - game over\n" );
!               //request end
!               b_module_request_stop( (BModule *)pPacmanModule );
! 	      //do nothing else and return game over
  	      return 1;
              }
            }
  	}
!       //pacman is alive
        else
  	{
! 	  //pacman is at a position where changing direction is allowed
! 	  if (BPacmanCheckPixel (pPacmanModule->PosX, pPacmanModule->PosY))
  	    {
! 	      if (BPacmanChDir[pPacmanModule->PosY][pPacmanModule->PosX])
  		{
! 		  //change direction to new one
! 		  pPacmanModule->CurDirX = pPacmanModule->NextDirX;
! 		  pPacmanModule->CurDirY = pPacmanModule->NextDirY;
  		}
  	    }
  
! 	  //get new position (move in current direction)
! 	  X = pPacmanModule->PosX + pPacmanModule->CurDirX;
! 	  Y = pPacmanModule->PosY + pPacmanModule->CurDirY;
! 	  //check if there is a wall at the new position
! 	  if (BPacmanCheckPos (X, Y))
  	    {
! 	      //set pacman to new position
! 	      pPacmanModule->PosX = X;
! 	      pPacmanModule->PosY = Y;
! 	      //wrap around
! 	      if (pPacmanModule->PosX < -1 && pPacmanModule->CurDirX < 0)
! 		pPacmanModule->PosX = BPacmanSizeXMin;
! 	      if (pPacmanModule->PosX > BPacmanSizeXMin
! 		  && pPacmanModule->CurDirX > 0)
! 		pPacmanModule->PosX = -1;
! 	      if (pPacmanModule->PosY < -1 && pPacmanModule->CurDirY < 0)
! 		pPacmanModule->PosY = BPacmanSizeYMin;
! 	      if (pPacmanModule->PosY > BPacmanSizeYMin
! 		  && pPacmanModule->CurDirY > 0)
! 		pPacmanModule->PosY = -1;
  
! 	      //point at this position
  	      if (BPacmanCheckPixel
! 		  (pPacmanModule->PosX, pPacmanModule->PosY))
  		{
! 		  if (pPacmanModule->
! 		      Points[pPacmanModule->PosY][pPacmanModule->PosX])
  		    {
! 		      //eat point
! 		      pPacmanModule->Points[pPacmanModule->
! 					    PosY][pPacmanModule->PosX] = 0;
  		      pPacmanModule->PointsLeft--;
! 		      //all points eaten
  		      if (pPacmanModule->PointsLeft == 0)
  			{
! 			  //monsters are dead now
  			  pPacmanModule->MonstersDead = 1;
  			}
  		    }
--- 375,590 ----
  	}
      }
  
!   /* get pacman color (dead or alive) */
    if (pPacmanModule->DeadCnt > 0)
      Color = BPacmanColorPacmanDead (pPacmanModule->MaxColor);
    else
      Color = BPacmanColorPacmanAlive (pPacmanModule->MaxColor);
!   /* draw pacman */
    if (!pPacmanModule->MouthOpen)
!     BPacmanOutputPixel (pPacmanModule, pPacmanModule->pacman.xPos,
! 			pPacmanModule->pacman.yPos, Color);
!   if (!pPacmanModule->MouthOpen || pPacmanModule->pacman.xDir != -1)
!     BPacmanOutputPixel (pPacmanModule, pPacmanModule->pacman.xPos - 1,
! 			pPacmanModule->pacman.yPos, Color);
!   if (!pPacmanModule->MouthOpen || pPacmanModule->pacman.xDir != 1)
!     BPacmanOutputPixel (pPacmanModule, pPacmanModule->pacman.xPos + 1,
! 			pPacmanModule->pacman.yPos, Color);
!   if (!pPacmanModule->MouthOpen || pPacmanModule->pacman.yDir != -1)
!     BPacmanOutputPixel (pPacmanModule, pPacmanModule->pacman.xPos,
! 			pPacmanModule->pacman.yPos - 1, Color);
!   if (!pPacmanModule->MouthOpen || pPacmanModule->pacman.yDir != 1)
!     BPacmanOutputPixel (pPacmanModule, pPacmanModule->pacman.xPos,
! 			pPacmanModule->pacman.yPos + 1, Color);
  
!   /* get monster color (dead or alive) */
    if (pPacmanModule->MonstersDead)
      Color = BPacmanColorMonsterDead (pPacmanModule->MaxColor);
    else
      Color = BPacmanColorMonsterAlive (pPacmanModule->MaxColor);
!   /* draw monsters */
!   for (I = 0; I < pPacmanModule->field->monsterCnt; I++)
      {
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->monsters[I].xPos,
! 			  pPacmanModule->monsters[I].yPos - 1, Color);
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->monsters[I].xPos - 1,
! 			  pPacmanModule->monsters[I].yPos, Color);
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->monsters[I].xPos,
! 			  pPacmanModule->monsters[I].yPos, Color);
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->monsters[I].xPos + 1,
! 			  pPacmanModule->monsters[I].yPos, Color);
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->monsters[I].xPos - 1,
! 			  pPacmanModule->monsters[I].yPos + 1, Color);
!       BPacmanOutputPixel (pPacmanModule, pPacmanModule->monsters[I].xPos + 1,
! 			  pPacmanModule->monsters[I].yPos + 1, Color);
      }
  
!   /* update screen */
    b_module_paint ((BModule *) pPacmanModule);
  }
  
! /* start a new game */
! static void
  BPacmanNewGame (BPacmanModule *pPacmanModule)
  {
!   gint xTotal, yTotal, X, Y, I;
! 
!   xTotal = pPacmanModule->field->xTotal;
!   yTotal = pPacmanModule->field->yTotal;
  
!   /* copy points into local points array and count them */
    pPacmanModule->PointsLeft = 0;
!   for (Y = 0, I = 0; Y < yTotal; Y++)
      {
!       for (X = 0; X < xTotal; X++, I++)
  	{
!           gint data = pPacmanModule->field->fieldData[I];
! 	  pPacmanModule->Points[I] = (data & BPacmanFieldPoint) != 0;
! 	  if (data & BPacmanFieldPoint)
  	    pPacmanModule->PointsLeft++;
  	}
      }
  
!   /* set start position and direction of pacman */
!   pPacmanModule->pacman = pPacmanModule->field->pacmanStart;
!   pPacmanModule->nextPacman = pPacmanModule->pacman;
    pPacmanModule->MouthOpen = 0;
    pPacmanModule->DeadCnt = 0;
!   /* set start position and direction of monsters */
!   for (I = 0; I < pPacmanModule->field->monsterCnt; I++)
!     pPacmanModule->monsters[I] = pPacmanModule->field->monsterStarts[I];
    pPacmanModule->MonstersDead = 0;
  
    dbg_print ("BPacman: new game\n");
  
!   /* output current picture */
    BPacmanOutput (pPacmanModule);
  }
  
! /* key-procedure */
! static void
  BPacmanKey (BPacmanModule *pPacmanModule,
              BModuleKey     Key)
  {
    switch (Key)
      {
      case B_KEY_2:
!       /* set pacman's next direction to upwards */
!       pPacmanModule->nextPacman.xDir = 0;
!       pPacmanModule->nextPacman.yDir = -1;
        break;
      case B_KEY_4:
!       /* set pacman's next direction to leftwards */
!       pPacmanModule->nextPacman.xDir = -1;
!       pPacmanModule->nextPacman.yDir = 0;
        break;
      case B_KEY_6:
!       /* set pacman's next direction to rightwards */
!       pPacmanModule->nextPacman.xDir = 1;
!       pPacmanModule->nextPacman.yDir = 0;
        break;
      case B_KEY_8:
!       /* set pacman's next direction to downwards */
!       pPacmanModule->nextPacman.xDir = 0;
!       pPacmanModule->nextPacman.yDir = 1;
        break;
  
      default:
        break;
      }
  
!   /* output current picture */
    BPacmanOutput (pPacmanModule);
  }
  
! /* tick-procedure */
! /* returns 1 if game over or 0 if game not over */
! gint
  BPacmanTick (BPacmanModule *pPacmanModule)
  {
!   gint X, Y, I, J, Left, Right, Up, Down, Cnt, DirX[4], DirY[4];
! 
!   gint xTotal = pPacmanModule->field->xTotal;
  
!   /* toggle mouth state */
    pPacmanModule->MouthOpen = !pPacmanModule->MouthOpen;
  
!   /* mouth now open */
    if (pPacmanModule->MouthOpen)
      {
!       /* pacman is dead */
        if (pPacmanModule->DeadCnt > 0)
  	{
! 	  /* decrement dead count */
  	  pPacmanModule->DeadCnt--;
  	  if (pPacmanModule->DeadCnt == 0)
            {
!             /* another life */
!             if (pPacmanModule->Lives > 0)
              {
!               dbg_print ("BPacman: Pacman is alive again - %d live(s) left\n", pPacmanModule->Lives);
              }
!             /* game over */
              else
              {
!               dbg_print ("BPacman: Pacman has no lives left - game over\n");
!               /* request end */
!               b_module_request_stop ((BModule *)pPacmanModule);
! 	      /* do nothing else and return game over */
  	      return 1;
              }
            }
  	}
!       /* pacman is alive */
        else
  	{
! 	  /* pacman is at a position where changing direction is allowed */
! 	  if (BPacmanCheckPixel (pPacmanModule, pPacmanModule->pacman.xPos, pPacmanModule->pacman.yPos))
  	    {
! 	      if (pPacmanModule->field->fieldData[pPacmanModule->pacman.yPos * pPacmanModule->field->xTotal
!                                                 + pPacmanModule->pacman.xPos] & BPacmanFieldChDir)
  		{
! 		  /* change direction to new one */
! 		  pPacmanModule->pacman.xDir = pPacmanModule->nextPacman.xDir;
! 		  pPacmanModule->pacman.yDir = pPacmanModule->nextPacman.yDir;
  		}
  	    }
  
! 	  /* get new position (move in current direction) */
! 	  X = pPacmanModule->pacman.xPos + pPacmanModule->pacman.xDir;
! 	  Y = pPacmanModule->pacman.yPos + pPacmanModule->pacman.yDir;
! 	  /* check if there is a wall at the new position */
! 	  if (BPacmanCheckPos (pPacmanModule, X, Y))
  	    {
! 	      /* set pacman to new position */
! 	      pPacmanModule->pacman.xPos = X;
! 	      pPacmanModule->pacman.yPos = Y;
! 	      /* wrap around */
! 	      if (pPacmanModule->pacman.xPos < -1 && pPacmanModule->pacman.xDir < 0)
! 		pPacmanModule->pacman.xPos = pPacmanModule->field->xTotal;
! 	      if (pPacmanModule->pacman.xPos > pPacmanModule->field->xTotal
! 		  && pPacmanModule->pacman.xDir > 0)
! 		pPacmanModule->pacman.xPos = -1;
! 	      if (pPacmanModule->pacman.yPos < -1 && pPacmanModule->pacman.yDir < 0)
! 		pPacmanModule->pacman.yPos = pPacmanModule->field->yTotal;
! 	      if (pPacmanModule->pacman.yPos > pPacmanModule->field->yTotal
! 		  && pPacmanModule->pacman.yDir > 0)
! 		pPacmanModule->pacman.yPos = -1;
  
! 	      /* point at this position */
  	      if (BPacmanCheckPixel
! 		  (pPacmanModule, pPacmanModule->pacman.xPos, pPacmanModule->pacman.yPos))
  		{
!                   gint i = pPacmanModule->pacman.yPos * xTotal + pPacmanModule->pacman.xPos;
! 		  if (pPacmanModule->Points[i])
  		    {
! 		      /* eat point */
! 		      pPacmanModule->Points[i] = 0;
  		      pPacmanModule->PointsLeft--;
! 		      /* all points eaten */
  		      if (pPacmanModule->PointsLeft == 0)
  			{
! 			  /* monsters are dead now */
  			  pPacmanModule->MonstersDead = 1;
  			}
  		    }
***************
*** 518,551 ****
  	    }
  	}
  
!       //monsters are alive
        if (!pPacmanModule->MonstersDead)
  	{
! 	  //move monsters
! 	  for (I = 0; I < BPacmanMonsterCnt; I++)
  	    {
! 	      //monster is at a position where changing direction is allowed
  	      if (BPacmanCheckPixel
! 		  (pPacmanModule->MonsterPosX[I],
! 		   pPacmanModule->MonsterPosY[I]))
  		{
! 		  if (BPacmanChDir[pPacmanModule->MonsterPosY[I]]
! 		      [pPacmanModule->MonsterPosX[I]])
  		    {
! 		      //get possible directions
  		      Left =
! 			BPacmanCheckPos (pPacmanModule->MonsterPosX[I] - 1,
! 					 pPacmanModule->MonsterPosY[I]);
  		      Right =
! 			BPacmanCheckPos (pPacmanModule->MonsterPosX[I] + 1,
! 					 pPacmanModule->MonsterPosY[I]);
  		      Up =
! 			BPacmanCheckPos (pPacmanModule->MonsterPosX[I],
! 					 pPacmanModule->MonsterPosY[I] - 1);
  		      Down =
! 			BPacmanCheckPos (pPacmanModule->MonsterPosX[I],
! 					 pPacmanModule->MonsterPosY[I] + 1);
! 		      //count directions
  		      Cnt = 0;
  		      if (Left)
  			Cnt++;
--- 592,630 ----
  	    }
  	}
  
!       /* monsters are alive */
        if (!pPacmanModule->MonstersDead)
  	{
! 	  /* move monsters */
! 	  for (I = 0; I < pPacmanModule->field->monsterCnt; I++)
  	    {
! 	      /* monster is at a position where changing direction is allowed */
  	      if (BPacmanCheckPixel
! 		  (pPacmanModule,
! 		   pPacmanModule->monsters[I].xPos,
! 		   pPacmanModule->monsters[I].yPos))
  		{
! 		  if (pPacmanModule->field->fieldData[pPacmanModule->monsters[I].yPos * xTotal
! 		      + pPacmanModule->monsters[I].xPos] & BPacmanFieldChDir)
  		    {
! 		      /* get possible directions */
  		      Left =
! 			BPacmanCheckPos (pPacmanModule,
! 					 pPacmanModule->monsters[I].xPos - 1,
! 					 pPacmanModule->monsters[I].yPos);
  		      Right =
! 			BPacmanCheckPos (pPacmanModule,
! 					 pPacmanModule->monsters[I].xPos + 1,
! 					 pPacmanModule->monsters[I].yPos);
  		      Up =
! 			BPacmanCheckPos (pPacmanModule,
! 					 pPacmanModule->monsters[I].xPos,
! 					 pPacmanModule->monsters[I].yPos - 1);
  		      Down =
! 			BPacmanCheckPos (pPacmanModule,
! 					 pPacmanModule->monsters[I].xPos,
! 					 pPacmanModule->monsters[I].yPos + 1);
! 		      /* count directions */
  		      Cnt = 0;
  		      if (Left)
  			Cnt++;
***************
*** 555,574 ****
  			Cnt++;
  		      if (Down)
  			Cnt++;
! 		      //more than one direction possible
  		      if (Cnt > 1)
  			{
! 			  //exclude backward direction
! 			  if (pPacmanModule->MonsterDirX[I] == -1)
  			    Right = 0;
! 			  if (pPacmanModule->MonsterDirX[I] == 1)
  			    Left = 0;
! 			  if (pPacmanModule->MonsterDirY[I] == -1)
  			    Down = 0;
! 			  if (pPacmanModule->MonsterDirY[I] == 1)
  			    Up = 0;
  			}
! 		      //put possible directions into an array
  		      Cnt = 0;
  		      if (Left)
  			{
--- 634,653 ----
  			Cnt++;
  		      if (Down)
  			Cnt++;
! 		      /* more than one direction possible */
  		      if (Cnt > 1)
  			{
! 			  /* exclude backward direction */
! 			  if (pPacmanModule->monsters[I].xDir == -1)
  			    Right = 0;
! 			  if (pPacmanModule->monsters[I].xDir == 1)
  			    Left = 0;
! 			  if (pPacmanModule->monsters[I].yDir == -1)
  			    Down = 0;
! 			  if (pPacmanModule->monsters[I].yDir == 1)
  			    Up = 0;
  			}
! 		      /* put possible directions into an array */
  		      Cnt = 0;
  		      if (Left)
  			{
***************
*** 594,690 ****
  			  DirY[Cnt] = 1;
  			  Cnt++;
  			}
! 		      //change direction to new one
  		      if (Cnt > 0)
  			{
! 			  J = rand () % Cnt;	//select one of the possible directions per coincidence
! 			  pPacmanModule->MonsterDirX[I] = DirX[J];
! 			  pPacmanModule->MonsterDirY[I] = DirY[J];
  			}
  		    }
  		}
  
! 	      //get new position (move in current direction)
  	      X =
! 		pPacmanModule->MonsterPosX[I] + pPacmanModule->MonsterDirX[I];
  	      Y =
! 		pPacmanModule->MonsterPosY[I] + pPacmanModule->MonsterDirY[I];
! 	      //check if there is a wall at the new position
! 	      if (BPacmanCheckPos (X, Y))
  		{
! 		  //set monster to new position
! 		  pPacmanModule->MonsterPosX[I] = X;
! 		  pPacmanModule->MonsterPosY[I] = Y;
! 		  //wrap around
! 		  if (pPacmanModule->MonsterPosX[I] < -1
! 		      && pPacmanModule->MonsterDirX[I] < 0)
! 		    pPacmanModule->MonsterPosX[I] = BPacmanSizeXMin;
! 		  if (pPacmanModule->MonsterPosX[I] > BPacmanSizeXMin
! 		      && pPacmanModule->MonsterDirX[I] > 0)
! 		    pPacmanModule->MonsterPosX[I] = -1;
! 		  if (pPacmanModule->MonsterPosY[I] < -1
! 		      && pPacmanModule->MonsterDirY[I] < 0)
! 		    pPacmanModule->MonsterPosY[I] = BPacmanSizeYMin;
! 		  if (pPacmanModule->MonsterPosY[I] > BPacmanSizeYMin
! 		      && pPacmanModule->MonsterDirY[I] > 0)
! 		    pPacmanModule->MonsterPosY[I] = -1;
  		}
  	    }
  	}
      }
  
!   //check if monster kills pacman / pacman kills monster
!   for (I = 0; I < BPacmanMonsterCnt; I++)
      {
!       //get distance
!       X = pPacmanModule->PosX - pPacmanModule->MonsterPosX[I];
        if (X < 0)
  	X = -X;
!       Y = pPacmanModule->PosY - pPacmanModule->MonsterPosY[I];
        if (Y < 0)
  	Y = -Y;
!       //monster kills pacman / pacman kills monster
        if (X + Y < 4)
  	{
! 	  //pacman kills monster
  	  if (pPacmanModule->MonstersDead)
  	    {
! 	      //move monster out of sight
! 	      pPacmanModule->MonsterPosX[I] = BPacmanMonsterNirvana;
! 	      pPacmanModule->MonsterPosY[I] = BPacmanMonsterNirvana;
  	      dbg_print ("BPacman: Pacman ate Monster\n");
! 	      //check if all monsters are gone
! 	      for (J = 0; J < BPacmanMonsterCnt; J++)
! 		if (pPacmanModule->MonsterPosX[J] != BPacmanMonsterNirvana
! 		    || pPacmanModule->MonsterPosY[J] != BPacmanMonsterNirvana)
  		  break;
! 	      //all monsters are gone
! 	      if (J >= BPacmanMonsterCnt)
  		{
  		  dbg_print ("BPacman: Pacman has won game\n");
! 		  //start new game
  		  BPacmanNewGame (pPacmanModule);
  		}
  	    }
! 	  //monster kills pacman
  	  else
  	    {
!               //decrease number of lives
!               if( pPacmanModule->DeadCnt == 0 )
                {
                  pPacmanModule->Lives--;
!                 dbg_print( "BPacman: Monster killed Pacman\n" );
                }
!               //pacman is dead for the next few steps
                pPacmanModule->DeadCnt = BPacmanDeadTime;
  	    }
  	}
      }
  
!   //output current picture
    BPacmanOutput (pPacmanModule);
  
!   //return game not over
    return 0;
  }
  
--- 673,769 ----
  			  DirY[Cnt] = 1;
  			  Cnt++;
  			}
! 		      /* change direction to new one */
  		      if (Cnt > 0)
  			{
! 			  J = rand () % Cnt;	/* select one of the possible directions per coincidence */
! 			  pPacmanModule->monsters[I].xDir = DirX[J];
! 			  pPacmanModule->monsters[I].yDir = DirY[J];
  			}
  		    }
  		}
  
! 	      /* get new position (move in current direction) */
  	      X =
! 		pPacmanModule->monsters[I].xPos + pPacmanModule->monsters[I].xDir;
  	      Y =
! 		pPacmanModule->monsters[I].yPos + pPacmanModule->monsters[I].yDir;
! 	      /* check if there is a wall at the new position */
! 	      if (BPacmanCheckPos (pPacmanModule, X, Y))
  		{
! 		  /* set monster to new position */
! 		  pPacmanModule->monsters[I].xPos = X;
! 		  pPacmanModule->monsters[I].yPos = Y;
! 		  /* wrap around */
! 		  if (pPacmanModule->monsters[I].xPos < -1
! 		      && pPacmanModule->monsters[I].xDir < 0)
! 		    pPacmanModule->monsters[I].xPos = pPacmanModule->field->xTotal;
! 		  if (pPacmanModule->monsters[I].xPos > pPacmanModule->field->xTotal
! 		      && pPacmanModule->monsters[I].xDir > 0)
! 		    pPacmanModule->monsters[I].xPos = -1;
! 		  if (pPacmanModule->monsters[I].yPos < -1
! 		      && pPacmanModule->monsters[I].yDir < 0)
! 		    pPacmanModule->monsters[I].yPos = pPacmanModule->field->yTotal;
! 		  if (pPacmanModule->monsters[I].yPos > pPacmanModule->field->yTotal
! 		      && pPacmanModule->monsters[I].yDir > 0)
! 		    pPacmanModule->monsters[I].yPos = -1;
  		}
  	    }
  	}
      }
  
!   /* check if monster kills pacman / pacman kills monster */
!   for (I = 0; I < pPacmanModule->field->monsterCnt; I++)
      {
!       /* get distance */
!       X = pPacmanModule->pacman.xPos - pPacmanModule->monsters[I].xPos;
        if (X < 0)
  	X = -X;
!       Y = pPacmanModule->pacman.yPos - pPacmanModule->monsters[I].yPos;
        if (Y < 0)
  	Y = -Y;
!       /* monster kills pacman / pacman kills monster */
        if (X + Y < 4)
  	{
! 	  /* pacman kills monster */
  	  if (pPacmanModule->MonstersDead)
  	    {
! 	      /* move monster out of sight */
! 	      pPacmanModule->monsters[I].xPos = BPacmanMonsterNirvana;
! 	      pPacmanModule->monsters[I].yPos = BPacmanMonsterNirvana;
  	      dbg_print ("BPacman: Pacman ate Monster\n");
! 	      /* check if all monsters are gone */
! 	      for (J = 0; J < pPacmanModule->field->monsterCnt; J++)
! 		if (pPacmanModule->monsters[J].xPos != BPacmanMonsterNirvana
! 		    || pPacmanModule->monsters[J].yPos != BPacmanMonsterNirvana)
  		  break;
! 	      /* all monsters are gone */
! 	      if (J >= pPacmanModule->field->monsterCnt)
  		{
  		  dbg_print ("BPacman: Pacman has won game\n");
! 		  /* start new game */
  		  BPacmanNewGame (pPacmanModule);
  		}
  	    }
! 	  /* monster kills pacman */
  	  else
  	    {
!               /* decrease number of lives */
!               if (pPacmanModule->DeadCnt == 0)
                {
                  pPacmanModule->Lives--;
!                 dbg_print ("BPacman: Monster killed Pacman\n");
                }
!               /* pacman is dead for the next few steps */
                pPacmanModule->DeadCnt = BPacmanDeadTime;
  	    }
  	}
      }
  
!   /* output current picture */
    BPacmanOutput (pPacmanModule);
  
!   /* return game not over */
    return 0;
  }
  
***************
*** 700,705 ****
--- 779,785 ----
    module_class->query    = b_pacman_module_query;
    module_class->prepare  = b_pacman_module_prepare;
    module_class->start    = b_pacman_module_start;
+   module_class->stop     = b_pacman_module_stop;
    module_class->event    = b_pacman_module_event;
    module_class->tick     = b_pacman_module_tick;
    module_class->describe = b_pacman_module_describe;
***************
*** 717,723 ****
                         gint channels,
                         gint maxval)
  {
!   return (width >= BPacmanSizeXMin && height >= BPacmanSizeYMin
  	  && channels == 1 && maxval + 1 >= BPacmanColorCntMin);
  }
  
--- 797,803 ----
                         gint channels,
                         gint maxval)
  {
!   return (b_pacman_module_select_field (width, height)
  	  && channels == 1 && maxval + 1 >= BPacmanColorCntMin);
  }
  
***************
*** 727,735 ****
  {
    BPacmanModule *pacman_module = B_PACMAN_MODULE (module);
  
    /* initialize the module values that depend on the output device */
!   pacman_module->OfsX = (module->width - BPacmanSizeXMin) / 2;	/* offset of top left corner of game-field */
!   pacman_module->OfsY = (module->height - BPacmanSizeYMin) / 2;
    pacman_module->MaxColor = module->maxval;	/* maximum color value */
  
    return TRUE;
--- 807,820 ----
  {
    BPacmanModule *pacman_module = B_PACMAN_MODULE (module);
  
+   /* select game field */
+   pacman_module->field = b_pacman_module_select_field (module->width, module->height);
+   if (pacman_module->field == NULL)
+     pacman_module->field = &BPacmanFields[0];
+ 
    /* initialize the module values that depend on the output device */
!   pacman_module->OfsX = (module->width - pacman_module->field->xVisible) / 2;	/* offset of top left corner of game-field */
!   pacman_module->OfsY = (module->height - pacman_module->field->yVisible) / 2;
    pacman_module->MaxColor = module->maxval;	/* maximum color value */
  
    return TRUE;
***************
*** 738,743 ****
--- 823,833 ----
  static void
  b_pacman_module_start (BModule *module)
  {
+   BPacmanModule * pPacmanModule = (BPacmanModule *)module;
+ 
+   /* allocate array for points */
+   pPacmanModule->Points = malloc (pPacmanModule->field->xTotal * pPacmanModule->field->yTotal * sizeof (int));
+ 
    /* set pacman's lives */
    ((BPacmanModule *)module)->Lives = BPacmanLives;
  
***************
*** 749,754 ****
--- 839,853 ----
  }
  
  static void
+ b_pacman_module_stop (BModule *module)
+ {
+   BPacmanModule * pPacmanModule = (BPacmanModule *)module;
+ 
+   /* free array for points */
+   free (pPacmanModule->Points);
+ }
+ 
+ static void
  b_pacman_module_event (BModule      *module,
                         BModuleEvent *event)
  {
***************
*** 789,801 ****
  static gint
  b_pacman_module_tick (BModule *module)
  {
!   int GameOver;
  
    /* call tick-procedure */
    GameOver = BPacmanTick ((BPacmanModule *) module);
  
    /* we want to be called again in some milliseconds, if game is not over */
!   if( GameOver )
      return 0;
    else
      return BPacmanTicks;
--- 888,900 ----
  static gint
  b_pacman_module_tick (BModule *module)
  {
!   gint GameOver;
  
    /* call tick-procedure */
    GameOver = BPacmanTick ((BPacmanModule *) module);
  
    /* we want to be called again in some milliseconds, if game is not over */
!   if (GameOver)
      return 0;
    else
      return BPacmanTicks;
diff -r -C 3 -N blib-1.1.7/modules/bpong.c blib-1.1.7-ba20070811/modules/bpong.c
*** blib-1.1.7/modules/bpong.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bpong.c	Sat Aug 11 22:18:43 2007
***************
*** 71,76 ****
--- 71,77 ----
    gint          anim_steps;
  
    gint          paddle_size;
+   gint          paddle_step;
  
    gint          lpaddle;
    gint          rpaddle;
***************
*** 210,215 ****
--- 211,217 ----
    BPong *pong = B_PONG (module);
  
    pong->paddle_size = MAX (3, module->height / 4);
+   pong->paddle_step = MAX (1, pong->paddle_size / 3);
  
    return TRUE;
  }
***************
*** 266,276 ****
            /* up */
            if (event->device_id == pong->lplayer_device_id)
              {
!               pong->lpaddle = MAX (pong->lpaddle--, 0);
              }
            else if (event->device_id == pong->rplayer_device_id)
              {
!               pong->rpaddle = MAX (pong->rpaddle--, 0);
              }
            break;
  
--- 268,278 ----
            /* up */
            if (event->device_id == pong->lplayer_device_id)
              {
!               pong->lpaddle = MAX (pong->lpaddle - pong->paddle_step, 0);
              }
            else if (event->device_id == pong->rplayer_device_id)
              {
!               pong->rpaddle = MAX (pong->rpaddle - pong->paddle_step, 0);
              }
            break;
  
***************
*** 283,294 ****
            /* down */
            if (event->device_id == pong->lplayer_device_id)
              {
!               pong->lpaddle = MIN (pong->lpaddle++,
                                     module->height - pong->paddle_size);
              }
            else if (event->device_id == pong->rplayer_device_id)
              {
!               pong->rpaddle = MIN (pong->rpaddle++,
                                     module->height - pong->paddle_size);
              }
            break;
--- 285,296 ----
            /* down */
            if (event->device_id == pong->lplayer_device_id)
              {
!               pong->lpaddle = MIN (pong->lpaddle + pong->paddle_step,
                                     module->height - pong->paddle_size);
              }
            else if (event->device_id == pong->rplayer_device_id)
              {
!               pong->rpaddle = MIN (pong->rpaddle + pong->paddle_step,
                                     module->height - pong->paddle_size);
              }
            break;
***************
*** 511,517 ****
      }
  
    /* collision with left paddle or out ? */
!   if (pong->ball_x == 0)
      {
        if (! b_pong_reflect (pong, pong->lpaddle))
          return 1;  /* right wins */
--- 513,519 ----
      }
  
    /* collision with left paddle or out ? */
!   if (pong->ball_x <= 0)
      {
        if (! b_pong_reflect (pong, pong->lpaddle))
          return 1;  /* right wins */
***************
*** 520,530 ****
        pong->ball_xdir = RIGHT;
      }
    /* collision with right paddle or out ? */
!   else if (pong->ball_x == module->width - 1)
      {
        if (! b_pong_reflect (pong, pong->rpaddle))
          return -1;  /* left wins */
!       pong->ball_x = module->width - pong->paddle_size;
        pong->ball_xdir = LEFT;
      }
  
--- 522,532 ----
        pong->ball_xdir = RIGHT;
      }
    /* collision with right paddle or out ? */
!   else if (pong->ball_x >= module->width - 1)
      {
        if (! b_pong_reflect (pong, pong->rpaddle))
          return -1;  /* left wins */
!       pong->ball_x = module->width - 2;
        pong->ball_xdir = LEFT;
      }
  
***************
*** 640,647 ****
    gint         x, y;
    gint         n, i;
    const BFont *digits = &b_digits_3x5;
!     
!   
    module = B_MODULE (pong);
  
    text = g_strdup_printf ("%d:%d", pong->lplayer_score, pong->rplayer_score);
--- 642,649 ----
    gint         x, y;
    gint         n, i;
    const BFont *digits = &b_digits_3x5;
!    
!  
    module = B_MODULE (pong);
  
    text = g_strdup_printf ("%d:%d", pong->lplayer_score, pong->rplayer_score);
diff -r -C 3 -N blib-1.1.7/modules/bpongmulti.c blib-1.1.7-ba20070811/modules/bpongmulti.c
*** blib-1.1.7/modules/bpongmulti.c	Thu Jan  1 01:00:00 1970
--- blib-1.1.7-ba20070811/modules/bpongmulti.c	Sat Aug 11 22:18:43 2007
***************
*** 0 ****
--- 1,738 ----
+ /* blib - Library of useful things to hack the Blinkenlights
+  *
+  * Copyright (c) 2001-2002  Sven Neumann <sven@gimp.org>
+  *                          Michael Natterer <mitch@gimp.org>
+  * Changed: 2006 Stefan Schuermans <1stein@blinkenarea.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.
+  *
+  * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #include <stdlib.h>
+ #include <string.h>
+ 
+ #include <glib-object.h>
+ 
+ #include <blib/blib.h>
+ 
+ #include "digits.h"
+ 
+ 
+ #define PONG_START_TIMEOUT       70
+ #define COMPUTER_LOOSE_SPEEDUP   3
+ #define BALL_CNT_MAX             5
+ #define BALL_INTERVAL10_MIN      20
+ #define BALL_INTERVAL10_MAX      40
+ 
+ 
+ typedef enum
+ {
+   RIGHT,
+   LEFT
+ } XDirection;
+ 
+ typedef enum
+ {
+   UP,
+   DOWN
+ } YDirection;
+ 
+ typedef enum
+ {
+   GAME_INIT,
+   LPLAYER_JOIN,
+   RPLAYER_JOIN,
+   GAME_OVER
+ } AnimType;
+ 
+ typedef struct
+ {
+   gint        x;
+   gint        y;
+   XDirection  xdir;
+   YDirection  ydir;
+   gint        interval10;   /* 1/10 inverse speed of ball (BALL_INTERVAL10_MIN..BALL_INTERVAL10_MAX) */
+   gint        tick10;       /* 1/10 ticks since last move of ball */
+ } Ball;
+ 
+ 
+ #define B_TYPE_PONG            (b_type_pong)
+ #define B_PONG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_PONG, BPongMulti))
+ #define B_PONG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_PONG, BPongMultiClass))
+ #define B_IS_PONG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_PONG))
+ #define B_IS_PONG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_PONG))
+ 
+ typedef struct _BPongMulti      BPongMulti;
+ typedef struct _BPongMultiClass BPongMultiClass;
+ 
+ struct _BPongMulti
+ {
+   BModule       parent_instance;
+ 
+   AnimType      anim;
+   gint          anim_steps;
+ 
+   gint		ball_cnt;
+   gint          paddle_size;
+ 
+   gint          lpaddle;
+   gint          rpaddle;
+   Ball          balls[BALL_CNT_MAX];
+ 
+   gint          lplayer_score;
+   gint          rplayer_score;
+ 
+   gint          lplayer_device_id;
+   gint          rplayer_device_id;
+ 
+   gint          timeout;
+ };
+ 
+ struct _BPongMultiClass
+ {
+   BModuleClass  parent_class;
+ };
+ 
+ 
+ static GType      b_pong_multi_get_type      (GTypeModule   *module);
+ 
+ static void       b_pong_multi_class_init    (BPongMultiClass    *klass);
+ static void       b_pong_multi_init          (BPongMulti         *pong);
+ 
+ static gboolean   b_pong_multi_query         (gint           width,
+                                               gint           height,
+                                               gint           channels,
+                                               gint           maxval);
+ static gboolean   b_pong_multi_prepare       (BModule       *module,
+                                               GError       **error);
+ static void       b_pong_multi_relax         (BModule       *module);
+ static void       b_pong_multi_start         (BModule       *module);
+ static void       b_pong_multi_stop          (BModule       *module);
+ static void       b_pong_multi_event         (BModule       *module,
+                                               BModuleEvent  *event);
+ static gint       b_pong_multi_tick          (BModule       *module);
+ static void       b_pong_multi_describe      (BModule       *module,
+                                               const gchar  **title,
+                                               const gchar  **description,
+                                               const gchar  **author);
+ 
+ static void       b_pong_multi_init_game     (BPongMulti    *pong);
+ static gint       b_pong_multi_move_ball     (BPongMulti    *pong);
+ static void       b_pong_multi_computer_move (BPongMulti    *pong,
+                                               gint          *paddle,
+                                               gint          x);
+ static gboolean   b_pong_multi_reflect       (BPongMulti     *pong,
+                                               gint           paddle,
+                                               gint           ball_no);
+ static void       b_pong_multi_draw          (BPongMulti    *pong,
+                                               gint           lpaddle,
+                                               gint           rpaddle,
+                                               gint           balls_draw_flags);
+ static void       b_pong_multi_draw_scores   (BPongMulti    *pong);
+ 
+ 
+ static GType b_type_pong = 0;
+ 
+ 
+ G_MODULE_EXPORT gboolean
+ b_module_register (GTypeModule *module)
+ {
+   b_pong_multi_get_type (module);
+   return TRUE;
+ }
+ 
+ static GType
+ b_pong_multi_get_type (GTypeModule *module)
+ {
+   if (! b_type_pong)
+     {
+       static const GTypeInfo pong_info =
+       {
+         sizeof (BPongMultiClass),
+         NULL,           /* base_init */
+         NULL,           /* base_finalize */
+         (GClassInitFunc) b_pong_multi_class_init,
+         NULL,           /* class_finalize */
+         NULL,           /* class_data */
+         sizeof (BPongMulti),
+         0,              /* n_preallocs */
+         (GInstanceInitFunc) b_pong_multi_init,
+       };
+ 
+       b_type_pong = g_type_module_register_type (module,
+                                                  B_TYPE_MODULE, "BPongMulti",
+                                                  &pong_info, 0);
+     }
+ 
+   return b_type_pong;
+ }
+ 
+ static void
+ b_pong_multi_class_init (BPongMultiClass *klass)
+ {
+   BModuleClass *module_class;
+ 
+   module_class = B_MODULE_CLASS (klass);
+ 
+   module_class->max_players = 2;
+ 
+   module_class->query    = b_pong_multi_query;
+   module_class->prepare  = b_pong_multi_prepare;
+   module_class->relax    = b_pong_multi_relax;
+   module_class->start    = b_pong_multi_start;
+   module_class->stop     = b_pong_multi_stop;
+   module_class->event    = b_pong_multi_event;
+   module_class->tick     = b_pong_multi_tick;
+   module_class->describe = b_pong_multi_describe;
+ }
+ 
+ static void
+ b_pong_multi_init (BPongMulti *pong)
+ {
+   pong->anim_steps        = 0;
+ 
+   pong->lplayer_device_id = -1;
+   pong->rplayer_device_id = -1;
+ }
+ 
+ static gboolean
+ b_pong_multi_query (gint     width,
+                     gint     height,
+                     gint     channels,
+                     gint     maxval)
+ {
+   return (width >= 7 && height >= 7 && channels == 1);
+ }
+ 
+ static gboolean
+ b_pong_multi_prepare (BModule  *module,
+                       GError  **error)
+ {
+   BPongMulti *pong = B_PONG (module);
+ 
+   pong->ball_cnt    = MAX (1, MIN (module->width / 12, BALL_CNT_MAX));
+   pong->paddle_size = MAX (3, module->height / 4);
+ 
+   return TRUE;
+ }
+ 
+ static void
+ b_pong_multi_relax (BModule *module)
+ {
+ }
+ 
+ static void
+ b_pong_multi_start (BModule *module)
+ {
+   BPongMulti *pong = B_PONG (module);
+ 
+   pong->lpaddle       = pong->rpaddle       = module->height / 2 - 1;
+   pong->lplayer_score = pong->rplayer_score = 0;
+ 
+   b_pong_multi_init_game (pong);
+ 
+   pong->timeout = PONG_START_TIMEOUT;
+ 
+   b_module_ticker_start (module, pong->timeout);
+ }
+ 
+ static void
+ b_pong_multi_stop (BModule *module)
+ {
+   BPongMulti *pong = B_PONG (module);
+ 
+   pong->lplayer_device_id = -1;
+   pong->rplayer_device_id = -1;
+ }
+ 
+ static void
+ b_pong_multi_event (BModule      *module,
+                     BModuleEvent *event)
+ {
+   BPongMulti *pong = B_PONG (module);
+ 
+   switch (event->type)
+     {
+     case B_EVENT_TYPE_KEY:
+       if (pong->anim_steps)
+         return;
+ 
+       switch (event->key)
+         {
+         case B_KEY_1:
+         case B_KEY_2:
+         case B_KEY_3:
+         case B_KEY_4:
+         case B_KEY_5:
+         case B_KEY_6:
+           /* up */
+           if (event->device_id == pong->lplayer_device_id)
+             {
+               pong->lpaddle = MAX (pong->lpaddle--, 0);
+             }
+           else if (event->device_id == pong->rplayer_device_id)
+             {
+               pong->rpaddle = MAX (pong->rpaddle--, 0);
+             }
+           break;
+ 
+         case B_KEY_7:
+         case B_KEY_8:
+         case B_KEY_9:
+         case B_KEY_ASTERISK:
+         case B_KEY_0:
+         case B_KEY_HASH:
+           /* down */
+           if (event->device_id == pong->lplayer_device_id)
+             {
+               pong->lpaddle = MIN (pong->lpaddle++,
+                                    module->height - pong->paddle_size);
+             }
+           else if (event->device_id == pong->rplayer_device_id)
+             {
+               pong->rpaddle = MIN (pong->rpaddle++,
+                                    module->height - pong->paddle_size);
+             }
+           break;
+ 
+         default:
+           break;
+         }
+       break;
+ 
+     case B_EVENT_TYPE_PLAYER_ENTERED:
+       if (pong->lplayer_device_id == -1)
+         {
+           pong->anim              = LPLAYER_JOIN;
+           pong->anim_steps        = 18;
+           pong->lplayer_device_id = event->device_id;
+ 
+           module->num_players++;
+         }
+       else if (pong->rplayer_device_id == -1)
+         {
+           pong->anim              = RPLAYER_JOIN;
+           pong->anim_steps        = 18;
+           pong->rplayer_device_id = event->device_id;
+ 
+           module->num_players++;
+         }
+       break;
+ 
+     case B_EVENT_TYPE_PLAYER_LEFT:
+       if (pong->lplayer_device_id == event->device_id)
+         {
+           pong->lplayer_device_id = -1;
+ 
+           module->num_players--;
+         }
+       else if (pong->rplayer_device_id == event->device_id)
+         {
+           pong->rplayer_device_id = -1;
+ 
+           module->num_players--;
+         }
+       break;
+ 
+     default:
+       break;
+     }
+ }
+ 
+ static gint
+ b_pong_multi_tick (BModule *module)
+ {
+   BPongMulti *pong = B_PONG (module);
+ 
+   if (pong->anim_steps > 0)
+     {
+       pong->anim_steps--;
+ 
+       switch (pong->anim)
+         {
+         case GAME_INIT:
+           b_pong_multi_draw (pong,
+                        pong->lpaddle, pong->rpaddle,
+                        pong->anim_steps < 3 ? -1 : 0);
+           break;
+         case LPLAYER_JOIN:
+           b_pong_multi_draw (pong,
+                        (pong->anim_steps / 3 & 1) ? pong->lpaddle : -1,
+                        pong->rpaddle,
+                        0);
+           break;
+         case RPLAYER_JOIN:
+           b_pong_multi_draw (pong,
+                        pong->lpaddle,
+                        (pong->anim_steps / 3 & 1) ? pong->rpaddle : -1,
+                        0);
+           break;
+         case GAME_OVER:
+           b_pong_multi_draw (pong,
+                        pong->lpaddle, pong->rpaddle,
+                        (pong->anim_steps / 3 & 1) ? -1 : 0);
+ 
+           if (pong->anim_steps == 0)
+             {
+               if ((pong->lplayer_score != pong->rplayer_score) &&
+                   (pong->lplayer_score >= 10 || pong->rplayer_score >= 10))
+                 {
+                   b_module_request_stop (module);
+                   return 0;
+                 }
+               else
+                 b_pong_multi_init_game (pong);
+             }
+ 
+           break;
+         }
+     }
+   else
+     {
+       switch (b_pong_multi_move_ball (pong))
+         {
+         case 1: /* left wins */
+           pong->lplayer_score++;
+           pong->anim_steps = 18;
+           pong->anim = GAME_OVER;
+ 	  if (pong->lplayer_device_id == -1) /* computer lost */
+ 	    pong->timeout -= COMPUTER_LOOSE_SPEEDUP;
+           break;
+ 
+         case 2: /* right wins*/
+           pong->rplayer_score++;
+           pong->anim_steps = 18;
+           pong->anim = GAME_OVER;
+ 	  if (pong->rplayer_device_id == -1) /* computer lost */
+ 	    pong->timeout -= COMPUTER_LOOSE_SPEEDUP;
+           break;
+ 
+         case -1: /* stalemate */
+           pong->anim_steps = 18;
+           pong->anim = GAME_OVER;
+           break;
+ 
+         case 0: /* game goes on */
+           if (pong->lplayer_device_id == -1)
+             b_pong_multi_computer_move (pong, &pong->lpaddle, 0);
+           if (pong->rplayer_device_id == -1)
+             b_pong_multi_computer_move (pong, &pong->rpaddle, module->width - 1);
+           break;
+         }
+ 
+       b_pong_multi_draw (pong,
+                    pong->lpaddle, pong->rpaddle,
+                    -1);
+     }
+ 
+   return pong->timeout;
+ }
+ 
+ static void
+ b_pong_multi_describe (BModule      *module,
+                  const gchar **title,
+                  const gchar **description,
+                  const gchar **author)
+ {
+   *title       = "BPongMulti";
+   *description = "Pong game";
+   *author      = "Sven Neumann";
+ }
+ 
+ static void
+ b_pong_multi_init_game (BPongMulti *pong)
+ {
+   BModule *module;
+   gint     paddle;
+   gint     foo;
+   gint     i;
+ 
+   module = B_MODULE (pong);
+ 
+   for (i = 0; i < pong->ball_cnt; i++)  {
+     foo = rand ();
+ 
+     if (foo & 0x1) {
+       paddle = pong->lpaddle;
+       pong->balls[i].x    = 0;
+       pong->balls[i].xdir = RIGHT;
+     } else {
+     paddle = pong->rpaddle;
+       pong->balls[i].x    = module->width - 1;
+       pong->balls[i].xdir = LEFT;
+     }
+ 
+     if ((foo & 0x2 && paddle != 0) ||
+         paddle == module->height - pong->paddle_size)
+     {
+       pong->balls[i].y    = 0;
+       pong->balls[i].ydir = DOWN;
+     } else {
+       pong->balls[i].y    = module->height - 1;
+       pong->balls[i].ydir = UP;
+     }
+ 
+     pong->balls[i].interval10 = rand () % (BALL_INTERVAL10_MAX - BALL_INTERVAL10_MIN + 1) + BALL_INTERVAL10_MIN;
+     for (;;)  {
+       gint j; /* check for balls with same speed */
+       for (j = 0; j < i; j++)
+         if (pong->balls[j].interval10 == pong->balls[i].interval10)
+           break;
+       if (j >= i)  /* no other ball has same speed */
+         break;
+       pong->balls[i].interval10++; /* modify speed */
+       if (pong->balls[i].interval10 >= BALL_INTERVAL10_MAX)
+         pong->balls[i].interval10 = BALL_INTERVAL10_MIN;
+     }
+     pong->balls[i].tick10 = 0;
+   }
+ 
+   pong->anim       = GAME_INIT;
+   pong->anim_steps = 12;
+ }
+ 
+ static gint
+ b_pong_multi_move_ball (BPongMulti *pong)
+ {
+   gint b;
+   BModule *module = B_MODULE (pong);
+   gint win_left = 0;
+   gint win_right = 0;
+ 
+   for (b = 0; b < pong->ball_cnt; b++)  {
+     /* check if ball is to move now */
+     pong->balls[b].tick10 += 10;
+     if (pong->balls[b].tick10 >= pong->balls[b].interval10)  {
+       pong->balls[b].tick10 -= pong->balls[b].interval10;
+ 
+       switch (pong->balls[b].xdir)
+         {
+         case RIGHT:
+           pong->balls[b].x++;
+           break;
+         case LEFT:
+           pong->balls[b].x--;
+           break;
+         }
+       switch (pong->balls[b].ydir)
+         {
+         case UP:
+           pong->balls[b].y--;
+           break;
+         case DOWN:
+           pong->balls[b].y++;
+           break;
+         }
+ 
+       /* collision with walls ? */
+       if (pong->balls[b].y < 0)
+         {
+           pong->balls[b].y = 1;
+           pong->balls[b].ydir = DOWN;
+         }
+       else if (pong->balls[b].y >= module->height)
+         {
+           pong->balls[b].y = module->height - 2;
+           pong->balls[b].ydir = UP;
+         }
+ 
+       /* collision with left paddle or out ? */
+       if (pong->balls[b].x <= 0)
+         {
+           if (! b_pong_multi_reflect (pong, pong->lpaddle, b))
+             win_right++;  /* right wins */
+ 
+           pong->balls[b].x = 2;
+           pong->balls[b].xdir = RIGHT;
+         }
+       /* collision with right paddle or out ? */
+       else if (pong->balls[b].x >= module->width - 1)
+         {
+           if (! b_pong_multi_reflect (pong, pong->rpaddle, b))
+             win_left++;  /* left wins */
+ 
+           pong->balls[b].x = module->width - pong->paddle_size;
+           pong->balls[b].xdir = LEFT;
+         }
+ 
+     }
+   }
+ 
+   if (win_left + win_right > 0)  {
+     if (win_left > win_right)
+       return 1; /* left wins */
+     if (win_right > win_left)
+       return 2; /* right wins */
+     return -1; /* stalemate */
+   }
+   return 0;
+ }
+ 
+ static void
+ b_pong_multi_computer_move (BPongMulti *pong,
+                             gint  *paddle,
+                             gint  x)
+ {
+   BModule *module = B_MODULE (pong);
+   gint ball_no, b, dx, dx_min;
+ 
+   /* computer is not perfect - it forgets to move often enough */
+   if (rand () & 7)
+     return;
+ 
+   /* determine number of nearest ball */
+   dx_min = module->width << 1;
+   ball_no = 0;
+   for (b = 0; b < pong->ball_cnt; b++)  {
+     dx = pong->balls[b].x - x; /* get distance */
+     if (dx < 0)
+       dx = -dx;
+     if (dx < dx_min)  { /* ball is nearer */
+       ball_no = b;
+       dx_min = dx;
+     }
+   }
+ 
+   /* move computer towards nearest ball */
+   if (*paddle - pong->balls[ball_no].y > -1)
+     (*paddle)--;
+   else if (*paddle - pong->balls[ball_no].y < 1)
+     (*paddle)++;
+ 
+   *paddle = CLAMP (*paddle, 0, module->height - pong->paddle_size);
+ }
+ 
+ static gboolean
+ b_pong_multi_reflect (BPongMulti *pong,
+                       gint   paddle,
+                       gint   ball_no)
+ {
+   gint d = pong->balls[ball_no].y - paddle;
+ 
+   switch (pong->balls[ball_no].ydir)
+     {
+     case DOWN: /* we hit the paddle coming from the top */
+ 
+       if (d < 0)
+         return FALSE;
+       else if (d == 0)
+         {
+           pong->balls[ball_no].ydir = UP;
+           pong->balls[ball_no].y -= 2;
+           return TRUE;
+         }
+       else if (d <= pong->paddle_size)
+         return TRUE;
+       else
+         return FALSE;
+ 
+       break;
+ 
+     case UP: /* we hit the paddle coming from the bottom */
+ 
+       if (d < -1)
+         return FALSE;
+       else if (d < pong->paddle_size - 1)
+         return TRUE;
+       else if (d == pong->paddle_size - 1)
+         {
+           pong->balls[ball_no].ydir = DOWN;
+           pong->balls[ball_no].y += 2;
+           return TRUE;
+         }
+       else
+         return FALSE;
+ 
+       break;
+     }
+ 
+   return TRUE;
+ }
+ 
+ static void
+ b_pong_multi_draw (BPongMulti *pong,
+              gint   lpaddle,
+              gint   rpaddle,
+              gint   balls_draw_flags)
+ {
+   BModule *module;
+   gint     width;
+   gint     height;
+   gint     i;
+   gint     ball_x;
+   gint     ball_y;
+ 
+   module = B_MODULE (pong);
+ 
+   width  = module->width;
+   height = module->height;
+ 
+   b_module_fill (module, 0);
+ 
+   if (lpaddle >= 0 && lpaddle <= height - pong->paddle_size)
+     for (i = 0; i < pong->paddle_size; i++)
+       b_module_draw_point (module, 0, lpaddle + i, module->maxval);
+ 
+   if (rpaddle >= 0 && rpaddle <= height - pong->paddle_size)
+     for (i = 0; i < pong->paddle_size; i++)
+       b_module_draw_point (module, width - 1, rpaddle + i, module->maxval);
+ 
+   for (i = 0; i < pong->ball_cnt; i++)  {
+     ball_x = balls_draw_flags & (1 << i) ? pong->balls[i].x : -1;
+     ball_y = balls_draw_flags & (1 << i) ? pong->balls[i].y : -1;
+     if (ball_x >= 0 && ball_x < width && ball_y >= 0 && ball_y < height)
+       b_module_draw_point (module, ball_x, ball_y, module->maxval);
+   }
+ 
+   if (pong->anim == GAME_OVER)
+     b_pong_multi_draw_scores (pong);
+ 
+   b_module_paint (module);
+ }
+ 
+ static void
+ b_pong_multi_draw_scores (BPongMulti *pong)
+ {
+   BModule     *module;
+   gchar       *text;
+   gint         len;
+   gint         x0, y0;
+   gint         x, y;
+   gint         n, i;
+   const BFont *digits = &b_digits_3x5;
+    
+  
+   module = B_MODULE (pong);
+ 
+   text = g_strdup_printf ("%d:%d", pong->lplayer_score, pong->rplayer_score);
+   len = strlen (text);
+ 
+   x0 = (module->width - len * digits->advance) / 2;
+   y0 = (module->height / 2) - 3;
+ 
+   for (n = 0; n < len; n++)
+     {
+       for (i = 0; i < digits->num_digits && digits->digits_str[i] != text[n]; i++);
+ 
+       if (i < digits->num_digits)
+         for (x = 0; x < digits->width; x++)
+           for (y = 0; y < digits->height; y++)
+             if (digits->data[i][y * digits->width + x] != '0')
+               b_module_draw_point (module, x0 + x, y0 + y, module->maxval);
+ 
+       x0 += digits->advance;
+     }
+ 
+   g_free (text);
+ }
diff -r -C 3 -N blib-1.1.7/modules/bpongv.c blib-1.1.7-ba20070811/modules/bpongv.c
*** blib-1.1.7/modules/bpongv.c	Thu Jan  1 01:00:00 1970
--- blib-1.1.7-ba20070811/modules/bpongv.c	Sat Aug 11 22:18:43 2007
***************
*** 0 ****
--- 1,683 ----
+ /* blib - Library of useful things to hack the Blinkenlights
+  *
+  * Copyright (c) 2001-2002  Sven Neumann <sven@gimp.org>
+  *                          Michael Natterer <mitch@gimp.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.
+  *
+  * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #include <stdlib.h>
+ #include <string.h>
+ 
+ #include <glib-object.h>
+ 
+ #include <blib/blib.h>
+ 
+ #include "digits.h"
+ 
+ 
+ #define PONG_START_TIMEOUT      200
+ #define COMPUTER_LOOSE_SPEEDUP   10
+ 
+ 
+ typedef enum
+ {
+   RIGHT,
+   LEFT
+ } XDirection;
+ 
+ typedef enum
+ {
+   UP,
+   DOWN
+ } YDirection;
+ 
+ 
+ typedef enum
+ {
+   GAME_INIT,
+   TPLAYER_JOIN,
+   BPLAYER_JOIN,
+   GAME_OVER
+ } AnimType;
+ 
+ 
+ #define B_TYPE_PONG            (b_type_pong)
+ #define B_PONG_V(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_PONG, BPongV))
+ #define B_PONG_V_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_PONG, BPongVClass))
+ #define B_IS_PONG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_PONG))
+ #define B_IS_PONG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_PONG))
+ 
+ typedef struct _BPongV      BPongV;
+ typedef struct _BPongVClass BPongVClass;
+ 
+ struct _BPongV
+ {
+   BModule       parent_instance;
+ 
+   AnimType      anim;
+   gint          anim_steps;
+ 
+   gint          paddle_size;
+   gint          paddle_step;
+ 
+   gint          tpaddle;
+   gint          bpaddle;
+   gint          ball_x;
+   gint          ball_y;
+   XDirection    ball_xdir;
+   YDirection    ball_ydir;
+ 
+   gint          tplayer_score;
+   gint          bplayer_score;
+ 
+   gint          tplayer_device_id;
+   gint          bplayer_device_id;
+ 
+   gint          timeout;
+ };
+ 
+ struct _BPongVClass
+ {
+   BModuleClass  parent_class;
+ };
+ 
+ 
+ static GType      b_pong_v_get_type      (GTypeModule   *module);
+ 
+ static void       b_pong_v_class_init    (BPongVClass    *klass);
+ static void       b_pong_v_init          (BPongV         *pong);
+ 
+ static gboolean   b_pong_v_query         (gint           width,
+                                         gint           height,
+                                         gint           channels,
+                                         gint           maxval);
+ static gboolean   b_pong_v_prepare       (BModule       *module,
+                                         GError       **error);
+ static void       b_pong_v_relax         (BModule       *module);
+ static void       b_pong_v_start         (BModule       *module);
+ static void       b_pong_v_stop          (BModule       *module);
+ static void       b_pong_v_event         (BModule       *module,
+                                         BModuleEvent  *event);
+ static gint       b_pong_v_tick          (BModule       *module);
+ static void       b_pong_v_describe      (BModule       *module,
+                                         const gchar  **title,
+                                         const gchar  **description,
+                                         const gchar  **author);
+ 
+ static void       b_pong_v_init_game     (BPongV         *pong);
+ static gint       b_pong_v_move_ball     (BPongV         *pong);
+ static void       b_pong_v_computer_move (BPongV         *pong,
+                                         gint          *paddle);
+ static gboolean   b_pong_v_reflect       (BPongV         *pong,
+                                         gint           paddle);
+ static void       b_pong_v_draw          (BPongV         *pong,
+                                         gint           lpaddle,
+                                         gint           rpaddle,
+                                         gint           ball_x,
+                                         gint           ball_y);
+ static void       b_pong_v_draw_scores   (BPongV         *pong);
+ 
+ 
+ static GType b_type_pong = 0;
+ 
+ 
+ G_MODULE_EXPORT gboolean
+ b_module_register (GTypeModule *module)
+ {
+   b_pong_v_get_type (module);
+   return TRUE;
+ }
+ 
+ static GType
+ b_pong_v_get_type (GTypeModule *module)
+ {
+   if (! b_type_pong)
+     {
+       static const GTypeInfo pong_info =
+       {
+         sizeof (BPongVClass),
+         NULL,           /* base_init */
+         NULL,           /* base_finalize */
+         (GClassInitFunc) b_pong_v_class_init,
+         NULL,           /* class_finalize */
+         NULL,           /* class_data */
+         sizeof (BPongV),
+         0,              /* n_preallocs */
+         (GInstanceInitFunc) b_pong_v_init,
+       };
+ 
+       b_type_pong = g_type_module_register_type (module,
+                                                  B_TYPE_MODULE, "BPongV",
+                                                  &pong_info, 0);
+     }
+ 
+   return b_type_pong;
+ }
+ 
+ static void
+ b_pong_v_class_init (BPongVClass *klass)
+ {
+   BModuleClass *module_class;
+ 
+   module_class = B_MODULE_CLASS (klass);
+ 
+   module_class->max_players = 2;
+ 
+   module_class->query    = b_pong_v_query;
+   module_class->prepare  = b_pong_v_prepare;
+   module_class->relax    = b_pong_v_relax;
+   module_class->start    = b_pong_v_start;
+   module_class->stop     = b_pong_v_stop;
+   module_class->event    = b_pong_v_event;
+   module_class->tick     = b_pong_v_tick;
+   module_class->describe = b_pong_v_describe;
+ }
+ 
+ static void
+ b_pong_v_init (BPongV *pong)
+ {
+   pong->anim_steps        = 0;
+ 
+   pong->tplayer_device_id = -1;
+   pong->bplayer_device_id = -1;
+ }
+ 
+ static gboolean
+ b_pong_v_query (gint     width,
+               gint     height,
+               gint     channels,
+               gint     maxval)
+ {
+   return (width > 7 && height > 7 && channels == 1);
+ }
+ 
+ static gboolean
+ b_pong_v_prepare (BModule  *module,
+                 GError  **error)
+ {
+   BPongV *pong = B_PONG_V (module);
+ 
+   pong->paddle_size = MAX (3, module->width / 4);
+   pong->paddle_step = MAX (1, pong->paddle_size / 3);
+ 
+   return TRUE;
+ }
+ 
+ static void
+ b_pong_v_relax (BModule *module)
+ {
+ }
+ 
+ static void
+ b_pong_v_start (BModule *module)
+ {
+   BPongV *pong = B_PONG_V (module);
+ 
+   pong->tpaddle       = pong->bpaddle       = module->width / 2 - 1;
+   pong->tplayer_score = pong->bplayer_score = 0;
+ 
+   b_pong_v_init_game (pong);
+ 
+   pong->timeout = PONG_START_TIMEOUT;
+ 
+   b_module_ticker_start (module, pong->timeout);
+ }
+ 
+ static void
+ b_pong_v_stop (BModule *module)
+ {
+   BPongV *pong = B_PONG_V (module);
+ 
+   pong->tplayer_device_id = -1;
+   pong->bplayer_device_id = -1;
+ }
+ 
+ static void
+ b_pong_v_event (BModule      *module,
+               BModuleEvent *event)
+ {
+   BPongV *pong = B_PONG_V (module);
+ 
+   switch (event->type)
+     {
+     case B_EVENT_TYPE_KEY:
+       if (pong->anim_steps)
+         return;
+ 
+       switch (event->key)
+         {
+         case B_KEY_1:
+         case B_KEY_2:
+         case B_KEY_4:
+         case B_KEY_5:
+         case B_KEY_7:
+         case B_KEY_8:
+           /* left */
+           if (event->device_id == pong->tplayer_device_id)
+             {
+               pong->tpaddle = MAX (pong->tpaddle - pong->paddle_step, 0);
+             }
+           else if (event->device_id == pong->bplayer_device_id)
+             {
+               pong->bpaddle = MAX (pong->bpaddle - pong->paddle_step, 0);
+             }
+           break;
+ 
+         case B_KEY_3:
+         case B_KEY_6:
+         case B_KEY_9:
+           /* right */
+           if (event->device_id == pong->tplayer_device_id)
+             {
+               pong->tpaddle = MIN (pong->tpaddle + pong->paddle_step,
+                                    module->width - pong->paddle_size);
+             }
+           else if (event->device_id == pong->bplayer_device_id)
+             {
+               pong->bpaddle = MIN (pong->bpaddle + pong->paddle_step,
+                                    module->width - pong->paddle_size);
+             }
+           break;
+ 
+         default:
+           break;
+         }
+       break;
+ 
+     case B_EVENT_TYPE_PLAYER_ENTERED:
+       if (pong->tplayer_device_id == -1)
+         {
+           pong->anim              = TPLAYER_JOIN;
+           pong->anim_steps        = 6;
+           pong->tplayer_device_id = event->device_id;
+ 
+           module->num_players++;
+         }
+       else if (pong->bplayer_device_id == -1)
+         {
+           pong->anim              = BPLAYER_JOIN;
+           pong->anim_steps        = 6;
+           pong->bplayer_device_id = event->device_id;
+ 
+           module->num_players++;
+         }
+       break;
+ 
+     case B_EVENT_TYPE_PLAYER_LEFT:
+       if (pong->tplayer_device_id == event->device_id)
+         {
+           pong->tplayer_device_id = -1;
+ 
+           module->num_players--;
+         }
+       else if (pong->bplayer_device_id == event->device_id)
+         {
+           pong->bplayer_device_id = -1;
+ 
+           module->num_players--;
+         }
+       break;
+ 
+     default:
+       break;
+     }
+ }
+ 
+ static gint
+ b_pong_v_tick (BModule *module)
+ {
+   BPongV *pong = B_PONG_V (module);
+ 
+   if (pong->anim_steps > 0)
+     {
+       pong->anim_steps--;
+ 
+       switch (pong->anim)
+         {
+         case GAME_INIT:
+           b_pong_v_draw (pong,
+                        pong->tpaddle, pong->bpaddle,
+                        pong->anim_steps == 0 ? pong->ball_x : -1,
+                        pong->anim_steps == 0 ? pong->ball_y : -1);
+           break;
+         case TPLAYER_JOIN:
+           b_pong_v_draw (pong,
+                        (pong->anim_steps & 1) ? pong->tpaddle : -1,
+                        pong->bpaddle,
+                        -1, -1);
+           break;
+         case BPLAYER_JOIN:
+           b_pong_v_draw (pong,
+                        pong->tpaddle,
+                        (pong->anim_steps & 1) ? pong->bpaddle : -1,
+                        -1, -1);
+           break;
+         case GAME_OVER:
+           b_pong_v_draw (pong,
+                        pong->tpaddle, pong->bpaddle,
+                        (pong->anim_steps & 1) ? pong->ball_x : -1,
+                        (pong->anim_steps & 1) ? pong->ball_y : -1);
+ 
+           if (pong->anim_steps == 0)
+             {
+               if ((pong->tplayer_score != pong->bplayer_score) &&
+                   (pong->tplayer_score >= 10 || pong->bplayer_score >= 10))
+                 {
+                   b_module_request_stop (module);
+                   return 0;
+                 }
+               else
+                 b_pong_v_init_game (pong);
+             }
+ 
+           break;
+         }
+     }
+   else
+     {
+       switch (b_pong_v_move_ball (pong))
+         {
+         case -1:
+           pong->tplayer_score++;
+           pong->anim_steps = 6;
+           pong->anim = GAME_OVER;
+ 	  if (pong->tplayer_device_id == -1) /* computer lost */
+ 	    pong->timeout -= COMPUTER_LOOSE_SPEEDUP;
+           break;
+ 
+         case 1:
+           pong->bplayer_score++;
+           pong->anim_steps = 6;
+           pong->anim = GAME_OVER;
+ 	  if (pong->bplayer_device_id == -1) /* computer lost */
+ 	    pong->timeout -= COMPUTER_LOOSE_SPEEDUP;
+           break;
+ 
+         case 0:
+           if (pong->tplayer_device_id == -1)
+             b_pong_v_computer_move (pong, &pong->tpaddle);
+           if (pong->bplayer_device_id == -1)
+             b_pong_v_computer_move (pong, &pong->bpaddle);
+           break;
+         }
+ 
+       b_pong_v_draw (pong,
+                    pong->tpaddle, pong->bpaddle,
+                    pong->ball_x, pong->ball_y);
+     }
+ 
+   return pong->timeout;
+ }
+ 
+ static void
+ b_pong_v_describe (BModule      *module,
+                  const gchar **title,
+                  const gchar **description,
+                  const gchar **author)
+ {
+   *title       = "BPongV";
+   *description = "vertical Pong game";
+   *author      = "Sven Neumann";
+ }
+ 
+ static void
+ b_pong_v_init_game (BPongV *pong)
+ {
+   BModule *module;
+   gint     paddle;
+   gint     foo;
+ 
+   module = B_MODULE (pong);
+ 
+   foo = rand ();
+ 
+   if (foo & 0x1)
+     {
+       paddle = pong->tpaddle;
+       pong->ball_y    = 0;
+       pong->ball_ydir = DOWN;
+     }
+   else
+     {
+       paddle = pong->bpaddle;
+       pong->ball_y    = module->height - 1;
+       pong->ball_ydir = UP;
+     }
+ 
+   if ((foo & 0x2 && paddle != 0) ||
+       paddle == module->width - pong->paddle_size)
+     {
+       pong->ball_x    = 0;
+       pong->ball_xdir = RIGHT;
+     }
+   else
+     {
+       pong->ball_x    = module->width - 1;
+       pong->ball_xdir = LEFT;
+     }
+ 
+   pong->anim       = GAME_INIT;
+   pong->anim_steps = 4;
+ }
+ 
+ static gint
+ b_pong_v_move_ball (BPongV *pong)
+ {
+   BModule *module = B_MODULE (pong);
+ 
+   switch (pong->ball_ydir)
+     {
+     case DOWN:
+       pong->ball_y++;
+       break;
+     case UP:
+       pong->ball_y--;
+       break;
+     }
+   switch (pong->ball_xdir)
+     {
+     case LEFT:
+       pong->ball_x--;
+       break;
+     case RIGHT:
+       pong->ball_x++;
+       break;
+     }
+ 
+   /* collision with walls ? */
+   if (pong->ball_x < 0)
+     {
+       pong->ball_x = 1;
+       pong->ball_xdir = RIGHT;
+     }
+   else if (pong->ball_x >= module->width)
+     {
+       pong->ball_x = module->width - 2;
+       pong->ball_xdir = LEFT;
+     }
+ 
+   /* collision with top paddle or out ? */
+   if (pong->ball_y <= 0)
+     {
+       if (! b_pong_v_reflect (pong, pong->tpaddle))
+         return 1;  /* bottom wins */
+ 
+       pong->ball_y = 2;
+       pong->ball_ydir = DOWN;
+     }
+   /* collision with bottom paddle or out ? */
+   else if (pong->ball_y >= module->height - 1)
+     {
+       if (! b_pong_v_reflect (pong, pong->bpaddle))
+         return -1;  /* left wins */
+       pong->ball_y = module->height - 2;
+       pong->ball_ydir = UP;
+     }
+ 
+   return 0;
+ }
+ 
+ static void
+ b_pong_v_computer_move (BPongV *pong,
+                       gint  *paddle)
+ {
+   BModule *module = B_MODULE (pong);
+ 
+   if (rand () & 1)
+     return;
+ 
+   if (*paddle - pong->ball_x > -1)
+     (*paddle)--;
+   else if (*paddle - pong->ball_x < 1)
+     (*paddle)++;
+ 
+   *paddle = CLAMP (*paddle, 0, module->width - pong->paddle_size);
+ }
+ 
+ static gboolean
+ b_pong_v_reflect (BPongV *pong,
+                 gint   paddle)
+ {
+   gint d = pong->ball_x - paddle;
+ 
+   switch (pong->ball_xdir)
+     {
+     case RIGHT: /* we hit the paddle coming from the left */
+ 
+       if (d < 0)
+         return FALSE;
+       else if (d == 0)
+         {
+           pong->ball_xdir = LEFT;
+           pong->ball_x -= 2;
+           return TRUE;
+         }
+       else if (d <= pong->paddle_size)
+         return TRUE;
+       else
+         return FALSE;
+ 
+       break;
+ 
+     case LEFT: /* we hit the paddle coming from the right */
+ 
+       if (d < -1)
+         return FALSE;
+       else if (d < pong->paddle_size - 1)
+         return TRUE;
+       else if (d == pong->paddle_size - 1)
+         {
+           pong->ball_xdir = RIGHT;
+           pong->ball_x += 2;
+           return TRUE;
+         }
+       else
+         return FALSE;
+ 
+       break;
+     }
+ 
+   return TRUE;
+ }
+ 
+ static void
+ b_pong_v_draw (BPongV *pong,
+              gint   tpaddle,
+              gint   bpaddle,
+              gint   ball_x,
+              gint   ball_y)
+ {
+   BModule *module;
+   gint     width;
+   gint     height;
+   gint     i;
+ 
+   module = B_MODULE (pong);
+ 
+   width  = module->width;
+   height = module->height;
+ 
+   b_module_fill (module, 0);
+ 
+   if (tpaddle >= 0 && tpaddle <= width - pong->paddle_size)
+     for (i = 0; i < pong->paddle_size; i++)
+       b_module_draw_point (module, tpaddle + i, 0, module->maxval);
+ 
+   if (bpaddle >= 0 && bpaddle <= width - pong->paddle_size)
+     for (i = 0; i < pong->paddle_size; i++)
+       b_module_draw_point (module, bpaddle + i, height - 1, module->maxval);
+ 
+   if (ball_x >= 0 && ball_x < width && ball_y >= 0 && ball_y < height)
+     b_module_draw_point (module, ball_x, ball_y, module->maxval);
+ 
+   if (pong->anim == GAME_OVER)
+     b_pong_v_draw_scores (pong);
+ 
+   b_module_paint (module);
+ }
+ 
+ static void
+ b_pong_v_draw_scores (BPongV *pong)
+ {
+   BModule     *module;
+   gchar       *ttext, *btext;
+   gint         tlen, blen;
+   gint         x0, y0;
+   gint         x, y;
+   gint         n, i;
+   const BFont *digits = &b_digits_3x5;
+    
+  
+   module = B_MODULE (pong);
+ 
+   ttext = g_strdup_printf ("%d", pong->tplayer_score);
+   btext = g_strdup_printf ("%d", pong->bplayer_score);
+   tlen = strlen (ttext);
+   blen = strlen (btext);
+ 
+   x0 = (module->width - tlen * digits->advance) / 2;
+   y0 = (module->height / 3) - 4;
+   for (n = 0; n < tlen; n++)
+     {
+       for (i = 0; i < digits->num_digits && digits->digits_str[i] != ttext[n]; i++);
+ 
+       if (i < digits->num_digits)
+         for (x = 0; x < digits->width; x++)
+           for (y = 0; y < digits->height; y++)
+             if (digits->data[i][y * digits->width + x] != '0')
+               b_module_draw_point (module, x0 + x, y0 + y, module->maxval);
+ 
+       x0 += digits->advance;
+     }
+ 
+   x0 = (module->width - blen * digits->advance) / 2;
+   y0 = (module->height - module->height / 3) - 4;
+   for (n = 0; n < blen; n++)
+     {
+       for (i = 0; i < digits->num_digits && digits->digits_str[i] != btext[n]; i++);
+ 
+       if (i < digits->num_digits)
+         for (x = 0; x < digits->width; x++)
+           for (y = 0; y < digits->height; y++)
+             if (digits->data[i][y * digits->width + x] != '0')
+               b_module_draw_point (module, x0 + x, y0 + y, module->maxval);
+ 
+       x0 += digits->advance;
+     }
+ 
+   g_free (ttext);
+   g_free (btext);
+ }
diff -r -C 3 -N blib-1.1.7/modules/bpushline.c blib-1.1.7-ba20070811/modules/bpushline.c
*** blib-1.1.7/modules/bpushline.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bpushline.c	Sat Aug 11 22:18:43 2007
***************
*** 147,158 ****
  	  0,              /* n_preallocs */
  	  (GInstanceInitFunc) b_pushline_init,
  	};
!       
        b_type_pushline = g_type_module_register_type (module, B_TYPE_MODULE,
                                                       "BPushline",
  						     &pushline_info, 0);
      }
!   
    return b_type_pushline;
  }
  
--- 147,158 ----
  	  0,              /* n_preallocs */
  	  (GInstanceInitFunc) b_pushline_init,
  	};
!      
        b_type_pushline = g_type_module_register_type (module, B_TYPE_MODULE,
                                                       "BPushline",
  						     &pushline_info, 0);
      }
!  
    return b_type_pushline;
  }
  
***************
*** 170,182 ****
    module_class = B_MODULE_CLASS (klass);
  
    object_class->set_property = b_pushline_set_property;
!  
    param_spec = g_param_spec_enum ("direction", NULL,
                                   "The direction the line moves.",
                                    B_TYPE_PUSHLINE_DIR, dir,
                                    G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
    g_object_class_install_property (object_class, PROP_DIR, param_spec);
!  
    module_class->query    = b_pushline_query;
    module_class->prepare  = b_pushline_prepare;
    module_class->relax    = b_pushline_relax;
--- 170,182 ----
    module_class = B_MODULE_CLASS (klass);
  
    object_class->set_property = b_pushline_set_property;
! 
    param_spec = g_param_spec_enum ("direction", NULL,
                                   "The direction the line moves.",
                                    B_TYPE_PUSHLINE_DIR, dir,
                                    G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
    g_object_class_install_property (object_class, PROP_DIR, param_spec);
! 
    module_class->query    = b_pushline_query;
    module_class->prepare  = b_pushline_prepare;
    module_class->relax    = b_pushline_relax;
***************
*** 241,247 ****
        pushline->pos = -1;
        break;
      }
!   
    return TRUE;
  }
  
--- 241,247 ----
        pushline->pos = -1;
        break;
      }
!  
    return TRUE;
  }
  
diff -r -C 3 -N blib-1.1.7/modules/bqix.c blib-1.1.7-ba20070811/modules/bqix.c
*** blib-1.1.7/modules/bqix.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bqix.c	Sat Aug 11 22:18:43 2007
***************
*** 302,308 ****
    else if (point > max) point = max, delta = -delta, point += delta / 2;
  
    for (i = qix->nlines - 1; i > 0; i--)
!     memcpy (qix->lines + i, qix->lines + i - 1, sizeof (BQixLine)); 
  
    line = qix->lines;
  
--- 302,308 ----
    else if (point > max) point = max, delta = -delta, point += delta / 2;
  
    for (i = qix->nlines - 1; i > 0; i--)
!     memcpy (qix->lines + i, qix->lines + i - 1, sizeof (BQixLine));
  
    line = qix->lines;
  
diff -r -C 3 -N blib-1.1.7/modules/bretris.c blib-1.1.7-ba20070811/modules/bretris.c
*** blib-1.1.7/modules/bretris.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bretris.c	Sat Aug 11 22:18:43 2007
***************
*** 33,54 ****
  #define BRetrisVerMin 0
  #define BRetrisVerRev 2
  
! //minimum size and color count of display
  #define BRetrisSizeXMin 18
  #define BRetrisSizeYMin 8
  #define BRetrisMaxColorMin 1
! //speed of game (small number = fast)
  #define BRetrisSpeedMin 500
  #define BRetrisSpeedMax 50
! #define BRetrisSpeedInc 7 //how fast to increase speed
! #define BRetrisSpeedDrop 20 //speed for dropping stones
! //the colors
! #define BRetrisColorEmpty( MaxColor ) (0)
! #define BRetrisColorActiveStone( MaxColor ) (MaxColor)
! #define BRetrisColorStone( MaxColor ) ((MaxColor) * 3 / 4)
! #define BRetrisColorRemoveStone( MaxColor ) (MaxColor)
  
! #define count( array ) (sizeof( (array) ) / sizeof( (array)[0] ))
  
  #ifdef RETRIS_DEBUG
  #define dbg_print g_print
--- 33,54 ----
  #define BRetrisVerMin 0
  #define BRetrisVerRev 2
  
! /* minimum size and color count of display */
  #define BRetrisSizeXMin 18
  #define BRetrisSizeYMin 8
  #define BRetrisMaxColorMin 1
! /* speed of game (small number = fast) */
  #define BRetrisSpeedMin 500
  #define BRetrisSpeedMax 50
! #define BRetrisSpeedInc 7 /* how fast to increase speed */
! #define BRetrisSpeedDrop 20 /* speed for dropping stones */
! /* the colors */
! #define BRetrisColorEmpty(MaxColor)       (0)
! #define BRetrisColorActiveStone(MaxColor) (MaxColor)
! #define BRetrisColorStone(MaxColor)       ((MaxColor) * 3 / 4)
! #define BRetrisColorRemoveStone(MaxColor) (MaxColor)
  
! #define count(array)  (sizeof ((array))  / sizeof ((array)[0]))
  
  #ifdef RETRIS_DEBUG
  #define dbg_print g_print
***************
*** 69,84 ****
  {
    BModule parent_instance;
  
!   int SizeX, SizeY; //size of game-field
!   int MaxColor;     //maximum color value
!   int PlayerId;     //device id of the player
!   int Speed;        //current speed
!   int * * ppStones; //two-dimensional array with stones [SizeX+4][SizeY]
!   int CurStone;     //number of current stone, -1 if none
!   int CurX, CurY;   //position of current stone
!   int CurRot;       //rotation of current stone
!   int RemoveCol;    //column being removed, -1 if none
!   int Dropping;     //flag if dropping current stone
  };
  
  struct _BRetrisModuleClass
--- 69,84 ----
  {
    BModule parent_instance;
  
!   gint SizeX, SizeY; /* size of game-field */
!   gint MaxColor;     /* maximum color value */
!   gint PlayerId;     /* device id of the player */
!   gint Speed;        /* current speed */
!   gint * * ppStones; /* two-dimensional array with stones [SizeX+4][SizeY] */
!   gint CurStone;     /* number of current stone, -1 if none */
!   gint CurX, CurY;   /* position of current stone */
!   gint CurRot;       /* rotation of current stone */
!   gint RemoveCol;    /* column being removed, -1 if none */
!   gint Dropping;     /* flag if dropping current stone */
  };
  
  struct _BRetrisModuleClass
***************
*** 146,155 ****
    return b_type_retris_module;
  }
  
! //stones (always 4 lines with same stone in different rotation angles)
  typedef struct sBRetrisStonePos
  {
!   int X, Y;
  } stBRetrisStonePos;
  typedef struct sBRetrisStoneRot
  {
--- 146,155 ----
    return b_type_retris_module;
  }
  
! /* stones (always 4 lines with same stone in different rotation angles) */
  typedef struct sBRetrisStonePos
  {
!   gint X, Y;
  } stBRetrisStonePos;
  typedef struct sBRetrisStoneRot
  {
***************
*** 161,319 ****
  } stBRetrisStone;
  stBRetrisStone BRetrisStoneTable[] =
  {
!   { { { { { -2,  0 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } }, //the I
        { { {  0, -2 }, {  0, -1 }, {  0,  0 }, {  0,  1 } } },
        { { { -2,  0 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } },
        { { {  0, -2 }, {  0, -1 }, {  0,  0 }, {  0,  1 } } } } },
!   { { { { {  1, -1 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } }, //the L
        { { {  0, -1 }, {  0,  0 }, {  0,  1 }, {  1,  1 } } },
        { { { -1,  0 }, {  0,  0 }, {  1,  0 }, { -1,  1 } } },
        { { { -1, -1 }, {  0, -1 }, {  0,  0 }, {  0,  1 } } } } },
!   { { { { { -1, -1 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } }, //the J
        { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  0,  1 } } },
        { { { -1,  0 }, {  0,  0 }, {  1,  0 }, {  1,  1 } } },
        { { {  0, -1 }, {  0,  0 }, { -1,  1 }, {  0,  1 } } } } },
!   { { { { {  0, -1 }, { -1,  0 }, {  0,  0 }, {  0,  1 } } }, //the T
        { { {  0, -1 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } },
        { { {  0, -1 }, {  0,  0 }, {  1,  0 }, {  0,  1 } } },
        { { { -1,  0 }, {  0,  0 }, {  1,  0 }, {  0,  1 } } } } },
!   { { { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } }, //the block
        { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } },
        { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } },
        { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } } } },
!   { { { { {  0, -1 }, { -1,  0 }, {  0,  0 }, { -1,  1 } } }, //the Z
        { { { -1, -1 }, {  0, -1 }, {  0,  0 }, {  1,  0 } } },
        { { {  0, -1 }, { -1,  0 }, {  0,  0 }, { -1,  1 } } },
        { { { -1, -1 }, {  0, -1 }, {  0,  0 }, {  1,  0 } } } } },
!   { { { { { -1, -1 }, { -1,  0 }, {  0,  0 }, {  0,  1 } } }, //the S
        { { {  0, -1 }, {  1, -1 }, { -1,  0 }, {  0,  0 } } },
        { { { -1, -1 }, { -1,  0 }, {  0,  0 }, {  0,  1 } } },
        { { {  0, -1 }, {  1, -1 }, { -1,  0 }, {  0,  0 } } } } },
  };
  
! //check if a stone fits at a position
! //retuns true if stone fits
! static int
  BRetrisCheckStone (BRetrisModule *pRetrisModule,
!                    int Stone, int PosX, int PosY, int Rot)
  {
    stBRetrisStoneRot * pStoneRot;
    stBRetrisStonePos * pStonePos;
!   int I, X, Y, SizeX, SizeY;
  
!   //check if stone is available
    if (Stone < 0 || Stone >= count (BRetrisStoneTable))
      return 0;
  
!   //get size of stone array
    SizeX = pRetrisModule->SizeX + 4;
    SizeY = pRetrisModule->SizeY;
  
!   //get pointer to stone rotation
    pStoneRot = &BRetrisStoneTable[Stone]
                 .Rot[Rot & 3];
  
!   //all 4 positions
    for (I = 0; I < 4; I++)
    {
!     //get position
      pStonePos = &pStoneRot->Pos[I];
!     //get coordinates
      X = PosX + pStonePos->X;
      Y = PosY + pStonePos->Y;
!     //outside of array
!     if( X < 0 || X >= SizeX || Y < 0 || Y >= SizeY )
        return 0;
!     //position not free
!     if( pRetrisModule->ppStones[X][Y] )
        return 0;
    }
  
!   //stone fits
    return 1;
  }
  
! //deactivate stone
  static void
  BRetrisDeactivateStone (BRetrisModule *pRetrisModule)
  {
    stBRetrisStoneRot * pStoneRot;
    stBRetrisStonePos * pStonePos;
!   int I, X, Y, SizeX, SizeY;
  
!   //check if stone is available
    if (pRetrisModule->CurStone < 0 || pRetrisModule->CurStone >= count (BRetrisStoneTable))
      return;
  
!   //get size of stone array
    SizeX = pRetrisModule->SizeX + 4;
    SizeY = pRetrisModule->SizeY;
  
!   //get pointer to stone rotation
    pStoneRot = &BRetrisStoneTable[pRetrisModule->CurStone]
                 .Rot[pRetrisModule->CurRot & 3];
  
!   //all 4 positions
    for (I = 0; I < 4; I++)
    {
!     //get position
      pStonePos = &pStoneRot->Pos[I];
!     //get coordinates
      X = pRetrisModule->CurX + pStonePos->X;
      Y = pRetrisModule->CurY + pStonePos->Y;
!     //put stone into stone array
!     if( X >= 0 && X < SizeX && Y >= 0 && Y < SizeY )
        pRetrisModule->ppStones[X][Y] = 1;
    }
  }
  
! //draw active stone
  static void
  BRetrisDrawStone (BRetrisModule *pRetrisModule)
  {
    stBRetrisStoneRot * pStoneRot;
    stBRetrisStonePos * pStonePos;
!   int I, X, Y, SizeX, SizeY;
  
!   //check if stone is available
    if (pRetrisModule->CurStone < 0 || pRetrisModule->CurStone >= count (BRetrisStoneTable))
      return;
  
!   //get size of display
    SizeX = pRetrisModule->SizeX;
    SizeY = pRetrisModule->SizeY;
  
!   //get pointer to stone rotation
    pStoneRot = &BRetrisStoneTable[pRetrisModule->CurStone]
                 .Rot[pRetrisModule->CurRot & 3];
  
!   //all 4 positions
    for (I = 0; I < 4; I++)
    {
!     //get position
      pStonePos = &pStoneRot->Pos[I];
!     //get coordinates
      X = pRetrisModule->CurX + pStonePos->X;
      Y = pRetrisModule->CurY + pStonePos->Y;
!     //draw position
!     if( X >= 0 && X < SizeX && Y >= 0 && Y < SizeY )
        b_module_draw_point ((BModule *) pRetrisModule,
                             X, Y,
                             BRetrisColorActiveStone (pRetrisModule->MaxColor));
    }
  }
  
! //output current picture
  static void
  BRetrisOutput (BRetrisModule *pRetrisModule)
  {
!   int X, Y;
  
!   //empty the screen
    b_module_fill ((BModule *) pRetrisModule,
  		 BRetrisColorEmpty (pRetrisModule->MaxColor));
  
!   //draw stones
    for (X = 0; X < pRetrisModule->SizeX; X++)
    {
      for (Y = 0; Y < pRetrisModule->SizeY; Y++)
--- 161,319 ----
  } stBRetrisStone;
  stBRetrisStone BRetrisStoneTable[] =
  {
!   { { { { { -2,  0 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } }, /* the I */
        { { {  0, -2 }, {  0, -1 }, {  0,  0 }, {  0,  1 } } },
        { { { -2,  0 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } },
        { { {  0, -2 }, {  0, -1 }, {  0,  0 }, {  0,  1 } } } } },
!   { { { { {  1, -1 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } }, /* the L */
        { { {  0, -1 }, {  0,  0 }, {  0,  1 }, {  1,  1 } } },
        { { { -1,  0 }, {  0,  0 }, {  1,  0 }, { -1,  1 } } },
        { { { -1, -1 }, {  0, -1 }, {  0,  0 }, {  0,  1 } } } } },
!   { { { { { -1, -1 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } }, /* the J */
        { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  0,  1 } } },
        { { { -1,  0 }, {  0,  0 }, {  1,  0 }, {  1,  1 } } },
        { { {  0, -1 }, {  0,  0 }, { -1,  1 }, {  0,  1 } } } } },
!   { { { { {  0, -1 }, { -1,  0 }, {  0,  0 }, {  0,  1 } } }, /* the T */
        { { {  0, -1 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } },
        { { {  0, -1 }, {  0,  0 }, {  1,  0 }, {  0,  1 } } },
        { { { -1,  0 }, {  0,  0 }, {  1,  0 }, {  0,  1 } } } } },
!   { { { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } }, /* the block */
        { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } },
        { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } },
        { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } } } },
!   { { { { {  0, -1 }, { -1,  0 }, {  0,  0 }, { -1,  1 } } }, /* the Z */
        { { { -1, -1 }, {  0, -1 }, {  0,  0 }, {  1,  0 } } },
        { { {  0, -1 }, { -1,  0 }, {  0,  0 }, { -1,  1 } } },
        { { { -1, -1 }, {  0, -1 }, {  0,  0 }, {  1,  0 } } } } },
!   { { { { { -1, -1 }, { -1,  0 }, {  0,  0 }, {  0,  1 } } }, /* the S */
        { { {  0, -1 }, {  1, -1 }, { -1,  0 }, {  0,  0 } } },
        { { { -1, -1 }, { -1,  0 }, {  0,  0 }, {  0,  1 } } },
        { { {  0, -1 }, {  1, -1 }, { -1,  0 }, {  0,  0 } } } } },
  };
  
! /* check if a stone fits at a position */
! /* retuns true if stone fits */
! static gint
  BRetrisCheckStone (BRetrisModule *pRetrisModule,
!                    gint Stone, gint PosX, gint PosY, gint Rot)
  {
    stBRetrisStoneRot * pStoneRot;
    stBRetrisStonePos * pStonePos;
!   gint I, X, Y, SizeX, SizeY;
  
!   /* check if stone is available */
    if (Stone < 0 || Stone >= count (BRetrisStoneTable))
      return 0;
  
!   /* get size of stone array */
    SizeX = pRetrisModule->SizeX + 4;
    SizeY = pRetrisModule->SizeY;
  
!   /* get pointer to stone rotation */
    pStoneRot = &BRetrisStoneTable[Stone]
                 .Rot[Rot & 3];
  
!   /* all 4 positions */
    for (I = 0; I < 4; I++)
    {
!     /* get position */
      pStonePos = &pStoneRot->Pos[I];
!     /* get coordinates */
      X = PosX + pStonePos->X;
      Y = PosY + pStonePos->Y;
!     /* outside of array */
!     if (X < 0 || X >= SizeX || Y < 0 || Y >= SizeY)
        return 0;
!     /* position not free */
!     if (pRetrisModule->ppStones[X][Y])
        return 0;
    }
  
!   /* stone fits */
    return 1;
  }
  
! /* deactivate stone */
  static void
  BRetrisDeactivateStone (BRetrisModule *pRetrisModule)
  {
    stBRetrisStoneRot * pStoneRot;
    stBRetrisStonePos * pStonePos;
!   gint I, X, Y, SizeX, SizeY;
  
!   /* check if stone is available */
    if (pRetrisModule->CurStone < 0 || pRetrisModule->CurStone >= count (BRetrisStoneTable))
      return;
  
!   /* get size of stone array */
    SizeX = pRetrisModule->SizeX + 4;
    SizeY = pRetrisModule->SizeY;
  
!   /* get pointer to stone rotation */
    pStoneRot = &BRetrisStoneTable[pRetrisModule->CurStone]
                 .Rot[pRetrisModule->CurRot & 3];
  
!   /* all 4 positions */
    for (I = 0; I < 4; I++)
    {
!     /* get position */
      pStonePos = &pStoneRot->Pos[I];
!     /* get coordinates */
      X = pRetrisModule->CurX + pStonePos->X;
      Y = pRetrisModule->CurY + pStonePos->Y;
!     /* put stone into stone array */
!     if (X >= 0 && X < SizeX && Y >= 0 && Y < SizeY)
        pRetrisModule->ppStones[X][Y] = 1;
    }
  }
  
! /* draw active stone */
  static void
  BRetrisDrawStone (BRetrisModule *pRetrisModule)
  {
    stBRetrisStoneRot * pStoneRot;
    stBRetrisStonePos * pStonePos;
!   gint I, X, Y, SizeX, SizeY;
  
!   /* check if stone is available */
    if (pRetrisModule->CurStone < 0 || pRetrisModule->CurStone >= count (BRetrisStoneTable))
      return;
  
!   /* get size of display */
    SizeX = pRetrisModule->SizeX;
    SizeY = pRetrisModule->SizeY;
  
!   /* get pointer to stone rotation */
    pStoneRot = &BRetrisStoneTable[pRetrisModule->CurStone]
                 .Rot[pRetrisModule->CurRot & 3];
  
!   /* all 4 positions */
    for (I = 0; I < 4; I++)
    {
!     /* get position */
      pStonePos = &pStoneRot->Pos[I];
!     /* get coordinates */
      X = pRetrisModule->CurX + pStonePos->X;
      Y = pRetrisModule->CurY + pStonePos->Y;
!     /* draw position */
!     if (X >= 0 && X < SizeX && Y >= 0 && Y < SizeY)
        b_module_draw_point ((BModule *) pRetrisModule,
                             X, Y,
                             BRetrisColorActiveStone (pRetrisModule->MaxColor));
    }
  }
  
! /* output current picture */
  static void
  BRetrisOutput (BRetrisModule *pRetrisModule)
  {
!   gint X, Y;
  
!   /* empty the screen */
    b_module_fill ((BModule *) pRetrisModule,
  		 BRetrisColorEmpty (pRetrisModule->MaxColor));
  
!   /* draw stones */
    for (X = 0; X < pRetrisModule->SizeX; X++)
    {
      for (Y = 0; Y < pRetrisModule->SizeY; Y++)
***************
*** 332,379 ****
      }
    }
  
!   //draw active stone
    BRetrisDrawStone (pRetrisModule);
  
!   //update screen
    b_module_paint ((BModule *) pRetrisModule);
  }
  
! //start a new game
  static void
  BRetrisNewGame (BRetrisModule *pRetrisModule)
  {
!   int X, Y;
  
!   //set speed to minimal
    pRetrisModule->Speed = BRetrisSpeedMin;
  
!   //remove all stones
    for (X = 0; X < pRetrisModule->SizeX + 4; X++)
      for (Y = 0; Y < pRetrisModule->SizeY; Y++)
        pRetrisModule->ppStones[X][Y] = 0;
  
!   //no current stone yet
    pRetrisModule->CurStone = -1;
!   //no column ist being removed
    pRetrisModule->RemoveCol = -1;
!   //no stone is being dropped
    pRetrisModule->Dropping = 0;
  
    dbg_print ("BRetris: new game\n");
  
!   //output current picture
    BRetrisOutput (pRetrisModule);
  }
  
! //key-procedure
  static void
  BRetrisKey (BRetrisModule *pRetrisModule,
              BModuleKey     Key)
  {
    switch (Key)
    {
!     //move stone up
      case B_KEY_2:
        if (BRetrisCheckStone (pRetrisModule,
                               pRetrisModule->CurStone,
--- 332,379 ----
      }
    }
  
!   /* draw active stone */
    BRetrisDrawStone (pRetrisModule);
  
!   /* update screen */
    b_module_paint ((BModule *) pRetrisModule);
  }
  
! /* start a new game */
  static void
  BRetrisNewGame (BRetrisModule *pRetrisModule)
  {
!   gint X, Y;
  
!   /* set speed to minimal */
    pRetrisModule->Speed = BRetrisSpeedMin;
  
!   /* remove all stones */
    for (X = 0; X < pRetrisModule->SizeX + 4; X++)
      for (Y = 0; Y < pRetrisModule->SizeY; Y++)
        pRetrisModule->ppStones[X][Y] = 0;
  
!   /* no current stone yet */
    pRetrisModule->CurStone = -1;
!   /* no column ist being removed */
    pRetrisModule->RemoveCol = -1;
!   /* no stone is being dropped */
    pRetrisModule->Dropping = 0;
  
    dbg_print ("BRetris: new game\n");
  
!   /* output current picture */
    BRetrisOutput (pRetrisModule);
  }
  
! /* key-procedure */
  static void
  BRetrisKey (BRetrisModule *pRetrisModule,
              BModuleKey     Key)
  {
    switch (Key)
    {
!     /* move stone up */
      case B_KEY_2:
        if (BRetrisCheckStone (pRetrisModule,
                               pRetrisModule->CurStone,
***************
*** 386,392 ****
        }
        break;
  
!     //rotate stone
      case B_KEY_3:
      case B_KEY_6:
        if (BRetrisCheckStone (pRetrisModule,
--- 386,392 ----
        }
        break;
  
!     /* rotate stone */
      case B_KEY_3:
      case B_KEY_6:
        if (BRetrisCheckStone (pRetrisModule,
***************
*** 400,413 ****
        }
        break;
  
!     //drop stone
      case B_KEY_4:
!       pRetrisModule->Dropping = 1; //set flag for dropping stone
!       b_module_ticker_stop ((BModule *) pRetrisModule); //restart the tick machinery
        b_module_ticker_start ((BModule *) pRetrisModule, BRetrisSpeedDrop);
        break;
  
!     //move stone down
      case B_KEY_8:
        if (BRetrisCheckStone (pRetrisModule,
                               pRetrisModule->CurStone,
--- 400,413 ----
        }
        break;
  
!     /* drop stone */
      case B_KEY_4:
!       pRetrisModule->Dropping = 1; /* set flag for dropping stone */
!       b_module_ticker_stop ((BModule *) pRetrisModule); /* restart the tick machinery */
        b_module_ticker_start ((BModule *) pRetrisModule, BRetrisSpeedDrop);
        break;
  
!     /* move stone down */
      case B_KEY_8:
        if (BRetrisCheckStone (pRetrisModule,
                               pRetrisModule->CurStone,
***************
*** 420,426 ****
        }
        break;
  
!     //rotate stone in other direction
      case B_KEY_9:
        if (BRetrisCheckStone (pRetrisModule,
                               pRetrisModule->CurStone,
--- 420,426 ----
        }
        break;
  
!     /* rotate stone in other direction */
      case B_KEY_9:
        if (BRetrisCheckStone (pRetrisModule,
                               pRetrisModule->CurStone,
***************
*** 438,549 ****
    }
  }
  
! //tick-procedure
! //returns 1 if game over or 0 if game not over
! static int
  BRetrisTick (BRetrisModule *pRetrisModule)
  {
!   int X, Y;
  
!   //dropping a stone
    if (pRetrisModule->Dropping)
    {
!     //move stone one down
      if (BRetrisCheckStone (pRetrisModule,
                             pRetrisModule->CurStone,
                             pRetrisModule->CurX - 1,
                             pRetrisModule->CurY,
                             pRetrisModule->CurRot))
        pRetrisModule->CurX--;
!     //stone has hit ground
      else
!       //stop dropping stone
        pRetrisModule->Dropping = 0;
!   } //dropping a stone
  
!   //not dropping a stone
    else
    {
!     //stone active
      if (pRetrisModule->CurStone >= 0)
      {
!       //move stone one down
        if (BRetrisCheckStone (pRetrisModule,
                               pRetrisModule->CurStone,
                               pRetrisModule->CurX - 1,
                               pRetrisModule->CurY,
                               pRetrisModule->CurRot))
          pRetrisModule->CurX--;
!       //stone has hit ground
        else
        {
!         BRetrisDeactivateStone (pRetrisModule); //deactivate stone
!         pRetrisModule->CurStone = -1; //no current stone
!         dbg_print( "BRetris: stone hit ground\n" );
        }
!     } //stone active
  
!     //no active stone
      else
      {
!       //column is being removed
        if (pRetrisModule->RemoveCol >= 0)
        {
!         //remove the column
          for (X = pRetrisModule->RemoveCol; X < pRetrisModule->SizeX + 4 - 1; X++)
            for (Y = 0; Y < pRetrisModule->SizeY; Y++)
              pRetrisModule->ppStones[X][Y] = pRetrisModule->ppStones[X + 1][Y];
!         dbg_print( "BRetris: column %d removed\n", pRetrisModule->RemoveCol );
!         pRetrisModule->RemoveCol = -1; //no column is being removed
! 	//increase speed
          pRetrisModule->Speed = (pRetrisModule->Speed * (BRetrisSpeedInc - 1) + BRetrisSpeedMax) / BRetrisSpeedInc;
!       } //column is being removed
  
!       //no column is being removed
        else
        {
!         //check for a column to remove
          for (X = 0; X < pRetrisModule->SizeX + 4; X++)
          {
            for (Y = 0; Y < pRetrisModule->SizeY; Y++)
              if (! pRetrisModule->ppStones[X][Y])
                break;
!           if (Y >= pRetrisModule->SizeY) //column is full
              break;
          }
  
!         //found a column to remove
          if (X < pRetrisModule->SizeX + 4)
          {
            pRetrisModule->RemoveCol = X;
!           dbg_print( "BRetris: column %d is full\n", pRetrisModule->RemoveCol );
          }
  
!         //found no column to remove
          else
          {
!           //check game over
            for (X = pRetrisModule->SizeX; X < pRetrisModule->SizeX + 4; X++)
              for (Y = 0; Y < pRetrisModule->SizeY; Y++)
                if (pRetrisModule->ppStones[X][Y])
!                 //found inactive stone right of display - game over
                  return 1;
  
!           //create new stone
!           pRetrisModule->CurStone = rand( ) % count (BRetrisStoneTable);
            pRetrisModule->CurX = pRetrisModule->SizeX + 2;
            pRetrisModule->CurY = pRetrisModule->SizeY / 2;
!           pRetrisModule->CurRot = rand( ) & 3;
!           dbg_print( "BRetris: created new stone\n" );
!         } //found no column to remove
!       } //no column is being removed
!     } //no active stone
!   } //not dropping a stone
  
!   //output new picture
    BRetrisOutput (pRetrisModule);
  
!   //return game not over
    return 0;
  }
  
--- 438,549 ----
    }
  }
  
! /* tick-procedure */
! /* returns 1 if game over or 0 if game not over */
! static gint
  BRetrisTick (BRetrisModule *pRetrisModule)
  {
!   gint X, Y;
  
!   /* dropping a stone */
    if (pRetrisModule->Dropping)
    {
!     /* move stone one down */
      if (BRetrisCheckStone (pRetrisModule,
                             pRetrisModule->CurStone,
                             pRetrisModule->CurX - 1,
                             pRetrisModule->CurY,
                             pRetrisModule->CurRot))
        pRetrisModule->CurX--;
!     /* stone has hit ground */
      else
!       /* stop dropping stone */
        pRetrisModule->Dropping = 0;
!   } /* dropping a stone */
  
!   /* not dropping a stone */
    else
    {
!     /* stone active */
      if (pRetrisModule->CurStone >= 0)
      {
!       /* move stone one down */
        if (BRetrisCheckStone (pRetrisModule,
                               pRetrisModule->CurStone,
                               pRetrisModule->CurX - 1,
                               pRetrisModule->CurY,
                               pRetrisModule->CurRot))
          pRetrisModule->CurX--;
!       /* stone has hit ground */
        else
        {
!         BRetrisDeactivateStone (pRetrisModule); /* deactivate stone */
!         pRetrisModule->CurStone = -1; /* no current stone */
!         dbg_print ("BRetris: stone hit ground\n");
        }
!     } /* stone active */
  
!     /* no active stone */
      else
      {
!       /* column is being removed */
        if (pRetrisModule->RemoveCol >= 0)
        {
!         /* remove the column */
          for (X = pRetrisModule->RemoveCol; X < pRetrisModule->SizeX + 4 - 1; X++)
            for (Y = 0; Y < pRetrisModule->SizeY; Y++)
              pRetrisModule->ppStones[X][Y] = pRetrisModule->ppStones[X + 1][Y];
!         dbg_print ("BRetris: column %d removed\n", pRetrisModule->RemoveCol);
!         pRetrisModule->RemoveCol = -1; /* no column is being removed */
! 	/* increase speed */
          pRetrisModule->Speed = (pRetrisModule->Speed * (BRetrisSpeedInc - 1) + BRetrisSpeedMax) / BRetrisSpeedInc;
!       } /* column is being removed */
  
!       /* no column is being removed */
        else
        {
!         /* check for a column to remove */
          for (X = 0; X < pRetrisModule->SizeX + 4; X++)
          {
            for (Y = 0; Y < pRetrisModule->SizeY; Y++)
              if (! pRetrisModule->ppStones[X][Y])
                break;
!           if (Y >= pRetrisModule->SizeY) /* column is full */
              break;
          }
  
!         /* found a column to remove */
          if (X < pRetrisModule->SizeX + 4)
          {
            pRetrisModule->RemoveCol = X;
!           dbg_print ("BRetris: column %d is full\n", pRetrisModule->RemoveCol);
          }
  
!         /* found no column to remove */
          else
          {
!           /* check game over */
            for (X = pRetrisModule->SizeX; X < pRetrisModule->SizeX + 4; X++)
              for (Y = 0; Y < pRetrisModule->SizeY; Y++)
                if (pRetrisModule->ppStones[X][Y])
!                 /* found inactive stone right of display - game over */
                  return 1;
  
!           /* create new stone */
!           pRetrisModule->CurStone = rand () % count (BRetrisStoneTable);
            pRetrisModule->CurX = pRetrisModule->SizeX + 2;
            pRetrisModule->CurY = pRetrisModule->SizeY / 2;
!           pRetrisModule->CurRot = rand () & 3;
!           dbg_print ("BRetris: created new stone\n");
!         } /* found no column to remove */
!       } /* no column is being removed */
!     } /* no active stone */
!   } /* not dropping a stone */
  
!   /* output new picture */
    BRetrisOutput (pRetrisModule);
  
!   /* return game not over */
    return 0;
  }
  
***************
*** 582,606 ****
  b_retris_module_prepare (BModule  *module,
                             GError  **error)
  {
!   int SizePtrs, SizeCol, Size, X;
!   char * Ptr;
  
    BRetrisModule *pRetris_module = B_RETRIS_MODULE (module);
  
!   //initialize the module values that depend on the output device
!   pRetris_module->SizeX = module->width; //size of game field
    pRetris_module->SizeY = module->height;
!   pRetris_module->MaxColor = module->maxval; //maximum color value
!   pRetris_module->PlayerId = -1; //no plyer in game yet
  
!   //allocate needed memory
!   SizePtrs = (pRetris_module->SizeX + 4) * sizeof( int * ); //get needed size
!   SizeCol = pRetris_module->SizeY * sizeof( int );
    Size = SizePtrs + (pRetris_module->SizeX + 4) * SizeCol;
    Ptr = g_new (gchar, Size);
  
!   pRetris_module->ppStones = (int * *)Ptr; //remember pointer
!   for( X = 0, Ptr += SizePtrs; X < pRetris_module->SizeX + 4; X++, Ptr += SizeCol ) //generate pointers to columns
      pRetris_module->ppStones[X] = (int *)Ptr;
  
    return TRUE;
--- 582,606 ----
  b_retris_module_prepare (BModule  *module,
                             GError  **error)
  {
!   gint SizePtrs, SizeCol, Size, X;
!   gchar *Ptr;
  
    BRetrisModule *pRetris_module = B_RETRIS_MODULE (module);
  
!   /* initialize the module values that depend on the output device */
!   pRetris_module->SizeX = module->width; /* size of game field */
    pRetris_module->SizeY = module->height;
!   pRetris_module->MaxColor = module->maxval; /* maximum color value */
!   pRetris_module->PlayerId = -1; /* no plyer in game yet */
  
!   /* allocate needed memory */
!   SizePtrs = (pRetris_module->SizeX + 4) * sizeof (int *); /* get needed size */
!   SizeCol = pRetris_module->SizeY * sizeof (int);
    Size = SizePtrs + (pRetris_module->SizeX + 4) * SizeCol;
    Ptr = g_new (gchar, Size);
  
!   pRetris_module->ppStones = (int * *)Ptr; /* remember pointer */
!   for (X = 0, Ptr += SizePtrs; X < pRetris_module->SizeX + 4; X++, Ptr += SizeCol)  /* generate pointers to columns */
      pRetris_module->ppStones[X] = (int *)Ptr;
  
    return TRUE;
***************
*** 618,627 ****
  static void
  b_retris_module_start (BModule *module)
  {
!   //start new game
    BRetrisNewGame ((BRetrisModule *) module);
  
!   //start the tick machinery
    b_module_ticker_start (module, BRetrisSpeedMin);
  }
  
--- 618,627 ----
  static void
  b_retris_module_start (BModule *module)
  {
!   /* start new game */
    BRetrisNewGame ((BRetrisModule *) module);
  
!   /* start the tick machinery */
    b_module_ticker_start (module, BRetrisSpeedMin);
  }
  
***************
*** 661,690 ****
  static gint
  b_retris_module_tick (BModule *module)
  {
!   int GameOver;
  
!   //call tick-procedure
    GameOver = BRetrisTick ((BRetrisModule *) module);
  
!   //game over
!   if( GameOver )
    {
      dbg_print ("BRetris: requesting stop\n");
!     //clear screen
      b_module_fill (module, 0);
      b_module_paint (module);
!     //request end of game
      b_module_request_stop (module);
!     //we do not want to be called again
      return 0;
    }
  
!   //dropping a stone at the moment
    if (((BRetrisModule *) module)->Dropping)
!     //we want to be called again in very few milliseconds
      return BRetrisSpeedDrop;
  
!   //we want to be called again in some milliseconds
    return ((BRetrisModule *) module)->Speed;
  }
  
--- 661,690 ----
  static gint
  b_retris_module_tick (BModule *module)
  {
!   gint GameOver;
  
!   /* call tick-procedure */
    GameOver = BRetrisTick ((BRetrisModule *) module);
  
!   /* game over */
!   if (GameOver)
    {
      dbg_print ("BRetris: requesting stop\n");
!     /* clear screen */
      b_module_fill (module, 0);
      b_module_paint (module);
!     /* request end of game */
      b_module_request_stop (module);
!     /* we do not want to be called again */
      return 0;
    }
  
!   /* dropping a stone at the moment */
    if (((BRetrisModule *) module)->Dropping)
!     /* we want to be called again in very few milliseconds */
      return BRetrisSpeedDrop;
  
!   /* we want to be called again in some milliseconds */
    return ((BRetrisModule *) module)->Speed;
  }
  
diff -r -C 3 -N blib-1.1.7/modules/bsitris4.c blib-1.1.7-ba20070811/modules/bsitris4.c
*** blib-1.1.7/modules/bsitris4.c	Thu Jan  1 01:00:00 1970
--- blib-1.1.7-ba20070811/modules/bsitris4.c	Sat Aug 11 22:18:43 2007
***************
*** 0 ****
--- 1,735 ----
+ /* BSitris4: Tetris (from sided to middle) module for Blinkenlights
+  *
+  * Copyright (c) 2003 1stein <1stein@schuermans.info>
+  *
+  * based on Test implementation for a BModule by the Blinkenlights Crew
+  *
+  * 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.
+  *
+  * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #include "config.h"
+ 
+ #include <string.h>
+ #include <stdlib.h>
+ 
+ #include <glib-object.h>
+ #include <gmodule.h>
+ 
+ #include <blib/blib.h>
+ 
+ #define BSitris4VerMaj 1
+ #define BSitris4VerMin 0
+ #define BSitris4VerRev 2
+ 
+ /* minimum size and color count of display */
+ #define BSitris4SizeXMin 26
+ #define BSitris4SizeYMin 6
+ #define BSitris4MaxColorMin 1
+ /* speed of game (small number = fast) */
+ #define BSitris4SpeedMin 500
+ #define BSitris4SpeedMax 50
+ #define BSitris4SpeedInc 7 /* how fast to increase speed */
+ #define BSitris4SpeedDrop 20 /* speed for dropping stones */
+ /* the colors */
+ #define BSitris4ColorEmpty(MaxColor)       (0)
+ #define BSitris4ColorActiveStone(MaxColor) (MaxColor)
+ #define BSitris4ColorStone(MaxColor)       ((MaxColor) * 3 / 4)
+ #define BSitris4ColorRemoveStone(MaxColor) (MaxColor)
+ 
+ #define count(array)  (sizeof ((array)) / sizeof ((array)[0]))
+ 
+ #ifdef SITRIS4_DEBUG
+ #define dbg_print g_print
+ #else
+ #define dbg_print(fmt, ...)
+ #endif
+ 
+ #define B_TYPE_SITRIS4_MODULE         (b_type_sitris4_module)
+ #define B_SITRIS4_MODULE(obj)         (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_SITRIS4_MODULE, BSitris4Module))
+ #define B_SITRIS4_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_SITRIS4_MODULE, BSitris4ModuleClass))
+ #define B_IS_SITRIS4_MODULE(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_SITRIS4_MODULE))
+ 
+ typedef struct _BSitris4Module BSitris4Module;
+ typedef struct _BSitris4ModuleClass BSitris4ModuleClass;
+ 
+ 
+ struct _BSitris4Module
+ {
+   BModule parent_instance;
+ 
+   gint RealSizeX, RealSizeY; /* real size of game-field */
+   gint CenterX;              /* center of game-field (X direction) */
+   gint LogSizeX, LogSizeY;   /* logical size of game-field */
+   gint MaxColor;             /* maximum color value */
+   gint PlayerId;             /* device id of the player */
+   gint Speed;                /* current speed */
+   gint * * ppStones;         /* two-dimensional array with stones [LogSizeX+4][LogSizeY] */
+   gint CurStone;             /* number of current stone, -1 if none */
+   gint CurX, CurY;           /* position of current stone */
+   gint CurRot;               /* rotation of current stone */
+   gint RemoveCol;            /* column being removed, -1 if none */
+   gint Dropping;             /* flag if dropping current stone */
+ };
+ 
+ struct _BSitris4ModuleClass
+ {
+   BModuleClass parent_class;
+ };
+ 
+ static GType    b_sitris4_module_get_type   (GTypeModule         *module);
+ static void     b_sitris4_module_class_init (BSitris4ModuleClass  *klass);
+ static void     b_sitris4_module_init       (BSitris4Module       *test_module);
+ static gboolean b_sitris4_module_query      (gint                 width,
+                                             gint                 height,
+                                             gint                 channels,
+                                             gint                 maxval);
+ static gboolean b_sitris4_module_prepare    (BModule             *module,
+                                             GError             **error);
+ static void     b_sitris4_module_relax      (BModule             *module);
+ static void     b_sitris4_module_start      (BModule             *module);
+ static void     b_sitris4_module_event      (BModule             *module,
+                                             BModuleEvent        *event);
+ static gint     b_sitris4_module_tick       (BModule             *module);
+ static void     b_sitris4_module_describe   (BModule             *module,
+                                             const gchar        **title,
+                                             const gchar        **description,
+                                             const gchar        **author);
+ 
+ 
+ static GType b_type_sitris4_module = 0;
+ 
+ 
+ G_MODULE_EXPORT gboolean
+ b_module_register (GTypeModule * module)
+ {
+   b_sitris4_module_get_type (module);
+ 
+   return TRUE;
+ }
+ 
+ GType
+ b_sitris4_module_get_type (GTypeModule * module)
+ {
+   if (!b_type_sitris4_module)
+     {
+       static const GTypeInfo sitris4_module_info = {
+ 	sizeof (BSitris4ModuleClass),
+ 	NULL,			/* base_init */
+ 	NULL,			/* base_finalize */
+ 	(GClassInitFunc) b_sitris4_module_class_init,
+ 	NULL,			/* class_finalize */
+ 	NULL,			/* class_data */
+ 	sizeof (BSitris4Module),
+ 	0,			/* n_preallocs */
+ 	(GInstanceInitFunc) b_sitris4_module_init,
+       };
+ 
+       /* !!!!!!!!! The name given in the next function MUST be unique! */
+ 
+       b_type_sitris4_module = g_type_module_register_type (module,
+ 							    B_TYPE_MODULE,
+ 							    "BSitris4",
+ 							    &sitris4_module_info,
+ 							    0);
+     }
+ 
+   return b_type_sitris4_module;
+ }
+ 
+ /* stones (always 4 lines with same stone in different rotation angles) */
+ typedef struct sBSitris4StonePos
+ {
+   gint X, Y;
+ } stBSitris4StonePos;
+ typedef struct sBSitris4StoneRot
+ {
+   stBSitris4StonePos Pos[4];
+ } stBSitris4StoneRot;
+ typedef struct sBSitris4Stone
+ {
+   stBSitris4StoneRot Rot[4];
+ } stBSitris4Stone;
+ stBSitris4Stone BSitris4StoneTable[] =
+ {
+   { { { { { -2,  0 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } }, /* the I */
+       { { {  0, -2 }, {  0, -1 }, {  0,  0 }, {  0,  1 } } },
+       { { { -2,  0 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } },
+       { { {  0, -2 }, {  0, -1 }, {  0,  0 }, {  0,  1 } } } } },
+   { { { { {  1, -1 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } }, /* the L */
+       { { {  0, -1 }, {  0,  0 }, {  0,  1 }, {  1,  1 } } },
+       { { { -1,  0 }, {  0,  0 }, {  1,  0 }, { -1,  1 } } },
+       { { { -1, -1 }, {  0, -1 }, {  0,  0 }, {  0,  1 } } } } },
+   { { { { { -1, -1 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } }, /* the J */
+       { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  0,  1 } } },
+       { { { -1,  0 }, {  0,  0 }, {  1,  0 }, {  1,  1 } } },
+       { { {  0, -1 }, {  0,  0 }, { -1,  1 }, {  0,  1 } } } } },
+   { { { { {  0, -1 }, { -1,  0 }, {  0,  0 }, {  0,  1 } } }, /* the T */
+       { { {  0, -1 }, { -1,  0 }, {  0,  0 }, {  1,  0 } } },
+       { { {  0, -1 }, {  0,  0 }, {  1,  0 }, {  0,  1 } } },
+       { { { -1,  0 }, {  0,  0 }, {  1,  0 }, {  0,  1 } } } } },
+   { { { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } }, /* the block */
+       { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } },
+       { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } },
+       { { {  0, -1 }, {  1, -1 }, {  0,  0 }, {  1,  0 } } } } },
+   { { { { {  0, -1 }, { -1,  0 }, {  0,  0 }, { -1,  1 } } }, /* the Z */
+       { { { -1, -1 }, {  0, -1 }, {  0,  0 }, {  1,  0 } } },
+       { { {  0, -1 }, { -1,  0 }, {  0,  0 }, { -1,  1 } } },
+       { { { -1, -1 }, {  0, -1 }, {  0,  0 }, {  1,  0 } } } } },
+   { { { { { -1, -1 }, { -1,  0 }, {  0,  0 }, {  0,  1 } } }, /* the S */
+       { { {  0, -1 }, {  1, -1 }, { -1,  0 }, {  0,  0 } } },
+       { { { -1, -1 }, { -1,  0 }, {  0,  0 }, {  0,  1 } } },
+       { { {  0, -1 }, {  1, -1 }, { -1,  0 }, {  0,  0 } } } } },
+ };
+ 
+ /* check if a stone fits at a position */
+ /* retuns true if stone fits */
+ static gint
+ BSitris4CheckStone (BSitris4Module *pSitris4Module,
+                     gint Stone, gint PosX, gint PosY, gint Rot)
+ {
+   stBSitris4StoneRot * pStoneRot;
+   stBSitris4StonePos * pStonePos;
+   gint I, X, Y, SizeX, SizeY;
+ 
+   /* check if stone is available */
+   if (Stone < 0 || Stone >= count (BSitris4StoneTable))
+     return 0;
+ 
+   /* get size of stone array */
+   SizeX = pSitris4Module->LogSizeX + 4;
+   SizeY = pSitris4Module->LogSizeY;
+ 
+   /* get pointer to stone rotation */
+   pStoneRot = &BSitris4StoneTable[Stone]
+                .Rot[Rot & 3];
+ 
+   /* all 4 positions */
+   for (I = 0; I < 4; I++)
+   {
+     /* get position */
+     pStonePos = &pStoneRot->Pos[I];
+     /* get coordinates */
+     X = PosX + pStonePos->X;
+     Y = PosY + pStonePos->Y;
+     /* outside of array */
+     if (X < 0 || X >= SizeX || Y < 0 || Y >= SizeY)
+       return 0;
+     /* position not free */
+     if (pSitris4Module->ppStones[X][Y])
+       return 0;
+   }
+ 
+   /* stone fits */
+   return 1;
+ }
+ 
+ /* deactivate stone */
+ static void
+ BSitris4DeactivateStone (BSitris4Module *pSitris4Module)
+ {
+   stBSitris4StoneRot * pStoneRot;
+   stBSitris4StonePos * pStonePos;
+   gint I, X, Y, SizeX, SizeY;
+ 
+   /* check if stone is available */
+   if (pSitris4Module->CurStone < 0
+       || pSitris4Module->CurStone >= count (BSitris4StoneTable))
+     return;
+ 
+   /* get size of stone array */
+   SizeX = pSitris4Module->LogSizeX + 4;
+   SizeY = pSitris4Module->LogSizeY;
+ 
+   /* get pointer to stone rotation */
+   pStoneRot = &BSitris4StoneTable[pSitris4Module->CurStone]
+                .Rot[pSitris4Module->CurRot & 3];
+ 
+   /* all 4 positions */
+   for (I = 0; I < 4; I++)
+   {
+     /* get position */
+     pStonePos = &pStoneRot->Pos[I];
+     /* get coordinates */
+     X = pSitris4Module->CurX + pStonePos->X;
+     Y = pSitris4Module->CurY + pStonePos->Y;
+     /* put stone into stone array */
+     if (X >= 0 && X < SizeX && Y >= 0 && Y < SizeY)
+       pSitris4Module->ppStones[X][Y] = 1;
+   }
+ }
+ 
+ /* draw active stone */
+ static void
+ BSitris4DrawStone (BSitris4Module *pSitris4Module)
+ {
+   stBSitris4StoneRot * pStoneRot;
+   stBSitris4StonePos * pStonePos;
+   gint I, X, Y, CenterX, LogSizeX, LogSizeY;
+ 
+   /* check if stone is available */
+   if (pSitris4Module->CurStone < 0
+       || pSitris4Module->CurStone >= count (BSitris4StoneTable))
+     return;
+ 
+   /* get center of display */
+   CenterX = pSitris4Module->CenterX;
+   /* get logical size of display */
+   LogSizeX = pSitris4Module->LogSizeX;
+   LogSizeY = pSitris4Module->LogSizeY;
+ 
+   /* get pointer to stone rotation */
+   pStoneRot = &BSitris4StoneTable[pSitris4Module->CurStone]
+                .Rot[pSitris4Module->CurRot & 3];
+ 
+   /* all 4 positions */
+   for (I = 0; I < 4; I++)
+   {
+     /* get position */
+     pStonePos = &pStoneRot->Pos[I];
+     /* get coordinates */
+     X = pSitris4Module->CurX + pStonePos->X;
+     Y = pSitris4Module->CurY + pStonePos->Y;
+     /* draw position */
+     /* - game field is mirrored at center */
+     /* - every field is two pixels wide */
+     if (X >= 0 && X < LogSizeX && Y >= 0 && Y < LogSizeY)  {
+       gint Color = BSitris4ColorActiveStone (pSitris4Module->MaxColor);
+       b_module_draw_point ((BModule *) pSitris4Module,
+                            CenterX - 2 * X - 2, Y,
+                            Color);
+       b_module_draw_point ((BModule *) pSitris4Module,
+                            CenterX - 2 * X - 1, Y,
+                            Color);
+       b_module_draw_point ((BModule *) pSitris4Module,
+                            CenterX + 2 * X, Y,
+                            Color);
+       b_module_draw_point ((BModule *) pSitris4Module,
+                            CenterX + 2 * X + 1, Y,
+                            Color);
+     }
+   }
+ }
+ 
+ /* output current picture */
+ static void
+ BSitris4Output (BSitris4Module *pSitris4Module)
+ {
+   gint CenterX, X, Y;
+ 
+   CenterX = pSitris4Module->CenterX;
+ 
+   /* empty the screen */
+   b_module_fill ((BModule *) pSitris4Module,
+ 		 BSitris4ColorEmpty (pSitris4Module->MaxColor));
+ 
+   /* draw stones */
+   for (X = 0; X < pSitris4Module->LogSizeX; X++)
+   {
+     for (Y = 0; Y < pSitris4Module->LogSizeY; Y++)
+     {
+       if (pSitris4Module->ppStones[X][Y])
+       {
+         gint Color = X == pSitris4Module->RemoveCol
+                   ? BSitris4ColorRemoveStone (pSitris4Module->MaxColor)
+                   : BSitris4ColorStone (pSitris4Module->MaxColor);
+         b_module_draw_point ((BModule *) pSitris4Module,
+                                CenterX - 2 * X - 2, Y,
+                                Color);
+         b_module_draw_point ((BModule *) pSitris4Module,
+                                CenterX - 2 * X - 1, Y,
+                                Color);
+         b_module_draw_point ((BModule *) pSitris4Module,
+                                CenterX + 2 * X, Y,
+                                Color);
+         b_module_draw_point ((BModule *) pSitris4Module,
+                                CenterX + 2 * X + 1, Y,
+                                Color);
+       }
+     }
+   }
+ 
+   /* draw active stone */
+   BSitris4DrawStone (pSitris4Module);
+ 
+   /* update screen */
+   b_module_paint ((BModule *) pSitris4Module);
+ }
+ 
+ /* start a new game */
+ static void
+ BSitris4NewGame (BSitris4Module *pSitris4Module)
+ {
+   gint X, Y;
+ 
+   /* set speed to minimal */
+   pSitris4Module->Speed = BSitris4SpeedMin;
+ 
+   /* remove all stones */
+   for (X = 0; X < pSitris4Module->LogSizeX + 4; X++)
+     for (Y = 0; Y < pSitris4Module->LogSizeY; Y++)
+       pSitris4Module->ppStones[X][Y] = 0;
+ 
+   /* no current stone yet */
+   pSitris4Module->CurStone = -1;
+   /* no column ist being removed */
+   pSitris4Module->RemoveCol = -1;
+   /* no stone is being dropped */
+   pSitris4Module->Dropping = 0;
+ 
+   dbg_print ("BSitris4: new game\n");
+ 
+   /* output current picture */
+   BSitris4Output (pSitris4Module);
+ }
+ 
+ /* key-procedure */
+ static void
+ BSitris4Key (BSitris4Module *pSitris4Module,
+             BModuleKey     Key)
+ {
+   switch (Key)
+   {
+     /* move stone up */
+     case B_KEY_2:
+       if (BSitris4CheckStone (pSitris4Module,
+                              pSitris4Module->CurStone,
+                              pSitris4Module->CurX,
+                              pSitris4Module->CurY - 1,
+                              pSitris4Module->CurRot))
+       {
+         pSitris4Module->CurY--;
+         BSitris4Output (pSitris4Module);
+       }
+       break;
+ 
+     /* rotate stone */
+     case B_KEY_3:
+     case B_KEY_6:
+       if (BSitris4CheckStone (pSitris4Module,
+                              pSitris4Module->CurStone,
+                              pSitris4Module->CurX,
+                              pSitris4Module->CurY,
+                              (pSitris4Module->CurRot + 1) & 3))
+       {
+         pSitris4Module->CurRot = (pSitris4Module->CurRot + 1) & 3;
+         BSitris4Output (pSitris4Module);
+       }
+       break;
+ 
+     /* drop stone */
+     case B_KEY_4:
+       pSitris4Module->Dropping = 1;                       /* set flag for dropping stone */
+       b_module_ticker_stop  ((BModule *) pSitris4Module); /* restart the tick machinery */
+       b_module_ticker_start ((BModule *) pSitris4Module, BSitris4SpeedDrop);
+       break;
+ 
+     /* move stone down */
+     case B_KEY_8:
+       if (BSitris4CheckStone (pSitris4Module,
+                              pSitris4Module->CurStone,
+                              pSitris4Module->CurX,
+                              pSitris4Module->CurY + 1,
+                              pSitris4Module->CurRot))
+       {
+         pSitris4Module->CurY++;
+         BSitris4Output (pSitris4Module);
+       }
+       break;
+ 
+     /* rotate stone in other direction */
+     case B_KEY_9:
+       if (BSitris4CheckStone (pSitris4Module,
+                              pSitris4Module->CurStone,
+                              pSitris4Module->CurX,
+                              pSitris4Module->CurY,
+                              (pSitris4Module->CurRot + 3) & 3))
+       {
+         pSitris4Module->CurRot = (pSitris4Module->CurRot + 3) & 3;
+         BSitris4Output (pSitris4Module);
+       }
+       break;
+ 
+     default:
+       break;
+   }
+ }
+ 
+ /* tick-procedure */
+ /* returns 1 if game over or 0 if game not over */
+ static gint
+ BSitris4Tick (BSitris4Module *pSitris4Module)
+ {
+   gint X, Y;
+ 
+   /* dropping a stone */
+   if (pSitris4Module->Dropping)
+   {
+     /* move stone one down */
+     if (BSitris4CheckStone (pSitris4Module,
+                            pSitris4Module->CurStone,
+                            pSitris4Module->CurX - 1,
+                            pSitris4Module->CurY,
+                            pSitris4Module->CurRot))
+       pSitris4Module->CurX--;
+     /* stone has hit ground */
+     else
+       /* stop dropping stone */
+       pSitris4Module->Dropping = 0;
+   } /* dropping a stone */
+ 
+   /* not dropping a stone */
+   else
+   {
+     /* stone active */
+     if (pSitris4Module->CurStone >= 0)
+     {
+       /* move stone one down */
+       if (BSitris4CheckStone (pSitris4Module,
+                              pSitris4Module->CurStone,
+                              pSitris4Module->CurX - 1,
+                              pSitris4Module->CurY,
+                              pSitris4Module->CurRot))
+         pSitris4Module->CurX--;
+       /* stone has hit ground */
+       else
+       {
+         BSitris4DeactivateStone (pSitris4Module); /* deactivate stone */
+         pSitris4Module->CurStone = -1;            /* no current stone */
+         dbg_print ("BSitris4: stone hit ground\n");
+       }
+     } /* stone active */
+ 
+     /* no active stone */
+     else
+     {
+       /* column is being removed */
+       if (pSitris4Module->RemoveCol >= 0)
+       {
+         /* remove the column */
+         for (X = pSitris4Module->RemoveCol; X < pSitris4Module->LogSizeX + 4 - 1; X++)
+           for (Y = 0; Y < pSitris4Module->LogSizeY; Y++)
+             pSitris4Module->ppStones[X][Y] = pSitris4Module->ppStones[X + 1][Y];
+         dbg_print ("BSitris4: column %d removed\n", pSitris4Module->RemoveCol);
+         pSitris4Module->RemoveCol = -1; /* no column is being removed */
+ 	/* increase speed */
+         pSitris4Module->Speed = (pSitris4Module->Speed * (BSitris4SpeedInc - 1)
+                                  + BSitris4SpeedMax) / BSitris4SpeedInc;
+       } /* column is being removed */
+ 
+       /* no column is being removed */
+       else
+       {
+         /* check for a column to remove */
+         for (X = 0; X < pSitris4Module->LogSizeX + 4; X++)
+         {
+           for (Y = 0; Y < pSitris4Module->LogSizeY; Y++)
+             if (! pSitris4Module->ppStones[X][Y])
+               break;
+           if (Y >= pSitris4Module->LogSizeY) /* column is full */
+             break;
+         }
+ 
+         /* found a column to remove */
+         if (X < pSitris4Module->LogSizeX + 4)
+         {
+           pSitris4Module->RemoveCol = X;
+           dbg_print ("BSitris4: column %d is full\n", pSitris4Module->RemoveCol);
+         }
+ 
+         /* found no column to remove */
+         else
+         {
+           /* check game over */
+           for (X = pSitris4Module->LogSizeX; X < pSitris4Module->LogSizeX + 4; X++)
+             for (Y = 0; Y < pSitris4Module->LogSizeY; Y++)
+               if (pSitris4Module->ppStones[X][Y])
+                 /* found inactive stone right of display - game over */
+                 return 1;
+ 
+           /* create new stone */
+           pSitris4Module->CurStone = rand () % count (BSitris4StoneTable);
+           pSitris4Module->CurX = pSitris4Module->LogSizeX + 2;
+           pSitris4Module->CurY = pSitris4Module->LogSizeY / 2;
+           pSitris4Module->CurRot = rand () & 3;
+           dbg_print ("BSitris4: created new stone\n");
+         } /* found no column to remove */
+       } /* no column is being removed */
+     } /* no active stone */
+   } /* not dropping a stone */
+ 
+   /* output new picture */
+   BSitris4Output (pSitris4Module);
+ 
+   /* return game not over */
+   return 0;
+ }
+ 
+ static void
+ b_sitris4_module_class_init (BSitris4ModuleClass *klass)
+ {
+   BModuleClass *module_class;
+ 
+   module_class = B_MODULE_CLASS (klass);
+ 
+   module_class->query    = b_sitris4_module_query;
+   module_class->prepare  = b_sitris4_module_prepare;
+   module_class->relax    = b_sitris4_module_relax;
+   module_class->start    = b_sitris4_module_start;
+   module_class->event    = b_sitris4_module_event;
+   module_class->tick     = b_sitris4_module_tick;
+   module_class->describe = b_sitris4_module_describe;
+ }
+ 
+ static void
+ b_sitris4_module_init (BSitris4Module *sitris4_module)
+ {
+ }
+ 
+ static gboolean
+ b_sitris4_module_query (gint width,
+                          gint height,
+                          gint channels,
+                          gint maxval)
+ {
+   return (width >= BSitris4SizeXMin && height >= BSitris4SizeYMin
+ 	  && channels == 1 && maxval >= BSitris4MaxColorMin);
+ }
+ 
+ static gboolean
+ b_sitris4_module_prepare (BModule  *module,
+                            GError  **error)
+ {
+   gint SizePtrs, SizeCol, Size, X;
+   gchar *Ptr;
+ 
+   BSitris4Module *pSitris4_module = B_SITRIS4_MODULE (module);
+ 
+   /* initialize the module values that depend on the output device */
+   pSitris4_module->RealSizeX = module->width; /* size of game field */
+   pSitris4_module->RealSizeY = module->height;
+   pSitris4_module->CenterX = pSitris4_module->RealSizeX / 2;
+   pSitris4_module->LogSizeX = pSitris4_module->RealSizeX / 4;
+   pSitris4_module->LogSizeY = pSitris4_module->RealSizeY;
+   pSitris4_module->MaxColor = module->maxval; /* maximum color value */
+   pSitris4_module->PlayerId = -1; /* no plyer in game yet */
+ 
+   /* allocate needed memory */
+   SizePtrs = (pSitris4_module->LogSizeX + 4) * sizeof (int *); /* get needed size */
+   SizeCol = pSitris4_module->LogSizeY * sizeof (int);
+   Size = SizePtrs + (pSitris4_module->LogSizeX + 4) * SizeCol;
+   Ptr = g_new (gchar, Size);
+ 
+   pSitris4_module->ppStones = (int * *)Ptr; /* remember pointer */
+   for (X = 0, Ptr += SizePtrs; /* generate pointers to columns */
+        X < pSitris4_module->LogSizeX + 4;
+        X++, Ptr += SizeCol)
+     pSitris4_module->ppStones[X] = (int *)Ptr;
+ 
+   return TRUE;
+ }
+ 
+ static void
+ b_sitris4_module_relax (BModule  *module)
+ {
+   BSitris4Module *pSitris4_module = B_SITRIS4_MODULE (module);
+ 
+   g_free (pSitris4_module->ppStones);
+   pSitris4_module->ppStones = NULL;
+ }
+ 
+ static void
+ b_sitris4_module_start (BModule *module)
+ {
+   /* start new game */
+   BSitris4NewGame ((BSitris4Module *) module);
+ 
+   /* start the tick machinery */
+   b_module_ticker_start (module, BSitris4SpeedMin);
+ }
+ 
+ static void
+ b_sitris4_module_event (BModule      *module,
+                        BModuleEvent *event)
+ {
+   BSitris4Module *sitris4 = B_SITRIS4_MODULE (module);
+ 
+   switch (event->type)
+     {
+     case B_EVENT_TYPE_KEY:
+       BSitris4Key (sitris4, event->key);
+       break;
+ 
+     case B_EVENT_TYPE_PLAYER_ENTERED:
+      if (sitris4->PlayerId == -1)
+        {
+          sitris4->PlayerId = event->device_id;
+          module->num_players++;
+        }
+       break;
+ 
+     case B_EVENT_TYPE_PLAYER_LEFT:
+       if (sitris4->PlayerId == event->device_id)
+         {
+           sitris4->PlayerId = -1;
+           module->num_players--;
+         }
+       break;
+ 
+     default:
+       break;
+     }
+ }
+ 
+ static gint
+ b_sitris4_module_tick (BModule *module)
+ {
+   gint GameOver;
+ 
+   /* call tick-procedure */
+   GameOver = BSitris4Tick ((BSitris4Module *) module);
+ 
+   /* game over */
+   if (GameOver)
+   {
+     dbg_print ("BSitris4: requesting stop\n");
+     /* clear screen */
+     b_module_fill (module, 0);
+     b_module_paint (module);
+     /* request end of game */
+     b_module_request_stop (module);
+     /* we do not want to be called again */
+     return 0;
+   }
+ 
+   /* dropping a stone at the moment */
+   if (((BSitris4Module *) module)->Dropping)
+     /* we want to be called again in very few milliseconds */
+     return BSitris4SpeedDrop;
+ 
+   /* we want to be called again in some milliseconds */
+   return ((BSitris4Module *) module)->Speed;
+ }
+ 
+ static void
+ b_sitris4_module_describe (BModule      *module,
+                           const gchar **title,
+                           const gchar **description,
+                           const gchar **author)
+ {
+   *title       = "BSitris4";
+   *description = "Tetris game from the sides to the middle";
+   *author      = "1stein";
+ }
+ 
diff -r -C 3 -N blib-1.1.7/modules/bsnake.c blib-1.1.7-ba20070811/modules/bsnake.c
*** blib-1.1.7/modules/bsnake.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bsnake.c	Sat Aug 11 22:18:43 2007
***************
*** 35,58 ****
  #define BSnakeVerRev 2
  #define BSnakeVerTxt "1.1.2"
  
! //minimum size and color count of display
  #define BSnakeSizeXMin 18
  #define BSnakeSizeYMin 8
  #define BSnakeMaxColorMin 1
! //initial and maximum length of the snake
! #define BSnakeLenIni( Width, Height ) 3
! #define BSnakeLenMax( Width, Height ) ((Width) + (Height) + 3)
! //time snake is dead after chrashing before game ends
  #define BSnakeDeadTime 10
  #define BSnakeLives 3
! //initial and maximum speed of game (high number = slow)
  #define BSnakeSpeedIni 500
  #define BSnakeSpeedMax 100
! //the colors
! #define BSnakeColorEmpty( MaxColor ) (0)
! #define BSnakeColorSnakeHead( MaxColor ) (MaxColor)
! #define BSnakeColorSnakeBody( MaxColor ) ((MaxColor) * 2 / 3)
! #define BSnakeColorMouse( MaxColor ) ((MaxColor) * 3 / 4)
  
  #ifdef SNAKE_DEBUG
  #define dbg_print g_print
--- 35,58 ----
  #define BSnakeVerRev 2
  #define BSnakeVerTxt "1.1.2"
  
! /* minimum size and color count of display */
  #define BSnakeSizeXMin 18
  #define BSnakeSizeYMin 8
  #define BSnakeMaxColorMin 1
! /* initial and maximum length of the snake */
! #define BSnakeLenIni(Width, Height) 3
! #define BSnakeLenMax(Width, Height) ((Width) + (Height) + 3)
! /* time snake is dead after chrashing before game ends */
  #define BSnakeDeadTime 10
  #define BSnakeLives 3
! /* initial and maximum speed of game (high number = slow) */
  #define BSnakeSpeedIni 500
  #define BSnakeSpeedMax 100
! /* the colors */
! #define BSnakeColorEmpty(MaxColor)     (0)
! #define BSnakeColorSnakeHead(MaxColor) (MaxColor)
! #define BSnakeColorSnakeBody(MaxColor) ((MaxColor) * 2 / 3)
! #define BSnakeColorMouse(MaxColor)     ((MaxColor) * 3 / 4)
  
  #ifdef SNAKE_DEBUG
  #define dbg_print g_print
***************
*** 70,95 ****
  
  typedef struct sBSnakePoint
  {
!   int X, Y;
  } stBSnakePoint;
  
  struct _BSnakeModule
  {
    BModule parent_instance;
  
!   int MaxColor;               //maximum color value
!   stBSnakePoint Size;         //size of game-field
!   int SnakeLenIni;            //initial size of the snake
!   int SnakeLenMax;            //maximum size of the snake
!   int PlayerId;               //device id of the player
!   int SnakeLen;               //current length of the snake
!   stBSnakePoint * pSnake;     //array with fields of the snake (index 0 is head)
!   stBSnakePoint SnakeDir;     //current direction of snake head
!   stBSnakePoint SnakeLastDir; //direction of the last step made by the snake
!   stBSnakePoint Mouse;        //position of the current mouse to eat ({-1,-1} if no mouse)
!   int Speed;                  //current speed of game
!   int DeadCnt;                //if > 0: snake has been dead for DeadCnt ticks
!   int Lives;                  // number of lives left
  };
  
  struct _BSnakeModuleClass
--- 70,95 ----
  
  typedef struct sBSnakePoint
  {
!   gint X, Y;
  } stBSnakePoint;
  
  struct _BSnakeModule
  {
    BModule parent_instance;
  
!   gint MaxColor;              /* maximum color value */
!   stBSnakePoint Size;         /* size of game-field */
!   gint SnakeLenIni;           /* initial size of the snake */
!   gint SnakeLenMax;           /* maximum size of the snake */
!   gint PlayerId;              /* device id of the player */
!   gint SnakeLen;              /* current length of the snake */
!   stBSnakePoint * pSnake;     /* array with fields of the snake (index 0 is head) */
!   stBSnakePoint SnakeDir;     /* current direction of snake head */
!   stBSnakePoint SnakeLastDir; /* direction of the last step made by the snake */
!   stBSnakePoint Mouse;        /* position of the current mouse to eat ({-1,-1} if no mouse) */
!   gint Speed;                 /* current speed of game */
!   gint DeadCnt;               /* if > 0: snake has been dead for DeadCnt ticks */
!   gint Lives;                 /* number of lives left */
  };
  
  struct _BSnakeModuleClass
***************
*** 157,170 ****
    return b_type_snake_module;
  }
  
! //check if two points are equal
! static int BSnakePointEqual( stBSnakePoint P1, stBSnakePoint P2 )
  {
    return P1.X == P2.X && P1.Y == P2.Y;
  }
  
! //check if two points are near to each other (euclidian distance < 2)
! static int BSnakePointNear( stBSnakePoint P1, stBSnakePoint P2 )
  {
    stBSnakePoint Delta;
    Delta.X = P2.X - P1.X;
--- 157,170 ----
    return b_type_snake_module;
  }
  
! /* check if two points are equal */
! static gint BSnakePointEqual (stBSnakePoint P1, stBSnakePoint P2)
  {
    return P1.X == P2.X && P1.Y == P2.Y;
  }
  
! /* check if two points are near to each other (euclidian distance < 2) */
! static gint BSnakePointNear (stBSnakePoint P1, stBSnakePoint P2)
  {
    stBSnakePoint Delta;
    Delta.X = P2.X - P1.X;
***************
*** 172,319 ****
    return Delta.X >= -1 && Delta.X <= 1 && Delta.Y >= -1 && Delta.Y <= 1;
  }
  
! //output current picture
! void
  BSnakeOutput (BSnakeModule *pSnakeModule)
  {
!   int Color, I;
  
!   //empty the screen
    b_module_fill ((BModule *) pSnakeModule,
                   BSnakeColorEmpty (pSnakeModule->MaxColor));
  
!   //output nothing if not almost end of game
!   if( pSnakeModule->DeadCnt < BSnakeDeadTime )
    {
!     //let snake blink when dead
!     if( (pSnakeModule->DeadCnt & 1) == 0 )
      {
!       //draw snake
!       if( pSnakeModule->pSnake[0].X >= 0 //snake head
         && pSnakeModule->pSnake[0].X < pSnakeModule->Size.X
         && pSnakeModule->pSnake[0].Y >= 0
!        && pSnakeModule->pSnake[0].Y < pSnakeModule->Size.Y )
          b_module_draw_point ((BModule *) pSnakeModule,
                               pSnakeModule->pSnake[0].X,
                               pSnakeModule->pSnake[0].Y,
                               BSnakeColorSnakeHead (pSnakeModule->MaxColor));
!       Color = BSnakeColorSnakeBody (pSnakeModule->MaxColor); //snake body
!       for( I = 1; I < pSnakeModule->SnakeLen; I++ )
!         if( pSnakeModule->pSnake[I].X >= 0
           && pSnakeModule->pSnake[I].X < pSnakeModule->Size.X
           && pSnakeModule->pSnake[I].Y >= 0
!          && pSnakeModule->pSnake[I].Y < pSnakeModule->Size.Y )
              b_module_draw_point ((BModule *) pSnakeModule,
                                   pSnakeModule->pSnake[I].X,
                                   pSnakeModule->pSnake[I].Y,
                                   Color);
      }
  
!     //draw mouse
!     if( pSnakeModule->Mouse.X >= 0
       && pSnakeModule->Mouse.X < pSnakeModule->Size.X
       && pSnakeModule->Mouse.Y >= 0
!      && pSnakeModule->Mouse.Y < pSnakeModule->Size.Y )
        b_module_draw_point ((BModule *) pSnakeModule,
                             pSnakeModule->Mouse.X,
                             pSnakeModule->Mouse.Y,
                             BSnakeColorMouse (pSnakeModule->MaxColor));
    }
  
!   //update screen
    b_module_paint ((BModule *) pSnakeModule);
  }
  
! //start a new game
! void
  BSnakeNewGame (BSnakeModule *pSnakeModule)
  {
!   int I;
  
!   //initialize snake
!   pSnakeModule->SnakeLen = pSnakeModule->SnakeLenIni; //length of snake to initial size
!   switch( rand( ) % 4 ) //place snake head and set direction
    {
!     case 0: //snake comes from top
        pSnakeModule->SnakeDir.X = 0;
        pSnakeModule->SnakeDir.Y = 1;
!       pSnakeModule->pSnake[0].X = rand( ) % pSnakeModule->Size.X;
        pSnakeModule->pSnake[0].Y = 0;
        break;
!     case 1: //snake comes from left
        pSnakeModule->SnakeDir.X = 1;
        pSnakeModule->SnakeDir.Y = 0;
        pSnakeModule->pSnake[0].X = 0;
!       pSnakeModule->pSnake[0].Y = rand( ) % pSnakeModule->Size.Y;
        break;
!     case 2: //snake comes from right
        pSnakeModule->SnakeDir.X = -1;
        pSnakeModule->SnakeDir.Y = 0;
        pSnakeModule->pSnake[0].X = pSnakeModule->Size.X - 1;
!       pSnakeModule->pSnake[0].Y = rand( ) % pSnakeModule->Size.Y;
        break;
!     case 3: //snake comes from bottom
        pSnakeModule->SnakeDir.X = 0;
        pSnakeModule->SnakeDir.Y = -1;
!       pSnakeModule->pSnake[0].X = rand( ) % pSnakeModule->Size.X;
        pSnakeModule->pSnake[0].Y = pSnakeModule->Size.Y - 1;
        break;
    }
!   for( I = 1; I < pSnakeModule->SnakeLen; I++ ) //initialize body of snake
    {
      pSnakeModule->pSnake[I].X = pSnakeModule->pSnake[I-1].X
                                - pSnakeModule->SnakeDir.X;
      pSnakeModule->pSnake[I].Y = pSnakeModule->pSnake[I-1].Y
                                - pSnakeModule->SnakeDir.Y;
    }
!   pSnakeModule->SnakeLastDir = pSnakeModule->SnakeDir; //last step was in same direction
  
!   //no mouse yet
    pSnakeModule->Mouse.X = -1;
    pSnakeModule->Mouse.Y = -1;
  
!   //set speed to initial value
    pSnakeModule->Speed = BSnakeSpeedIni;
  
!   //snake is alive
    pSnakeModule->DeadCnt = 0;
  
    dbg_print ("BSnake: new game\n");
  
!   //output current picture
    BSnakeOutput (pSnakeModule);
  }
  
! //key-procedure
  void
  BSnakeKey (BSnakeModule *pSnakeModule,
             BModuleKey    Key)
  {
    switch (Key)
    {
!     case B_KEY_2: //set snake direction to up
!       if( pSnakeModule->SnakeLastDir.Y < 1 ) //not if last step was down
        {
          pSnakeModule->SnakeDir.X = 0;
          pSnakeModule->SnakeDir.Y = -1;
        }
        break;
!     case B_KEY_4: //set snake direction to left
!       if( pSnakeModule->SnakeLastDir.X < 1 ) //not if last step was right
        {
          pSnakeModule->SnakeDir.X = -1;
          pSnakeModule->SnakeDir.Y = 0;
        }
        break;
!     case B_KEY_6: //set snake direction to right
!       if( pSnakeModule->SnakeLastDir.X > -1 ) //not if last step was left
        {
          pSnakeModule->SnakeDir.X = 1;
          pSnakeModule->SnakeDir.Y = 0;
        }
        break;
!     case B_KEY_8: //set snake direction to down
!       if( pSnakeModule->SnakeLastDir.Y > -1 ) //not if last step was up
        {
          pSnakeModule->SnakeDir.X = 0;
          pSnakeModule->SnakeDir.Y = 1;
--- 172,319 ----
    return Delta.X >= -1 && Delta.X <= 1 && Delta.Y >= -1 && Delta.Y <= 1;
  }
  
! /* output current picture */
! static void
  BSnakeOutput (BSnakeModule *pSnakeModule)
  {
!   gint Color, I;
  
!   /* empty the screen */
    b_module_fill ((BModule *) pSnakeModule,
                   BSnakeColorEmpty (pSnakeModule->MaxColor));
  
!   /* output nothing if not almost end of game */
!   if (pSnakeModule->DeadCnt < BSnakeDeadTime)
    {
!     /* let snake blink when dead */
!     if ((pSnakeModule->DeadCnt & 1) == 0)
      {
!       /* draw snake */
!       if (pSnakeModule->pSnake[0].X >= 0 /* snake head */
         && pSnakeModule->pSnake[0].X < pSnakeModule->Size.X
         && pSnakeModule->pSnake[0].Y >= 0
!        && pSnakeModule->pSnake[0].Y < pSnakeModule->Size.Y)
          b_module_draw_point ((BModule *) pSnakeModule,
                               pSnakeModule->pSnake[0].X,
                               pSnakeModule->pSnake[0].Y,
                               BSnakeColorSnakeHead (pSnakeModule->MaxColor));
!       Color = BSnakeColorSnakeBody (pSnakeModule->MaxColor); /* snake body */
!       for (I = 1; I < pSnakeModule->SnakeLen; I++)
!         if (pSnakeModule->pSnake[I].X >= 0
           && pSnakeModule->pSnake[I].X < pSnakeModule->Size.X
           && pSnakeModule->pSnake[I].Y >= 0
!          && pSnakeModule->pSnake[I].Y < pSnakeModule->Size.Y)
              b_module_draw_point ((BModule *) pSnakeModule,
                                   pSnakeModule->pSnake[I].X,
                                   pSnakeModule->pSnake[I].Y,
                                   Color);
      }
  
!     /* draw mouse */
!     if (pSnakeModule->Mouse.X >= 0
       && pSnakeModule->Mouse.X < pSnakeModule->Size.X
       && pSnakeModule->Mouse.Y >= 0
!      && pSnakeModule->Mouse.Y < pSnakeModule->Size.Y)
        b_module_draw_point ((BModule *) pSnakeModule,
                             pSnakeModule->Mouse.X,
                             pSnakeModule->Mouse.Y,
                             BSnakeColorMouse (pSnakeModule->MaxColor));
    }
  
!   /* update screen */
    b_module_paint ((BModule *) pSnakeModule);
  }
  
! /* start a new game */
! static void
  BSnakeNewGame (BSnakeModule *pSnakeModule)
  {
!   gint I;
  
!   /* initialize snake */
!   pSnakeModule->SnakeLen = pSnakeModule->SnakeLenIni; /* length of snake to initial size */
!   switch (rand () % 4)  /* place snake head and set direction */
    {
!     case 0: /* snake comes from top */
        pSnakeModule->SnakeDir.X = 0;
        pSnakeModule->SnakeDir.Y = 1;
!       pSnakeModule->pSnake[0].X = rand () % pSnakeModule->Size.X;
        pSnakeModule->pSnake[0].Y = 0;
        break;
!     case 1: /* snake comes from left */
        pSnakeModule->SnakeDir.X = 1;
        pSnakeModule->SnakeDir.Y = 0;
        pSnakeModule->pSnake[0].X = 0;
!       pSnakeModule->pSnake[0].Y = rand () % pSnakeModule->Size.Y;
        break;
!     case 2: /* snake comes from right */
        pSnakeModule->SnakeDir.X = -1;
        pSnakeModule->SnakeDir.Y = 0;
        pSnakeModule->pSnake[0].X = pSnakeModule->Size.X - 1;
!       pSnakeModule->pSnake[0].Y = rand () % pSnakeModule->Size.Y;
        break;
!     case 3: /* snake comes from bottom */
        pSnakeModule->SnakeDir.X = 0;
        pSnakeModule->SnakeDir.Y = -1;
!       pSnakeModule->pSnake[0].X = rand () % pSnakeModule->Size.X;
        pSnakeModule->pSnake[0].Y = pSnakeModule->Size.Y - 1;
        break;
    }
!   for (I = 1; I < pSnakeModule->SnakeLen; I++)  /* initialize body of snake */
    {
      pSnakeModule->pSnake[I].X = pSnakeModule->pSnake[I-1].X
                                - pSnakeModule->SnakeDir.X;
      pSnakeModule->pSnake[I].Y = pSnakeModule->pSnake[I-1].Y
                                - pSnakeModule->SnakeDir.Y;
    }
!   pSnakeModule->SnakeLastDir = pSnakeModule->SnakeDir; /* last step was in same direction */
  
!   /* no mouse yet */
    pSnakeModule->Mouse.X = -1;
    pSnakeModule->Mouse.Y = -1;
  
!   /* set speed to initial value */
    pSnakeModule->Speed = BSnakeSpeedIni;
  
!   /* snake is alive */
    pSnakeModule->DeadCnt = 0;
  
    dbg_print ("BSnake: new game\n");
  
!   /* output current picture */
    BSnakeOutput (pSnakeModule);
  }
  
! /* key-procedure */
  void
  BSnakeKey (BSnakeModule *pSnakeModule,
             BModuleKey    Key)
  {
    switch (Key)
    {
!     case B_KEY_2: /* set snake direction to up */
!       if (pSnakeModule->SnakeLastDir.Y < 1)  /* not if last step was down */
        {
          pSnakeModule->SnakeDir.X = 0;
          pSnakeModule->SnakeDir.Y = -1;
        }
        break;
!     case B_KEY_4: /* set snake direction to left */
!       if (pSnakeModule->SnakeLastDir.X < 1)  /* not if last step was right */
        {
          pSnakeModule->SnakeDir.X = -1;
          pSnakeModule->SnakeDir.Y = 0;
        }
        break;
!     case B_KEY_6: /* set snake direction to right */
!       if (pSnakeModule->SnakeLastDir.X > -1)  /* not if last step was left */
        {
          pSnakeModule->SnakeDir.X = 1;
          pSnakeModule->SnakeDir.Y = 0;
        }
        break;
!     case B_KEY_8: /* set snake direction to down */
!       if (pSnakeModule->SnakeLastDir.Y > -1)  /* not if last step was up */
        {
          pSnakeModule->SnakeDir.X = 0;
          pSnakeModule->SnakeDir.Y = 1;
***************
*** 324,441 ****
    }
  }
  
! //tick-procedure
! //returns TRUE if game over or FALSE if game not over
! gboolean
  BSnakeTick (BSnakeModule *pSnakeModule)
  {
    stBSnakePoint NewPos;
!   int I, Crash;
  
!   //snake is dead
!   if( pSnakeModule->DeadCnt > 0 )
    {
!     //track time snake is dead
      pSnakeModule->DeadCnt++;
  
!     //output current picture
      BSnakeOutput (pSnakeModule);
  
!     //return game over when snake was dead long enough
      return pSnakeModule->DeadCnt > BSnakeDeadTime;
    }
  
!   //get direction of snake head after next step
    NewPos.X = pSnakeModule->pSnake[0].X + pSnakeModule->SnakeDir.X;
    NewPos.Y = pSnakeModule->pSnake[0].Y + pSnakeModule->SnakeDir.Y;
  
!   //no mouse available
!   if( pSnakeModule->Mouse.X < 0 || pSnakeModule->Mouse.Y < 0 )
    {
!     //generate new mouse
!     pSnakeModule->Mouse.X = rand( ) % pSnakeModule->Size.X;
!     pSnakeModule->Mouse.Y = rand( ) % pSnakeModule->Size.Y;
! 
!     //check if new mouse position is valid
!     //(i.e. not exactly at snake position and not directly next to snake)
!     if( BSnakePointNear( pSnakeModule->Mouse, NewPos ) )
      {
!       //remove mouse
        pSnakeModule->Mouse.X = -1;
        pSnakeModule->Mouse.Y = -1;
      }
!     for( I = 0; I < pSnakeModule->SnakeLen; I++ )
      {
!       if( BSnakePointNear( pSnakeModule->Mouse, pSnakeModule->pSnake[I] ) )
        {
!         //remove mouse
          pSnakeModule->Mouse.X = -1;
          pSnakeModule->Mouse.Y = -1;
        }
      }
  
!     if( pSnakeModule->Mouse.X >= 0 && pSnakeModule->Mouse.Y >= 0 )
        dbg_print ("BSnake: new mouse\n");
    }
  
!   //snake eats mouse
!   if( pSnakeModule->Mouse.X >= 0
     && pSnakeModule->Mouse.Y >= 0
!    && BSnakePointEqual( NewPos, pSnakeModule->Mouse ) )
    {
!     //remove mouse
      pSnakeModule->Mouse.X = -1;
      pSnakeModule->Mouse.Y = -1;
  
!     //increase snake length
!     //(last field of snake body will be set when moving snake one step)
!     if( pSnakeModule->SnakeLen < pSnakeModule->SnakeLenMax )
        pSnakeModule->SnakeLen++;
  
!     //increase game speed if snake already has got maximum length
!     //(this formula will not increase the speed above maximum speed)
      else
        pSnakeModule->Speed = (3 * pSnakeModule->Speed + BSnakeSpeedMax) / 4;
  
      dbg_print ("BSnake: snake ate mouse\n");
    }
  
!   //check if snake crashes
    Crash = 0;
!   if( NewPos.X < 0 //snake crashes into wall
     || NewPos.Y < 0
     || NewPos.X >= pSnakeModule->Size.X
!    || NewPos.Y >= pSnakeModule->Size.Y )
      Crash = 1;
!   for( I = 0; I < pSnakeModule->SnakeLen - 1; I++ ) //snake crashes into its body
!     if( BSnakePointEqual( NewPos, pSnakeModule->pSnake[I] ) )
        Crash = 1;
  
!   //snake crashes
!   if( Crash )
    {
!     //mark Snake as dead
      pSnakeModule->DeadCnt = 1;
  
      dbg_print ("BSnake: snake crashed\n");
    }
  
! 
!   //snake does not crash
    else
    {
!     //move snake one step
!     for( I = pSnakeModule->SnakeLen; I > 0; I-- )
        pSnakeModule->pSnake[I] = pSnakeModule->pSnake[I-1];
      pSnakeModule->pSnake[0] = NewPos;
!     //remember direction of last step
      pSnakeModule->SnakeLastDir = pSnakeModule->SnakeDir;
    }
  
!   //output current picture
    BSnakeOutput (pSnakeModule);
  
!   //return game not over
    return FALSE;
  }
  
--- 324,440 ----
    }
  }
  
! /* tick-procedure */
! /* returns TRUE if game over or FALSE if game not over */
! static gboolean
  BSnakeTick (BSnakeModule *pSnakeModule)
  {
    stBSnakePoint NewPos;
!   gint I, Crash;
  
!   /* snake is dead */
!   if (pSnakeModule->DeadCnt > 0)
    {
!     /* track time snake is dead */
      pSnakeModule->DeadCnt++;
  
!     /* output current picture */
      BSnakeOutput (pSnakeModule);
  
!     /* return game over when snake was dead long enough */
      return pSnakeModule->DeadCnt > BSnakeDeadTime;
    }
  
!   /* get direction of snake head after next step */
    NewPos.X = pSnakeModule->pSnake[0].X + pSnakeModule->SnakeDir.X;
    NewPos.Y = pSnakeModule->pSnake[0].Y + pSnakeModule->SnakeDir.Y;
  
!   /* no mouse available */
!   if (pSnakeModule->Mouse.X < 0 || pSnakeModule->Mouse.Y < 0)
    {
!     /* generate new mouse */
!     pSnakeModule->Mouse.X = rand () % pSnakeModule->Size.X;
!     pSnakeModule->Mouse.Y = rand () % pSnakeModule->Size.Y;
! 
!     /* check if new mouse position is valid */
!     /* (i.e. not exactly at snake position and not directly next to snake) */
!     if (BSnakePointNear (pSnakeModule->Mouse, NewPos))
      {
!       /* remove mouse */
        pSnakeModule->Mouse.X = -1;
        pSnakeModule->Mouse.Y = -1;
      }
!     for (I = 0; I < pSnakeModule->SnakeLen; I++)
      {
!       if (BSnakePointNear (pSnakeModule->Mouse, pSnakeModule->pSnake[I]))
        {
!         /* remove mouse */
          pSnakeModule->Mouse.X = -1;
          pSnakeModule->Mouse.Y = -1;
        }
      }
  
!     if (pSnakeModule->Mouse.X >= 0 && pSnakeModule->Mouse.Y >= 0)
        dbg_print ("BSnake: new mouse\n");
    }
  
!   /* snake eats mouse */
!   if (pSnakeModule->Mouse.X >= 0
     && pSnakeModule->Mouse.Y >= 0
!    && BSnakePointEqual (NewPos, pSnakeModule->Mouse))
    {
!     /* remove mouse */
      pSnakeModule->Mouse.X = -1;
      pSnakeModule->Mouse.Y = -1;
  
!     /* increase snake length */
!     /* (last field of snake body will be set when moving snake one step) */
!     if (pSnakeModule->SnakeLen < pSnakeModule->SnakeLenMax)
        pSnakeModule->SnakeLen++;
  
!     /* increase game speed if snake already has got maximum length */
!     /* (this formula will not increase the speed above maximum speed) */
      else
        pSnakeModule->Speed = (3 * pSnakeModule->Speed + BSnakeSpeedMax) / 4;
  
      dbg_print ("BSnake: snake ate mouse\n");
    }
  
!   /* check if snake crashes */
    Crash = 0;
!   if (NewPos.X < 0 /* snake crashes into wall */
     || NewPos.Y < 0
     || NewPos.X >= pSnakeModule->Size.X
!    || NewPos.Y >= pSnakeModule->Size.Y)
      Crash = 1;
!   for (I = 0; I < pSnakeModule->SnakeLen - 1; I++)  /* snake crashes into its body */
!     if (BSnakePointEqual (NewPos, pSnakeModule->pSnake[I]))
        Crash = 1;
  
!   /* snake crashes */
!   if (Crash)
    {
!     /* mark Snake as dead */
      pSnakeModule->DeadCnt = 1;
  
      dbg_print ("BSnake: snake crashed\n");
    }
  
!   /* snake does not crash */
    else
    {
!     /* move snake one step */
!     for (I = pSnakeModule->SnakeLen; I > 0; I--)
        pSnakeModule->pSnake[I] = pSnakeModule->pSnake[I-1];
      pSnakeModule->pSnake[0] = NewPos;
!     /* remember direction of last step */
      pSnakeModule->SnakeLastDir = pSnakeModule->SnakeDir;
    }
  
!   /* output current picture */
    BSnakeOutput (pSnakeModule);
  
!   /* return game not over */
    return FALSE;
  }
  
***************
*** 476,488 ****
  {
    BSnakeModule *snake = B_SNAKE_MODULE (module);
  
!   //initialize the module values that depend on the output device
!   snake->MaxColor = module->maxval; //maximum color value
!   snake->Size.X = module->width; //size of game field
    snake->Size.Y = module->height;
!   snake->SnakeLenIni = BSnakeLenIni( module->width, module->height ); //initial size of the snake
!   snake->SnakeLenMax = BSnakeLenMax( module->width, module->height ); //initial size of the snake
!   snake->PlayerId = -1; //no player in game yet
  
    snake->pSnake = g_new (stBSnakePoint, snake->SnakeLenMax);
  
--- 475,487 ----
  {
    BSnakeModule *snake = B_SNAKE_MODULE (module);
  
!   /* initialize the module values that depend on the output device */
!   snake->MaxColor = module->maxval; /* maximum color value */
!   snake->Size.X = module->width; /* size of game field */
    snake->Size.Y = module->height;
!   snake->SnakeLenIni = BSnakeLenIni (module->width, module->height); /* initial size of the snake */
!   snake->SnakeLenMax = BSnakeLenMax (module->width, module->height); /* initial size of the snake */
!   snake->PlayerId = -1; /* no player in game yet */
  
    snake->pSnake = g_new (stBSnakePoint, snake->SnakeLenMax);
  
***************
*** 518,524 ****
    switch (event->type)
      {
      case B_EVENT_TYPE_KEY:
!       BSnakeKey (snake, event->key);
        break;
  
      case B_EVENT_TYPE_PLAYER_ENTERED:
--- 517,524 ----
    switch (event->type)
      {
      case B_EVENT_TYPE_KEY:
!       if (snake->PlayerId == event->device_id)
!         BSnakeKey (snake, event->key);
        break;
  
      case B_EVENT_TYPE_PLAYER_ENTERED:
***************
*** 550,567 ****
  
    GameOver = BSnakeTick (snake);
  
!   if( GameOver )
      {
        snake->Lives--;
!       if( snake->Lives <= 0 )
      {
!       b_module_request_stop (module); //request end
        return 0;
      }
        BSnakeNewGame (snake);
    }
  
!   //we want to be called again in some milliseconds, if game is not over
    return (snake->Speed);
  }
  
--- 550,567 ----
  
    GameOver = BSnakeTick (snake);
  
!   if (GameOver)
      {
        snake->Lives--;
!       if (snake->Lives <= 0)
      {
!       b_module_request_stop (module); /* request end */
        return 0;
      }
        BSnakeNewGame (snake);
    }
  
!   /* we want to be called again in some milliseconds, if game is not over */
    return (snake->Speed);
  }
  
diff -r -C 3 -N blib-1.1.7/modules/btetris.c blib-1.1.7-ba20070811/modules/btetris.c
*** blib-1.1.7/modules/btetris.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/btetris.c	Sat Aug 11 22:18:43 2007
***************
*** 34,40 ****
  #define FALL_SPEED     50
  #define BOTTOM_OFFSET  0   /* we used a value of 2 for Arcade/Paris */
  
! /*  #define TETRIS_DEBUG 1  */
  
  
  #define B_TYPE_TETRIS         (b_type_tetris)
--- 34,40 ----
  #define FALL_SPEED     50
  #define BOTTOM_OFFSET  0   /* we used a value of 2 for Arcade/Paris */
  
! #define TETRIS_DEBUG 1
  
  
  #define B_TYPE_TETRIS         (b_type_tetris)
***************
*** 260,266 ****
  {
    gint x, y, v;
    guchar *pixel;
!  
    for (y = 0; y < module->height; y++)
      for (v = 255; v >= 0; v -= 0xf)
        {
--- 260,266 ----
  {
    gint x, y, v;
    guchar *pixel;
! 
    for (y = 0; y < module->height; y++)
      for (v = 255; v >= 0; v -= 0xf)
        {
***************
*** 332,338 ****
    gchar   *tile_data;
    gint     x, y;
    gint     tile_width, tile_height;
!   
    tetris = B_TETRIS (module);
  
    memcpy (module->buffer, tetris->field, tetris->field_size);
--- 332,338 ----
    gchar   *tile_data;
    gint     x, y;
    gint     tile_width, tile_height;
!  
    tetris = B_TETRIS (module);
  
    memcpy (module->buffer, tetris->field, tetris->field_size);
***************
*** 352,358 ****
  	  {
  	    if (tile_data[y * 4 + x])
  	      {
! 		guchar *data = (module->buffer + 
  				module->width * (tetris->y + y) +
  				(tetris->x + x) * 2);
  		
--- 352,358 ----
  	  {
  	    if (tile_data[y * 4 + x])
  	      {
! 		guchar *data = (module->buffer +
  				module->width * (tetris->y + y) +
  				(tetris->x + x) * 2);
  		
***************
*** 361,367 ****
  	      }
  	  }
      }
!  
    b_module_paint (module);
  }
  
--- 361,367 ----
  	      }
  	  }
      }
! 
    b_module_paint (module);
  }
  
***************
*** 388,394 ****
    tile_height  = b_tetris_tile_height (tetris->tile, rotation);
    tile_leftoff = b_tetris_tile_left_offset (tetris->tile, rotation);
  
!   
    if (tetris->y + tile_height > module->height - BOTTOM_OFFSET)
      return;
  
--- 388,394 ----
    tile_height  = b_tetris_tile_height (tetris->tile, rotation);
    tile_leftoff = b_tetris_tile_left_offset (tetris->tile, rotation);
  
!  
    if (tetris->y + tile_height > module->height - BOTTOM_OFFSET)
      return;
  
***************
*** 467,473 ****
  	  }
  
  
!       /* check for completed rows */      
        for (y = module->height-BOTTOM_OFFSET-1; y > 0; y--)
  	{
  	  tetris->completed[y] = TRUE;
--- 467,473 ----
  	  }
  
  
!       /* check for completed rows */     
        for (y = module->height-BOTTOM_OFFSET-1; y > 0; y--)
  	{
  	  tetris->completed[y] = TRUE;
***************
*** 644,650 ****
  
    tetris->field_size = module->width * module->height;
    tetris->field      = g_new0 (guchar, tetris->field_size);
!   tetris->completed  = g_new0 (gboolean, module->width);
  
    return TRUE;
  }
--- 644,650 ----
  
    tetris->field_size = module->width * module->height;
    tetris->field      = g_new0 (guchar, tetris->field_size);
!   tetris->completed  = g_new0 (gboolean, module->height);
  
    return TRUE;
  }
***************
*** 692,701 ****
  #ifdef TETRIS_DEBUG
    g_print (" tetris tile: %d\n", tetris->tile);
  #endif
!   
    memset (tetris->field, 0, tetris->field_size);
!   memset (tetris->completed, 0, module->width);
!   
    tetris->flash_state = FALSE;
    tetris->n_completed = 0;
    tetris->falling     = FALSE;
--- 692,701 ----
  #ifdef TETRIS_DEBUG
    g_print (" tetris tile: %d\n", tetris->tile);
  #endif
!  
    memset (tetris->field, 0, tetris->field_size);
!   memset (tetris->completed, 0, sizeof (gboolean) * module->height);
!  
    tetris->flash_state = FALSE;
    tetris->n_completed = 0;
    tetris->falling     = FALSE;
***************
*** 715,721 ****
  
    tetris = B_TETRIS (module);
  
!   b_module_fill (module, 0);  
    b_module_paint (module);
  }
  
--- 715,721 ----
  
    tetris = B_TETRIS (module);
  
!   b_module_fill (module, 0); 
    b_module_paint (module);
  }
  
***************
*** 798,804 ****
  #ifdef TETRIS_DEBUG
    g_print ("b_tetris_tick\n");
  #endif
!  
    tetris = B_TETRIS (module);
  
    if (tetris->game_over)
--- 798,804 ----
  #ifdef TETRIS_DEBUG
    g_print ("b_tetris_tick\n");
  #endif
! 
    tetris = B_TETRIS (module);
  
    if (tetris->game_over)
***************
*** 831,837 ****
  	  for (y = 0; y < module->height; y++)
  	    if (tetris->completed[y])
  	      memset (module->buffer + module->width * y, 0, module->width);
! 	  
  	  b_module_paint (module);
  
  	  /* finally remove completed rows */
--- 831,837 ----
  	  for (y = 0; y < module->height; y++)
  	    if (tetris->completed[y])
  	      memset (module->buffer + module->width * y, 0, module->width);
! 	 
  	  b_module_paint (module);
  
  	  /* finally remove completed rows */
***************
*** 862,868 ****
  
    if (b_tetris_down (module)) /* if stuck */
      return b_tetris_tick (module);
!   
    return tetris->speed;
  }
  
--- 862,868 ----
  
    if (b_tetris_down (module)) /* if stuck */
      return b_tetris_tick (module);
!  
    return tetris->speed;
  }
  
diff -r -C 3 -N blib-1.1.7/modules/btext.c blib-1.1.7-ba20070811/modules/btext.c
*** blib-1.1.7/modules/btext.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/btext.c	Sat Aug 11 22:18:43 2007
***************
*** 2,7 ****
--- 2,8 ----
   *
   * Copyright (c) 2001-2002  The Blinkenlights Crew
   *                          Michael Natterer <mitch@gimp.org>
+  *                          Stefan Schuermans <1stein@blinkenarea.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
***************
*** 18,383 ****
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   */
  
- #include <stdlib.h>
  #include <string.h>
! 
  #include <glib-object.h>
  
  #include <blib/blib.h>
  
  
- #define TEXT_TIMEOUT   200
- #define BLINK_TIMEOUT  200
- #define SCROLL_TIMEOUT 100
- #define CHAR_WIDTH     3
- #define CHAR_HEIGHT    5
- #define CHAR_ADVANCE   4
- #define LINE_ADVANCE   6
- #define BLINK_STEPS    4
- 
- 
- typedef struct _BChar BChar;
- 
- struct _BChar
- {
-   gchar  character;
-   gchar  width;
-   guchar matrix[CHAR_WIDTH * CHAR_HEIGHT];
- };
- 
- static const BChar unknown_char =
- {
-   0, 3,
-   { 1, 1, 1,
-     1, 1, 1,
-     1, 1, 1,
-     1, 1, 1,
-     1, 1, 1
-   }
- };
  
! static const BChar chars[] =
! {
!   { '0', 3,
!     { 1, 1, 1,
!       1, 0, 1,
!       1, 0, 1,
!       1, 0, 1,
!       1, 1, 1
!     }
!   },
!   { '1', 3,
!     { 1, 1, 0,
!       0, 1, 0,
!       0, 1, 0,
!       0, 1, 0,
!       0, 1, 0
!     }
!   },
!   { '2', 3,
!     { 0, 1, 1,
!       1, 0, 1,
!       0, 0, 1,
!       0, 1, 0,
!       1, 1, 1
!     }
!   },
!   { '3', 3,
!     { 1, 1, 1,
!       0, 0, 1,
!       1, 1, 1,
!       0, 0, 1,
!       1, 1, 1
!     }
!   },
!   { '4', 3,
!     { 1, 0, 1,
!       1, 0, 1,
!       1, 1, 1,
!       0, 0, 1,
!       0, 0, 1
!     }
!   },
!   { '5', 3,
!     { 1, 1, 1,
!       1, 0, 0,
!       1, 1, 1,
!       0, 0, 1,
!       1, 1, 0
!     }
!   },
!   { '6', 3,
!     { 1, 1, 1,
!       1, 0, 0,
!       1, 1, 1,
!       1, 0, 1,
!       1, 1, 1
!     }
!   },
!   { '7', 3,
!     { 1, 1, 1,
!       0, 0, 1,
!       0, 1, 0,
!       1, 0, 0,
!       1, 0, 0
!     }
!   },
!   { '8', 3,
!     { 1, 1, 1,
!       1, 0, 1,
!       1, 1, 1,
!       1, 0, 1,
!       1, 1, 1
!     }
!   },
!   { '9', 3,
!     { 1, 1, 1, 
!       1, 0, 1,
!       1, 1, 1,
!       0, 0, 1,
!       1, 1, 1
!     }
!   },
! 
!   { ':', 1,
!     { 0, 0, 0, 
!       1, 0, 0,
!       0, 0, 0,
!       1, 0, 0,
!       0, 0, 0
!     }
!   },
!   { '.', 1,
!     { 0, 0, 0, 
!       0, 0, 0,
!       0, 0, 0,
!       0, 0, 0,
!       1, 0, 0
!     }
!   },
! 
!   { 'A', 3,
!     { 1, 1, 1, 
!       1, 0, 1,
!       1, 1, 1,
!       1, 0, 1,
!       1, 0, 1
!     }
!   },
!   { 'B', 3,
!     { 1, 1, 0, 
!       1, 0, 1,
!       1, 1, 0,
!       1, 0, 1,
!       1, 1, 0
!     }
!   },
!   { 'C', 3,
!     { 1, 1, 1, 
!       1, 0, 0,
!       1, 0, 0,
!       1, 0, 0,
!       1, 1, 1
!     }
!   },
!   { 'D', 3,
!     { 1, 1, 0, 
!       1, 0, 1,
!       1, 0, 1,
!       1, 0, 1,
!       1, 1, 0
!     }
!   },
!   { 'E', 3,
!     { 1, 1, 1, 
!       1, 0, 0,
!       1, 1, 0,
!       1, 0, 0,
!       1, 1, 1
!     }
!   },
!   { 'F', 3,
!     { 1, 1, 1, 
!       1, 0, 0,
!       1, 1, 0,
!       1, 0, 0,
!       1, 0, 0
!     }
!   },
!   { 'G', 3,
!     { 1, 1, 1, 
!       1, 0, 0,
!       1, 0, 1,
!       1, 0, 1,
!       1, 1, 1
!     }
!   },
!   { 'H', 3,
!     { 1, 0, 1, 
!       1, 0, 1,
!       1, 1, 1,
!       1, 0, 1,
!       1, 0, 1
!     }
!   },
!   { 'I', 1,
!     { 1, 0, 0, 
!       1, 0, 0,
!       1, 0, 0,
!       1, 0, 0,
!       1, 0, 0
!     }
!   },
!   { 'J', 3,
!     { 0, 0, 1, 
!       0, 0, 1,
!       0, 0, 1,
!       1, 0, 1,
!       0, 1, 0
!     }
!   },
!   { 'K', 3,
!     { 1, 0, 1, 
!       1, 0, 1,
!       1, 1, 0,
!       1, 0, 1,
!       1, 0, 1
!     }
!   },
!   { 'L', 3,
!     { 1, 0, 0, 
!       1, 0, 0,
!       1, 0, 0,
!       1, 0, 0,
!       1, 1, 1
!     }
!   },
!   { 'M', 3,
!     { 1, 0, 1, 
!       1, 1, 1,
!       1, 0, 1,
!       1, 0, 1,
!       1, 0, 1
!     }
!   },
!   { 'N', 3,
!     { 1, 1, 1, 
!       1, 0, 1,
!       1, 0, 1,
!       1, 0, 1,
!       1, 0, 1
!     }
!   },
!   { 'O', 3,
!     { 0, 1, 0, 
!       1, 0, 1,
!       1, 0, 1,
!       1, 0, 1,
!       0, 1, 0
!     }
!   },
!   { 'P', 3,
!     { 1, 1, 0, 
!       1, 0, 1,
!       1, 1, 0,
!       1, 0, 0,
!       1, 0, 0
!     }
!   },
!   { 'Q', 3,
!     { 0, 1, 0, 
!       1, 0, 1,
!       1, 0, 1,
!       1, 0, 1,
!       0, 1, 1
!     }
!   },
!   { 'R', 3,
!     { 1, 1, 0, 
!       1, 0, 1,
!       1, 1, 0,
!       1, 0, 1,
!       1, 0, 1
!     }
!   },
!   { 'S', 3,
!     { 1, 1, 1, 
!       1, 0, 0,
!       1, 1, 1,
!       0, 0, 1,
!       1, 1, 1
!     }
!   },
!   { 'T', 3,
!     { 1, 1, 1, 
!       0, 1, 0,
!       0, 1, 0,
!       0, 1, 0,
!       0, 1, 0
!     }
!   },
!   { 'U', 3,
!     { 1, 0, 1, 
!       1, 0, 1,
!       1, 0, 1,
!       1, 0, 1,
!       1, 1, 1
!     }
!   },
!   { 'V', 3,
!     { 1, 0, 1, 
!       1, 0, 1,
!       1, 0, 1,
!       1, 0, 1,
!       0, 1, 0
!     }
!   },
!   { 'W', 3,
!     { 1, 0, 1, 
!       1, 0, 1,
!       1, 0, 1,
!       1, 1, 1,
!       1, 0, 1
!     }
!   },
!   { 'X', 3,
!     { 1, 0, 1, 
!       1, 0, 1,
!       0, 1, 0,
!       1, 0, 1,
!       1, 0, 1
!     }
!   },
!   { 'Y', 3,
!     { 1, 0, 1, 
!       1, 0, 1,
!       0, 1, 0,
!       0, 1, 0,
!       0, 1, 0
!     }
!   },
!   { 'Z', 3,
!     { 1, 1, 1, 
!       0, 0, 1,
!       0, 1, 0,
!       1, 0, 0,
!       1, 1, 1
!     }
!   },
! };
  
  typedef enum
  {
    SCROLL_UP,
    CURSOR_BLINK,
-   FINISH
  } AnimType;
  
  
  enum
  {
    PROP_0,
!   PROP_STRING
  };
  
  
--- 19,61 ----
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   */
  
  #include <string.h>
! #include <sys/stat.h>
! #include <sys/types.h>
! #include <unistd.h>
! #include <glib/gstdio.h>
  #include <glib-object.h>
  
  #include <blib/blib.h>
  
+ #include "characters.h"
  
  
! #define TIMEOUT_MIN 10
  
  typedef enum
  {
    SCROLL_UP,
    CURSOR_BLINK,
  } AnimType;
  
  
  enum
  {
    PROP_0,
!   PROP_STRING,
!   PROP_FILE,
!   PROP_DIR,
!   PROP_TEXT_TIMEOUT,
!   PROP_BLINK_TIMEOUT,
!   PROP_SCROLL_TIMEOUT,
!   PROP_INIT_BLINK_STEPS,
!   PROP_BEGIN_BLINK_STEPS,
!   PROP_END_BLINK_STEPS,
!   PROP_EXIT_BLINK_STEPS,
!   PROP_BG_COLOR,
!   PROP_FG_COLOR,
!   PROP_FONT_SIZE,
  };
  
  
***************
*** 394,418 ****
  {
    BModule       parent_instance;
  
    gchar        *string;
    gchar        *cursor_pos;
  
    gint          cursor_x;
    gint          cursor_y;
  
-   guchar        bg_color;
-   guchar        fg_color;
- 
    gint          player_device_id;
  
    gint          timeout;
  
    AnimType      anim;
    gint          anim_steps;
  
!   gint          cursor_size;
  
-   GRand        *rand;
  };
  
  struct _BTextClass
--- 72,122 ----
  {
    BModule       parent_instance;
  
+   /* settings from config */
+   gchar        *setting_string;
+   gchar        *setting_file;
+   gchar        *setting_dir;
+ 
+   gint          setting_text_timeout; /* may be 0 to turn off waiting */
+   gint          setting_blink_timeout;
+   gint          setting_scroll_timeout; /* may be zero to turn off waiting */
+   gint          setting_init_blink_steps;
+   gint          setting_begin_blink_steps;
+   gint          setting_end_blink_steps;
+   gint          setting_exit_blink_steps;
+ 
+   guchar        setting_bg_color;
+   guchar        setting_fg_color;
+ 
+   gint          setting_font_width;
+   gint          setting_font_height;
+   gint          setting_font_columns;
+   gint          setting_font_lines;
+ 
+   /* selected font */
+   const ChFont *p_font;
+ 
+   /* string to display, position in string, if last char was a newline char */
    gchar        *string;
    gchar        *cursor_pos;
+   gboolean      newline;
  
+   /* position on display */
    gint          cursor_x;
    gint          cursor_y;
  
    gint          player_device_id;
  
+   /* timeout to use for tick procedure */
    gint          timeout;
  
+   /* type of current animation (if anmin_steps > 0) */
    AnimType      anim;
    gint          anim_steps;
  
!   /* if blinking before exit has been started */
!   gboolean      exit_blink;
  
  };
  
  struct _BTextClass
***************
*** 449,456 ****
                                          const gchar  **author);
  
  
! static BModuleClass * parent_class = NULL;
! static GType          b_type_text  = 0;
  
  
  G_MODULE_EXPORT gboolean
--- 153,160 ----
                                          const gchar  **author);
  
  
! static BModuleClass *parent_class = NULL;
! static GType         b_type_text  = 0;
  
  
  G_MODULE_EXPORT gboolean
***************
*** 493,553 ****
    BModuleClass *module_class;
    GParamSpec   *param_spec;
  
!   object_class = G_OBJECT_CLASS (klass);
!   module_class = B_MODULE_CLASS (klass);
  
!   parent_class = g_type_class_peek_parent (klass);
  
    object_class->finalize     = b_text_finalize;
    object_class->set_property = b_text_set_property;
  
    param_spec = g_param_spec_string ("string", NULL,
!                                     "The string to draw.",
!                                     "blinken\nbis die\nkotze\nkommt",
                                      G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
    g_object_class_install_property (object_class, PROP_STRING, param_spec);
  
    module_class->max_players = 1;
  
!   module_class->query    = b_text_query;
!   module_class->prepare  = b_text_prepare;
!   module_class->relax    = b_text_relax;
!   module_class->start    = b_text_start;
!   module_class->stop     = b_text_stop;
!   module_class->event    = b_text_event;
!   module_class->tick     = b_text_tick;
!   module_class->describe = b_text_describe;
  }
  
  static void
  b_text_init (BText *text)
  {
!   text->string = NULL;
  
!   text->anim_steps       = 0;
!   text->player_device_id = -1;
  
!   text->rand             = g_rand_new ();
  }
  
  static void
  b_text_finalize (GObject *object)
  {
!   BText *text;
  
!   text = B_TEXT (object);
  
!   if (text->string)
!     {
!       g_free (text->string);
!       text->string = NULL;
!     }
! 
!   if (text->rand)
!     {
!       g_rand_free (text->rand);
!       text->rand = NULL;
!     }
  
    G_OBJECT_CLASS (parent_class)->finalize (object);
  }
--- 197,339 ----
    BModuleClass *module_class;
    GParamSpec   *param_spec;
  
!   object_class               = G_OBJECT_CLASS (klass);
!   module_class               = B_MODULE_CLASS (klass);
  
!   parent_class               = g_type_class_peek_parent (klass);
  
    object_class->finalize     = b_text_finalize;
    object_class->set_property = b_text_set_property;
  
    param_spec = g_param_spec_string ("string", NULL,
!                                     "The string to draw (if no file is found).",
!                                     "",
                                      G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
    g_object_class_install_property (object_class, PROP_STRING, param_spec);
  
+   param_spec = g_param_spec_string ("file", NULL,
+                                     "The file to read the string to draw from (if dir contains no file).",
+                                     "",
+                                     G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_FILE, param_spec);
+ 
+   param_spec = g_param_spec_string ("dir", NULL,
+                                     "The directory to read (and then DELETE) the oldest file with a string to draw from.",
+                                     "",
+                                     G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_DIR, param_spec);
+ 
+   param_spec = g_param_spec_int ("text_timeout", NULL,
+ 				 "Timeout in miliseconds between displaying two characters.",
+ 				 0, 1000, 200,
+ 				 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_TEXT_TIMEOUT, param_spec);
+ 
+   param_spec = g_param_spec_int ("blink_timeout", NULL,
+ 				 "Timeout in miliseconds how long the cursor is displayed when it blinks.",
+ 				 TIMEOUT_MIN, 1000, 200,
+ 				 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_BLINK_TIMEOUT, param_spec);
+ 
+   param_spec = g_param_spec_int ("scroll_timeout", NULL,
+ 				 "Timeout in miliseconds between moving up the text one row when scrolling.",
+ 				 0, 1000, 100,
+ 				 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_SCROLL_TIMEOUT, param_spec);
+ 
+   param_spec = g_param_spec_int ("init_blink_steps", NULL,
+ 				 "Number of times the cursor blinks at the begin of the text.",
+ 				 0, 20, 2,
+ 				 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_INIT_BLINK_STEPS, param_spec);
+ 
+   param_spec = g_param_spec_int ("begin_blink_steps", NULL,
+ 				 "Number of times the cursor blinks at the begin of every line.",
+ 				 0, 20, 2,
+ 				 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_BEGIN_BLINK_STEPS, param_spec);
+ 
+   param_spec = g_param_spec_int ("end_blink_steps", NULL,
+ 				 "Number of times the cursor blinks at the end of every line.",
+ 				 0, 20, 2,
+ 				 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_END_BLINK_STEPS, param_spec);
+ 
+   param_spec = g_param_spec_int ("exit_blink_steps", NULL,
+ 				 "Number of times the cursor blinks at the end of the text.",
+ 				 0, 80, 8,
+ 				 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_EXIT_BLINK_STEPS, param_spec);
+ 
+   param_spec = g_param_spec_int ("bg_color", NULL,
+ 				 "The background color.",
+ 				 0, 255, 0,
+ 				 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_BG_COLOR, param_spec);
+ 
+   param_spec = g_param_spec_int ("fg_color", NULL,
+ 				 "The foreround color.",
+ 				 0, 255, 255,
+ 				 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_FG_COLOR, param_spec);
+ 
+   param_spec = g_param_spec_string ("font_size", NULL,
+                                     "The size of the font to use (<width>x<height>[@<columns>x<lines>]).",
+                                     "",
+                                     G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
+   g_object_class_install_property (object_class, PROP_FONT_SIZE, param_spec);
+ 
    module_class->max_players = 1;
  
!   module_class->query       = b_text_query;
!   module_class->prepare     = b_text_prepare;
!   module_class->relax       = b_text_relax;
!   module_class->start       = b_text_start;
!   module_class->stop        = b_text_stop;
!   module_class->event       = b_text_event;
!   module_class->tick        = b_text_tick;
!   module_class->describe    = b_text_describe;
  }
  
  static void
  b_text_init (BText *text)
  {
!   text->setting_string            = g_strdup ("");
!   text->setting_file              = g_strdup ("");
!   text->setting_dir               = g_strdup ("");
! 
!   text->setting_text_timeout      = 200;
!   text->setting_blink_timeout     = 200;
!   text->setting_scroll_timeout    = 100;
!   text->setting_init_blink_steps  = 2;
!   text->setting_begin_blink_steps = 2;
!   text->setting_end_blink_steps   = 2;
!   text->setting_exit_blink_steps  = 8;
! 
!   text->setting_bg_color          = 0;
!   text->setting_fg_color          = text->parent_instance.maxval;
! 
!   text->setting_font_width        = -1;
!   text->setting_font_height       = -1;
!   text->setting_font_columns      = -1;
!   text->setting_font_lines        = -1;
  
!   text->string                    = g_strdup ("");
  
!   text->anim_steps                = 0;
!   text->player_device_id          = -1;
  }
  
  static void
  b_text_finalize (GObject *object)
  {
!   BText * text = B_TEXT (object);
  
!   g_free (text->setting_string);
!   g_free (text->setting_file);
!   g_free (text->setting_dir);
  
!   g_free (text->string);
  
    G_OBJECT_CLASS (parent_class)->finalize (object);
  }
***************
*** 558,572 ****
                       const GValue *value,
                       GParamSpec   *pspec)
  {
!   BText *text;
! 
!   text = B_TEXT (object);
  
    switch (property_id)
      {
      case PROP_STRING:
!       g_free (text->string);
!       text->string = g_value_dup_string (value);
        break;
  
      default:
--- 344,429 ----
                       const GValue *value,
                       GParamSpec   *pspec)
  {
!   BText *text = B_TEXT (object);
!   gchar *str;
!   gint width, height, columns, lines;
  
    switch (property_id)
      {
      case PROP_STRING:
!       g_free (text->setting_string);
!       text->setting_string = g_value_dup_string (value);
!       break;
! 
!     case PROP_FILE:
!       g_free (text->setting_file);
!       text->setting_file = g_value_dup_string (value);
!       break;
! 
!     case PROP_DIR:
!       g_free (text->setting_dir);
!       text->setting_dir = g_value_dup_string (value);
!       break;
! 
!     case PROP_TEXT_TIMEOUT:
!       text->setting_text_timeout = g_value_get_int (value);
!       if (text->setting_text_timeout > 0 && text->setting_text_timeout < TIMEOUT_MIN)
!         text->setting_text_timeout = TIMEOUT_MIN;
!       break;
! 
!     case PROP_BLINK_TIMEOUT:
!       text->setting_blink_timeout = g_value_get_int (value);
!       break;
! 
!     case PROP_SCROLL_TIMEOUT:
!       text->setting_scroll_timeout = g_value_get_int (value);
!       if (text->setting_scroll_timeout > 0 && text->setting_scroll_timeout < TIMEOUT_MIN)
!         text->setting_scroll_timeout = TIMEOUT_MIN;
!       break;
! 
!     case PROP_INIT_BLINK_STEPS:
!       text->setting_init_blink_steps = g_value_get_int (value);
!       break;
! 
!     case PROP_BEGIN_BLINK_STEPS:
!       text->setting_begin_blink_steps = g_value_get_int (value);
!       break;
! 
!     case PROP_END_BLINK_STEPS:
!       text->setting_end_blink_steps = g_value_get_int (value);
!       break;
! 
!     case PROP_EXIT_BLINK_STEPS:
!       text->setting_exit_blink_steps = g_value_get_int (value);
!       break;
! 
!     case PROP_BG_COLOR:
!       text->setting_bg_color = g_value_get_int (value);
!       break;
! 
!     case PROP_FG_COLOR:
!       text->setting_fg_color = g_value_get_int (value);
!       break;
! 
!     case PROP_FONT_SIZE:
!       str = g_value_dup_string (value);
!       if (sscanf (str, "%dx%d@%dx%d", &width, &height, &columns, &lines) == 4
!           && width >= 1 && height >= 1 && columns >= 1 && lines >= 1)
!         {
!           text->setting_font_width   = width;
!           text->setting_font_height  = height;
!           text->setting_font_columns = columns;
!           text->setting_font_lines   = lines;
!         }
!       else if (sscanf (str, "%dx%d", &width, &height) == 2
! 		 && width >= 1 && height >= 1)
!         {
!           text->setting_font_width   = width;
!           text->setting_font_height  = height;
!           text->setting_font_columns = 1;
!           text->setting_font_lines   = 1;
!         }
!       g_free (str);
        break;
  
      default:
***************
*** 581,605 ****
                gint     channels,
                gint     maxval)
  {
!   return (width  >= 5 * CHAR_ADVANCE &&
!           height >= 2 * LINE_ADVANCE &&
!           channels == 1);
  }
  
  static gboolean
  b_text_prepare (BModule  *module,
                  GError  **error)
  {
!   BText *text;
! 
!   text = B_TEXT (module);
  
!   text->bg_color    = 0;
!   text->fg_color    = module->maxval;
  
!   text->cursor_size = CHAR_WIDTH;
  
!   return TRUE;
  }
  
  static void
--- 438,577 ----
                gint     channels,
                gint     maxval)
  {
!   /* check that a font is available that can at least display 3 characters on the display */
!   const ChFont *p_font = selectChFont (3, 1, width, height);
!   return p_font != pChFontNone && channels == 1; /* this module is only for one channel */
! }
! 
! static gchar *get_oldest_filename_in_dir (gchar *dirname)
! {
!   GDir *dir;
!   const gchar *cur_file_name;
!   gchar *cur_name, *oldest_name = NULL;
!   struct stat st;
!   time_t oldest_mtime = 0;
! 
!   /* find oldest file in dir */
!   if ((dir = g_dir_open (dirname, 0, NULL)))
!     {
!       while ((cur_file_name = g_dir_read_name (dir)))
!         {
!           /* construct complete filename */
!           cur_name = (gchar *)g_malloc (strlen (dirname) + 1
!                                         + strlen (cur_file_name) + 1);
!           strcpy (cur_name, dirname);
!           strcat (cur_name, "/");
!           strcat (cur_name, cur_file_name);
!           /* check if older than current */
!           if (g_stat (cur_name, &st) == 0
!               && S_ISREG (st.st_mode)
!               && (! oldest_name || st.st_mtime < oldest_mtime))
!             {
!               if (oldest_name)
!                 g_free (oldest_name);
!               oldest_name = cur_name;
!               oldest_mtime = st.st_mtime;
!             }
!           else
!             g_free (cur_name);
!         }
!       g_dir_close (dir);
!     }
! 
!   return oldest_name;
! }
! 
! static gchar *read_oldest_file_from_dir_and_delete (gchar *dirname)
! { 
!   gchar *name, *contents;
!   gsize size;
!   if ((name = get_oldest_filename_in_dir (dirname)))
!     {
!       contents = NULL;
!       size = 0;
!       if (g_file_get_contents (name, &contents, &size, NULL))
!         {
!           g_unlink (name);
!           g_free (name);
!           return contents;
!         }
!       g_free (name);
!     }
!   return NULL;
! }
! 
! /* fetch text to display */
! static gboolean b_text_fetch_text (BText *text)
! {
!   gchar *str;
!   gsize size;
! 
!   /* free old text */
!   g_free (text->string);
! 
!   /* try to get text from directory */
!   if (text->setting_dir[0] != 0)
!     {
!       if ((str = read_oldest_file_from_dir_and_delete (text->setting_dir)))
!         {
!           text->string = str;
!           return TRUE;
!         }
!     }
! 
!   /* try to get text from file */
!   if (text->setting_file[0] != 0)
!     {
!       if (g_file_get_contents (text->setting_file, &str, &size, NULL))
!         {
!           text->string = str;
!           return TRUE;
!         }
!     }
! 
!   /* try to get text from string */
!   if (text->setting_string[0] != 0)
!     {
!       /* create a copy to work with */
!       text->string = g_strdup (text->setting_string);
!       return TRUE;
!     }
! 
!   /* no text available -> fail */
!   text->string = g_strdup ("");
!   return FALSE;
  }
  
  static gboolean
  b_text_prepare (BModule  *module,
                  GError  **error)
  {
!   BText *text = B_TEXT (module);
!   gboolean text_avail;
  
!   /* correct colors */
!   if (text->setting_bg_color > module->maxval)
!      text->setting_bg_color = module->maxval;
!   if (text->setting_fg_color > module->maxval)
!      text->setting_fg_color = module->maxval;
! 
!   text->p_font = pChFontNone;
!   /* select font chosen by user */
!   if (text->setting_font_width >= 1 && text->setting_font_height >= 1
!    && text->setting_font_columns >= 1 && text->setting_font_lines >= 1)
!     text->p_font = selectChFont (text->setting_font_columns,
!                                  text->setting_font_lines,
!                                  text->setting_font_width,
!                                  text->setting_font_height);
!   /* select font that can at least display 3 characters on the display */
!   if (text->p_font == pChFontNone)
!     text->p_font = selectChFont (3, 1, module->width, module->height);
  
!   /* fetch string to display */
!   text_avail = b_text_fetch_text (text);
  
!   /* only proceed if text is available */
!   return text_avail ? TRUE : FALSE;
  }
  
  static void
***************
*** 613,628 ****
    BText *text = B_TEXT (module);
  
    text->cursor_pos = text->string;
  
    text->cursor_x   = 0;
    text->cursor_y   = 0;
  
    text->anim       = CURSOR_BLINK;
!   text->anim_steps = BLINK_STEPS;
  
!   text->timeout    = TEXT_TIMEOUT;
  
!   b_module_fill (module, text->bg_color);
  
    b_module_ticker_start (module, text->timeout);
  }
--- 585,603 ----
    BText *text = B_TEXT (module);
  
    text->cursor_pos = text->string;
+   text->newline    = FALSE;
  
    text->cursor_x   = 0;
    text->cursor_y   = 0;
  
    text->anim       = CURSOR_BLINK;
!   text->anim_steps = text->setting_init_blink_steps * 2;
  
!   text->exit_blink = FALSE;
  
!   text->timeout    = text->setting_blink_timeout;
! 
!   b_module_fill (module, text->setting_bg_color);
  
    b_module_ticker_start (module, text->timeout);
  }
***************
*** 630,638 ****
  static void
  b_text_stop (BModule *module)
  {
!   BText *text;
! 
!   text = B_TEXT (module);
  
    text->player_device_id = -1;
  }
--- 605,611 ----
  static void
  b_text_stop (BModule *module)
  {
!   BText *text = B_TEXT (module);
  
    text->player_device_id = -1;
  }
***************
*** 641,649 ****
  b_text_event (BModule      *module,
                BModuleEvent *event)
  {
!   BText *text;
! 
!   text = B_TEXT (module);
  
    switch (event->type)
      {
--- 614,620 ----
  b_text_event (BModule      *module,
                BModuleEvent *event)
  {
!   BText *text = B_TEXT (module);
  
    switch (event->type)
      {
***************
*** 681,827 ****
      }
  }
  
! static gint
! b_text_tick (BModule *module)
  {
!   BText *text;
! 
!   text = B_TEXT (module);
  
    if (text->anim_steps > 0)
      {
        text->anim_steps--;
  
        switch (text->anim)
          {
-         case SCROLL_UP:
-           memmove (module->buffer,
-                    module->buffer + module->width * module->channels,
-                    module->width * (module->height - 1) * module->channels);
-           b_module_draw_line (module,
-                               0, module->height - 1,
-                               module->width - 1, module->height - 1,
-                               text->bg_color);
-           text->timeout = SCROLL_TIMEOUT;
- 
-           if (text->anim_steps == 0)
-             {
-               text->anim       = CURSOR_BLINK;
-               text->anim_steps = BLINK_STEPS;
-             }
-           break;
  
!         case CURSOR_BLINK:
!         case FINISH:
!           b_module_draw_line (module,
!                               text->cursor_x,
!                               text->cursor_y + CHAR_HEIGHT - 1,
!                               text->cursor_x + text->cursor_size - 1,
!                               text->cursor_y + CHAR_HEIGHT - 1,
!                               text->anim_steps % 2 ?
!                               text->fg_color : text->bg_color);
  
!           if (text->anim == FINISH && text->anim_steps == 0)
!             {
!               b_module_request_stop (module);
!               return 0;
!             }
  
!           text->timeout = BLINK_TIMEOUT;
            break;
          }
-     }
-   else
-     {
-       text->timeout = TEXT_TIMEOUT;
  
!       if (text->cursor_pos && *text->cursor_pos)
          {
!           gint advance = CHAR_WIDTH;
  
!           b_module_draw_line (module,
!                               text->cursor_x,
!                               text->cursor_y + CHAR_HEIGHT - 1,
!                               text->cursor_x + text->cursor_size - 1,
!                               text->cursor_y + CHAR_HEIGHT - 1,
!                               text->bg_color);
  
!           if (! g_ascii_isspace (*text->cursor_pos))
              {
!               const BChar *bchar = &unknown_char;
!               gint         i, x, y;
! 
!               for (i = 0; i < G_N_ELEMENTS (chars); i++)
!                 {
!                   if (chars[i].character == g_ascii_toupper (*text->cursor_pos))
!                     bchar = &chars[i];
!                 }
! 
!               for (x = 0; x < CHAR_WIDTH; x++)
!                 for (y = 0; y < CHAR_HEIGHT; y++)
!                   {
!                     if (bchar->matrix[y * CHAR_WIDTH + x])
!                       b_module_draw_point (module,
!                                            text->cursor_x + x,
!                                            text->cursor_y + y,
!                                            text->fg_color);
!                     else
!                       b_module_draw_point (module,
!                                            text->cursor_x + x,
!                                            text->cursor_y + y,
!                                            text->bg_color);
!                   }
! 
!               advance = bchar->width + 1;
              }
  
!           text->cursor_x += advance;
  
!           if (*text->cursor_pos == '\n' ||
!               (text->cursor_x + CHAR_WIDTH > module->width))
              {
!               text->cursor_pos++;
  
!               /* no whitespace at the start of a line */
!               if (g_ascii_isspace (*text->cursor_pos) &&
!                   (*text->cursor_pos != '\n' ||
!                    (text->cursor_x + CHAR_WIDTH > module->width)))
!                 text->cursor_pos++;
  
!               text->cursor_x  = 0;
!               text->cursor_y += LINE_ADVANCE;
  
!               text->anim       = CURSOR_BLINK;
!               text->anim_steps = BLINK_STEPS;
!             }
!           else
!             {
!               text->cursor_pos++;
  
!               if (g_rand_double (text->rand) > 0.5)
!                 b_module_draw_line (module,
!                                     text->cursor_x,
!                                     text->cursor_y + CHAR_HEIGHT - 1,
!                                     text->cursor_x + text->cursor_size - 1,
!                                     text->cursor_y + CHAR_HEIGHT - 1,
!                                     text->fg_color);
!             }
  
!           if (text->cursor_y + CHAR_HEIGHT > module->height)
!             {
!               text->cursor_y  -= LINE_ADVANCE;
  
!               text->anim       = SCROLL_UP;
!               text->anim_steps = LINE_ADVANCE;
!             }
!         }
!       else
!         {
!           text->anim       = FINISH;
!           text->anim_steps = BLINK_STEPS * 4;
!           text->timeout    = BLINK_TIMEOUT;
!         }
      }
  
    b_module_paint (module);
  
--- 652,850 ----
      }
  }
  
! static gboolean
! b_text_tick_intern (BModule *module)
  {
!   BText *text = B_TEXT (module);
!   const ChFont *p_font = text->p_font;
!   gboolean cursor_blinked = FALSE;
  
+   /* animation in progress */
    if (text->anim_steps > 0)
      {
        text->anim_steps--;
  
        switch (text->anim)
          {
  
!           case SCROLL_UP:
!             g_memmove (module->buffer,
!                        module->buffer + module->width * module->channels,
!                        module->width * (module->height - 1) * module->channels);
!             b_module_draw_line (module,
!                                 0, module->height - 1,
!                                 module->width - 1, module->height - 1,
!                                 text->setting_bg_color);
! 
!             if (text->anim_steps > 0)
!               text->timeout = text->setting_scroll_timeout;
!               return TRUE;
! 
!             /* blink at begin of new line after newline character */
!             if (text->newline && text->setting_begin_blink_steps > 0)
!               {
!                 text->anim       = CURSOR_BLINK;
!                 text->anim_steps = text->setting_begin_blink_steps * 2;
!                 text->timeout    = text->setting_blink_timeout;
!                 return TRUE;
!               }
!             break;
! 
!           case CURSOR_BLINK:
!             cursor_blinked = TRUE;
!             /* draw / clear cursor */
!             if (text->cursor_x + p_font->width <= module->width)
!               b_module_draw_line (module,
!                                   text->cursor_x,
!                                   text->cursor_y + p_font->height - 1,
!                                   text->cursor_x + p_font->width - 1,
!                                   text->cursor_y + p_font->height - 1,
!                                   text->anim_steps & 1
!                                     ? text->setting_fg_color
!                                     : text->setting_bg_color);
!             text->timeout = text->setting_blink_timeout;
! 
!             if (text->anim_steps > 0)
!               return TRUE;
!             break;
! 
!         } /* switch (text->anim) */
! 
!     } /* if (text->anim_steps > 0) */
! 
!   /* clear cursor */
!   if (text->cursor_x + p_font->width <= module->width)
!     b_module_draw_line (module,
!                         text->cursor_x,
!                         text->cursor_y + p_font->height - 1,
!                         text->cursor_x + p_font->width - 1,
!                         text->cursor_y + p_font->height - 1,
!                         text->setting_bg_color);
  
!   while (1) /* this loop is here to be able to use break and continue */
!     {
  
!       /* end of display */
!       if (text->cursor_y + p_font->height > module->height)
!         {
!           /* scroll up one line */
!           text->cursor_y  -= p_font->line_advance;
!           text->anim       = SCROLL_UP;
!           text->anim_steps = p_font->line_advance;
!           text->timeout    = text->setting_scroll_timeout;
            break;
          }
  
!       /* end of text */
!       if (text->cursor_pos == NULL || *text->cursor_pos == '\0')
          {
!             /* stop or blink cursor */
!             if (text->setting_exit_blink_steps <= 0 || text->exit_blink)
!               {
!                 b_module_request_stop (module);
!                 return FALSE;
!               }
!             text->anim       = CURSOR_BLINK;
!             text->anim_steps = text->setting_exit_blink_steps * 2;
!             text->timeout    = text->setting_blink_timeout;
!             text->exit_blink = TRUE;
!             break;
!         }
  
!       /* cursor animation at begin of line */
!       if (text->newline
!           && text->setting_begin_blink_steps > 0
!           && ! cursor_blinked)
!         {
!           text->anim       = CURSOR_BLINK;
!           text->anim_steps = text->setting_begin_blink_steps * 2;
!           text->timeout    = text->setting_blink_timeout;
!           break;
!         }
  
!       /* newline character */
!       if (*text->cursor_pos == '\n')
!         {
!           /* cursor animation at end of line */
!           if (text->setting_end_blink_steps > 0 && ! cursor_blinked)
              {
!               text->anim       = CURSOR_BLINK;
!               text->anim_steps = text->setting_end_blink_steps * 2;
!               text->timeout    = text->setting_blink_timeout;
!               break;
              }
+           cursor_blinked = FALSE; /* allow for new cursor blinking at begin of line */
+ 
+           text->cursor_pos++; /* skip newline character, do not display it */
+           text->newline = TRUE;
+           /* next line */
+           text->cursor_x  = 0;
+           text->cursor_y += p_font->line_advance;
+           continue;
+         }
  
!         text->newline = FALSE;
!         cursor_blinked = FALSE;
  
!         /* end of line */
!         if (text->cursor_x + p_font->width > module->width)
!           {
!             /* next line */
!             text->cursor_x  = 0;
!             text->cursor_y += p_font->line_advance;
!             continue;
!           }
! 
!         /* get character data */
!         const gchar *char_data = getChFontChar (p_font, *text->cursor_pos);
!         gint x, y;
! 
!         /* draw character */
!         for (x = 0; x < p_font->width; x++)
!           for (y = 0; y < p_font->height; y++)
              {
!               gint color = char_data[y * p_font->width + x] == '1'
!                              ? text->setting_fg_color
!                              : text->setting_bg_color;
!               b_module_draw_point (module,
!                                    text->cursor_x + x,
!                                    text->cursor_y + y,
!                                    color);
!             }
  
!       /* next character */
!       text->cursor_x += p_font->advance;
!       text->cursor_pos++;
! 
!       /* draw cursor */
!       if (text->cursor_x + p_font->width <= module->width)
!         b_module_draw_line (module,
!                             text->cursor_x,
!                             text->cursor_y + p_font->height - 1,
!                             text->cursor_x + p_font->width - 1,
!                             text->cursor_y + p_font->height - 1,
!                             text->setting_fg_color);
  
!       /* wait between characters */
!       text->timeout = text->setting_text_timeout;
!       break;
  
!     } /* this loop is here to be able to use break and continue */
  
!   return TRUE;
! }
  
! static gint
! b_text_tick (BModule *module)
! {
!   BText *text = B_TEXT (module);
  
!   do
!     {
!       if (! b_text_tick_intern (module))
!         return 0;
      }
+   while (text->timeout <= 0);
  
    b_module_paint (module);
  
***************
*** 836,840 ****
  {
    *title       = "BText";
    *description = "Text display";
!   *author      = "Michael Natterer";
  }
--- 859,863 ----
  {
    *title       = "BText";
    *description = "Text display";
!   *author      = "Michael Natterer, Stefan Schuermans";
  }
diff -r -C 3 -N blib-1.1.7/modules/bxxo.c blib-1.1.7-ba20070811/modules/bxxo.c
*** blib-1.1.7/modules/bxxo.c	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/bxxo.c	Sat Aug 11 22:18:43 2007
***************
*** 33,51 ****
  #define BxxoVerMin 0
  #define BxxoVerRev 0
  
! //minimum size and color count of display
  #define BxxoSizeXMin 12
  #define BxxoSizeYMin 8
  #define BxxoMaxColorMin 1
! //time player has to chose next field (in seconds)
  #define BxxoChoseTime 9
! //time to blink winning line (in seconds)
  #define BxxoWinTime 3
! //the colors
! #define BxxoColorEmpty( MaxColor ) (0)
! #define BxxoColorField( MaxColor ) ((MaxColor) * 3 / 5)
! #define BxxoColorMark( MaxColor ) (MaxColor)
! #define BxxoColorNumber( MaxColor ) (MaxColor)
  
  #ifdef XXO_DEBUG
  #define dbg_print g_print
--- 33,51 ----
  #define BxxoVerMin 0
  #define BxxoVerRev 0
  
! /* minimum size and color count of display */
  #define BxxoSizeXMin 12
  #define BxxoSizeYMin 8
  #define BxxoMaxColorMin 1
! /* time player has to chose next field (in seconds) */
  #define BxxoChoseTime 9
! /* time to blink winning line (in seconds) */
  #define BxxoWinTime 3
! /* the colors */
! #define BxxoColorEmpty(MaxColor)  (0)
! #define BxxoColorField(MaxColor)  ((MaxColor) * 3 / 5)
! #define BxxoColorMark(MaxColor)   (MaxColor)
! #define BxxoColorNumber(MaxColor) (MaxColor)
  
  #ifdef XXO_DEBUG
  #define dbg_print g_print
***************
*** 65,82 ****
  {
    BModule parent_instance;
  
!   int MaxColor;                         //maximum color value
!   int SizeX, SizeY;                     //size of game-field
!   int MarkX, MarkY;                     //size of a mark
!   int PlayerAvail[2];                   //boolean flags if players are available
!   int PlayerId[2];                      //id of player
!   int Field[3][3];                      //game field: Field[Y][X], -1 = free, 0 = first player, 1 = second player
!   int Player;                           //number of player who has to chose a field next
!   int ChoseTime;                        //time to chose (seconds)
!   int Ticks;                            //tick counter (0.1 seconds)
!   int GameOver;                         //boolean value set if game over
!   int WinX, WinY, WinDX, WinDY;         //variables indicating winning line
!   int WinTime;                          //time to let winning line blink (seconds)
  };
  
  struct _BxxoModuleClass
--- 65,82 ----
  {
    BModule parent_instance;
  
!   gint MaxColor;                 /* maximum color value */
!   gint SizeX, SizeY;             /* size of game-field */
!   gint MarkX, MarkY;             /* size of a mark */
!   gint PlayerAvail[2];           /* boolean flags if players are available */
!   gint PlayerId[2];              /* id of player */
!   gint Field[3][3];              /* game field: Field[Y][X], -1 = free, 0 = first player, 1 = second player */
!   gint Player;                   /* number of player who has to chose a field next */
!   gint ChoseTime;                /* time to chose (seconds) */
!   gint Ticks;                    /* tick counter (0.1 seconds) */
!   gint GameOver;                 /* boolean value set if game over */
!   gint WinX, WinY, WinDX, WinDY; /* variables indicating winning line */
!   gint WinTime;                  /* time to let winning line blink (seconds) */
  };
  
  struct _BxxoModuleClass
***************
*** 106,123 ****
  
  static GType b_type_xxo_module = 0;
  
! //output a player mark
  static void BxxoOutMark (BxxoModule * pBxxoModule,
!                          int StartX, int StartY,
!                          int SizeX, int SizeY,
!                          int Player)
  {
!   int X, Y, Con, Coff;
    Con = BxxoColorMark (pBxxoModule->MaxColor);
    Coff = BxxoColorEmpty (pBxxoModule->MaxColor);
!   for( Y = 0; Y < SizeY; Y++ )
!     for( X = 0; X < SizeX; X++ )
!       if( Player == 0 || (Player == 1 && ((X + Y) & 1) == 0) )
          b_module_draw_point ((BModule*)pBxxoModule, StartX + X, StartY + Y,
                               Con);
        else
--- 106,123 ----
  
  static GType b_type_xxo_module = 0;
  
! /* output a player mark */
  static void BxxoOutMark (BxxoModule * pBxxoModule,
!                          gint StartX, gint StartY,
!                          gint SizeX, gint SizeY,
!                          gint Player)
  {
!   gint X, Y, Con, Coff;
    Con = BxxoColorMark (pBxxoModule->MaxColor);
    Coff = BxxoColorEmpty (pBxxoModule->MaxColor);
!   for (Y = 0; Y < SizeY; Y++)
!     for (X = 0; X < SizeX; X++)
!       if (Player == 0 || (Player == 1 && ((X + Y) & 1) == 0))
          b_module_draw_point ((BModule*)pBxxoModule, StartX + X, StartY + Y,
                               Con);
        else
***************
*** 126,133 ****
  }
  
  
! //output a number (0..9) (3x5 pixels)
! const char BxxoNumbers[11][5][3] =
  {
    {
      {1,1,1},
--- 126,133 ----
  }
  
  
! /* output a number (0..9) (3x5 pixels) */
! const gchar BxxoNumbers[11][5][3] =
  {
    {
      {1,1,1},
***************
*** 208,217 ****
    }
  };
  static void BxxoOutNumber (BxxoModule * pBxxoModule,
!                            int X, int Y,
!                            int N)
  {
!   int Con, Coff, XX, YY;
    Con = BxxoColorNumber (pBxxoModule->MaxColor);
    Coff = BxxoColorEmpty (pBxxoModule->MaxColor);
    if (N > 9) N %= 10;
--- 208,217 ----
    }
  };
  static void BxxoOutNumber (BxxoModule * pBxxoModule,
!                            gint X, gint Y,
!                            gint N)
  {
!   gint Con, Coff, XX, YY;
    Con = BxxoColorNumber (pBxxoModule->MaxColor);
    Coff = BxxoColorEmpty (pBxxoModule->MaxColor);
    if (N > 9) N %= 10;
***************
*** 219,238 ****
    for (YY = 0; YY < 5; YY++)
      for (XX = 0; XX < 3; XX++)
        b_module_draw_point ((BModule*)pBxxoModule, X + XX, Y + YY,
!                            BxxoNumbers[N][YY][XX] ? Con : Coff );
  }
  
! //check if current player has won
! static int BxxoWinCheck( BxxoModule * pBxxoModule )
  {
!   int X, Y, Cnt;
!   //horizontal
!   for( Y = 0; Y < 3; Y++ )
    {
!     for( X = 0; X < 3; X++ )
!       if( pBxxoModule->Field[Y][X] != pBxxoModule->Player )
          break;
!     if( X >= 3 )
      {
        pBxxoModule->WinX = 0;
        pBxxoModule->WinY = Y;
--- 219,238 ----
    for (YY = 0; YY < 5; YY++)
      for (XX = 0; XX < 3; XX++)
        b_module_draw_point ((BModule*)pBxxoModule, X + XX, Y + YY,
!                            BxxoNumbers[N][YY][XX] ? Con : Coff);
  }
  
! /* check if current player has won */
! static gint BxxoWinCheck (BxxoModule * pBxxoModule)
  {
!   gint X, Y, Cnt;
!   /* horizontal */
!   for (Y = 0; Y < 3; Y++)
    {
!     for (X = 0; X < 3; X++)
!       if (pBxxoModule->Field[Y][X] != pBxxoModule->Player)
          break;
!     if (X >= 3)
      {
        pBxxoModule->WinX = 0;
        pBxxoModule->WinY = Y;
***************
*** 241,253 ****
        return 1;
      }
    }
!   //vertical
!   for( X = 0; X < 3; X++ )
    {
!     for( Y = 0; Y < 3; Y++ )
!       if( pBxxoModule->Field[Y][X] != pBxxoModule->Player )
          break;
!     if( Y >= 3 )
      {
        pBxxoModule->WinX = X;
        pBxxoModule->WinY = 0;
--- 241,253 ----
        return 1;
      }
    }
!   /* vertical */
!   for (X = 0; X < 3; X++)
    {
!     for (Y = 0; Y < 3; Y++)
!       if (pBxxoModule->Field[Y][X] != pBxxoModule->Player)
          break;
!     if (Y >= 3)
      {
        pBxxoModule->WinX = X;
        pBxxoModule->WinY = 0;
***************
*** 256,266 ****
        return 1;
      }
    }
!   //diagonal
!   for( Y = 0, X = 0; Y < 3; Y++, X++ )
!     if( pBxxoModule->Field[Y][X] != pBxxoModule->Player )
        break;
!   if( Y >= 3 )
    {
      pBxxoModule->WinX = 0;
      pBxxoModule->WinY = 0;
--- 256,266 ----
        return 1;
      }
    }
!   /* diagonal */
!   for (Y = 0, X = 0; Y < 3; Y++, X++)
!     if (pBxxoModule->Field[Y][X] != pBxxoModule->Player)
        break;
!   if (Y >= 3)
    {
      pBxxoModule->WinX = 0;
      pBxxoModule->WinY = 0;
***************
*** 268,278 ****
      pBxxoModule->WinDY = 1;
      return 1;
    }
!   //reverse diagonal
!   for( Y = 0, X = 2; Y < 3; Y++, X-- )
!     if( pBxxoModule->Field[Y][X] != pBxxoModule->Player )
        break;
!   if( Y >= 3 )
    {
      pBxxoModule->WinX = 2;
      pBxxoModule->WinY = 0;
--- 268,278 ----
      pBxxoModule->WinDY = 1;
      return 1;
    }
!   /* reverse diagonal */
!   for (Y = 0, X = 2; Y < 3; Y++, X--)
!     if (pBxxoModule->Field[Y][X] != pBxxoModule->Player)
        break;
!   if (Y >= 3)
    {
      pBxxoModule->WinX = 2;
      pBxxoModule->WinY = 0;
***************
*** 280,292 ****
      pBxxoModule->WinDY = 1;
      return 1;
    }
!   //no more free fields
    Cnt = 0;
!   for( Y = 0; Y < 3; Y++ )
!     for( X = 0; X < 3; X++ )
!       if( pBxxoModule->Field[Y][X] == -1 )
          Cnt++;
!   if( Cnt == 0 )
    {
      pBxxoModule->WinX = -1;
      pBxxoModule->WinY = -1;
--- 280,292 ----
      pBxxoModule->WinDY = 1;
      return 1;
    }
!   /* no more free fields */
    Cnt = 0;
!   for (Y = 0; Y < 3; Y++)
!     for (X = 0; X < 3; X++)
!       if (pBxxoModule->Field[Y][X] == -1)
          Cnt++;
!   if (Cnt == 0)
    {
      pBxxoModule->WinX = -1;
      pBxxoModule->WinY = -1;
***************
*** 297,546 ****
    return 0;
  }
  
! //chose a field for current player
! static void BxxoModuleChose( BxxoModule * pBxxoModule, int * pX, int * pY )
  {
!   int X, Y, Cnt, I;
  
!   //try to win
  
!   //horizontal
!   for( Y = 0; Y < 3; Y++ )
    {
!     if( pBxxoModule->Field[Y][0] == pBxxoModule->Player
       && pBxxoModule->Field[Y][1] == pBxxoModule->Player
!      && pBxxoModule->Field[Y][2] == -1 )
      {
        *pX = 2;
        *pY = Y;
        return;
      }
!     if( pBxxoModule->Field[Y][0] == pBxxoModule->Player
       && pBxxoModule->Field[Y][1] == -1
!      && pBxxoModule->Field[Y][2] == pBxxoModule->Player )
      {
        *pX = 1;
        *pY = Y;
        return;
      }
!     if( pBxxoModule->Field[Y][0] == -1
       && pBxxoModule->Field[Y][1] == pBxxoModule->Player
!      && pBxxoModule->Field[Y][2] == pBxxoModule->Player )
      {
        *pX = 0;
        *pY = Y;
        return;
      }
    }
!   //vertical
!   for( X = 0; X < 3; X++ )
    {
!     if( pBxxoModule->Field[0][X] == pBxxoModule->Player
       && pBxxoModule->Field[1][X] == pBxxoModule->Player
!      && pBxxoModule->Field[2][X] == -1 )
      {
        *pX = X;
        *pY = 2;
        return;
      }
!     if( pBxxoModule->Field[0][X] == pBxxoModule->Player
       && pBxxoModule->Field[1][X] == -1
!      && pBxxoModule->Field[2][X] == pBxxoModule->Player )
      {
        *pX = X;
        *pY = 1;
        return;
      }
!     if( pBxxoModule->Field[0][X] == -1
       && pBxxoModule->Field[1][X] == pBxxoModule->Player
!      && pBxxoModule->Field[2][X] == pBxxoModule->Player )
      {
        *pX = X;
        *pY = 0;
        return;
      }
    }
!   //diagonal
!   if( pBxxoModule->Field[0][0] == pBxxoModule->Player
     && pBxxoModule->Field[1][1] == pBxxoModule->Player
!    && pBxxoModule->Field[2][2] == -1 )
    {
      *pX = 2;
      *pY = 2;
      return;
    }
!   if( pBxxoModule->Field[0][0] == pBxxoModule->Player
     && pBxxoModule->Field[1][1] == -1
!    && pBxxoModule->Field[2][2] == pBxxoModule->Player )
    {
      *pX = 1;
      *pY = 1;
      return;
    }
!   if( pBxxoModule->Field[0][0] == -1
     && pBxxoModule->Field[1][1] == pBxxoModule->Player
!    && pBxxoModule->Field[2][2] == pBxxoModule->Player )
    {
      *pX = 0;
      *pY = 0;
      return;
    }
!   //reverse diagonal
!   if( pBxxoModule->Field[0][2] == pBxxoModule->Player
     && pBxxoModule->Field[1][1] == pBxxoModule->Player
!    && pBxxoModule->Field[2][0] == -1 )
    {
      *pX = 0;
      *pY = 2;
      return;
    }
!   if( pBxxoModule->Field[0][2] == pBxxoModule->Player
     && pBxxoModule->Field[1][1] == -1
!    && pBxxoModule->Field[2][0] == pBxxoModule->Player )
    {
      *pX = 1;
      *pY = 1;
      return;
    }
!   if( pBxxoModule->Field[0][2] == -1
     && pBxxoModule->Field[1][1] == pBxxoModule->Player
!    && pBxxoModule->Field[2][0] == pBxxoModule->Player )
    {
      *pX = 2;
      *pY = 0;
      return;
    }
  
!   //no direct chance to win
  
!   //try to block other player
  
!   //horizontal
!   for( Y = 0; Y < 3; Y++ )
    {
!     if( pBxxoModule->Field[Y][0] == 1 - pBxxoModule->Player
       && pBxxoModule->Field[Y][1] == 1 - pBxxoModule->Player
!      && pBxxoModule->Field[Y][2] == -1 )
      {
        *pX = 2;
        *pY = Y;
        return;
      }
!     if( pBxxoModule->Field[Y][0] == 1 - pBxxoModule->Player
       && pBxxoModule->Field[Y][1] == -1
!      && pBxxoModule->Field[Y][2] == 1 - pBxxoModule->Player )
      {
        *pX = 1;
        *pY = Y;
        return;
      }
!     if( pBxxoModule->Field[Y][0] == -1
       && pBxxoModule->Field[Y][1] == 1 - pBxxoModule->Player
!      && pBxxoModule->Field[Y][2] == 1 - pBxxoModule->Player )
      {
        *pX = 0;
        *pY = Y;
        return;
      }
    }
!   //vertical
!   for( X = 0; X < 3; X++ )
    {
!     if( pBxxoModule->Field[0][X] == 1 - pBxxoModule->Player
       && pBxxoModule->Field[1][X] == 1 - pBxxoModule->Player
!      && pBxxoModule->Field[2][X] == -1 )
      {
        *pX = X;
        *pY = 2;
        return;
      }
!     if( pBxxoModule->Field[0][X] == 1 - pBxxoModule->Player
       && pBxxoModule->Field[1][X] == -1
!      && pBxxoModule->Field[2][X] == 1 - pBxxoModule->Player )
      {
        *pX = X;
        *pY = 1;
        return;
      }
!     if( pBxxoModule->Field[0][X] == -1
       && pBxxoModule->Field[1][X] == 1 - pBxxoModule->Player
!      && pBxxoModule->Field[2][X] == 1 - pBxxoModule->Player )
      {
        *pX = X;
        *pY = 0;
        return;
      }
    }
!   //diagonal
!   if( pBxxoModule->Field[0][0] == 1 - pBxxoModule->Player
     && pBxxoModule->Field[1][1] == 1 - pBxxoModule->Player
!    && pBxxoModule->Field[2][2] == -1 )
    {
      *pX = 2;
      *pY = 2;
      return;
    }
!   if( pBxxoModule->Field[0][0] == 1 - pBxxoModule->Player
     && pBxxoModule->Field[1][1] == -1
!    && pBxxoModule->Field[2][2] == 1 - pBxxoModule->Player )
    {
      *pX = 1;
      *pY = 1;
      return;
    }
!   if( pBxxoModule->Field[0][0] == -1
     && pBxxoModule->Field[1][1] == 1 - pBxxoModule->Player
!    && pBxxoModule->Field[2][2] == 1 - pBxxoModule->Player )
    {
      *pX = 0;
      *pY = 0;
      return;
    }
!   //reverse diagonal
!   if( pBxxoModule->Field[0][2] == 1 - pBxxoModule->Player
     && pBxxoModule->Field[1][1] == 1 - pBxxoModule->Player
!    && pBxxoModule->Field[2][0] == -1 )
    {
      *pX = 0;
      *pY = 2;
      return;
    }
!   if( pBxxoModule->Field[0][2] == 1 - pBxxoModule->Player
     && pBxxoModule->Field[1][1] == -1
!    && pBxxoModule->Field[2][0] == 1 - pBxxoModule->Player )
    {
      *pX = 1;
      *pY = 1;
      return;
    }
!   if( pBxxoModule->Field[0][2] == -1
     && pBxxoModule->Field[1][1] == 1 - pBxxoModule->Player
!    && pBxxoModule->Field[2][0] == 1 - pBxxoModule->Player )
    {
      *pX = 2;
      *pY = 0;
      return;
    }
  
!   //no need to block other player
  
!   //count free fields
    Cnt = 0;
!   for( Y = 0; Y < 3; Y++ )
!     for( X = 0; X < 3; X++ )
!       if( pBxxoModule->Field[Y][X] == -1 )
          Cnt++;
!   //there is a free field
!   if( Cnt > 0 )
    {
!     //select a random one
!     I = rand( ) % Cnt;
!     //return the I-th free field
!     for( Y = 0; Y < 3; Y++ )
!       for( X = 0; X < 3; X++ )
!         if( pBxxoModule->Field[Y][X] == -1 )
          {
!           if( I == 0 )
            {
              *pX = X;
              *pY = Y;
--- 297,546 ----
    return 0;
  }
  
! /* chose a field for current player */
! static void BxxoModuleChose (BxxoModule * pBxxoModule, gint * pX, gint * pY)
  {
!   gint X, Y, Cnt, I;
  
!   /* try to win */
  
!   /* horizontal */
!   for (Y = 0; Y < 3; Y++)
    {
!     if (pBxxoModule->Field[Y][0] == pBxxoModule->Player
       && pBxxoModule->Field[Y][1] == pBxxoModule->Player
!      && pBxxoModule->Field[Y][2] == -1)
      {
        *pX = 2;
        *pY = Y;
        return;
      }
!     if (pBxxoModule->Field[Y][0] == pBxxoModule->Player
       && pBxxoModule->Field[Y][1] == -1
!      && pBxxoModule->Field[Y][2] == pBxxoModule->Player)
      {
        *pX = 1;
        *pY = Y;
        return;
      }
!     if (pBxxoModule->Field[Y][0] == -1
       && pBxxoModule->Field[Y][1] == pBxxoModule->Player
!      && pBxxoModule->Field[Y][2] == pBxxoModule->Player)
      {
        *pX = 0;
        *pY = Y;
        return;
      }
    }
!   /* vertical */
!   for (X = 0; X < 3; X++)
    {
!     if (pBxxoModule->Field[0][X] == pBxxoModule->Player
       && pBxxoModule->Field[1][X] == pBxxoModule->Player
!      && pBxxoModule->Field[2][X] == -1)
      {
        *pX = X;
        *pY = 2;
        return;
      }
!     if (pBxxoModule->Field[0][X] == pBxxoModule->Player
       && pBxxoModule->Field[1][X] == -1
!      && pBxxoModule->Field[2][X] == pBxxoModule->Player)
      {
        *pX = X;
        *pY = 1;
        return;
      }
!     if (pBxxoModule->Field[0][X] == -1
       && pBxxoModule->Field[1][X] == pBxxoModule->Player
!      && pBxxoModule->Field[2][X] == pBxxoModule->Player)
      {
        *pX = X;
        *pY = 0;
        return;
      }
    }
!   /* diagonal */
!   if (pBxxoModule->Field[0][0] == pBxxoModule->Player
     && pBxxoModule->Field[1][1] == pBxxoModule->Player
!    && pBxxoModule->Field[2][2] == -1)
    {
      *pX = 2;
      *pY = 2;
      return;
    }
!   if (pBxxoModule->Field[0][0] == pBxxoModule->Player
     && pBxxoModule->Field[1][1] == -1
!    && pBxxoModule->Field[2][2] == pBxxoModule->Player)
    {
      *pX = 1;
      *pY = 1;
      return;
    }
!   if (pBxxoModule->Field[0][0] == -1
     && pBxxoModule->Field[1][1] == pBxxoModule->Player
!    && pBxxoModule->Field[2][2] == pBxxoModule->Player)
    {
      *pX = 0;
      *pY = 0;
      return;
    }
!   /* reverse diagonal */
!   if (pBxxoModule->Field[0][2] == pBxxoModule->Player
     && pBxxoModule->Field[1][1] == pBxxoModule->Player
!    && pBxxoModule->Field[2][0] == -1)
    {
      *pX = 0;
      *pY = 2;
      return;
    }
!   if (pBxxoModule->Field[0][2] == pBxxoModule->Player
     && pBxxoModule->Field[1][1] == -1
!    && pBxxoModule->Field[2][0] == pBxxoModule->Player)
    {
      *pX = 1;
      *pY = 1;
      return;
    }
!   if (pBxxoModule->Field[0][2] == -1
     && pBxxoModule->Field[1][1] == pBxxoModule->Player
!    && pBxxoModule->Field[2][0] == pBxxoModule->Player)
    {
      *pX = 2;
      *pY = 0;
      return;
    }
  
!   /* no direct chance to win */
  
!   /* try to block other player */
  
!   /* horizontal */
!   for (Y = 0; Y < 3; Y++)
    {
!     if (pBxxoModule->Field[Y][0] == 1 - pBxxoModule->Player
       && pBxxoModule->Field[Y][1] == 1 - pBxxoModule->Player
!      && pBxxoModule->Field[Y][2] == -1)
      {
        *pX = 2;
        *pY = Y;
        return;
      }
!     if (pBxxoModule->Field[Y][0] == 1 - pBxxoModule->Player
       && pBxxoModule->Field[Y][1] == -1
!      && pBxxoModule->Field[Y][2] == 1 - pBxxoModule->Player)
      {
        *pX = 1;
        *pY = Y;
        return;
      }
!     if (pBxxoModule->Field[Y][0] == -1
       && pBxxoModule->Field[Y][1] == 1 - pBxxoModule->Player
!      && pBxxoModule->Field[Y][2] == 1 - pBxxoModule->Player)
      {
        *pX = 0;
        *pY = Y;
        return;
      }
    }
!   /* vertical */
!   for (X = 0; X < 3; X++)
    {
!     if (pBxxoModule->Field[0][X] == 1 - pBxxoModule->Player
       && pBxxoModule->Field[1][X] == 1 - pBxxoModule->Player
!      && pBxxoModule->Field[2][X] == -1)
      {
        *pX = X;
        *pY = 2;
        return;
      }
!     if (pBxxoModule->Field[0][X] == 1 - pBxxoModule->Player
       && pBxxoModule->Field[1][X] == -1
!      && pBxxoModule->Field[2][X] == 1 - pBxxoModule->Player)
      {
        *pX = X;
        *pY = 1;
        return;
      }
!     if (pBxxoModule->Field[0][X] == -1
       && pBxxoModule->Field[1][X] == 1 - pBxxoModule->Player
!      && pBxxoModule->Field[2][X] == 1 - pBxxoModule->Player)
      {
        *pX = X;
        *pY = 0;
        return;
      }
    }
!   /* diagonal */
!   if (pBxxoModule->Field[0][0] == 1 - pBxxoModule->Player
     && pBxxoModule->Field[1][1] == 1 - pBxxoModule->Player
!    && pBxxoModule->Field[2][2] == -1)
    {
      *pX = 2;
      *pY = 2;
      return;
    }
!   if (pBxxoModule->Field[0][0] == 1 - pBxxoModule->Player
     && pBxxoModule->Field[1][1] == -1
!    && pBxxoModule->Field[2][2] == 1 - pBxxoModule->Player)
    {
      *pX = 1;
      *pY = 1;
      return;
    }
!   if (pBxxoModule->Field[0][0] == -1
     && pBxxoModule->Field[1][1] == 1 - pBxxoModule->Player
!    && pBxxoModule->Field[2][2] == 1 - pBxxoModule->Player)
    {
      *pX = 0;
      *pY = 0;
      return;
    }
!   /* reverse diagonal */
!   if (pBxxoModule->Field[0][2] == 1 - pBxxoModule->Player
     && pBxxoModule->Field[1][1] == 1 - pBxxoModule->Player
!    && pBxxoModule->Field[2][0] == -1)
    {
      *pX = 0;
      *pY = 2;
      return;
    }
!   if (pBxxoModule->Field[0][2] == 1 - pBxxoModule->Player
     && pBxxoModule->Field[1][1] == -1
!    && pBxxoModule->Field[2][0] == 1 - pBxxoModule->Player)
    {
      *pX = 1;
      *pY = 1;
      return;
    }
!   if (pBxxoModule->Field[0][2] == -1
     && pBxxoModule->Field[1][1] == 1 - pBxxoModule->Player
!    && pBxxoModule->Field[2][0] == 1 - pBxxoModule->Player)
    {
      *pX = 2;
      *pY = 0;
      return;
    }
  
!   /* no need to block other player */
  
!   /* count free fields */
    Cnt = 0;
!   for (Y = 0; Y < 3; Y++)
!     for (X = 0; X < 3; X++)
!       if (pBxxoModule->Field[Y][X] == -1)
          Cnt++;
!   /* there is a free field */
!   if (Cnt > 0)
    {
!     /* select a random one */
!     I = rand () % Cnt;
!     /* return the I-th free field */
!     for (Y = 0; Y < 3; Y++)
!       for (X = 0; X < 3; X++)
!         if (pBxxoModule->Field[Y][X] == -1)
          {
!           if (I == 0)
            {
              *pX = X;
              *pY = Y;
***************
*** 550,558 ****
          }
    }
  
!   //reaching this line should not occur
  
!   //choose the middle field to be on the safe side and return indices within the field
    *pX = 1;
    *pY = 1;
  }
--- 550,558 ----
          }
    }
  
!   /* reaching this line should not occur */
  
!   /* choose the middle field to be on the safe side and return indices within the field */
    *pX = 1;
    *pY = 1;
  }
***************
*** 585,594 ****
        /* !!!!!!!!! The name given in the next function MUST be unique! */
  
        b_type_xxo_module = g_type_module_register_type (module,
! 							 B_TYPE_MODULE,
! 							 "Bxxo",
! 							 &xxo_module_info,
! 							 0);
      }
  
    return b_type_xxo_module;
--- 585,594 ----
        /* !!!!!!!!! The name given in the next function MUST be unique! */
  
        b_type_xxo_module = g_type_module_register_type (module,
! 						       B_TYPE_MODULE,
! 						       "Bxxo",
! 						       &xxo_module_info,
! 						       0);
      }
  
    return b_type_xxo_module;
***************
*** 631,642 ****
  {
    BxxoModule *pBxxoModule = B_XXO_MODULE (module);
  
!   //initialize the module values that depend on the output device
!   pBxxoModule->MaxColor = module->maxval; //maximum color value
!   pBxxoModule->SizeX = module->width; //size of game field
!   pBxxoModule->SizeY = module->height;
!   pBxxoModule->MarkX = (pBxxoModule->SizeX - 6) / 3; //size of a mark
!   pBxxoModule->MarkY = (pBxxoModule->SizeY - 2) / 3;
  
    return TRUE;
  }
--- 631,642 ----
  {
    BxxoModule *pBxxoModule = B_XXO_MODULE (module);
  
!   /* initialize the module values that depend on the output device */
!   pBxxoModule->MaxColor = module->maxval; /* maximum color value */
!   pBxxoModule->SizeX    = module->width; /* size of game field */
!   pBxxoModule->SizeY    = module->height;
!   pBxxoModule->MarkX    = (pBxxoModule->SizeX - 6) / 3; /* size of a mark */
!   pBxxoModule->MarkY    = (pBxxoModule->SizeY - 2) / 3;
  
    return TRUE;
  }
***************
*** 650,676 ****
  b_xxo_module_start (BModule *module)
  {
    BxxoModule *pBxxoModule = B_XXO_MODULE (module);
!   int X, Y;
  
!   //no player available yet
    pBxxoModule->PlayerAvail[0] = 0;
    pBxxoModule->PlayerAvail[1] = 0;
!   //game field is empty
!   for( Y = 0; Y < 3; Y++ )
!     for( X = 0; X < 3; X++ )
        pBxxoModule->Field[Y][X] = -1;
!   //player 1 starts
    pBxxoModule->Player = 0;
    pBxxoModule->ChoseTime = BxxoChoseTime;
!   //no ticks in current second yet
    pBxxoModule->Ticks = 0;
!   //game not over
    pBxxoModule->GameOver = 0;
  
!   //initialize screen
!   b_module_fill ((BModule *) pBxxoModule, //empty the screen
                   BxxoColorEmpty (pBxxoModule->MaxColor));
!   b_module_draw_line ((BModule *) pBxxoModule, //draw the field
                        pBxxoModule->MarkX, 0,
                        pBxxoModule->MarkX, pBxxoModule->SizeY - 1,
                        BxxoColorField (pBxxoModule->MaxColor));
--- 650,676 ----
  b_xxo_module_start (BModule *module)
  {
    BxxoModule *pBxxoModule = B_XXO_MODULE (module);
!   gint X, Y;
  
!   /* no player available yet */
    pBxxoModule->PlayerAvail[0] = 0;
    pBxxoModule->PlayerAvail[1] = 0;
!   /* game field is empty */
!   for (Y = 0; Y < 3; Y++)
!     for (X = 0; X < 3; X++)
        pBxxoModule->Field[Y][X] = -1;
!   /* player 1 starts */
    pBxxoModule->Player = 0;
    pBxxoModule->ChoseTime = BxxoChoseTime;
!   /* no ticks in current second yet */
    pBxxoModule->Ticks = 0;
!   /* game not over */
    pBxxoModule->GameOver = 0;
  
!   /* initialize screen */
!   b_module_fill ((BModule *) pBxxoModule, /* empty the screen */
                   BxxoColorEmpty (pBxxoModule->MaxColor));
!   b_module_draw_line ((BModule *) pBxxoModule, /* draw the field */
                        pBxxoModule->MarkX, 0,
                        pBxxoModule->MarkX, pBxxoModule->SizeY - 1,
                        BxxoColorField (pBxxoModule->MaxColor));
***************
*** 686,696 ****
                        0, pBxxoModule->MarkY * 2 + 1,
                        pBxxoModule->SizeX - 5, pBxxoModule->MarkY * 2 + 1,
                        BxxoColorField (pBxxoModule->MaxColor));
!   BxxoOutNumber( pBxxoModule, pBxxoModule->SizeX - 3, pBxxoModule->SizeY - 5,
                   pBxxoModule->ChoseTime);
!   b_module_paint ((BModule *) pBxxoModule); //put image onto screen
  
!   //start the tick machinery
    b_module_ticker_start (module, 100);
  }
  
--- 686,696 ----
                        0, pBxxoModule->MarkY * 2 + 1,
                        pBxxoModule->SizeX - 5, pBxxoModule->MarkY * 2 + 1,
                        BxxoColorField (pBxxoModule->MaxColor));
!   BxxoOutNumber (pBxxoModule, pBxxoModule->SizeX - 3, pBxxoModule->SizeY - 5,
                   pBxxoModule->ChoseTime);
!   b_module_paint ((BModule *) pBxxoModule); /* put image onto screen */
  
!   /* start the tick machinery */
    b_module_ticker_start (module, 100);
  }
  
***************
*** 698,767 ****
  b_xxo_module_event (BModule      *module,
                      BModuleEvent *event)
  {
!   int I, X, Y;
  
    BxxoModule *pBxxoModule = B_XXO_MODULE (module);
  
!   //ignore events if game over
    if (pBxxoModule->GameOver)
      return;
  
!   //player entered
    if (event->type == B_EVENT_TYPE_PLAYER_ENTERED)
    {
!     //search for player not available
      for (I = 0; I < 2; I++)
        if (!pBxxoModule->PlayerAvail[I])
          break;
!     //found player
!     if( I < 2 )
      {
!       //player joins
        pBxxoModule->PlayerAvail[I] = 1;
        pBxxoModule->PlayerId[I] = event->device_id;
        dbg_print ("Bxxo: player %d (dev_id %d) joined\n", I, event->device_id);
!       //show player indicator
        if (I == pBxxoModule->Player)
        {
!         BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0, 3, pBxxoModule->MarkY, I);
!         b_module_paint ((BModule *) pBxxoModule); //put image onto screen
        }
      }
    }
  
!   //player left
    else if (event->type == B_EVENT_TYPE_PLAYER_LEFT)
    {
!     //search for player with device-id
      for (I = 0; I < 2; I++)
!       if (pBxxoModule->PlayerAvail[I] && pBxxoModule->PlayerId[I] == event->device_id)
          break;
!     //found player
      if (I < 2)
      {
!       //player leaves
        pBxxoModule->PlayerAvail[I] = 0;
        dbg_print ("Bxxo: player %d (dev_id %d) left\n", I, event->device_id);
!       //remove player indicator
        if (I == pBxxoModule->Player)
        {
!         BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0, 3, pBxxoModule->MarkY, -1);
!         b_module_paint ((BModule *) pBxxoModule); //put image onto screen
        }
      }
    }
  
!   //key-event
    else if (event->type == B_EVENT_TYPE_KEY)
    {
!     //search for player with device-id
      for (I = 0; I < 2; I++)
!       if (pBxxoModule->PlayerAvail[I] && pBxxoModule->PlayerId[I] == event->device_id)
          break;
!     //found player
      if (I < 2)
      {
!       //get position from key
        switch (event->key)
        {
          case B_KEY_1: X = 0; Y = 0; break;
--- 698,771 ----
  b_xxo_module_event (BModule      *module,
                      BModuleEvent *event)
  {
!   gint I, X, Y;
  
    BxxoModule *pBxxoModule = B_XXO_MODULE (module);
  
!   /* ignore events if game over */
    if (pBxxoModule->GameOver)
      return;
  
!   /* player entered */
    if (event->type == B_EVENT_TYPE_PLAYER_ENTERED)
    {
!     /* search for player not available */
      for (I = 0; I < 2; I++)
        if (!pBxxoModule->PlayerAvail[I])
          break;
!     /* found player */
!     if (I < 2)
      {
!       /* player joins */
        pBxxoModule->PlayerAvail[I] = 1;
        pBxxoModule->PlayerId[I] = event->device_id;
        dbg_print ("Bxxo: player %d (dev_id %d) joined\n", I, event->device_id);
!       /* show player indicator */
        if (I == pBxxoModule->Player)
        {
!         BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0,
!                      3, pBxxoModule->MarkY, I);
!         b_module_paint ((BModule *) pBxxoModule); /* put image onto screen */
        }
      }
    }
  
!   /* player left */
    else if (event->type == B_EVENT_TYPE_PLAYER_LEFT)
    {
!     /* search for player with device-id */
      for (I = 0; I < 2; I++)
!       if (pBxxoModule->PlayerAvail[I]
!           && pBxxoModule->PlayerId[I] == event->device_id)
          break;
!     /* found player */
      if (I < 2)
      {
!       /* player leaves */
        pBxxoModule->PlayerAvail[I] = 0;
        dbg_print ("Bxxo: player %d (dev_id %d) left\n", I, event->device_id);
!       /* remove player indicator */
        if (I == pBxxoModule->Player)
        {
!         BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0,
!                      3, pBxxoModule->MarkY, -1);
!         b_module_paint ((BModule *) pBxxoModule); /* put image onto screen */
        }
      }
    }
  
!   /* key-event */
    else if (event->type == B_EVENT_TYPE_KEY)
    {
!     /* search for player with device-id */
      for (I = 0; I < 2; I++)
!       if (pBxxoModule->PlayerAvail[I]
!           && pBxxoModule->PlayerId[I] == event->device_id)
          break;
!     /* found player */
      if (I < 2)
      {
!       /* get position from key */
        switch (event->key)
        {
          case B_KEY_1: X = 0; Y = 0; break;
***************
*** 775,824 ****
          case B_KEY_9: X = 2; Y = 2; break;
          default: X = -1; Y = -1;
        }
!       //a valid key was pressed by the active player
        if (X >= 0 && Y >= 0 && I == pBxxoModule->Player)
        {
!         //check if position is still free
          if (pBxxoModule->Field[Y][X] < 0)
          {
!           dbg_print ("Bxxo: player %d (dev_id %d) chose field (%d,%d)\n", I, event->device_id, X, Y );
!           //place mark
            pBxxoModule->Field[Y][X] = I;
            BxxoOutMark (pBxxoModule,
!                        (pBxxoModule->MarkX + 1) * X, (pBxxoModule->MarkY + 1) * Y,
                         pBxxoModule->MarkX, pBxxoModule->MarkY, I);
!           //player has won
!           if( BxxoWinCheck( pBxxoModule ) )
            {
!             //game is over
              pBxxoModule->GameOver = 1;
!             //start win time
              pBxxoModule->ChoseTime = -1;
              pBxxoModule->WinTime = BxxoWinTime;
!             //no ticks in current second yet
              pBxxoModule->Ticks = 0;
            }
!           //player has not won
            else
            {
!             //switch to other player
              pBxxoModule->Player = 1 - pBxxoModule->Player;
              pBxxoModule->ChoseTime = BxxoChoseTime;
!             //no ticks in current second yet
              pBxxoModule->Ticks = 0;
            }
  
!           //update player indicator
            if (pBxxoModule->PlayerAvail[pBxxoModule->Player])
!             BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0, 3, pBxxoModule->MarkY,
!                          pBxxoModule->Player);
            else
!             BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0, 3, pBxxoModule->MarkY,
!                          -1);
!           //show choose time
!           BxxoOutNumber( pBxxoModule, pBxxoModule->SizeX - 3, pBxxoModule->SizeY - 5,
                           pBxxoModule->ChoseTime);
!           //put image onto screen
            b_module_paint ((BModule *) pBxxoModule);
          }
        }
--- 779,831 ----
          case B_KEY_9: X = 2; Y = 2; break;
          default: X = -1; Y = -1;
        }
!       /* a valid key was pressed by the active player */
        if (X >= 0 && Y >= 0 && I == pBxxoModule->Player)
        {
!         /* check if position is still free */
          if (pBxxoModule->Field[Y][X] < 0)
          {
!           dbg_print ("Bxxo: player %d (dev_id %d) chose field (%d,%d)\n",
!                      I, event->device_id, X, Y);
!           /* place mark */
            pBxxoModule->Field[Y][X] = I;
            BxxoOutMark (pBxxoModule,
!                        (pBxxoModule->MarkX + 1) * X,
!                        (pBxxoModule->MarkY + 1) * Y,
                         pBxxoModule->MarkX, pBxxoModule->MarkY, I);
!           /* player has won */
!           if (BxxoWinCheck (pBxxoModule))
            {
!             /* game is over */
              pBxxoModule->GameOver = 1;
!             /* start win time */
              pBxxoModule->ChoseTime = -1;
              pBxxoModule->WinTime = BxxoWinTime;
!             /* no ticks in current second yet */
              pBxxoModule->Ticks = 0;
            }
!           /* player has not won */
            else
            {
!             /* switch to other player */
              pBxxoModule->Player = 1 - pBxxoModule->Player;
              pBxxoModule->ChoseTime = BxxoChoseTime;
!             /* no ticks in current second yet */
              pBxxoModule->Ticks = 0;
            }
  
!           /* update player indicator */
            if (pBxxoModule->PlayerAvail[pBxxoModule->Player])
!             BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0,
!                          3, pBxxoModule->MarkY, pBxxoModule->Player);
            else
!             BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0,
!                          3, pBxxoModule->MarkY, -1);
!           /* show choose time */
!           BxxoOutNumber (pBxxoModule, pBxxoModule->SizeX - 3,
!                          pBxxoModule->SizeY - 5,
                           pBxxoModule->ChoseTime);
!           /* put image onto screen */
            b_module_paint ((BModule *) pBxxoModule);
          }
        }
***************
*** 830,946 ****
  b_xxo_module_tick (BModule *module)
  {
    BxxoModule *pBxxoModule = B_XXO_MODULE (module);
!   int X, Y, I;
  
!   //game over - blink with winning line
    if (pBxxoModule->GameOver && pBxxoModule->WinX >= 0 && pBxxoModule->WinY >= 0)
    {
!     //off
      if (pBxxoModule->Ticks == 0)
      {
!       for( I = 0, X = pBxxoModule->WinX, Y = pBxxoModule->WinY; I < 3; I++, X += pBxxoModule->WinDX, Y += pBxxoModule->WinDY )
          BxxoOutMark (pBxxoModule,
                       (pBxxoModule->MarkX + 1) * X, (pBxxoModule->MarkY + 1) * Y,
                       pBxxoModule->MarkX, pBxxoModule->MarkY,
                       -1);
        b_module_paint ((BModule *) pBxxoModule);
      }
!     //on
      if (pBxxoModule->Ticks == 5)
      {
!       for( I = 0, X = pBxxoModule->WinX, Y = pBxxoModule->WinY; I < 3; I++, X += pBxxoModule->WinDX, Y += pBxxoModule->WinDY )
          BxxoOutMark (pBxxoModule,
                       (pBxxoModule->MarkX + 1) * X, (pBxxoModule->MarkY + 1) * Y,
                       pBxxoModule->MarkX, pBxxoModule->MarkY,
                       pBxxoModule->Player);
        b_module_paint ((BModule *) pBxxoModule);
      }
!   } //if (pBxxModule->GameOver ...
  
!   //count ticks
    pBxxoModule->Ticks++;
  
!   //one second elapsed
    if (pBxxoModule->Ticks >= 10)
    {
      pBxxoModule->Ticks = 0;
  
!     //game over
      if (pBxxoModule->GameOver)
      {
!       //decrease win time
        pBxxoModule->WinTime--;
  
!       //win time reached zero
        if (pBxxoModule->WinTime <= 0)
        {
          dbg_print ("Bxxo: requesting stop\n");
!         //clear screen
          b_module_fill (module, 0);
          b_module_paint (module);
!         //request end of game
          b_module_request_stop (module);
!         //we do not want to be called again
          return 0;
        }
!     } //game over
  
!     //game not over
      else
      {
!       //decrease choose time
        pBxxoModule->ChoseTime--;
  
!       //choose time reached zero
        if (pBxxoModule->ChoseTime <= 0)
        {
!         //find position to place mark
!         BxxoModuleChose( pBxxoModule, &X, &Y );
!         dbg_print ("Bxxo: computer chose field (%d,%d) for player %d\n", X, Y, pBxxoModule->Player );
!         //place mark
          pBxxoModule->Field[Y][X] = pBxxoModule->Player;
          BxxoOutMark (pBxxoModule,
                       (pBxxoModule->MarkX + 1) * X, (pBxxoModule->MarkY + 1) * Y,
                       pBxxoModule->MarkX, pBxxoModule->MarkY, pBxxoModule->Player);
!         //player has won
!         if( BxxoWinCheck( pBxxoModule ) )
          {
!           //game is over
            pBxxoModule->GameOver = 1;
!           //start win time
            pBxxoModule->ChoseTime = -1;
            pBxxoModule->WinTime = BxxoWinTime;
!           //no ticks in current second yet
            pBxxoModule->Ticks = 0;
          }
!         //player has not won
          else
          {
!           //switch to other player
            pBxxoModule->Player = 1 - pBxxoModule->Player;
            pBxxoModule->ChoseTime = BxxoChoseTime;
!           //no ticks in current second yet
            pBxxoModule->Ticks = 0;
          }
  
!         //update player indicator
          if (pBxxoModule->PlayerAvail[pBxxoModule->Player])
!           BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0, 3, pBxxoModule->MarkY,
!                        pBxxoModule->Player);
          else
!           BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0, 3, pBxxoModule->MarkY,
!                        -1);
        }
  
!       //show choose time
!       BxxoOutNumber( pBxxoModule, pBxxoModule->SizeX - 3, pBxxoModule->SizeY - 5,
                       pBxxoModule->ChoseTime);
!       //put image onto screen
        b_module_paint ((BModule *) pBxxoModule);
!     } //game not over
!   } //one second elapsed
  
!   //we want to be called again in 100 milliseconds
    return 100;
  }
  
--- 837,957 ----
  b_xxo_module_tick (BModule *module)
  {
    BxxoModule *pBxxoModule = B_XXO_MODULE (module);
!   gint X, Y, I;
  
!   /* game over - blink with winning line */
    if (pBxxoModule->GameOver && pBxxoModule->WinX >= 0 && pBxxoModule->WinY >= 0)
    {
!     /* off */
      if (pBxxoModule->Ticks == 0)
      {
!       for (I = 0, X = pBxxoModule->WinX, Y = pBxxoModule->WinY;
!            I < 3; I++, X += pBxxoModule->WinDX, Y += pBxxoModule->WinDY)
          BxxoOutMark (pBxxoModule,
                       (pBxxoModule->MarkX + 1) * X, (pBxxoModule->MarkY + 1) * Y,
                       pBxxoModule->MarkX, pBxxoModule->MarkY,
                       -1);
        b_module_paint ((BModule *) pBxxoModule);
      }
!     /* on */
      if (pBxxoModule->Ticks == 5)
      {
!       for (I = 0, X = pBxxoModule->WinX, Y = pBxxoModule->WinY;
!            I < 3; I++, X += pBxxoModule->WinDX, Y += pBxxoModule->WinDY)
          BxxoOutMark (pBxxoModule,
                       (pBxxoModule->MarkX + 1) * X, (pBxxoModule->MarkY + 1) * Y,
                       pBxxoModule->MarkX, pBxxoModule->MarkY,
                       pBxxoModule->Player);
        b_module_paint ((BModule *) pBxxoModule);
      }
!   } /* if (pBxxModule->GameOver ... */
  
!   /* count ticks */
    pBxxoModule->Ticks++;
  
!   /* one second elapsed */
    if (pBxxoModule->Ticks >= 10)
    {
      pBxxoModule->Ticks = 0;
  
!     /* game over */
      if (pBxxoModule->GameOver)
      {
!       /* decrease win time */
        pBxxoModule->WinTime--;
  
!       /* win time reached zero */
        if (pBxxoModule->WinTime <= 0)
        {
          dbg_print ("Bxxo: requesting stop\n");
!         /* clear screen */
          b_module_fill (module, 0);
          b_module_paint (module);
!         /* request end of game */
          b_module_request_stop (module);
!         /* we do not want to be called again */
          return 0;
        }
!     } /* game over */
  
!     /* game not over */
      else
      {
!       /* decrease choose time */
        pBxxoModule->ChoseTime--;
  
!       /* choose time reached zero */
        if (pBxxoModule->ChoseTime <= 0)
        {
!         /* find position to place mark */
!         BxxoModuleChose (pBxxoModule, &X, &Y);
!         dbg_print ("Bxxo: computer chose field (%d,%d) for player %d\n",
!                    X, Y, pBxxoModule->Player);
!         /* place mark */
          pBxxoModule->Field[Y][X] = pBxxoModule->Player;
          BxxoOutMark (pBxxoModule,
                       (pBxxoModule->MarkX + 1) * X, (pBxxoModule->MarkY + 1) * Y,
                       pBxxoModule->MarkX, pBxxoModule->MarkY, pBxxoModule->Player);
!         /* player has won */
!         if (BxxoWinCheck (pBxxoModule))
          {
!           /* game is over */
            pBxxoModule->GameOver = 1;
!           /* start win time */
            pBxxoModule->ChoseTime = -1;
            pBxxoModule->WinTime = BxxoWinTime;
!           /* no ticks in current second yet */
            pBxxoModule->Ticks = 0;
          }
!         /* player has not won */
          else
          {
!           /* switch to other player */
            pBxxoModule->Player = 1 - pBxxoModule->Player;
            pBxxoModule->ChoseTime = BxxoChoseTime;
!           /* no ticks in current second yet */
            pBxxoModule->Ticks = 0;
          }
  
!         /* update player indicator */
          if (pBxxoModule->PlayerAvail[pBxxoModule->Player])
!           BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0,
!                        3, pBxxoModule->MarkY, pBxxoModule->Player);
          else
!           BxxoOutMark (pBxxoModule, pBxxoModule->SizeX - 3, 0,
!                        3, pBxxoModule->MarkY, -1);
        }
  
!       /* show choose time */
!       BxxoOutNumber (pBxxoModule, pBxxoModule->SizeX - 3,
!                      pBxxoModule->SizeY - 5,
                       pBxxoModule->ChoseTime);
!       /* put image onto screen */
        b_module_paint ((BModule *) pBxxoModule);
!     } /* game not over */
!   } /* one second elapsed */
  
!   /* we want to be called again in 100 milliseconds */
    return 100;
  }
  
diff -r -C 3 -N blib-1.1.7/modules/characters.c blib-1.1.7-ba20070811/modules/characters.c
*** blib-1.1.7/modules/characters.c	Thu Jan  1 01:00:00 1970
--- blib-1.1.7-ba20070811/modules/characters.c	Sat Aug 11 22:18:43 2007
***************
*** 0 ****
--- 1,2076 ----
+ /* blib - Library of useful things to hack the Blinkenlights
+  *
+  * Copyright (c) 2002-2007  The Blinkenlights Crew
+  *                          Stefan Schuermans <1stein@blinkenarea.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.
+  *
+  * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #include <glib.h>
+ 
+ #include "characters.h"
+ 
+ static const ChFont ChFontNone =
+   {
+     width:        1,
+     height:       1,
+     advance:      1,
+     line_advance: 1,
+     chars:        "",
+     unknown:      "1",
+     data:         { }
+   };
+ 
+ const ChFont *const pChFontNone = &ChFontNone; /* extern */
+ 
+ static const ChFont chfont_3x5 =
+   {
+     width:        3,
+     height:       5,
+     advance:      4,
+     line_advance: 6,
+     chars:        " 0123456789:.-+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
+     unknown: 
+       "111"
+       "111"
+       "111"
+       "111"
+       "111",
+     data:
+       {
+         /* space */
+         "000"
+         "000"
+         "000"
+         "000"
+         "000",
+         /* 0 */
+         "111"
+         "101"
+         "101"
+         "101"
+         "111",
+         /* 1 */
+         "110"
+         "010"
+         "010"
+         "010"
+         "010",
+         /* 2 */
+         "011"
+         "101"
+         "001"
+         "010"
+         "111",
+         /* 3 */
+         "111"
+         "001"
+         "111"
+         "001"
+         "111",
+         /* 4 */
+         "101"
+         "101"
+         "111"
+         "001"
+         "001",
+         /* 5 */
+         "111"
+         "100"
+         "111"
+         "001"
+         "110",
+         /* 6 */
+         "111"
+         "100"
+         "111"
+         "101"
+         "111",
+         /* 7 */
+         "111"
+         "001"
+         "010"
+         "100"
+         "100",
+         /* 8 */
+         "111"
+         "101"
+         "111"
+         "101"
+         "111",
+         /* 9 */
+         "111"
+         "101"
+         "111"
+         "001"
+         "111",
+         /* : */
+         "000"
+         "010"
+         "000"
+         "010"
+         "000",
+         /* . */
+         "000"
+         "000"
+         "000"
+         "000"
+         "010",
+         /* - */
+         "000"
+         "000"
+         "111"
+         "000"
+         "000",
+         /* + */
+         "000"
+         "010"
+         "111"
+         "010"
+         "000",
+         /* A */
+         "111"
+         "101"
+         "111"
+         "101"
+         "101",
+         /* B */
+         "110"
+         "101"
+         "110"
+         "101"
+         "110",
+         /* C */
+         "111"
+         "100"
+         "100"
+         "100"
+         "111",
+         /* D */
+         "110"
+         "101"
+         "101"
+         "101"
+         "110",
+         /* E */
+         "111"
+         "100"
+         "110"
+         "100"
+         "111",
+         /* F */
+         "111"
+         "100"
+         "110"
+         "100"
+         "100",
+         /* G */
+         "111"
+         "100"
+         "101"
+         "101"
+         "111",
+         /* H */
+         "101"
+         "101"
+         "111"
+         "101"
+         "101",
+         /* I */
+         "010"
+         "010"
+         "010"
+         "010"
+         "010",
+         /* J */
+         "001"
+         "001"
+         "001"
+         "101"
+         "010",
+         /* K */
+         "101"
+         "101"
+         "110"
+         "101"
+         "101",
+         /* L */
+         "100"
+         "100"
+         "100"
+         "100"
+         "111",
+         /* M */
+         "101"
+         "111"
+         "101"
+         "101"
+         "101",
+         /* N */
+         "111"
+         "101"
+         "101"
+         "101"
+         "101",
+         /* O */
+         "010"
+         "101"
+         "101"
+         "101"
+         "010",
+         /* P */
+         "110"
+         "101"
+         "110"
+         "100"
+         "100",
+         /* Q */
+         "010"
+         "101"
+         "101"
+         "101"
+         "011",
+         /* R */
+         "110"
+         "101"
+         "110"
+         "101"
+         "101",
+         /* S */
+         "111"
+         "100"
+         "111"
+         "001"
+         "111",
+         /* T */
+         "111"
+         "010"
+         "010"
+         "010"
+         "010",
+         /* U */
+         "101"
+         "101"
+         "101"
+         "101"
+         "111",
+         /* V */
+         "101"
+         "101"
+         "101"
+         "101"
+         "010",
+         /* W */
+         "101"
+         "101"
+         "101"
+         "111"
+         "101",
+         /* X */
+         "101"
+         "101"
+         "010"
+         "101"
+         "101",
+         /* Y */
+         "101"
+         "101"
+         "010"
+         "010"
+         "010",
+         /* Z */
+         "111"
+         "001"
+         "010"
+         "100"
+         "111",
+         /* a */
+         "111"
+         "101"
+         "111"
+         "101"
+         "101",
+         /* b */
+         "110"
+         "101"
+         "110"
+         "101"
+         "110",
+         /* c */
+         "111"
+         "100"
+         "100"
+         "100"
+         "111",
+         /* d */
+         "110"
+         "101"
+         "101"
+         "101"
+         "110",
+         /* e */
+         "111"
+         "100"
+         "110"
+         "100"
+         "111",
+         /* f */
+         "111"
+         "100"
+         "110"
+         "100"
+         "100",
+         /* g */
+         "111"
+         "100"
+         "101"
+         "101"
+         "111",
+         /* h */
+         "101"
+         "101"
+         "111"
+         "101"
+         "101",
+         /* i */
+         "010"
+         "010"
+         "010"
+         "010"
+         "010",
+         /* j */
+         "001"
+         "001"
+         "001"
+         "101"
+         "010",
+         /* k */
+         "101"
+         "101"
+         "110"
+         "101"
+         "101",
+         /* l */
+         "100"
+         "100"
+         "100"
+         "100"
+         "111",
+         /* m */
+         "101"
+         "111"
+         "101"
+         "101"
+         "101",
+         /* n */
+         "111"
+         "101"
+         "101"
+         "101"
+         "101",
+         /* o */
+         "010"
+         "101"
+         "101"
+         "101"
+         "010",
+         /* p */
+         "110"
+         "101"
+         "110"
+         "100"
+         "100",
+         /* q */
+         "010"
+         "101"
+         "101"
+         "101"
+         "011",
+         /* r */
+         "110"
+         "101"
+         "110"
+         "101"
+         "101",
+         /* s */
+         "111"
+         "100"
+         "111"
+         "001"
+         "111",
+         /* t */
+         "111"
+         "010"
+         "010"
+         "010"
+         "010",
+         /* u */
+         "101"
+         "101"
+         "101"
+         "101"
+         "111",
+         /* v */
+         "101"
+         "101"
+         "101"
+         "101"
+         "010",
+         /* w */
+         "101"
+         "101"
+         "101"
+         "111"
+         "101",
+         /* x */
+         "101"
+         "101"
+         "010"
+         "101"
+         "101",
+         /* y */
+         "101"
+         "101"
+         "010"
+         "010"
+         "010",
+         /* z */
+         "111"
+         "001"
+         "010"
+         "100"
+         "111",
+       }
+   };
+ 
+ static const ChFont chfont_5x7 =
+   {
+     width:        5,
+     height:       7,
+     advance:      6,
+     line_advance: 8,
+     chars:        " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F",
+     unknown: 
+       "11111"
+       "11111"
+       "11111"
+       "11111"
+       "11111"
+       "11111"
+       "11111",
+     data:
+       {
+         /* space */
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* ! */
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00000"
+         "00100",
+         /* " */
+         "01010"
+         "01010"
+         "01010"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* # */
+         "01010"
+         "01010"
+         "11111"
+         "01010"
+         "11111"
+         "01010"
+         "01010",
+         /* $ */
+         "00100"
+         "01111"
+         "10100"
+         "01110"
+         "00101"
+         "11110"
+         "00100",
+         /* % */
+         "11000"
+         "11001"
+         "00010"
+         "00100"
+         "01000"
+         "10011"
+         "00011",
+         /* & */
+         "01100"
+         "10010"
+         "10100"
+         "01000"
+         "10101"
+         "10010"
+         "01101",
+         /* ' */
+         "01100"
+         "00100"
+         "01000"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* ( */
+         "00010"
+         "00100"
+         "01000"
+         "01000"
+         "01000"
+         "00100"
+         "00010",
+         /* ) */
+         "01000"
+         "00100"
+         "00010"
+         "00010"
+         "00010"
+         "00100"
+         "01000",
+         /* * */
+         "00000"
+         "00100"
+         "10101"
+         "01110"
+         "10101"
+         "00100"
+         "00000",
+         /* + */
+         "00000"
+         "00100"
+         "00100"
+         "11111"
+         "00100"
+         "00100"
+         "00000",
+         /* , */
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "01100"
+         "00100"
+         "01000",
+         /* - */
+         "00000"
+         "00000"
+         "00000"
+         "11111"
+         "00000"
+         "00000"
+         "00000",
+         /* . */
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "01100"
+         "01100",
+         /* / */
+         "00000"
+         "00001"
+         "00010"
+         "00100"
+         "01000"
+         "10000"
+         "00000",
+         /* 0 */
+         "01110"
+         "10001"
+         "10011"
+         "10101"
+         "11001"
+         "10001"
+         "01110",
+         /* 1 */
+         "00100"
+         "01100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "01110",
+         /* 2 */
+         "01110"
+         "10001"
+         "00001"
+         "00010"
+         "00100"
+         "01000"
+         "11111",
+         /* 3 */
+         "11111"
+         "00010"
+         "00100"
+         "00010"
+         "00001"
+         "10001"
+         "01110",
+         /* 4 */
+         "00010"
+         "00110"
+         "01010"
+         "10010"
+         "11111"
+         "00010"
+         "00010",
+         /* 5 */
+         "11111"
+         "10000"
+         "11110"
+         "00001"
+         "00001"
+         "10001"
+         "01110",
+         /* 6 */
+         "00110"
+         "01000"
+         "10000"
+         "11110"
+         "10001"
+         "10001"
+         "01110",
+         /* 7 */
+         "11111"
+         "00001"
+         "00010"
+         "00100"
+         "01000"
+         "01000"
+         "01000",
+         /* 8 */
+         "01110"
+         "10001"
+         "10001"
+         "01110"
+         "10001"
+         "10001"
+         "01110",
+         /* 9 */
+         "01110"
+         "10001"
+         "10001"
+         "01111"
+         "00001"
+         "00010"
+         "01100",
+         /* : */
+         "00000"
+         "01100"
+         "01100"
+         "00000"
+         "01100"
+         "01100"
+         "00000",
+         /* ; */
+         "00000"
+         "01100"
+         "01100"
+         "00000"
+         "01100"
+         "00100"
+         "01000",
+         /* < */
+         "00010"
+         "00100"
+         "01000"
+         "10000"
+         "01000"
+         "00100"
+         "00010",
+         /* = */
+         "00000"
+         "00000"
+         "11111"
+         "00000"
+         "11111"
+         "00000"
+         "00000",
+         /* > */
+         "10000"
+         "01000"
+         "00100"
+         "00010"
+         "00100"
+         "01000"
+         "10000",
+         /* ? */
+         "01110"
+         "10001"
+         "00001"
+         "00010"
+         "00100"
+         "00000"
+         "00100",
+         /* @ */
+         "01110"
+         "10001"
+         "10001"
+         "10111"
+         "10111"
+         "10000"
+         "01110",
+         /* A */
+         "01110"
+         "10001"
+         "10001"
+         "10001"
+         "11111"
+         "10001"
+         "10001",
+         /* B */
+         "11110"
+         "10001"
+         "10001"
+         "11110"
+         "10001"
+         "10001"
+         "11110",
+         /* C */
+         "01110"
+         "10001"
+         "10000"
+         "10000"
+         "10000"
+         "10001"
+         "01110",
+         /* D */
+         "11110"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "11110",
+         /* E */
+         "11111"
+         "10000"
+         "10000"
+         "11110"
+         "10000"
+         "10000"
+         "11111",
+         /* F */
+         "11111"
+         "10000"
+         "10000"
+         "11110"
+         "10000"
+         "10000"
+         "10000",
+         /* G */
+         "01110"
+         "10001"
+         "10000"
+         "10111"
+         "10001"
+         "10001"
+         "01111",
+         /* H */
+         "10001"
+         "10001"
+         "10001"
+         "11111"
+         "10001"
+         "10001"
+         "10001",
+         /* I */
+         "01110"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "01110",
+         /* J */
+         "00111"
+         "00010"
+         "00010"
+         "00010"
+         "00010"
+         "10010"
+         "01100",
+         /* K */
+         "10001"
+         "10010"
+         "10100"
+         "11000"
+         "10100"
+         "10010"
+         "10001",
+         /* L */
+         "10000"
+         "10000"
+         "10000"
+         "10000"
+         "10000"
+         "10000"
+         "11111",
+         /* M */
+         "11011"
+         "10101"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001",
+         /* N */
+         "10001"
+         "10001"
+         "11001"
+         "10101"
+         "10011"
+         "10001"
+         "10001",
+         /* O */
+         "01110"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "01110",
+         /* P */
+         "11110"
+         "10001"
+         "10001"
+         "11110"
+         "10000"
+         "10000"
+         "10000",
+         /* Q */
+         "01110"
+         "10001"
+         "10001"
+         "10001"
+         "10101"
+         "10010"
+         "01101",
+         /* R */
+         "11110"
+         "10001"
+         "10001"
+         "11110"
+         "10100"
+         "10010"
+         "10001",
+         /* S */
+         "01111"
+         "10000"
+         "10000"
+         "01110"
+         "00001"
+         "00001"
+         "11110",
+         /* T */
+         "11111"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100",
+         /* U */
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "01110",
+         /* V */
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "01010"
+         "00100",
+         /* W */
+         "10001"
+         "10001"
+         "10001"
+         "10101"
+         "10101"
+         "10101"
+         "01010",
+         /* X */
+         "10001"
+         "10001"
+         "01010"
+         "00100"
+         "01010"
+         "10001"
+         "10001",
+         /* Y */
+         "10001"
+         "10001"
+         "10001"
+         "01010"
+         "00100"
+         "00100"
+         "00100",
+         /* Z */
+         "11111"
+         "00001"
+         "00010"
+         "00100"
+         "01000"
+         "10000"
+         "11111",
+         /* [ */
+         "01110"
+         "01000"
+         "01000"
+         "01000"
+         "01000"
+         "01000"
+         "01110",
+         /* \ */
+         "00000"
+         "10000"
+         "01000"
+         "00100"
+         "00010"
+         "00001"
+         "00000",
+         /* ] */
+         "01110"
+         "00010"
+         "00010"
+         "00010"
+         "00010"
+         "00010"
+         "01110",
+         /* ^ */
+         "00100"
+         "01010"
+         "10001"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* _ */
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "11111",
+         /* ` */
+         "01000"
+         "00100"
+         "00010"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* a */
+         "00000"
+         "00000"
+         "01110"
+         "00001"
+         "01111"
+         "10001"
+         "01111",
+         /* b */
+         "10000"
+         "10000"
+         "10110"
+         "11001"
+         "10001"
+         "10001"
+         "11110",
+         /* c */
+         "00000"
+         "00000"
+         "01111"
+         "10000"
+         "10000"
+         "10000"
+         "01111",
+         /* d */
+         "00001"
+         "00001"
+         "01101"
+         "10011"
+         "10001"
+         "10001"
+         "01111",
+         /* e */
+         "00000"
+         "00000"
+         "01110"
+         "10001"
+         "11111"
+         "10000"
+         "01110",
+         /* f */
+         "00110"
+         "01001"
+         "01000"
+         "11100"
+         "01000"
+         "01000"
+         "01000",
+         /* g */
+         "00000"
+         "00000"
+         "01111"
+         "10001"
+         "01111"
+         "00001"
+         "01110",
+         /* h */
+         "10000"
+         "10000"
+         "10110"
+         "11001"
+         "10001"
+         "10001"
+         "10001",
+         /* i */
+         "00100"
+         "00000"
+         "01100"
+         "00100"
+         "00100"
+         "00100"
+         "01110",
+         /* j */
+         "00010"
+         "00000"
+         "00110"
+         "00010"
+         "00010"
+         "10010"
+         "01100",
+         /* k */
+         "10000"
+         "10000"
+         "10010"
+         "10100"
+         "11000"
+         "10100"
+         "10010",
+         /* l */
+         "01100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "01110",
+         /* m */
+         "00000"
+         "00000"
+         "11010"
+         "10101"
+         "10101"
+         "10001"
+         "10001",
+         /* n */
+         "00000"
+         "00000"
+         "10110"
+         "11001"
+         "10001"
+         "10001"
+         "10001",
+         /* o */
+         "00000"
+         "00000"
+         "01110"
+         "10001"
+         "10001"
+         "10001"
+         "01110",
+         /* p */
+         "00000"
+         "00000"
+         "11110"
+         "10001"
+         "11110"
+         "10000"
+         "10000",
+         /* q */
+         "00000"
+         "00000"
+         "01111"
+         "10001"
+         "01111"
+         "00001"
+         "00001",
+         /* r */
+         "00000"
+         "00000"
+         "10110"
+         "11001"
+         "10000"
+         "10000"
+         "10000",
+         /* s */
+         "00000"
+         "00000"
+         "01111"
+         "10000"
+         "01110"
+         "00001"
+         "11110",
+         /* t */
+         "01000"
+         "01000"
+         "11110"
+         "01000"
+         "01000"
+         "01001"
+         "00110",
+         /* u */
+         "00000"
+         "00000"
+         "10001"
+         "10001"
+         "10001"
+         "10011"
+         "01101",
+         /* v */
+         "00000"
+         "00000"
+         "10001"
+         "10001"
+         "10001"
+         "01010"
+         "00100",
+         /* w */
+         "00000"
+         "00000"
+         "10001"
+         "10001"
+         "10101"
+         "10101"
+         "01010",
+         /* x */
+         "00000"
+         "00000"
+         "10001"
+         "01010"
+         "00100"
+         "01010"
+         "10001",
+         /* y */
+         "00000"
+         "00000"
+         "10001"
+         "10001"
+         "01111"
+         "00001"
+         "01110",
+         /* z */
+         "00000"
+         "00000"
+         "11111"
+         "00010"
+         "00100"
+         "01000"
+         "11111",
+         /* { */
+         "00010"
+         "00100"
+         "00100"
+         "01000"
+         "00100"
+         "00100"
+         "00010",
+         /* | */
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100",
+         /* } */
+         "01000"
+         "00100"
+         "00100"
+         "00010"
+         "00100"
+         "00100"
+         "01000",
+         /* ~ */
+         "01101"
+         "10110"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* delete */
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+       }
+   };
+ 
+ static const ChFont chfont_5x7_wide =
+   {
+     width:        5,
+     height:       7,
+     advance:      9,
+     line_advance: 8,
+     chars:        " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F",
+     unknown: 
+       "11111"
+       "11111"
+       "11111"
+       "11111"
+       "11111"
+       "11111"
+       "11111",
+     data:
+       {
+         /* space */
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* ! */
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00000"
+         "00100",
+         /* " */
+         "01010"
+         "01010"
+         "01010"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* # */
+         "01010"
+         "01010"
+         "11111"
+         "01010"
+         "11111"
+         "01010"
+         "01010",
+         /* $ */
+         "00100"
+         "01111"
+         "10100"
+         "01110"
+         "00101"
+         "11110"
+         "00100",
+         /* % */
+         "11000"
+         "11001"
+         "00010"
+         "00100"
+         "01000"
+         "10011"
+         "00011",
+         /* & */
+         "01100"
+         "10010"
+         "10100"
+         "01000"
+         "10101"
+         "10010"
+         "01101",
+         /* ' */
+         "01100"
+         "00100"
+         "01000"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* ( */
+         "00010"
+         "00100"
+         "01000"
+         "01000"
+         "01000"
+         "00100"
+         "00010",
+         /* ) */
+         "01000"
+         "00100"
+         "00010"
+         "00010"
+         "00010"
+         "00100"
+         "01000",
+         /* * */
+         "00000"
+         "00100"
+         "10101"
+         "01110"
+         "10101"
+         "00100"
+         "00000",
+         /* + */
+         "00000"
+         "00100"
+         "00100"
+         "11111"
+         "00100"
+         "00100"
+         "00000",
+         /* , */
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "01100"
+         "00100"
+         "01000",
+         /* - */
+         "00000"
+         "00000"
+         "00000"
+         "11111"
+         "00000"
+         "00000"
+         "00000",
+         /* . */
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "01100"
+         "01100",
+         /* / */
+         "00000"
+         "00001"
+         "00010"
+         "00100"
+         "01000"
+         "10000"
+         "00000",
+         /* 0 */
+         "01110"
+         "10001"
+         "10011"
+         "10101"
+         "11001"
+         "10001"
+         "01110",
+         /* 1 */
+         "00100"
+         "01100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "01110",
+         /* 2 */
+         "01110"
+         "10001"
+         "00001"
+         "00010"
+         "00100"
+         "01000"
+         "11111",
+         /* 3 */
+         "11111"
+         "00010"
+         "00100"
+         "00010"
+         "00001"
+         "10001"
+         "01110",
+         /* 4 */
+         "00010"
+         "00110"
+         "01010"
+         "10010"
+         "11111"
+         "00010"
+         "00010",
+         /* 5 */
+         "11111"
+         "10000"
+         "11110"
+         "00001"
+         "00001"
+         "10001"
+         "01110",
+         /* 6 */
+         "00110"
+         "01000"
+         "10000"
+         "11110"
+         "10001"
+         "10001"
+         "01110",
+         /* 7 */
+         "11111"
+         "00001"
+         "00010"
+         "00100"
+         "01000"
+         "01000"
+         "01000",
+         /* 8 */
+         "01110"
+         "10001"
+         "10001"
+         "01110"
+         "10001"
+         "10001"
+         "01110",
+         /* 9 */
+         "01110"
+         "10001"
+         "10001"
+         "01111"
+         "00001"
+         "00010"
+         "01100",
+         /* : */
+         "00000"
+         "01100"
+         "01100"
+         "00000"
+         "01100"
+         "01100"
+         "00000",
+         /* ; */
+         "00000"
+         "01100"
+         "01100"
+         "00000"
+         "01100"
+         "00100"
+         "01000",
+         /* < */
+         "00010"
+         "00100"
+         "01000"
+         "10000"
+         "01000"
+         "00100"
+         "00010",
+         /* = */
+         "00000"
+         "00000"
+         "11111"
+         "00000"
+         "11111"
+         "00000"
+         "00000",
+         /* > */
+         "10000"
+         "01000"
+         "00100"
+         "00010"
+         "00100"
+         "01000"
+         "10000",
+         /* ? */
+         "01110"
+         "10001"
+         "00001"
+         "00010"
+         "00100"
+         "00000"
+         "00100",
+         /* @ */
+         "01110"
+         "10001"
+         "10001"
+         "10111"
+         "10111"
+         "10000"
+         "01110",
+         /* A */
+         "01110"
+         "10001"
+         "10001"
+         "10001"
+         "11111"
+         "10001"
+         "10001",
+         /* B */
+         "11110"
+         "10001"
+         "10001"
+         "11110"
+         "10001"
+         "10001"
+         "11110",
+         /* C */
+         "01110"
+         "10001"
+         "10000"
+         "10000"
+         "10000"
+         "10001"
+         "01110",
+         /* D */
+         "11110"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "11110",
+         /* E */
+         "11111"
+         "10000"
+         "10000"
+         "11110"
+         "10000"
+         "10000"
+         "11111",
+         /* F */
+         "11111"
+         "10000"
+         "10000"
+         "11110"
+         "10000"
+         "10000"
+         "10000",
+         /* G */
+         "01110"
+         "10001"
+         "10000"
+         "10111"
+         "10001"
+         "10001"
+         "01111",
+         /* H */
+         "10001"
+         "10001"
+         "10001"
+         "11111"
+         "10001"
+         "10001"
+         "10001",
+         /* I */
+         "01110"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "01110",
+         /* J */
+         "00111"
+         "00010"
+         "00010"
+         "00010"
+         "00010"
+         "10010"
+         "01100",
+         /* K */
+         "10001"
+         "10010"
+         "10100"
+         "11000"
+         "10100"
+         "10010"
+         "10001",
+         /* L */
+         "10000"
+         "10000"
+         "10000"
+         "10000"
+         "10000"
+         "10000"
+         "11111",
+         /* M */
+         "11011"
+         "10101"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001",
+         /* N */
+         "10001"
+         "10001"
+         "11001"
+         "10101"
+         "10011"
+         "10001"
+         "10001",
+         /* O */
+         "01110"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "01110",
+         /* P */
+         "11110"
+         "10001"
+         "10001"
+         "11110"
+         "10000"
+         "10000"
+         "10000",
+         /* Q */
+         "01110"
+         "10001"
+         "10001"
+         "10001"
+         "10101"
+         "10010"
+         "01101",
+         /* R */
+         "11110"
+         "10001"
+         "10001"
+         "11110"
+         "10100"
+         "10010"
+         "10001",
+         /* S */
+         "01111"
+         "10000"
+         "10000"
+         "01110"
+         "00001"
+         "00001"
+         "11110",
+         /* T */
+         "11111"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100",
+         /* U */
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "01110",
+         /* V */
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "10001"
+         "01010"
+         "00100",
+         /* W */
+         "10001"
+         "10001"
+         "10001"
+         "10101"
+         "10101"
+         "10101"
+         "01010",
+         /* X */
+         "10001"
+         "10001"
+         "01010"
+         "00100"
+         "01010"
+         "10001"
+         "10001",
+         /* Y */
+         "10001"
+         "10001"
+         "10001"
+         "01010"
+         "00100"
+         "00100"
+         "00100",
+         /* Z */
+         "11111"
+         "00001"
+         "00010"
+         "00100"
+         "01000"
+         "10000"
+         "11111",
+         /* [ */
+         "01110"
+         "01000"
+         "01000"
+         "01000"
+         "01000"
+         "01000"
+         "01110",
+         /* \ */
+         "00000"
+         "10000"
+         "01000"
+         "00100"
+         "00010"
+         "00001"
+         "00000",
+         /* ] */
+         "01110"
+         "00010"
+         "00010"
+         "00010"
+         "00010"
+         "00010"
+         "01110",
+         /* ^ */
+         "00100"
+         "01010"
+         "10001"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* _ */
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "11111",
+         /* ` */
+         "01000"
+         "00100"
+         "00010"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* a */
+         "00000"
+         "00000"
+         "01110"
+         "00001"
+         "01111"
+         "10001"
+         "01111",
+         /* b */
+         "10000"
+         "10000"
+         "10110"
+         "11001"
+         "10001"
+         "10001"
+         "11110",
+         /* c */
+         "00000"
+         "00000"
+         "01111"
+         "10000"
+         "10000"
+         "10000"
+         "01111",
+         /* d */
+         "00001"
+         "00001"
+         "01101"
+         "10011"
+         "10001"
+         "10001"
+         "01111",
+         /* e */
+         "00000"
+         "00000"
+         "01110"
+         "10001"
+         "11111"
+         "10000"
+         "01110",
+         /* f */
+         "00110"
+         "01001"
+         "01000"
+         "11100"
+         "01000"
+         "01000"
+         "01000",
+         /* g */
+         "00000"
+         "00000"
+         "01111"
+         "10001"
+         "01111"
+         "00001"
+         "01110",
+         /* h */
+         "10000"
+         "10000"
+         "10110"
+         "11001"
+         "10001"
+         "10001"
+         "10001",
+         /* i */
+         "00100"
+         "00000"
+         "01100"
+         "00100"
+         "00100"
+         "00100"
+         "01110",
+         /* j */
+         "00010"
+         "00000"
+         "00110"
+         "00010"
+         "00010"
+         "10010"
+         "01100",
+         /* k */
+         "10000"
+         "10000"
+         "10010"
+         "10100"
+         "11000"
+         "10100"
+         "10010",
+         /* l */
+         "01100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "01110",
+         /* m */
+         "00000"
+         "00000"
+         "11010"
+         "10101"
+         "10101"
+         "10001"
+         "10001",
+         /* n */
+         "00000"
+         "00000"
+         "10110"
+         "11001"
+         "10001"
+         "10001"
+         "10001",
+         /* o */
+         "00000"
+         "00000"
+         "01110"
+         "10001"
+         "10001"
+         "10001"
+         "01110",
+         /* p */
+         "00000"
+         "00000"
+         "11110"
+         "10001"
+         "11110"
+         "10000"
+         "10000",
+         /* q */
+         "00000"
+         "00000"
+         "01111"
+         "10001"
+         "01111"
+         "00001"
+         "00001",
+         /* r */
+         "00000"
+         "00000"
+         "10110"
+         "11001"
+         "10000"
+         "10000"
+         "10000",
+         /* s */
+         "00000"
+         "00000"
+         "01111"
+         "10000"
+         "01110"
+         "00001"
+         "11110",
+         /* t */
+         "01000"
+         "01000"
+         "11110"
+         "01000"
+         "01000"
+         "01001"
+         "00110",
+         /* u */
+         "00000"
+         "00000"
+         "10001"
+         "10001"
+         "10001"
+         "10011"
+         "01101",
+         /* v */
+         "00000"
+         "00000"
+         "10001"
+         "10001"
+         "10001"
+         "01010"
+         "00100",
+         /* w */
+         "00000"
+         "00000"
+         "10001"
+         "10001"
+         "10101"
+         "10101"
+         "01010",
+         /* x */
+         "00000"
+         "00000"
+         "10001"
+         "01010"
+         "00100"
+         "01010"
+         "10001",
+         /* y */
+         "00000"
+         "00000"
+         "10001"
+         "10001"
+         "01111"
+         "00001"
+         "01110",
+         /* z */
+         "00000"
+         "00000"
+         "11111"
+         "00010"
+         "00100"
+         "01000"
+         "11111",
+         /* { */
+         "00010"
+         "00100"
+         "00100"
+         "01000"
+         "00100"
+         "00100"
+         "00010",
+         /* | */
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100"
+         "00100",
+         /* } */
+         "01000"
+         "00100"
+         "00100"
+         "00010"
+         "00100"
+         "00100"
+         "01000",
+         /* ~ */
+         "01101"
+         "10110"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+         /* delete */
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000"
+         "00000",
+       }
+   };
+ 
+ const ChFont *fontList[] =
+   {
+     &chfont_3x5,
+     &chfont_5x7,
+     &chfont_5x7_wide,
+   };
+ 
+ /* select a font */
+ const ChFont *selectChFont (guint chars, guint lines,
+                             guint max_width, guint max_height)
+ {
+   /* search font meeting criteria */
+   gint i;
+   for (i = sizeof (fontList) / sizeof (fontList[0]) - 1;
+        i >= 0; i--)
+     {
+       /* check width */
+       if ((chars < 1
+            || (chars - 1) * fontList[i]->advance
+               + fontList[i]->width <= max_width) &&
+           (lines < 1
+            || (lines - 1) * fontList[i]->line_advance
+               + fontList[i]->height <= max_height))
+         /* return font */
+         return fontList[i];
+     }
+   /* no font found */
+   return &ChFontNone;
+ }
+ 
+ /* get a character from a font */
+ const char *getChFontChar (const ChFont *font, char chr)
+ {
+   /* search character */
+   gint i;
+   for (i = 0; font->chars[i] != 0; i++)
+     if (font->chars[i] == chr)
+       /* return charcter */
+       return font->data[i];
+   /* character not found-> return unknwon character */
+   return font->unknown;
+ }
+ 
diff -r -C 3 -N blib-1.1.7/modules/characters.h blib-1.1.7-ba20070811/modules/characters.h
*** blib-1.1.7/modules/characters.h	Thu Jan  1 01:00:00 1970
--- blib-1.1.7-ba20070811/modules/characters.h	Sat Aug 11 22:18:43 2007
***************
*** 0 ****
--- 1,58 ----
+ /* blib - Library of useful things to hack the Blinkenlights
+  *
+  * Copyright (c) 2002-2007  The Blinkenlights Crew
+  *                          Stefan Schuermans <1stein@blinkenarea.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.
+  *
+  * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #ifndef __CHARACTERS_H__
+ #define __CHARACTERS_H__
+ 
+ #include <glib.h>
+ 
+ /* type for a font */
+ struct _ChFont
+   {
+     guint width, height,          /* parameters of the font */
+           advance, line_advance;
+     gchar *chars;                 /* the characters contained in this font
+                                      (in same order as in data) */
+     gchar *unknown;               /* font data for unknown charcter */
+     gchar *data[];                /* font data for each character */
+                                   /* (top to bottom, line-wise left to right, */
+                                   /*  '0'=off, '1'=on) */
+   };
+ typedef struct _ChFont ChFont;
+ 
+ /* no font */
+ extern const ChFont *const pChFontNone;
+ 
+ /* select a font */
+ /*   returns pointer to font (or pChFontNone if no suitable font is found) */
+ const ChFont *selectChFont (guint chars,       /* number of characters to display */
+                                                /* in a line (for width comparison) */
+                             guint lines,       /* number of lines to display */
+                                                /* (for height comparison) */
+                             guint max_width,   /* maximum width of chars characters */
+                             guint max_height); /* maximum height of font */
+ 
+ /* get a character from a font */
+ /*   returns the character data as string */
+ /*     (top to bottom, line-wise left to right, '0'=off, '1'=on) */
+ const gchar * getChFontChar (const ChFont *font, /* the font to select the character from */
+                              gchar chr);         /* the character to select */
+ 
+ #endif /*  __CHARACTERS_H__  */
diff -r -C 3 -N blib-1.1.7/modules/digits.h blib-1.1.7-ba20070811/modules/digits.h
*** blib-1.1.7/modules/digits.h	Sat Aug 11 22:18:42 2007
--- blib-1.1.7-ba20070811/modules/digits.h	Sat Aug 11 22:18:43 2007
***************
*** 24,31 ****
  typedef struct _BFont {
    gint width, height, advance, num_digits;
  
!   guchar *digits_str;
!   guchar *data[];
  } BFont;
  
  
--- 24,31 ----
  typedef struct _BFont {
    gint width, height, advance, num_digits;
  
!   gchar *digits_str;
!   gchar *data[];
  } BFont;
  
  
***************
*** 323,326 ****
--- 323,432 ----
        }
  };
  
+ static const BFont b_digits_8x7wide = {
+    width: 8,
+    height: 7,
+    advance: 12,
+    num_digits: 12,
+    digits_str: "0123456789: ",
+    data: 
+       { /* 0 */
+         "01111110"
+         "11000111"
+         "11001011"
+         "11001011"
+         "11010011"
+         "11100011"
+         "01111110",
+         /* 1 */
+         "00011100"
+         "01111100"
+         "00011100"
+         "00011100"
+         "00011100"
+         "00011100"
+         "00011100",
+         /* 2 */
+         "00111100"
+         "11111110"
+         "00000110"
+         "00001110"
+         "00011100"
+         "01111000"
+         "11111111",
+         /* 3 */
+         "01111110"
+         "11111111"
+         "00000111"
+         "00111111"
+         "00000111"
+         "11111111"
+         "01111110",
+         /* 4 */
+         "00111111"
+         "01110111"
+         "11100111"
+         "11111111"
+         "00000111"
+         "00000111"
+         "00000111",
+         /* 5 */
+         "11111111"
+         "11111111"
+         "11100000"
+         "11111110"
+         "00000111"
+         "01111111"
+         "11111110",
+         /* 6 */
+         "01111110"
+         "11100111"
+         "11000000"
+         "11111110"
+         "11100111"
+         "11100111"
+         "01111110",
+         /* 7 */
+         "11111111"
+         "11111111"
+         "00000111"
+         "00001110"
+         "00011100"
+         "00111000"
+         "01110000",
+         /* 8 */
+         "00111100"
+         "11100111"
+         "11100111"
+         "01111110"
+         "11100111"
+         "11100111"
+         "00111100",
+         /* 9 */
+         "01111110"
+         "11100111"
+         "11100111"
+         "01111111"
+         "00000011"
+         "11100111"
+         "01111110",
+         /* : */
+         "00000000"
+         "00111000"
+         "00111000"
+         "00000000"
+         "00111000"
+         "00111000"
+         "00000000",
+         /*   */
+         "00000000"
+         "00000000"
+         "00000000"
+         "00000000"
+         "00000000"
+         "00000000"
+         "00000000"
+       }
+ };
+ 
  #endif /*  __DIGITS_H__  */
