diff options
Diffstat (limited to 'kpacman')
40 files changed, 7602 insertions, 0 deletions
diff --git a/kpacman/Makefile.am b/kpacman/Makefile.am new file mode 100644 index 0000000..a98f991 --- /dev/null +++ b/kpacman/Makefile.am @@ -0,0 +1,74 @@ +####### kdevelop will overwrite this part!!! (begin)########## +bin_PROGRAMS = kpacman + +## INCLUDES were found outside kdevelop specific part + +kpacman_SOURCES = kpacmanview.cpp referee.cpp status.cpp painter.cpp score.cpp pacman.cpp monster.cpp keys.cpp fruit.cpp energizer.cpp board.cpp bitfont.cpp kpacman.cpp main.cpp +kpacman_LDADD = -lkdegames $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) $(LIBSOCKET) + + +EXTRA_DIST = main.cpp kpacman.cpp kpacman.h kpacman.desktop lo32-app-kpacman.png lo16-app-kpacman.png bitfont.cpp bitfont.h colors.h bitmaps.h board.cpp board.h energizer.cpp energizer.h fruit.cpp fruit.h keys.cpp keys.h monster.cpp monster.h pacman.cpp pacman.h score.cpp score.h painter.cpp painter.h status.cpp status.h referee.cpp referee.h kpacmanrc kpacmanview.h kpacmanview.cpp kpacmanui.rc hi16-app-kpacman.png hi32-app-kpacman.png + +install-data-local: + $(mkinstalldirs) $(kde_appsdir)/Games/ + $(INSTALL_DATA) $(srcdir)/kpacman.desktop $(kde_appsdir)/Games/kpacman.desktop + $(mkinstalldirs) $(kde_icondir)/locolor/32x32/apps/ + $(INSTALL_DATA) $(srcdir)/lo32-app-kpacman.png $(kde_icondir)/locolor/32x32/apps/kpacman.png + $(mkinstalldirs) $(kde_icondir)/locolor/16x16/apps/ + $(INSTALL_DATA) $(srcdir)/lo16-app-kpacman.png $(kde_icondir)/locolor/16x16/apps/kpacman.png + $(mkinstalldirs) $(kde_confdir)/ + $(INSTALL_DATA) $(srcdir)/kpacmanrc $(kde_confdir)/kpacmanrc + $(mkinstalldirs) $(kde_icondir)/hicolor/16x16/apps/ + $(INSTALL_DATA) $(srcdir)/hi16-app-kpacman.png $(kde_icondir)/hicolor/16x16/apps/kpacman.png + $(mkinstalldirs) $(kde_icondir)/hicolor/32x32/apps/ + $(INSTALL_DATA) $(srcdir)/hi32-app-kpacman.png $(kde_icondir)/hicolor/32x32/apps/kpacman.png + +uninstall-local: + -rm -f $(kde_appsdir)/Games/kpacman.desktop + -rm -f $(kde_icondir)/locolor/32x32/apps/kpacman.png + -rm -f $(kde_icondir)/locolor/16x16/apps/kpacman.png + -rm -f $(kde_confdir)/kpacmanrc + -rm -f $(kde_icondir)/hicolor/16x16/apps/kpacman.png + -rm -f $(kde_icondir)/hicolor/32x32/apps/kpacman.png + +####### kdevelop will overwrite this part!!! (end)############ +# this 10 paths are KDE specific. Use them: +# kde_htmldir Where your docs should go to. (contains lang subdirs) +# kde_appsdir Where your application file (.kdelnk) should go to. +# kde_icondir Where your icon should go to. +# kde_minidir Where your mini icon should go to. +# kde_datadir Where you install application data. (Use a subdir) +# kde_locale Where translation files should go to.(contains lang subdirs) +# kde_cgidir Where cgi-bin executables should go to. +# kde_confdir Where config files should go to. +# kde_mimedir Where mimetypes should go to. +# kde_toolbardir Where general toolbar icons should go to. +# kde_wallpaperdir Where general wallpapers should go to. + +# set the include path for X, qt and KDE +INCLUDES= $(all_includes) + +METASOURCES = AUTO + +# the library search path. +kpacman_LDFLAGS = $(all_libraries) $(KDE_RPATH) + +# Uncomment the following two lines if you add a ui.rc file for your application to make use of +# KDE +rcdir = $(kde_datadir)/kpacman +rc_DATA = kpacmanui.rc + +#WARNING: if you use a ui.rc file above, use: + +# messages: rc.cpp + +# instead of + +# messages: + +messages: rc.cpp + LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \ + if test -n "$$LIST"; then \ + $(XGETTEXT) $$LIST -o $(podir)/kpacman.pot; \ + fi + diff --git a/kpacman/Makefile.in b/kpacman/Makefile.in new file mode 100644 index 0000000..22a7c3e --- /dev/null +++ b/kpacman/Makefile.in @@ -0,0 +1,808 @@ +# Makefile.in generated by automake 1.7.2 from Makefile.am. +# KDE tags expanded automatically by am_edit - $Revision: 1.349.2.2 $ +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@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 = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +ARTSCCONFIG = @ARTSCCONFIG@ +AUTOCONF = @AUTOCONF@ +AUTODIRS = @AUTODIRS@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONF_FILES = @CONF_FILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DCOPIDL = @DCOPIDL@ +DCOPIDL2CPP = @DCOPIDL2CPP@ +DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ +GMSGFMT = @GMSGFMT@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KDECONFIG = @KDECONFIG@ +KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ +KDE_INCLUDES = @KDE_INCLUDES@ +KDE_LDFLAGS = @KDE_LDFLAGS@ +KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ +KDE_MT_LIBS = @KDE_MT_LIBS@ +KDE_PLUGIN = @KDE_PLUGIN@ +KDE_RPATH = @KDE_RPATH@ +KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@ +KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@ +KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@ +KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@ +KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ +LDFLAGS = @LDFLAGS@ +LIBCOMPAT = @LIBCOMPAT@ +LIBCRYPT = @LIBCRYPT@ +LIBDL = @LIBDL@ +LIBJPEG = @LIBJPEG@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPTHREAD = @LIBPTHREAD@ +LIBRESOLV = @LIBRESOLV@ +LIBS = @LIBS@ +LIBSM = @LIBSM@ +LIBSOCKET = @LIBSOCKET@ +LIBTOOL = @LIBTOOL@ +LIBUCB = @LIBUCB@ +LIBUTIL = @LIBUTIL@ +LIBXINERAMA = @LIBXINERAMA@ +LIBZ = @LIBZ@ +LIB_KAB = @LIB_KAB@ +LIB_KABC = @LIB_KABC@ +LIB_KDECORE = @LIB_KDECORE@ +LIB_KDEPRINT = @LIB_KDEPRINT@ +LIB_KDEUI = @LIB_KDEUI@ +LIB_KFILE = @LIB_KFILE@ +LIB_KFM = @LIB_KFM@ +LIB_KHTML = @LIB_KHTML@ +LIB_KIO = @LIB_KIO@ +LIB_KPARTS = @LIB_KPARTS@ +LIB_KSPELL = @LIB_KSPELL@ +LIB_KSYCOCA = @LIB_KSYCOCA@ +LIB_POLL = @LIB_POLL@ +LIB_QPE = @LIB_QPE@ +LIB_QT = @LIB_QT@ +LIB_SMB = @LIB_SMB@ +LIB_X11 = @LIB_X11@ +LIB_XEXT = @LIB_XEXT@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MCOPIDL = @MCOPIDL@ +MEINPROC = @MEINPROC@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +NOOPT_CFLAGS = @NOOPT_CFLAGS@ +NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@ +NOREPO = @NOREPO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +QTE_NORTTI = @QTE_NORTTI@ +QT_INCLUDES = @QT_INCLUDES@ +QT_LDFLAGS = @QT_LDFLAGS@ +RANLIB = @RANLIB@ +REPO = @REPO@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPSUBDIRS = @TOPSUBDIRS@ +UIC = @UIC@ +UIC_TR = @UIC_TR@ +USER_INCLUDES = @USER_INCLUDES@ +USER_LDFLAGS = @USER_LDFLAGS@ +USE_EXCEPTIONS = @USE_EXCEPTIONS@ +USE_RTTI = @USE_RTTI@ +USE_THREADS = @USE_THREADS@ +VERSION = @VERSION@ +WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@ +XGETTEXT = @XGETTEXT@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_INCLUDES = @X_INCLUDES@ +X_LDFLAGS = @X_LDFLAGS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +all_includes = @all_includes@ +all_libraries = @all_libraries@ +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__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@ +kde_appsdir = @kde_appsdir@ +kde_bindir = @kde_bindir@ +kde_confdir = @kde_confdir@ +kde_datadir = @kde_datadir@ +kde_htmldir = @kde_htmldir@ +kde_icondir = @kde_icondir@ +kde_includes = @kde_includes@ +kde_libraries = @kde_libraries@ +kde_libs_htmldir = @kde_libs_htmldir@ +kde_libs_prefix = @kde_libs_prefix@ +kde_locale = @kde_locale@ +kde_mimedir = @kde_mimedir@ +kde_moduledir = @kde_moduledir@ +kde_qtver = @kde_qtver@ +kde_servicesdir = @kde_servicesdir@ +kde_servicetypesdir = @kde_servicetypesdir@ +kde_sounddir = @kde_sounddir@ +kde_styledir = @kde_styledir@ +kde_templatesdir = @kde_templatesdir@ +kde_wallpaperdir = @kde_wallpaperdir@ +kde_widgetdir = @kde_widgetdir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +qt_includes = @qt_includes@ +qt_libraries = @qt_libraries@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +x_includes = @x_includes@ +x_libraries = @x_libraries@ + +####### kdevelop will overwrite this part!!! (begin)########## +bin_PROGRAMS = kpacman + +kpacman_SOURCES = kpacmanview.cpp referee.cpp status.cpp painter.cpp score.cpp pacman.cpp monster.cpp keys.cpp fruit.cpp energizer.cpp board.cpp bitfont.cpp kpacman.cpp main.cpp +kpacman_LDADD = -lkdegames $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) $(LIBSOCKET) + +EXTRA_DIST = main.cpp kpacman.cpp kpacman.h kpacman.desktop lo32-app-kpacman.png lo16-app-kpacman.png bitfont.cpp bitfont.h colors.h bitmaps.h board.cpp board.h energizer.cpp energizer.h fruit.cpp fruit.h keys.cpp keys.h monster.cpp monster.h pacman.cpp pacman.h score.cpp score.h painter.cpp painter.h status.cpp status.h referee.cpp referee.h kpacmanrc kpacmanview.h kpacmanview.cpp kpacmanui.rc hi16-app-kpacman.png hi32-app-kpacman.png + +####### kdevelop will overwrite this part!!! (end)############ +# this 10 paths are KDE specific. Use them: +# kde_htmldir Where your docs should go to. (contains lang subdirs) +# kde_appsdir Where your application file (.kdelnk) should go to. +# kde_icondir Where your icon should go to. +# kde_minidir Where your mini icon should go to. +# kde_datadir Where you install application data. (Use a subdir) +# kde_locale Where translation files should go to.(contains lang subdirs) +# kde_cgidir Where cgi-bin executables should go to. +# kde_confdir Where config files should go to. +# kde_mimedir Where mimetypes should go to. +# kde_toolbardir Where general toolbar icons should go to. +# kde_wallpaperdir Where general wallpapers should go to. + +# set the include path for X, qt and KDE +INCLUDES = $(all_includes) + +#>- METASOURCES = AUTO + +# the library search path. +kpacman_LDFLAGS = $(all_libraries) $(KDE_RPATH) + +# Uncomment the following two lines if you add a ui.rc file for your application to make use of +# KDE +rcdir = $(kde_datadir)/kpacman +rc_DATA = kpacmanui.rc +subdir = kpacman +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +bin_PROGRAMS = kpacman$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) + +am_kpacman_OBJECTS = kpacmanview.$(OBJEXT) referee.$(OBJEXT) \ + status.$(OBJEXT) painter.$(OBJEXT) score.$(OBJEXT) \ + pacman.$(OBJEXT) monster.$(OBJEXT) keys.$(OBJEXT) \ + fruit.$(OBJEXT) energizer.$(OBJEXT) board.$(OBJEXT) \ + bitfont.$(OBJEXT) kpacman.$(OBJEXT) main.$(OBJEXT) +#>- kpacman_OBJECTS = $(am_kpacman_OBJECTS) +#>+ 9 +kpacman_final_OBJECTS = kpacman.all_cpp.o +kpacman_nofinal_OBJECTS = kpacmanview.$(OBJEXT) referee.$(OBJEXT) \ + status.$(OBJEXT) painter.$(OBJEXT) score.$(OBJEXT) \ + pacman.$(OBJEXT) monster.$(OBJEXT) keys.$(OBJEXT) \ + fruit.$(OBJEXT) energizer.$(OBJEXT) board.$(OBJEXT) \ + bitfont.$(OBJEXT) kpacman.$(OBJEXT) main.$(OBJEXT)\ +referee.moc.o keys.moc.o kpacmanview.moc.o status.moc.o score.moc.o kpacman.moc.o +@KDE_USE_FINAL_FALSE@kpacman_OBJECTS = $(kpacman_nofinal_OBJECTS) +@KDE_USE_FINAL_TRUE@kpacman_OBJECTS = $(kpacman_final_OBJECTS) +kpacman_DEPENDENCIES = + +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/admin/depcomp +am__depfiles_maybe = depfiles +#>- @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/bitfont.Po ./$(DEPDIR)/board.Po \ +#>- @AMDEP_TRUE@ ./$(DEPDIR)/energizer.Po ./$(DEPDIR)/fruit.Po \ +#>- @AMDEP_TRUE@ ./$(DEPDIR)/keys.Po ./$(DEPDIR)/kpacman.Po \ +#>- @AMDEP_TRUE@ ./$(DEPDIR)/kpacmanview.Po ./$(DEPDIR)/main.Po \ +#>- @AMDEP_TRUE@ ./$(DEPDIR)/monster.Po ./$(DEPDIR)/pacman.Po \ +#>- @AMDEP_TRUE@ ./$(DEPDIR)/painter.Po ./$(DEPDIR)/referee.Po \ +#>- @AMDEP_TRUE@ ./$(DEPDIR)/score.Po ./$(DEPDIR)/status.Po +#>+ 15 +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@DEP_FILES = $(DEPDIR)/referee.moc.P $(DEPDIR)/keys.moc.P $(DEPDIR)/kpacmanview.moc.P $(DEPDIR)/status.moc.P $(DEPDIR)/score.moc.P $(DEPDIR)/kpacman.moc.P $(DEPDIR)/kpacman.all_cpp.P ./$(DEPDIR)/bitfont.Po ./$(DEPDIR)/board.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/energizer.Po ./$(DEPDIR)/fruit.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/keys.Po ./$(DEPDIR)/kpacman.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/kpacmanview.Po ./$(DEPDIR)/main.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/monster.Po ./$(DEPDIR)/pacman.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/painter.Po ./$(DEPDIR)/referee.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/score.Po ./$(DEPDIR)/status.Po +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@DEP_FILES = $(DEPDIR)/referee.moc.P $(DEPDIR)/keys.moc.P $(DEPDIR)/kpacmanview.moc.P $(DEPDIR)/status.moc.P $(DEPDIR)/score.moc.P $(DEPDIR)/kpacman.moc.P ./$(DEPDIR)/bitfont.Po ./$(DEPDIR)/board.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/energizer.Po ./$(DEPDIR)/fruit.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/keys.Po ./$(DEPDIR)/kpacman.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/kpacmanview.Po ./$(DEPDIR)/main.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/monster.Po ./$(DEPDIR)/pacman.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/painter.Po ./$(DEPDIR)/referee.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/score.Po ./$(DEPDIR)/status.Po + +#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ +#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +#>+ 2 +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) +#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \ +#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ +#>- $(AM_CXXFLAGS) $(CXXFLAGS) +#>+ 3 +LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) +CXXLD = $(CXX) +#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ +#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@ +#>+ 2 +CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(kpacman_SOURCES) +DATA = $(rc_DATA) + +DIST_COMMON = Makefile.am Makefile.in +SOURCES = $(kpacman_SOURCES) + +#>- all: all-am +#>+ 1 +all: docs-am all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu kpacman/Makefile +#>+ 3 + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu kpacman/Makefile + cd $(top_srcdir) && perl admin/am_edit kpacman/Makefile.in +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ + rm -f $(DESTDIR)$(bindir)/$$f; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +kpacman$(EXEEXT): $(kpacman_OBJECTS) $(kpacman_DEPENDENCIES) + @rm -f kpacman$(EXEEXT) + $(CXXLINK) $(kpacman_LDFLAGS) $(kpacman_OBJECTS) $(kpacman_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitfont.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/board.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/energizer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fruit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keys.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kpacman.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kpacmanview.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monster.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pacman.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/painter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/referee.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/score.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status.Po@am__quote@ + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.cpp.o: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCXX_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCXX_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +.cpp.obj: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ +@am__fastdepCXX_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCXX_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` + +.cpp.lo: +@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCXX_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \ +@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCXX_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -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: +rcDATA_INSTALL = $(INSTALL_DATA) +install-rcDATA: $(rc_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(rcdir) + @list='$(rc_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(rcDATA_INSTALL) $$d$$p $(DESTDIR)$(rcdir)/$$f"; \ + $(rcDATA_INSTALL) $$d$$p $(DESTDIR)$(rcdir)/$$f; \ + done + +uninstall-rcDATA: + @$(NORMAL_UNINSTALL) + @list='$(rc_DATA)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(rcdir)/$$f"; \ + rm -f $(DESTDIR)$(rcdir)/$$f; \ + done + +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 $(PROGRAMS) $(DATA) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(rcdir) + +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_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(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 +#>+ 1 +clean: kde-rpo-clean clean-am + +#>- clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am +#>+ 1 +clean-am: clean-metasources clean-final clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-data-local install-rcDATA + +install-exec-am: install-binPROGRAMS + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +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-binPROGRAMS uninstall-info-am uninstall-local \ + uninstall-rcDATA + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-depend distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am info info-am install \ + install-am install-binPROGRAMS install-data install-data-am \ + install-data-local install-exec install-exec-am install-info \ + install-info-am install-man install-rcDATA 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-binPROGRAMS \ + uninstall-info-am uninstall-local uninstall-rcDATA + + +install-data-local: +#>- $(mkinstalldirs) $(kde_appsdir)/Games/ +#>+ 1 + $(mkinstalldirs) $(DESTDIR)$(kde_appsdir)/Games/ +#>- $(INSTALL_DATA) $(srcdir)/kpacman.desktop $(kde_appsdir)/Games/kpacman.desktop +#>+ 1 + $(INSTALL_DATA) $(srcdir)/kpacman.desktop $(DESTDIR)$(kde_appsdir)/Games/kpacman.desktop +#>- $(mkinstalldirs) $(kde_icondir)/locolor/32x32/apps/ +#>+ 1 + $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/locolor/32x32/apps/ +#>- $(INSTALL_DATA) $(srcdir)/lo32-app-kpacman.png $(kde_icondir)/locolor/32x32/apps/kpacman.png +#>+ 1 + $(INSTALL_DATA) $(srcdir)/lo32-app-kpacman.png $(DESTDIR)$(kde_icondir)/locolor/32x32/apps/kpacman.png +#>- $(mkinstalldirs) $(kde_icondir)/locolor/16x16/apps/ +#>+ 1 + $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/locolor/16x16/apps/ +#>- $(INSTALL_DATA) $(srcdir)/lo16-app-kpacman.png $(kde_icondir)/locolor/16x16/apps/kpacman.png +#>+ 1 + $(INSTALL_DATA) $(srcdir)/lo16-app-kpacman.png $(DESTDIR)$(kde_icondir)/locolor/16x16/apps/kpacman.png +#>- $(mkinstalldirs) $(kde_confdir)/ +#>+ 1 + $(mkinstalldirs) $(DESTDIR)$(kde_confdir)/ +#>- $(INSTALL_DATA) $(srcdir)/kpacmanrc $(kde_confdir)/kpacmanrc +#>+ 1 + $(INSTALL_DATA) $(srcdir)/kpacmanrc $(DESTDIR)$(kde_confdir)/kpacmanrc +#>- $(mkinstalldirs) $(kde_icondir)/hicolor/16x16/apps/ +#>+ 1 + $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/hicolor/16x16/apps/ +#>- $(INSTALL_DATA) $(srcdir)/hi16-app-kpacman.png $(kde_icondir)/hicolor/16x16/apps/kpacman.png +#>+ 1 + $(INSTALL_DATA) $(srcdir)/hi16-app-kpacman.png $(DESTDIR)$(kde_icondir)/hicolor/16x16/apps/kpacman.png +#>- $(mkinstalldirs) $(kde_icondir)/hicolor/32x32/apps/ +#>+ 1 + $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/hicolor/32x32/apps/ +#>- $(INSTALL_DATA) $(srcdir)/hi32-app-kpacman.png $(kde_icondir)/hicolor/32x32/apps/kpacman.png +#>+ 1 + $(INSTALL_DATA) $(srcdir)/hi32-app-kpacman.png $(DESTDIR)$(kde_icondir)/hicolor/32x32/apps/kpacman.png + +uninstall-local: +#>- -rm -f $(kde_appsdir)/Games/kpacman.desktop +#>+ 1 + -rm -f $(DESTDIR)$(kde_appsdir)/Games/kpacman.desktop +#>- -rm -f $(kde_icondir)/locolor/32x32/apps/kpacman.png +#>+ 1 + -rm -f $(DESTDIR)$(kde_icondir)/locolor/32x32/apps/kpacman.png +#>- -rm -f $(kde_icondir)/locolor/16x16/apps/kpacman.png +#>+ 1 + -rm -f $(DESTDIR)$(kde_icondir)/locolor/16x16/apps/kpacman.png +#>- -rm -f $(kde_confdir)/kpacmanrc +#>+ 1 + -rm -f $(DESTDIR)$(kde_confdir)/kpacmanrc +#>- -rm -f $(kde_icondir)/hicolor/16x16/apps/kpacman.png +#>+ 1 + -rm -f $(DESTDIR)$(kde_icondir)/hicolor/16x16/apps/kpacman.png +#>- -rm -f $(kde_icondir)/hicolor/32x32/apps/kpacman.png +#>+ 1 + -rm -f $(DESTDIR)$(kde_icondir)/hicolor/32x32/apps/kpacman.png + +#WARNING: if you use a ui.rc file above, use: + +# messages: rc.cpp + +# instead of + +# messages: + +messages: rc.cpp + LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \ + if test -n "$$LIST"; then \ + $(XGETTEXT) $$LIST -o $(podir)/kpacman.pot; \ + fi +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +#>+ 3 +referee.moc.cpp: $(srcdir)/referee.h + $(MOC) $(srcdir)/referee.h -o referee.moc.cpp + +#>+ 3 +keys.moc.cpp: $(srcdir)/keys.h + $(MOC) $(srcdir)/keys.h -o keys.moc.cpp + +#>+ 3 +kpacmanview.moc.cpp: $(srcdir)/kpacmanview.h + $(MOC) $(srcdir)/kpacmanview.h -o kpacmanview.moc.cpp + +#>+ 3 +status.moc.cpp: $(srcdir)/status.h + $(MOC) $(srcdir)/status.h -o status.moc.cpp + +#>+ 3 +score.moc.cpp: $(srcdir)/score.h + $(MOC) $(srcdir)/score.h -o score.moc.cpp + +#>+ 3 +kpacman.moc.cpp: $(srcdir)/kpacman.h + $(MOC) $(srcdir)/kpacman.h -o kpacman.moc.cpp + +#>+ 3 +clean-metasources: + -rm -f referee.moc.cpp keys.moc.cpp kpacmanview.moc.cpp status.moc.cpp score.moc.cpp kpacman.moc.cpp + +#>+ 2 +docs-am: + +#>+ 6 +force-reedit: + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu kpacman/Makefile + cd $(top_srcdir) && perl admin/am_edit kpacman/Makefile.in + + +#>+ 11 +kpacman.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/kpacmanview.cpp $(srcdir)/referee.cpp $(srcdir)/status.cpp $(srcdir)/painter.cpp $(srcdir)/score.cpp $(srcdir)/pacman.cpp $(srcdir)/monster.cpp $(srcdir)/keys.cpp $(srcdir)/fruit.cpp $(srcdir)/energizer.cpp $(srcdir)/board.cpp $(srcdir)/bitfont.cpp $(srcdir)/kpacman.cpp $(srcdir)/main.cpp keys.moc.cpp referee.moc.cpp kpacmanview.moc.cpp status.moc.cpp score.moc.cpp kpacman.moc.cpp + @echo 'creating kpacman.all_cpp.cpp ...'; \ + rm -f kpacman.all_cpp.files kpacman.all_cpp.final; \ + echo "#define KDE_USE_FINAL 1" >> kpacman.all_cpp.final; \ + for file in kpacmanview.cpp referee.cpp status.cpp painter.cpp score.cpp pacman.cpp monster.cpp keys.cpp fruit.cpp energizer.cpp board.cpp bitfont.cpp kpacman.cpp main.cpp keys.moc.cpp referee.moc.cpp kpacmanview.moc.cpp status.moc.cpp score.moc.cpp kpacman.moc.cpp ; do \ + echo "#include \"$$file\"" >> kpacman.all_cpp.files; \ + test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> kpacman.all_cpp.final; \ + done; \ + cat kpacman.all_cpp.final kpacman.all_cpp.files > kpacman.all_cpp.cpp; \ + rm -f kpacman.all_cpp.final kpacman.all_cpp.files + +#>+ 3 +clean-final: + -rm -f kpacman.all_cpp.cpp + +#>+ 2 +final: + $(MAKE) kpacman_OBJECTS="$(kpacman_final_OBJECTS)" all-am +#>+ 2 +final-install: + $(MAKE) kpacman_OBJECTS="$(kpacman_final_OBJECTS)" install-am +#>+ 2 +no-final: + $(MAKE) kpacman_OBJECTS="$(kpacman_nofinal_OBJECTS)" all-am +#>+ 2 +no-final-install: + $(MAKE) kpacman_OBJECTS="$(kpacman_nofinal_OBJECTS)" install-am +#>+ 3 +cvs-clean: + $(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo diff --git a/kpacman/bitfont.cpp b/kpacman/bitfont.cpp new file mode 100644 index 0000000..40581c8 --- /dev/null +++ b/kpacman/bitfont.cpp @@ -0,0 +1,71 @@ +#include "bitfont.h" + +Bitfont::Bitfont(QString fontname, uchar firstChar, uchar lastChar) +{ + if (!fontname.isEmpty()) + font.load(fontname); + if (font.width() == font.height()) { + fontWidth = fontHeight = font.width() / 16; + fontFirstChar = 1; + fontLastChar = 255; + } else { + fontWidth = font.width()/(lastChar-firstChar+1); + fontHeight = font.height(); + fontFirstChar = firstChar; + fontLastChar = lastChar; + } +} + +QRect Bitfont::rect(QString str) +{ + return QRect(0, 0, str.length()*fontWidth, fontHeight); +} + +QPixmap Bitfont::text(QString str, QColor fg, QColor bg) +{ + QPixmap FG(str.length()*fontWidth, fontHeight); + QBitmap MASK(str.length()*fontWidth, fontHeight, TRUE); + + const uchar *s = (const uchar *) str.data(); + for (uint i = 0; i < str.length(); i++) { + if (font.width() == font.height()) + bitBlt(&MASK, i*fontWidth, 0, &font, + (*s%16)*fontWidth, (*s/16)*fontWidth, fontWidth, fontHeight); + else + if (*s >= fontFirstChar && *s <= fontLastChar) + bitBlt(&MASK, i*fontWidth, 0, &font, + (*s-fontFirstChar)*fontWidth, 0, fontWidth, fontHeight); + s++; + } + + FG.fill(fg); + FG.setMask(MASK); + + if (bg.isValid()) { + QPixmap BG(str.length()*fontWidth, fontHeight); + BG.fill(bg); + bitBlt(&BG, 0, 0, &FG); + return BG; + } else + return FG; +} + +uchar Bitfont::firstChar() +{ + return fontFirstChar; +} + +uchar Bitfont::lastChar() +{ + return fontLastChar; +} + +int Bitfont::width() +{ + return fontWidth; +} + +int Bitfont::height() +{ + return fontHeight; +} diff --git a/kpacman/bitfont.h b/kpacman/bitfont.h new file mode 100644 index 0000000..c12aa0f --- /dev/null +++ b/kpacman/bitfont.h @@ -0,0 +1,31 @@ +#ifndef BITFONT_H +#define BITFONT_H + +#include <qstring.h> +#include <qbitmap.h> +#include <qpixmap.h> +#include <qrect.h> + +#include "colors.h" + +class Bitfont +{ +public: + Bitfont(QString fontname, uchar firstChar, uchar lastChar); + + QPixmap text(QString str, QColor fg = BLACK, QColor bg = QColor()); + QRect rect(QString str); + int width(); + int height(); + uchar firstChar(); + uchar lastChar(); +private: + QBitmap font; + int fontWidth; + int fontHeight; + uchar fontFirstChar; + uchar fontLastChar; +}; + +#endif // BITFONT_H + diff --git a/kpacman/bitmaps.h b/kpacman/bitmaps.h new file mode 100644 index 0000000..f430384 --- /dev/null +++ b/kpacman/bitmaps.h @@ -0,0 +1,67 @@ +static unsigned char demo_bits[] = { + "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + "++*******************************************************++" + "+*********************************************************+" + "+** *** **+" + "+** . . . . . . . . . . . . *** . . . . . . . . . . . . **+" + "+** *** **+" + "+** . ******* . ********* . *** . ********* . ******* . **+" + "+** ******* ********* *** ********* ******* **+" + "+** o ******* . ********* . *** . ********* . ******* o **+" + "+** ******* ********* *** ********* ******* **+" + "+** . ******* . ********* . *** . ********* . ******* . **+" + "+** **+" + "+** . . . . . . . . . . . . . . . . . . . . . . . . . . **+" + "+** **+" + "+** . ******* . *** . *************** . *** . ******* . **+" + "+** ******* *** *************** *** ******* **+" + "+** . ******* . *** . *************** . *** . ******* . **+" + "+** *** *** *** **+" + "+** . . . . . . *** . . . . *** . . . . *** . . . . . . **+" + "+** *** *** *** **+" + "+************ . ********* *** ********* . ************+" + "++*********** ********* *** ********* ***********++" + "+++++++++++** . ********* *** ********* . **+++++++++++" + "+++++++++++** *** *** **+++++++++++" + "+++++++++++** . *** 0 *** . **+++++++++++" + "+++++++++++** *** *** **+++++++++++" + "+++++++++++** . *** ######---###### *** . **+++++++++++" + "+************ *** ######---###### *** ************+" + "+************ . *** ## ## *** . ************+" + " ## ## " + " . ## 2 1 3 ## . " + " ## ## " + "+************ . *** ## ## *** . ************+" + "+************ *** ############### *** ************+" + "+++++++++++** . *** ############### *** . **+++++++++++" + "+++++++++++** *** *** **+++++++++++" + "+++++++++++** . *** F *** . **+++++++++++" + "+++++++++++** *** *** **+++++++++++" + "+++++++++++** . *** *************** *** . **+++++++++++" + "++*********** *** *************** *** ***********++" + "+************ . *** *************** *** . ************+" + "+** *** **+" + "+** . . . . . . . . . . . . *** . . . . . . . . . . . . **+" + "+** *** **+" + "+** . ******* . ********* . *** . ********* . ******* . **+" + "+** ******* ********* *** ********* ******* **+" + "+** . ******* . ********* . *** . ********* . ******* . **+" + "+** *** *** **+" + "+** o . . *** . . . . . . . P . . . . . . . *** . . o **+" + "+** *** *** **+" + "+****** . *** . *** . *************** . *** . *** . ******+" + "+****** *** *** *************** *** *** ******+" + "+****** . *** . *** . *************** . *** . *** . ******+" + "+** *** *** *** **+" + "+** . . . . . . *** . . . . *** . . . . *** . . . . . . **+" + "+** *** *** *** **+" + "+** . ******************* . *** . ******************* . **+" + "+** ******************* *** ******************* **+" + "+** . ******************* . *** . ******************* . **+" + "+** **+" + "+** . . . . . . . . . . . . . . . . . . . . . . . . . . **+" + "+** **+" + "+*********************************************************+" + "++*******************************************************++" + "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" +}; diff --git a/kpacman/board.cpp b/kpacman/board.cpp new file mode 100644 index 0000000..5a30994 --- /dev/null +++ b/kpacman/board.cpp @@ -0,0 +1,420 @@ +#include <kapp.h> +#include <klocale.h> + +#include <qrect.h> +#include <qregexp.h> +#include <qmessagebox.h> +#include <qfile.h> +#include <qtextstream.h> + +#include "board.h" +#include "bitmaps.h" + +Board::Board(int size) : QArray<int> (size) +{ + sz = size; // set size of board + + map = ""; + mapName = ""; // no map loaded so far + + init(None); // initialize varibales +} + +void Board::init(Image image, QString levelName) +{ + prisonEntry = OUT; + prisonExit = OUT; + fruitHome = OUT; + fruitPosition = OUT; + pacmanHome = OUT; + pacmanPosition = OUT; + for (int m = 0; m < 8; m++) { + monsterHome[m] = OUT; + monsterPosition[m] = OUT; + } + for (int e = 0; e < 8; e++) { + energizerPosition[e] = OUT; + } + for (int e = 0; e < 8; e++) { + tunnelPosition[e] = OUT; + } + + fill(0); + numPoints = 0; + numEnergizers = 0; + numMonsters = 0; + numTunnels = 0; + + if (!levelName.isNull() && !levelName.isEmpty()) + if (mapName == levelName) + image = File; + else { + QFile levelFile(levelName); + if (!levelFile.open(IO_ReadOnly)) { + + QString msg = i18n("The levelmap could not be constructed.\n\n" + "The file '@LEVELNAME@' does not exist,\n" + "or could not be opened for reading."); + msg.replace(QRegExp("@LEVELNAME@"), levelName); + // QMessageBox::information(0, i18n("Initialization Error"), msg); + printf("%s\n", msg.data()); + } else { + map.fill(' ', BoardHeight*BoardWidth); + int height = 0; + + QTextStream levelStream(&levelFile); + while (!levelStream.eof() && height < BoardHeight) { + QString line = levelStream.readLine(); + + if (line.find(QRegExp("^ *;")) == -1) { + + line.replace(QRegExp(";.*"), ""); // strip off comments + line.replace(QRegExp("\" *$"), ""); // strip off trailing " + line.replace(QRegExp("^ *\""), ""); // strip off leading " + + map.replace(height*BoardWidth, + (line.length() > BoardWidth) ? BoardWidth : line.length(), + line.data()); + + height++; + } + } + mapName = levelName; + levelFile.close(); + image = File; + } + } + + switch (image) { + case Intro : // setup(demo_bits); + break; + case Demo : setup(demo_bits); + break; + case Level : setup(demo_bits); + break; + case File : setup((uchar *) map.data()); + break; + default : break; + } +} + +void Board::setup(const uchar *buf) +{ + for ( int index = 0; buf[index] != 0 && index < BoardWidth*BoardHeight; index++ ) { + switch (buf[index]) { + case '*' : set(index, brick); break; + case '+' : set(index, out); break; + case '#' : set(index, prison); break; + case '-' : set(index, gate); break; + case 'E' : set(index, tunnel); break; + case '.' : set(index, Point); break; + case 'o' : set(index, energizer); break; + case 'I' : set(index, prisonentry); break; + case 'O' : set(index, prisonexit); break; + case 'F' : set(index, fruithome); break; + case 'P' : set(index, pacmanhome); break; + default : if (buf[index] >= '0' && buf[index] <= '7') { + set(index, monsterhome, buf[index]-(uchar)'0'); + } + } + } +} + +bool Board::inBounds(int pos) +{ + return ( pos < 0 || pos > sz-1 ? FALSE : TRUE); +} + +void Board::set(int pos, Square sq, int m) +{ + if (inBounds(pos)) + switch (sq) { + case out : at(pos) = OUT; break; + case Point : at(pos) |= pointBit; numPoints++; break; + case tunnel : at(pos) = sq; + for (int e = 0; e < numTunnels; e++) { // if tunnel is already on board + if (tunnelPosition[e] == pos) // don't do it again. + pos = OUT; + } + if (pos != OUT) { + tunnelPosition[numTunnels] = pos; + numTunnels++; + } + break; + case energizer : at(pos) |= energizerBit; + for (int e = 0; e < numEnergizers; e++) { + if (energizerPosition[e] == pos) + pos = OUT; + } + if (pos != OUT) { + energizerPosition[numEnergizers] = pos; + numEnergizers++; + } + break; + case fruit : at(pos) |= fruitBit; fruitPosition = pos; break; + case pacman : at(pos) |= pacmanBit; pacmanPosition = pos; break; + case monster : at(pos) |= (monsterBit << m); + monsterPosition[m] = pos; break; + case prisonentry : prisonEntry = pos; at(pos) = empty; break; + case prisonexit : prisonExit = pos; at(pos) = empty; break; + case fruithome : fruitHome = pos; at(pos) = empty; break; + case pacmanhome : pacmanHome = pos; at(pos) = empty; break; + case monsterhome : monsterHome[m] = pos; at(pos) = empty; + if (m == 0 && prisonExit == OUT) + prisonExit = pos; + if (m == 1 && prisonEntry == OUT) + prisonEntry = pos; + numMonsters++; + break; + default : at(pos) = sq; + } +} + +void Board::reset(int pos, Square sq, int m) +{ + bool found = FALSE; + if (inBounds(pos)) + switch (sq) { + case out : at(pos) = empty; break; + case Point : at(pos) &= ~ pointBit; numPoints--; break; + case energizer : at(pos) &= ~ energizerBit; + for (int e = 0; e < numEnergizers; e++) { // delete the position of the eaten + if (found) // energizer in the position array + energizerPosition[e-1] = energizerPosition[e]; + if (energizerPosition[e] == pos) + found = TRUE; + } + energizerPosition[numEnergizers--] = OUT; + break; + case fruit : at(pos) &= ~ fruitBit; fruitPosition = OUT; break; + case pacman : at(pos) &= ~ pacmanBit; pacmanPosition = OUT; break; + case monster : at(pos) &= ~ (monsterBit << m); + monsterPosition[m] = OUT; break; + default : at(pos) = at(pos) & varBits; + } +} + +int Board::position(Square sq, int m) +{ + switch(sq) { + case prisonentry : return prisonEntry; + case prisonexit : return prisonExit; + case fruit : return fruitPosition; + case fruithome : return fruitHome; + case pacman : return pacmanPosition; + case pacmanhome : return pacmanHome; + case monster : return monsterPosition[m]; + case monsterhome : return monsterHome[m]; + case energizer : return energizerPosition[m]; + case tunnel : return tunnelPosition[m]; + default : return OUT; + } +} + +bool Board::isOut(int pos) +{ + if (inBounds(pos)) + return (at(pos) == OUT ? TRUE : FALSE); + return TRUE; +} + +bool Board::isEmpty(int pos) +{ + if (inBounds(pos)) + return ((at(pos) & fixBits) == empty ? TRUE : FALSE); + return TRUE; +} + +bool Board::isBrick(int pos) +{ + if (inBounds(pos)) + return ((at(pos) & fixBits) == brick ? TRUE : FALSE); + return FALSE; +} + +bool Board::isPrison(int pos) +{ + if (inBounds(pos)) + return ((at(pos) & fixBits) == prison ? TRUE : FALSE); + return FALSE; +} + +bool Board::isGate(int pos) +{ + if (inBounds(pos)) + return ((at(pos) & fixBits) == gate ? TRUE : FALSE); + return FALSE; +} + +bool Board::isTunnel(int pos) +{ + if (inBounds(pos)) + return ((at(pos) & fixBits) == tunnel ? TRUE : FALSE); + return FALSE; +} + +bool Board::isPoint(int pos) +{ + if (inBounds(pos) && at(pos) != OUT) + return ((at(pos) & pointBit) != 0 ? TRUE : FALSE); + return FALSE; +} + +bool Board::isEnergizer(int pos) +{ + if (inBounds(pos) && at(pos) != OUT) + return ((at(pos) & energizerBit) != 0 ? TRUE : FALSE); + return FALSE; +} + +bool Board::isFruit(int pos) +{ + if (inBounds(pos) && at(pos) != OUT) + return ((at(pos) & fruitBit) != 0 ? TRUE : FALSE); + return FALSE; +} + +bool Board::isPacman(int pos) +{ + if (inBounds(pos) && at(pos) != OUT) + return ((at(pos) & pacmanBit) != 0 ? TRUE : FALSE); + return FALSE; +} + +bool Board::isMonster(int pos) +{ + if (inBounds(pos) && at(pos) != OUT) + return ((at(pos) & monsterBits) != 0 ? TRUE : FALSE); + return FALSE; +} + +bool Board::isWay(int pos, int dir, Square sq) { + int p1 = move(pos, dir, 2); + if (p1 == OUT) + return (sq == out ? TRUE : FALSE); + int p2, p3; + if (dir == N || dir == S) { + p2 = move(p1, E); + p3 = move(p1, W); + } else { + p2 = move(p1, N); + p3 = move(p1, S); + } + switch (sq) { + case out : return isOut(p1) | isOut(p2) | isOut(p3); + case empty : return isEmpty(p1) & isEmpty(p2) & isEmpty(p3); + case brick : return isBrick(p1) | isBrick(p2) | isBrick(p3); + case prison : return isPrison(p1) | isPrison(p2) | isPrison(p3); + case gate : return isGate(p1) & isGate(p2) & isGate(p3); + case tunnel : return isTunnel(p1) & + (isTunnel(p2) || isEmpty(p2)) & + (isTunnel(p3) || isEmpty(p3)); + default : return FALSE; + } +} + +bool Board::isJump(int pos, int dir) { + switch (dir) { + case NW: return pos < BoardWidth || x(pos) == 0; + case N: return pos < BoardWidth; + case NE: return pos < BoardWidth || x(pos) == BoardWidth-1; + case W: return x(pos) == 0; + case E: return x(pos) == BoardWidth-1; + case SW: return pos >= sz-BoardWidth || x(pos) == 0; + case S: return pos >= sz-BoardWidth; + case SE: return pos >= sz-BoardWidth || x(pos) == BoardWidth-1; + } + return FALSE; +} + +int Board::move(int pos, int dir, int steps) +{ + if (steps < 0) { // move backwards + dir = turn(dir); // turn around and do your steps + steps *= -1; + } + + while (steps-- != 0) { // until all steps are gone + switch (dir) { + case NW: pos = pos >= BoardWidth && x(pos) > 0 ? (pos-BoardWidth)-1 : sz-1; + break; + case N: pos = pos >= BoardWidth ? pos-BoardWidth : (sz-BoardWidth)+x(pos); + break; + case NE: pos = pos >= BoardWidth && x(pos) < BoardWidth-1 ? + (pos-BoardWidth)+1 : sz-BoardWidth; + break; + case W: pos = x(pos) > 0 ? pos-1 : pos+(BoardWidth-1); + break; + case E: pos = x(pos) < BoardWidth-1 ? pos+1 : pos-(BoardWidth-1); + break; + case SW: pos = pos < sz-BoardWidth && x(pos) > 0 ? (pos+BoardWidth)-1 : BoardWidth-1; + break; + case S: pos = pos < sz-BoardWidth ? pos+BoardWidth : x(pos); + break; + case SE: pos = pos < sz-BoardWidth && x(pos) < BoardWidth-1 ? (pos+BoardWidth)+1 : 0; + break; + } + } + return pos; // here we are +} + +int Board::closeup(int pos, int dir, int target) +{ + if (dir == N || dir == S) { + if (x(target) < x(pos)) + return W; + if (x(target) > x(pos)) + return E; + } else { + if (y(target) < y(pos)) + return N; + if (y(target) > y(pos)) + return S; + } + return dir; +} + +int Board::x(int pos) +{ + return pos % BoardWidth; +} + +int Board::y(int pos) +{ + return pos/BoardWidth; +} + +int Board::turn(int dir) +{ + switch (dir) { + case N : return S; + case NE : return SW; + case E : return W; + case SE : return NW; + case S : return N; + case SW : return NE; + case W : return E; + case NW : return SE; + default : return dir; + } +} + +int Board::points() +{ + return numPoints; +} + +int Board::energizers() +{ + return numEnergizers; +} + +int Board::monsters() +{ + return numMonsters; +} + +int Board::tunnels() +{ + return numTunnels; +} diff --git a/kpacman/board.h b/kpacman/board.h new file mode 100644 index 0000000..fffde95 --- /dev/null +++ b/kpacman/board.h @@ -0,0 +1,102 @@ +#ifndef BOARD_H +#define BOARD_H + +#include <qarray.h> +#include <qstring.h> +#include <qlist.h> +#include <qrect.h> + +#define OUT -1 + +enum Square {out = OUT, empty, brick, prison, gate, tunnel, prisonentry, prisonexit, + Point, energizer, fruit, pacman, monster, + fruithome, pacmanhome, monsterhome}; + +enum Image { None, Intro, Demo, Level, File }; + +#define X -1 +#define N 0 +#define S 1 +#define E 2 +#define W 3 +#define NE 4 +#define SE 5 +#define NW 6 +#define SW 7 + +#define BoardWidth 59 +#define BoardHeight 65 + +#define fixBits 0x0007 +#define varBits 0xFFF8 +#define monsterBits 0xFF00 + +#define pointBit 0x0008 +#define energizerBit 0x0010 +#define fruitBit 0x0020 +#define pacmanBit 0x0040 +#define monsterBit 0x0100 + +class Board : public QArray<int> +{ +public: + Board (int size); + ~Board() {}; + void init(Image image, QString levelName=0); + void setup(const uchar *buf); + + void set(int pos, Square sq, int m = 0); + void reset(int pos, Square sq, int m = 0); + int position(Square sq, int m = 0); + + bool isOut(int pos); + bool isEmpty(int pos); + bool isBrick(int pos); + bool isPrison(int pos); + bool isGate(int pos); + bool isTunnel(int pos); + bool isPoint(int pos); + bool isEnergizer(int pos); + bool isFruit(int pos); + bool isPacman(int pos); + bool isMonster(int pos); + bool isWay(int pos, int dir, Square sq); + bool isJump(int pos, int dir); + + int move(int pos, int dir, int steps = 1); + int closeup(int pos, int dir, int target); + int x(int pos); + int y(int pos); + int turn(int dir); + + int points(); + int energizers(); + int monsters(); + int tunnels(); + +private: + bool inBounds(int pos); + int sz; // size of board + + QString map; + QString mapName; // Filename of the latest loaded map + + int prisonEntry; // position of prisonentry + int prisonExit; // position of prisonexit + int pacmanHome; // startposition of pacman + int monsterHome[8]; // startposition of monsters + int fruitHome; // startposition of fruit + + int pacmanPosition; // actual position of pacman + int monsterPosition[8]; // actual position of monsters + int fruitPosition; // actual position of fruit + int energizerPosition[8]; // actual position of energizers + int tunnelPosition[8]; // position of tunnels + + int numMonsters; // number of monsters on the board + int numPoints; // number of points (left) on the board + int numEnergizers; // number of energizers (left) + int numTunnels; // number of tunnels on the board +}; + +#endif // BOARD_H diff --git a/kpacman/colors.h b/kpacman/colors.h new file mode 100644 index 0000000..6abf385 --- /dev/null +++ b/kpacman/colors.h @@ -0,0 +1,21 @@ +#ifndef COLORS_H +#define COLORS_H + +#include <qcolor.h> + +#define BLACK QColor(Qt::black) +#define RED QColor(Qt::red) +#define BROWN QColor(0xde, 0x95, 0x41) +#define PINK QColor(0xff, 0xba, 0xde) +#define CYAN QColor(0x00, 0xff, 0xde) +#define LIGHTBLUE QColor(0x41, 0xba, 0xde) +#define ORANGE QColor(0xff, 0xba, 0x41) +#define YELLOW QColor(Qt::yellow) +#define BLUE QColor(0x20, 0x20, 0xde) +#define GREEN QColor(Qt::green) +#define LIGHTGREEN QColor(0x41, 0xba, 0x94) +#define FLESH QColor(0xff, 0xba, 0x94) +#define WHITE QColor(0xd8, 0xdc, 0xd8) + +#endif // COLORS_H + diff --git a/kpacman/energizer.cpp b/kpacman/energizer.cpp new file mode 100644 index 0000000..ca08f3b --- /dev/null +++ b/kpacman/energizer.cpp @@ -0,0 +1,61 @@ +#include "energizer.h" + +Energizer::Energizer(Board *b) +{ + board = b; + setOn(); + actualPosition = OUT; + maxPixmaps = 0; +} + +void Energizer::setMaxPixmaps(int max) +{ + maxPixmaps = max; +} + +void Energizer::setOff() +{ + actualState = off; +} + +void Energizer::setOn() +{ + actualState = on; + actualPix = 0; +} + +void Energizer::setPosition(int pos) +{ + board->reset(actualPosition, energizer); + actualPosition = pos; + board->set(actualPosition, energizer); +} + +energizerState Energizer::state() +{ + return actualState; +} + +int Energizer::position() +{ + return actualPosition; +} + +bool Energizer::move() +{ + if (actualPosition == OUT) + return FALSE; + + if (++actualPix >= maxPixmaps) + actualPix = 0; + + return TRUE; +} + +int Energizer::pix() +{ + if (actualPosition == OUT || actualState == off) + return -1; + + return actualPix; +} diff --git a/kpacman/energizer.h b/kpacman/energizer.h new file mode 100644 index 0000000..377cd02 --- /dev/null +++ b/kpacman/energizer.h @@ -0,0 +1,30 @@ +#ifndef ENERGIZER_H +#define ENERGIZER_H + +#include "board.h" + +enum energizerState { on, off }; + +class Energizer { +public: + Energizer(Board *b); + void setMaxPixmaps(int max); + void setOff(); + void setOn(); + void setPosition(int pos); + energizerState state(); + int position(); + bool move(); + int pix(); + +private: + Board *board; + + energizerState actualState; // the state of energizer + + int actualPix; // last Pixmap-index + int maxPixmaps; // Number of Pixmaps (1..) + int actualPosition; // actual position on board +}; + +#endif // ENERGIZER_H diff --git a/kpacman/fruit.cpp b/kpacman/fruit.cpp new file mode 100644 index 0000000..e6ad2d5 --- /dev/null +++ b/kpacman/fruit.cpp @@ -0,0 +1,176 @@ +#include <stdlib.h> + +#include "fruit.h" + +Fruit::Fruit(Board *b) +{ + board = b; + maxPixmaps = 0; + setLevel(0, 0, 0, 0); +} + +void Fruit::setEaten(int duration) +{ + actualState = eaten; + timeLeft = duration; + actualDirection = X; +} + +void Fruit::setLevel(int level, int wDuration, int fDuration, int ticks) +{ + actualLevel = level; + waitDuration = wDuration; + fruitDuration = fDuration; + pauseDuration = ticks; + pause = 0; + actualState = inactive; + timeLeft = waitDuration; + lastPosition = OUT; + setPosition(OUT); + setMovement(OUT, OUT, 0); + actualDirection = X; + setMaxPixmaps(maxPixmaps); +} + +void Fruit::setMaxPixmaps(int max) +{ + maxPixmaps = max; + if (actualLevel-1 < maxPixmaps) + actualPix = actualLevel == 0 ? 0 : actualLevel-1; + else if (maxPixmaps > 0) + actualPix = rand() % maxPixmaps; + else + actualPix = -1; +} + +void Fruit::setMovement(int entry, int tunnel, int iq) +{ + homePosition = board->position(fruithome); + entryPosition = entry; + tunnelPosition = tunnel; + IQ = iq; +} + +void Fruit::setPosition(int pos) +{ + board->reset(lastPosition, fruit); + actualPosition = lastPosition = pos; + board->set(actualPosition, fruit); +} + +void Fruit::setDirection(int dir) +{ + actualDirection = dir; +} + +fruitState Fruit::state() +{ + return actualState; +} + +int Fruit::position() +{ + return actualPosition; +} + +int Fruit::direction() +{ + return actualDirection; +} + +bool Fruit::move(bool activate) +{ + if (timeLeft > 0) { + timeLeft--; + } + + if (actualDirection == X || actualState == inactive) { + if (timeLeft == 0 || (activate && actualState == inactive)) { + if (actualState == inactive) { + if (entryPosition == OUT || tunnelPosition == OUT) { + setPosition(board->position(fruithome)); + } else { + setPosition(entryPosition); + actualDirection = 0; + while (!board->isWay(actualPosition, actualDirection, empty) || + board->isJump(actualPosition, actualDirection)) + actualDirection++; + } + timeLeft = fruitDuration; + setMaxPixmaps(maxPixmaps); + actualState = active; + } else { + actualState = inactive; + setPosition(OUT); + timeLeft = waitDuration; + actualDirection = X; + } + return TRUE; + } + return FALSE; + } + + if (pause-- > 0) + return FALSE; + else + pause = pauseDuration; + + if (actualPosition == OUT) + return FALSE; + + if (actualDirection == X) + return TRUE; + + int d = actualDirection; + + if (rand() % (int) ((190-IQ)/10) == 0) + if (timeLeft > 0) // coming home or leaving again + d = board->closeup(actualPosition, d, homePosition); + else + d = board->closeup(actualPosition, d, tunnelPosition); + else + do // try new direction, but not the opposite + d = rand() % 4; // direction, to prevent hectic movement. + while (d == board->turn(actualDirection)); + + while ((!board->isWay(actualPosition, d, empty) && + !board->isWay(actualPosition, d, tunnel)) || + d == board->turn(actualDirection)) { + if (d != actualDirection) // if new direction is not possible, + d = actualDirection; // try current direction first. + else + d = rand() % 4; + } + + actualDirection = d; + actualPosition = board->move(actualPosition, actualDirection); + + if (actualPosition == homePosition) { + timeLeft = 0; + } + + if (board->isTunnel(actualPosition)) { + setPosition(OUT); + timeLeft = waitDuration; + actualState = inactive; + actualDirection = X; + if (board->tunnels() > 0) { + entryPosition = board->position(tunnel, rand() % board->tunnels()); + tunnelPosition = board->position(tunnel, rand() % board->tunnels()); + } + } + + if (actualPosition != lastPosition) { + setPosition(actualPosition); + } + + return TRUE; +} + +int Fruit::pix() +{ + if (actualPosition == OUT || actualState == inactive) + return -1; + else + return actualPix; +} diff --git a/kpacman/fruit.h b/kpacman/fruit.h new file mode 100644 index 0000000..fbbd9c0 --- /dev/null +++ b/kpacman/fruit.h @@ -0,0 +1,53 @@ +#ifndef FRUIT_H +#define FRUIT_H + +#include <stdlib.h> + +#include "board.h" + +enum fruitState { inactive, active, eaten }; + +class Fruit { +public: + Fruit(Board *b); + void setEaten(int duration); + void setLevel(int level, int wDuration, int fDuration, int ticks = -1); + void setMaxPixmaps(int max); + void setMovement(int entry, int tunnel, int iq); + void setPosition(int pos); + void setDirection(int dir); + fruitState state(); + int position(); + int direction(); + bool move(bool activate=FALSE); + int pix(); + +private: + Board *board; + + int IQ; // Intelligence of movement (0 = dumb..180=smart) + + fruitState actualState; // the state of fruit + + int pauseDuration; // number of ticks before next movement + int pause; // actual ticks before movement (0 = move) + + int timeLeft; // Ticks remaining of current state + + int waitDuration; // Time before fruit appears + int fruitDuration; // Length of active-time in ticks + + int actualDirection; // actual direction of the fruit + int actualPosition; // actual position on board + int lastPosition; // the last position of the fruit + int actualLevel; // level for kind of fruit and score + int actualPix; + int maxPixmaps; // Number of Pixmaps (1..) + + int entryPosition; // where to come in + int homePosition; // where to go, on the way in + int tunnelPosition; // where to exit +}; + +#endif // FRUIT_H + diff --git a/kpacman/hi16-app-kpacman.png b/kpacman/hi16-app-kpacman.png Binary files differnew file mode 100644 index 0000000..7dc8172 --- /dev/null +++ b/kpacman/hi16-app-kpacman.png diff --git a/kpacman/hi32-app-kpacman.png b/kpacman/hi32-app-kpacman.png Binary files differnew file mode 100644 index 0000000..2c2d2e6 --- /dev/null +++ b/kpacman/hi32-app-kpacman.png diff --git a/kpacman/keys.cpp b/kpacman/keys.cpp new file mode 100644 index 0000000..a3c2c81 --- /dev/null +++ b/kpacman/keys.cpp @@ -0,0 +1,190 @@ +#include <kapp.h> +#include <kconfig.h> +#include <klocale.h> +#include <kstddirs.h> + +#include <keys.h> + +#include <kaccel.h> +#include <qpushbt.h> +#include <qlabel.h> +#include <qframe.h> +#include <qkeycode.h> +#include <qpixmap.h> +#include <qstring.h> + +Keys::Keys( QWidget *parent, const char *name) + : QDialog( parent, name, TRUE ) +{ + KStandardDirs *dirs = KGlobal::dirs(); + + QPushButton *okButton = new QPushButton(this); + okButton->setText(i18n("Ok")); + okButton->setFixedSize(okButton->size()); + connect( okButton, SIGNAL(clicked()),this, SLOT(ok()) ); + okButton->move(20,210); + + QPushButton *defaultButton = new QPushButton(this); + defaultButton->setText(i18n("Defaults")); + defaultButton->setFixedSize(defaultButton->size()); + connect( defaultButton, SIGNAL(clicked()),this, SLOT(defaults()) ); + defaultButton->move(140,210); + + QPushButton *cancelButton = new QPushButton(this); + cancelButton->setText(i18n("Cancel")); + cancelButton->setFixedSize(cancelButton->size()); + connect( cancelButton, SIGNAL(clicked()),this, SLOT(reject()) ); + cancelButton->move(260,210); + + QFrame *separator = new QFrame(this); + separator->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + separator->setGeometry( 20, 190, 340, 4 ); + + for ( int x = 0; x < 4; x++) { + QLabel *l = new QLabel(this); + l->setAlignment(AlignCenter); + labels[x] = l; + } + + labels[0]->setGeometry(120, 20, 140, 20 ); + labels[1]->setGeometry(120,160, 140, 20 ); + labels[2]->setGeometry( 20, 92, 100, 20 ); + labels[3]->setGeometry(265, 92, 100, 20 ); + + QString pixPath; + + QPushButton *up = new QPushButton(this); + pixPath = dirs->findResource("appdata", "pics/up.xpm"); + up->setPixmap( QPixmap(pixPath)); + up->setFixedSize(up->pixmap()->size()); + connect( up, SIGNAL(clicked()),this, SLOT(butUp()) ); + up->move(180, 50); + + QPushButton *down = new QPushButton(this); + pixPath = dirs->findResource("appdata", "pics/down.xpm"); + down->setPixmap( QPixmap(pixPath)); + down->setFixedSize(down->pixmap()->size()); + connect( down, SIGNAL(clicked()),this, SLOT(butDown()) ); + down->move(180, 130); + + QPushButton *left = new QPushButton(this); + pixPath = dirs->findResource("appdata", "pics/left.xpm"); + left->setPixmap( QPixmap(pixPath)); + left->setFixedSize(left->pixmap()->size()); + connect( left, SIGNAL(clicked()),this, SLOT(butLeft()) ); + left->move(140, 90); + + QPushButton *right = new QPushButton(this); + pixPath = dirs->findResource("appdata", "pics/right.xpm"); + right->setPixmap( QPixmap(pixPath)); + right->setFixedSize(right->pixmap()->size()); + connect( right, SIGNAL(clicked()),this, SLOT(butRight()) ); + right->move(220, 90); + + + setCaption(i18n("Change Direction Keys")); + setFixedSize(380, 260); + lab = 0; + init(); +} + +void Keys::keyPressEvent( QKeyEvent *e ) +{ + uint kCode = e->key() & ~(SHIFT | CTRL | ALT); + QString string = KAccel::keyToString(kCode); + + if (lab != 0) { + if ( string.isNull() ) + lab->setText(i18n("Undefined key")); + else + lab->setText(string); + } + else if ( lab == 0 && e->key() == Key_Escape) + reject(); +} + +void Keys::butUp() +{ + getKey(0); +} + +void Keys::butDown() +{ + getKey(1); +} + +void Keys::butLeft() +{ + getKey(2); +} + +void Keys::butRight() +{ + getKey(3); +} + +void Keys::getKey(int i) +{ + if ( lab != 0) + focusOut(lab); + + focusIn(labels[i]); +} + +void Keys::focusOut(QLabel *l) +{ + l->setFrameStyle( QFrame::NoFrame ); + l->setBackgroundColor(backgroundColor()); + l->repaint(); +} + +void Keys::focusIn(QLabel *l) +{ + lab = l; + lab->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + lab->setBackgroundColor(white); + lab->repaint(); +} + +void Keys::defaults() +{ + if ( lab != 0) + focusOut(lab); + + lab = 0; + + labels[0]->setText("Up"); + labels[1]->setText("Down"); + labels[2]->setText("Left"); + labels[3]->setText("Right"); +} + +void Keys::init() +{ + QString up("Up"); + up = kapp->config()->readEntry("upKey", (const char*) up); + labels[0]->setText(up); + + QString down("Down"); + down = kapp->config()->readEntry("downKey", (const char*) down); + labels[1]->setText(down); + + QString left("Left"); + left = kapp->config()->readEntry("leftKey", (const char*) left); + labels[2]->setText(left); + + QString right("Right"); + right = kapp->config()->readEntry("rightKey", (const char*) right); + labels[3]->setText(right); +} + +void Keys::ok() +{ + kapp->config()->writeEntry("upKey", (const char*) labels[0]->text() ); + kapp->config()->writeEntry("downKey", (const char*) labels[1]->text() ); + kapp->config()->writeEntry("leftKey", (const char*) labels[2]->text() ); + kapp->config()->writeEntry("rightKey",(const char*) labels[3]->text() ); + kapp->config()->sync(); + + accept(); +} diff --git a/kpacman/keys.h b/kpacman/keys.h new file mode 100644 index 0000000..955afea --- /dev/null +++ b/kpacman/keys.h @@ -0,0 +1,45 @@ +#ifndef KEYS_H +#define KEYS_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kapp.h> + +#include <qdialog.h> +#include <qlabel.h> +#include <qstring.h> + +#include <kaccel.h> + +class Keys : public QDialog +{ + Q_OBJECT +public: + Keys( QWidget *parent=0, const char *name=0 ); + +private slots: + void butRight(); + void butLeft(); + void butUp(); + void butDown(); + + void getKey(int); + void defaults(); + void focusIn(QLabel *); + void focusOut(QLabel *); + + void ok(); + +protected: + void keyPressEvent( QKeyEvent * ); + +private: + void init(); + + QLabel *labels[4]; + QLabel *lab; +}; + +#endif // KEYS_H diff --git a/kpacman/kpacman.cpp b/kpacman/kpacman.cpp new file mode 100644 index 0000000..5479861 --- /dev/null +++ b/kpacman/kpacman.cpp @@ -0,0 +1,474 @@ +/*************************************************************************** + kpacman.cpp - description + ------------------- + begin : Sam Jan 19 13:37:57 CET 2002 + copyright : (C) 1998-2003 by Jörg Thönnissen + email : joe@dsite.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// include files for Qt +#include <qkeycode.h> +#include <qcolor.h> +#include <qstring.h> +#include <qmsgbox.h> + +// include files for KDE +#include <kcolordlg.h> +#include <kstatusbar.h> +#include <kstdaction.h> +#include <kstdgameaction.h> + +// application specific includes +#include "kpacman.h" + +#define ID_STATUS_MSG 1 + +KpacmanApp::KpacmanApp(QWidget *, const char *name) : KMainWindow(0, name) +{ + config=kapp->config(); + + /////////////////////////////////////////////////////////////////// + // call inits to invoke all other construction parts + initStatusBar(); + initActions(); + initView(); + + readOptions(); + + highscoresChecked = false; + focusedPause = false; + + connect(view->referee, SIGNAL(setScore(int, int)), view->score, SLOT(setScore(int, int))); + connect(view->referee, SIGNAL(setPoints(int)), view->score, SLOT(set(int))); + connect(view->referee, SIGNAL(setLifes(int)), view->status, SLOT(setLifes(int))); + connect(view->referee, SIGNAL(setLevel(int)), view->status, SLOT(setLevel(int))); + + connect(view->referee, SIGNAL(focusedGamePause()), this, SLOT(slotFocusedGamePause())); + connect(view->referee, SIGNAL(forcedGameHighscores()), this, SLOT(slotForcedGameHighscores())); + + connect(view->score, SIGNAL(gameHighscores()), this, SLOT(slotGameHighscores())); + connect(view->score, SIGNAL(gameFinished()), this, SLOT(slotGameFinished())); +} + +KpacmanApp::~KpacmanApp() +{ + +} + + +void KpacmanApp::initActions() +{ + gameNew = KStdGameAction::gameNew(this, SLOT(slotGameNew()), actionCollection()); + gamePause = KStdGameAction::pause(this, SLOT(slotGamePause()), actionCollection()); + gamePause->setAccel(Key_F3); + gameQuit = KStdGameAction::quit(this, SLOT(slotGameQuit()), actionCollection()); + gameHighscores = KStdGameAction::highscores(this, SLOT(slotGameHighscores()), actionCollection()); + showMenuBar = KStdAction::showMenubar(this, SLOT(slotShowMenuBar()), actionCollection()); + showToolBar = KStdAction::showToolbar(this, SLOT(slotShowToolBar()), actionCollection()); + showStatusBar = KStdAction::showStatusbar(this, SLOT(slotShowStatusBar()), actionCollection()); + showMouseCursor = new KToggleAction(i18n("Show Mouse&cursor"), 0, + this, SLOT(slotShowMouseCursor()), actionCollection(), + "options_show_mousecursor"); + selectGraphicScheme = new KActionMenu(i18n("&Select graphic scheme"), actionCollection(), + "options_select_graphic_scheme"); + KStdAction::keyBindings(this, SLOT(slotKeyBindings()), actionCollection()); + focusOutPause = new KToggleAction(i18n("Pause in &Background"), 0, + this, SLOT(slotFocusOutPause()), actionCollection(), + "options_focus_out_pause"); + focusInContinue = new KToggleAction(i18n("Continue in &Foreground"), 0, + this, SLOT(slotFocusInContinue()), actionCollection(), + "options_focus_in_continue"); + + showMenuBar->setStatusText(i18n("Enables/disables the menubar")); + showToolBar->setStatusText(i18n("Enables/disables the toolbar")); + showStatusBar->setStatusText(i18n("Enables/disables the statusbar")); + showMouseCursor->setStatusText(i18n("Enable/disables the mousecursor")); + + // use the absolute path to your kpacmanui.rc file for testing purpose in createGUI(); + createGUI(); +} + + +void KpacmanApp::initStatusBar() +{ + /////////////////////////////////////////////////////////////////// + // STATUSBAR + // TODO: add your own items you need for displaying current application status. + statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG); +} + +void KpacmanApp::initView() +{ + //////////////////////////////////////////////////////////////////// + // create the main widget here that is managed by KMainWindow's view-region and + // connect the widget. + + view = new KpacmanView(this); + setCentralWidget(view); + + setFixedSize(view->width(), view->height()); + view->referee->setFocus(); +} + +void KpacmanApp::saveOptions() +{ + // config->setGroup("General Options"); + config->writeEntry("Geometry", size()); + config->writeEntry("ShowMenubar", showMenuBar->isChecked()); + config->writeEntry("ShowToolbar", showToolBar->isChecked()); + config->writeEntry("ShowStatusbar", showStatusBar->isChecked()); + config->writeEntry("ShowMousecursor", showMouseCursor->isChecked()); + config->writeEntry("FocusOutPause", focusOutPause->isChecked()); + config->writeEntry("FocusInContinue", focusInContinue->isChecked()); + config->writeEntry("ToolBarPos", (int) toolBar("mainToolBar")->barPos()); + config->writeEntry("Scheme", scheme); + config->writeEntry("Mode", mode); +} + +void KpacmanApp::readOptions() +{ + + // config->setGroup("General Options"); + + // bar status settings + bool bShowMenubar = config->readBoolEntry("ShowMenubar", true); + showMenuBar->setChecked(bShowMenubar); + slotShowMenuBar(); + + bool bShowToolbar = config->readBoolEntry("ShowToolbar", true); + showToolBar->setChecked(bShowToolbar); + slotShowToolBar(); + + bool bShowStatusbar = config->readBoolEntry("ShowStatusbar", false); + showStatusBar->setChecked(bShowStatusbar); + slotShowStatusBar(); + + // cursor status settings + bool bShowMousecursor = config->readBoolEntry("ShowMousecursor", false); + showMouseCursor->setChecked(bShowMousecursor); + slotShowMouseCursor(); + + // focus status settings + bool bFocusOutPause = config->readBoolEntry("FocusOutPause", false); + focusOutPause->setChecked(bFocusOutPause); + slotFocusOutPause(); + + bool bFocusInContinue = config->readBoolEntry("FocusInContinue", false); + focusInContinue->setChecked(bFocusInContinue); + slotFocusInContinue(); + + // bar position settings + KToolBar::BarPosition toolBarPos; + toolBarPos = (KToolBar::BarPosition) config->readNumEntry("ToolBarPos", KToolBar::Top); + toolBar("mainToolBar")->setBarPos(toolBarPos); + + QSize size = config->readSizeEntry("Geometry"); + if (!size.isEmpty()) + { + resize(size); + } + + // scheme and mode + scheme = config->readNumEntry("Scheme", -1); + mode = config->readNumEntry("Mode", -1); + readSchemes(); +} + +void KpacmanApp::readSchemes() +{ + QString saveGroup = config->group(); + QString group; + QString description; + + int modeCount = config->readNumEntry("ModeCount", -1); + int schemeCount = config->readNumEntry("SchemeCount"); + + modeID.resize(modeCount > 0 ? modeCount : 0); + schemeID.resize(schemeCount); + schemeMode.resize(schemeCount); + + schemesPopup = new QList<KPopupMenu>; + schemesPopup->setAutoDelete(true); + + modesPopup = selectGraphicScheme->popupMenu(); + connect(modesPopup, SIGNAL(activated(int)), this, SLOT(slotSchemeActivated(int))); + + if (schemeCount == 0 || scheme == -1) { + QMessageBox::warning(this, i18n("Configuration Error"), + i18n("There are no schemes defined,\n" + "or no scheme is selected.")); + return; + } + + // create submenus (QPopupMenu) for graphic-modes + for (int m = 0; m < modeCount; m++) { + group.sprintf("Mode %d", m); + config->setGroup(group); + + description = config->readEntry("Description", group); + + KPopupMenu *p = new KPopupMenu; + p->setCheckable(true); + connect(p, SIGNAL(activated(int)), this, SLOT(slotSchemeActivated(int))); + schemesPopup->append(p); + + modeID[m] = modesPopup->insertItem(description, schemesPopup->at(m)); + modesPopup->setItemEnabled(modeID[m], false); + modesPopup->setItemChecked(modeID[m], m == mode); + } + + // create menuitems (insertItem) for graphic-schemes + for (int i = 0; i < schemeCount; i++) { + group.sprintf("Scheme %d", i); + config->setGroup(group); + + description = config->readEntry("Description", group); + schemeMode[i] = config->readNumEntry("Mode", -1); + + if (schemeMode[i] == -1) { + schemeID[i] = modesPopup->insertItem(description); + modesPopup->setItemChecked(schemeID[i], i == scheme); + } else { + schemeID[i] = schemesPopup->at(schemeMode[i])->insertItem(description); + schemesPopup->at(schemeMode[i])->setItemChecked(schemeID[i], i == scheme); + modesPopup->setItemEnabled(modeID[schemeMode[i]], true); + } + } + + config->setGroup(saveGroup); +} + +bool KpacmanApp::queryExit() +{ + saveOptions(); + return true; +} + + +///////////////////////////////////////////////////////////////////// +// SLOT IMPLEMENTATION +///////////////////////////////////////////////////////////////////// + +void KpacmanApp::slotGameNew() +{ + // enable the gameHighscores action, if disabled by forced highscores mode + if (!gameHighscores->isEnabled()) + gameHighscores->setEnabled(true); + + // hide highscores and show board again, if in highscores mode + if (highscoresChecked) + slotGameHighscores(); + + // deactivate pause and uncheck the menuitem, if in pause state + if (gamePause->isChecked()) { + gamePause->setChecked(false); + slotGamePause(); + } + // disable menuitem to prevent interruption of the game + gameNew->setEnabled(false); + + view->referee->play(); +} + +void KpacmanApp::slotGamePause() +{ + view->referee->pause(); + view->score->setPause(gamePause->isChecked()); +} + +void KpacmanApp::slotFocusedGamePause() +{ + // if an focus-event triggers the pause, toggle the gamePause checked + gamePause->setChecked(!gamePause->isChecked()); + focusedPause = !focusedPause; + + slotGamePause(); +} + +void KpacmanApp::slotGameHighscores() +{ + // toggle highscores mode flag + highscoresChecked = !highscoresChecked; + + view->referee->toggleHallOfFame(); + + // show highscore (by lowering referee and status) or return to play (by raising them again) + if (highscoresChecked) { + view->referee->lower(); + view->status->lower(); + } else { + view->status->raise(); + view->referee->raise(); + view->referee->setFocus(); + + // after forced highscores comes the intro again + if (!gameHighscores->isEnabled()) { + gameHighscores->setEnabled(true); + view->referee->intro(); + } + } +} + +void KpacmanApp::slotForcedGameHighscores() +{ + // disable menuitem to prevent closing highscores display + gameHighscores->setEnabled(false); + + slotGameHighscores(); +} + +void KpacmanApp::slotGameQuit() +{ + slotStatusMsg(i18n("Exiting...")); + saveOptions(); + kapp->quit(); +} + +void KpacmanApp::slotShowMenuBar() +{ + slotStatusMsg(i18n("Toggling menubar...")); + /////////////////////////////////////////////////////////////////// + // turn Menubar on or off + if(!showMenuBar->isChecked()) { + menuBar()->hide(); + setFixedSize(view->width(), view->height()); + } else { + menuBar()->show(); + } + + slotStatusMsg(i18n("Ready.")); +} + +void KpacmanApp::slotShowToolBar() +{ + slotStatusMsg(i18n("Toggling toolbar...")); + /////////////////////////////////////////////////////////////////// + // turn Toolbar on or off + if(!showToolBar->isChecked()) { + toolBar("mainToolBar")->hide(); + setFixedSize(view->width(), view->height()); + } else { + toolBar("mainToolBar")->show(); + } + + slotStatusMsg(i18n("Ready.")); +} + +void KpacmanApp::slotShowStatusBar() +{ + slotStatusMsg(i18n("Toggle the statusbar...")); + /////////////////////////////////////////////////////////////////// + // turn Statusbar on or off + if(!showStatusBar->isChecked()) { + statusBar()->hide(); + setFixedSize(view->width(), view->height()); + } else { + statusBar()->show(); + } + + slotStatusMsg(i18n("Ready.")); +} + +void KpacmanApp::slotShowMouseCursor() +{ + slotStatusMsg(i18n("Toggle the mousecursor...")); + /////////////////////////////////////////////////////////////////// + // turn Mousecursor on or off + if(!showMouseCursor->isChecked()) { + view->setCursor(blankCursor); + } else { + view->setCursor(arrowCursor); + } + + slotStatusMsg(i18n("Ready.")); +} + +void KpacmanApp::slotSchemeActivated(int id) +{ + slotStatusMsg(i18n("Graphic scheme selected...")); + /////////////////////////////////////////////////////////////////// + // select activated scheme/mode + + mode = -1; + scheme = -1; + + for (uint s = 0; s < schemeID.size(); s++) { + if (schemeID[s] == id) { + scheme = s; + mode = schemeMode[s]; + } + if (schemeMode[s] == -1) { + modesPopup->setItemChecked(schemeID[s], schemeID[s] == id); + } else { + modesPopup->setItemChecked(modeID[schemeMode[s]], schemeMode[s] == mode); + schemesPopup->at(schemeMode[s])->setItemChecked(schemeID[s], schemeID[s] == id); + } + } + + view->setScheme(scheme, mode); + setFixedSize(view->width(), view->height()); + + slotStatusMsg(i18n("Ready.")); +} + +void KpacmanApp::slotFocusOutPause() +{ + slotStatusMsg(i18n("Toggle focusOutPause...")); + /////////////////////////////////////////////////////////////////// + // turn focusOutPause on or off + view->referee->setFocusOutPause(focusOutPause->isChecked()); + + slotStatusMsg(i18n("Ready.")); +} + +void KpacmanApp::slotFocusInContinue() +{ + slotStatusMsg(i18n("Toggle focusInContinue...")); + /////////////////////////////////////////////////////////////////// + // turn focusInContinue on or off + view->referee->setFocusInContinue(focusInContinue->isChecked()); + + slotStatusMsg(i18n("Ready.")); +} + +void KpacmanApp::slotKeyBindings() +{ + slotStatusMsg(i18n("Configure key bindings...")); + /////////////////////////////////////////////////////////////////// + // configure key bindings + Keys *keys = new Keys(); + if (keys->exec() == QDialog::Accepted) { + view->referee->initKeys(); + view->score->initKeys(); + } + delete keys; + + slotStatusMsg(i18n("Ready.")); +} + +void KpacmanApp::slotGameFinished() +{ + slotStatusMsg(i18n("Game finished...")); + /////////////////////////////////////////////////////////////////// + // enable/disable the menuitem + gameNew->setEnabled(true); + + slotStatusMsg(i18n("Ready.")); +} + +void KpacmanApp::slotStatusMsg(const QString &text) +{ + /////////////////////////////////////////////////////////////////// + // change status message permanently + statusBar()->clear(); + statusBar()->changeItem(text, ID_STATUS_MSG); +} diff --git a/kpacman/kpacman.desktop b/kpacman/kpacman.desktop new file mode 100644 index 0000000..399ab77 --- /dev/null +++ b/kpacman/kpacman.desktop @@ -0,0 +1,12 @@ +# KDE Config File +[Desktop Entry] +Type=Application +Exec=kpacman -caption "%c" %i %m +Icon=kpacman.png +MiniIcon=kpacman.png +DocPath=kpacman/index.html +Comment= +Comment[de]= +Terminal=0 +Name=Kpacman +Name[de]=Kpacman diff --git a/kpacman/kpacman.h b/kpacman/kpacman.h new file mode 100644 index 0000000..527d344 --- /dev/null +++ b/kpacman/kpacman.h @@ -0,0 +1,185 @@ +/*************************************************************************** + kpacman.h - description + ------------------- + begin : Sam Jan 19 13:37:57 CET 2002 + copyright : (C) 1998-2003 by Jörg Thönnissen + email : joe@dsite.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KPACMAN_H +#define KPACMAN_H + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +// include files for Qt +#include <qlist.h> +#include <qfileinf.h> +#include <qregexp.h> + +//include files for KDE +#include <kapp.h> +#include <kmainwindow.h> +#include <kpopupmenu.h> +#include <kaction.h> +#include <klocale.h> +#include <kmenubar.h> + +// application specific includes +#include "kpacmanview.h" +#include "referee.h" +#include "status.h" +#include "score.h" +#include "keys.h" + +// forward declaration of the Kpacman classes +class KpacmanView; + +/** + * The base class for Kpacman application. + */ +class KpacmanApp : public KMainWindow +{ + Q_OBJECT + + friend class KpacmanView; + + public: + /** constructor of KpacmanApp, calls all init functions to create the application. + */ + KpacmanApp(QWidget *parent = 0, const char *name = 0); + virtual ~KpacmanApp(); + + protected: + /** save general Options like all bar positions and status as well as the application specific + * Options to the configuration file + */ + void saveOptions(); + /** read general Options again and initialize all variables + */ + void readOptions(); + /** read graphic schemes and build menu items for selection + */ + void readSchemes(); + /** initializes the KActions of the application */ + void initActions(); + /** sets up the statusbar for the main window by initialzing a statuslabel. + */ + void initStatusBar(); + /** creates the centerwidget of the KTMainWindow instance and sets it as the view + */ + void initView(); + /** queryExit is called by KTMainWindow when the last window of the application is going to be closed + * during the closeEvent(). + * Against the default implementation that just returns true, this calls saveOptions() to save the + * settings of the window's properties. + * @see KTMainWindow#queryExit + * @see KTMainWindow#closeEvent + */ + virtual bool queryExit(); + + + public slots: + /** play new game + */ + void slotGameNew(); + /** pause (continue) game + */ + void slotGamePause(); + /** pause (continue) game triggered by focus events + */ + void slotFocusedGamePause(); + /** toggle the highscores + */ + void slotGameHighscores(); + /** toggle the highscores, forced by the referee + */ + void slotForcedGameHighscores(); + /** save the options, then quits the application. + */ + void slotGameQuit(); + /** toggles the menubar + */ + void slotShowMenuBar(); + /** toggles the toolbar + */ + void slotShowToolBar(); + /** toggles the statusbar + */ + void slotShowStatusBar(); + /** toggles the mousecursor + */ + void slotShowMouseCursor(); + /** graphic scheme activated + * @param id the id of the activated/selected menuitem + */ + void slotSchemeActivated(int id); + /** toggles the focus out pause + */ + void slotFocusOutPause(); + /** toggles the focus in continue + */ + void slotFocusInContinue(); + /** changes the statusbar contents for the standard label permanently, used to indicate current actions. + * @param text the text that is displayed in the statusbar + */ + void slotStatusMsg(const QString &text); + /** configure keysbindings dialog + */ + void slotKeyBindings(); + /** game (including highscores displayed) has been finished + */ + void slotGameFinished(); + + private: + /** the configuration object of the application */ + KConfig *config; + /** view is the main widget which represents your working area. The View + * class should handle all events of the view widget. It is kept empty so + * you can create your view according to your application's needs by + * changing the view class. + */ + KpacmanView *view; + + // KAction pointers to enable/disable actions + KAction* gameNew; + KToggleAction* gamePause; + KAction* gameHighscores; + KAction* gameQuit; + KToggleAction* showMenuBar; + KToggleAction* showToolBar; + KToggleAction* showStatusBar; + KToggleAction* showMouseCursor; + KToggleAction* focusOutPause; + KToggleAction* focusInContinue; + KActionMenu* selectGraphicScheme; + + // active scheme/mode + int scheme; + int mode; + + KPopupMenu *modesPopup; // KAction main scheme selection menu + QList<KPopupMenu> *schemesPopup; // submenus for selecting scheme + + // ID's of the menuitem(s) for finding/selecting scheme by id + QArray<int> modeID; + QArray<int> schemeID; + + QArray<int> schemeMode; // mode(group) of the schemes, -1 if no group + + bool highscoresChecked; // highscores display active + bool focusedPause; // Pause caused by focusEvents +}; + +#endif // KPACMAN_H diff --git a/kpacman/kpacmanrc b/kpacman/kpacmanrc new file mode 100644 index 0000000..156c455 --- /dev/null +++ b/kpacman/kpacmanrc @@ -0,0 +1,70 @@ +FocusInContinue=true +FocusOutPause=true +HideMouseCursor=false +LevelPixmapName=fruit.xpm +Mode=0 +ModeCount=2 +Scheme=0 +SchemeCount=5 +downKey=Down +leftKey=Left +rightKey=Right +upKey=Up + +[Mode 0] +Description=&Pacman + +[Mode 1] +Description=&Ms.Pacman +DyingAnimationMS=150 +EnergizerPixmapName=switch.xpm,,,switch02.xpm,,,switch03.xpm,,,,switch.xpm,,,,,,,,,,,,switch03.xpm,,,,switch.xpm +ExtraLifeScore=-10000,-30000,-50000,30000 +FruitScore=100,200,500,700,1000,2000,5000 +FruitScorePixmapName=fruitscore.xpm +LevelPosition=0,1,2,3,4,5,6 +Levels=29 +MapDirectory=mspacman +MapName=map01,,,map02,,,map03,,,,map04,,,,map03,,,,map04,,,,map03,,,,map04 +PointPixmapName=point.xpm,,,point02.xpm,,,point03.xpm,,,,point.xpm,,,,,,,,,,,,point03.xpm,,,,point.xpm +PrisonPixmapName=prison.xpm,,,prison02.xpm,,,prison03.xpm,,,,prison04.xpm,,,,prison05.xpm,,,,prison06.xpm,,,,prison03.xpm,,,,prison04.xpm +WallPixmapName=wall.xpm,,,wall02.xpm,,,wall03.xpm,,,,wall04.xpm,,,,wall05.xpm,,,,wall06.xpm,,,,wall03.xpm,,,,wall04.xpm + +[Scheme 0] +Description=&MIDWAY MFG.CO. +Description[de]=&MIDWAY MFG.CO. +Font=font-smooth.pbm +Mode=0 +PixmapDirectory= + +[Scheme 1] +Description=MIDWAY MFG.CO. (&tiny) +Description[de]=MIDWAY MFG.CO. (&klein) +Font=font-small.pbm +Mode=0 +PixmapDirectory=tiny + +[Scheme 2] +Description=K&Zacman (incomplete) +Description[de]=K&Zacman (unvollständig) +Font=font-smooth.pbm +FruitPixmapName=../fruit.xpm +LevelPixmapName=../fruit.xpm +PixmapDirectory=zacman +PrisonPixmapName=../prison.xpm + +[Scheme 3] +Description=&MIDWAY MFG.CO. +EyesPixmapName=../eyes.xpm +Font=font-smooth.pbm +Mode=1 +MonsterPixmapName=../monster.xpm +PixmapDirectory=mspacman + +[Scheme 4] +Description=MIDWAY MFG.CO. (&tiny) +Description[de]=MIDWAY MFG.CO. (&klein) +EyesPixmapName=../tiny/eyes.xpm +Font=font-small.pbm +Mode=1 +MonsterPixmapName=../tiny/monster.xpm +PixmapDirectory=mspacman-tiny diff --git a/kpacman/kpacmanui.rc b/kpacman/kpacmanui.rc new file mode 100644 index 0000000..34c3ded --- /dev/null +++ b/kpacman/kpacmanui.rc @@ -0,0 +1,18 @@ +<!DOCTYPE kpartgui> +<kpartgui name="kpacman" version="0.3.2"> +<MenuBar> + <Menu name="game"><text>&Game</text> + </Menu> + <Menu name="settings"><text>&Settings</text> + <Action name="options_show_mousecursor" append="show_merge"/> + <Action name="options_select_graphic_scheme" append="configure_merge"/> + <Action name="options_focus_out_pause" append="configure_merge"/> + <Action name="options_focus_in_continue" append="configure_merge"/> + </Menu> +</MenuBar> + +<ToolBar noMerge="1" name="mainToolBar"><text>Main Toolbar</text> + <Action name="game_new"/> + <Action name="game_pause"/> +</ToolBar> +</kpartgui> diff --git a/kpacman/kpacmanview.cpp b/kpacman/kpacmanview.cpp new file mode 100644 index 0000000..73d3f44 --- /dev/null +++ b/kpacman/kpacmanview.cpp @@ -0,0 +1,161 @@ +/*************************************************************************** + kpacmanview.cpp - description + ------------------- + begin : Sam Jan 19 13:37:57 CET 2002 + copyright : (C) 1998-2003 by Jörg Thönnissen + email : joe@dsite.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// include files for Qt +#include <qmessagebox.h> + +// include files for KDE +#include <kapp.h> +#include <kconfig.h> +#include <kstddirs.h> + +// application specific includes +#include "kpacmanview.h" +#include "bitfont.h" +#include "score.h" +#include "referee.h" +#include "status.h" + +KpacmanView::KpacmanView( QWidget *parent, const char *name) : QWidget( parent, name ) +{ + bitfont = NULL; + fontName = ""; + + scheme = mode = -1; + confScheme(); + + score = new Score(this, name, scheme, mode, bitfont); + referee = new Referee( this, name, scheme, mode, bitfont); + status = new Status(this, name, scheme, mode); + + setFixedSize(referee->width(), bitfont->height()*3 + referee->height() + status->height()); +} + +KpacmanView::~KpacmanView() +{ +} + +void KpacmanView::confMisc(bool defGroup) +{ + KStandardDirs *dirs = KGlobal::dirs(); + QString findPath; + + if (defGroup || kapp->config()->hasKey("Font")) { + fontName = kapp->config()->readEntry("Font"); + + if (fontName.left(1) != "/" && fontName.left(1) != "~") + fontName.insert(0, "fonts/"); + if (fontName.right(1) == "/") + fontName.append("font.xbm"); + + findPath = dirs->findResource("appdata", fontName); + if (!findPath.isEmpty()) + fontName = findPath; + + bitfontFirstChar = kapp->config()->readNumEntry("FontFirstChar", 0x0e); + bitfontLastChar = kapp->config()->readNumEntry("FontLastChar", 0x5f); + } +} + +void KpacmanView::confScheme() +{ + QString lastFontName = fontName; + QString oldgroup = kapp->config()->group(); + QString newgroup; + + // if not set, read mode and scheme from the configfile + if (mode == -1 && scheme == -1) { + scheme = kapp->config()->readNumEntry("Scheme", -1); + mode = kapp->config()->readNumEntry("Mode", -1); + + // if mode is not set in the defGroup-group, lookup the scheme group + if (scheme != -1 || mode == -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + mode = kapp->config()->readNumEntry("Mode", -1); + kapp->config()->setGroup(oldgroup); + } + } + + confMisc(); + + if (mode != -1) { + newgroup.sprintf("Mode %d", mode); + kapp->config()->setGroup(newgroup); + + confMisc(FALSE); + } + + if (scheme != -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + confMisc(FALSE); + } + + if (lastFontName != fontName) { + + if (bitfont != 0) + delete bitfont; + + bitfont = new Bitfont(fontName, bitfontFirstChar, bitfontLastChar); + if (bitfont->width() == 0 || bitfont->height() == 0) { + QString msg = i18n("The bitfont could not be contructed.\n\n" + "The file '@FONTNAME@' does not exist,\n" + "or is of an unknown format."); + msg.replace(QRegExp("@FONTNAME@"), fontName); + // QMessageBox::critical(this, i18n("Initialization Error"), msg); + printf("%s\n", msg.data()); + } + } + + kapp->config()->setGroup(oldgroup); +} + +void KpacmanView::setScheme(int Scheme, int Mode) +{ + mode = Mode; + scheme = Scheme; + + confScheme(); + + score->setScheme(Scheme, Mode, bitfont); + referee->setScheme(Scheme, Mode, bitfont); + status->setScheme(Scheme, Mode); + + setFixedSize(referee->width(), + bitfont->height()*3 + referee->height() + status->height()); + updateGeometry(); + + score->repaint(FALSE); + referee->repaint(FALSE); + status->repaint(FALSE); +} + +void KpacmanView::resizeEvent( QResizeEvent * ) +{ + referee->setGeometry(0, bitfont->height()*3, referee->width(), referee->height()); + referee->setBackgroundColor(BLACK); + + status->setGeometry(0, bitfont->height()*3+referee->height(), referee->width(), + status->height()); + status->setBackgroundColor(BLACK); + + score->setGeometry(0, 0, referee->width(), bitfont->height()*3+referee->height()+status->height()); + score->setBackgroundColor(BLACK); +} diff --git a/kpacman/kpacmanview.h b/kpacman/kpacmanview.h new file mode 100644 index 0000000..e7025e1 --- /dev/null +++ b/kpacman/kpacmanview.h @@ -0,0 +1,68 @@ +/*************************************************************************** + kpacmanview.h - description + ------------------- + begin : Sam Jan 19 13:37:57 CET 2002 + copyright : (C) 1998-2003 by Jörg Thönnissen + email : joe@dsite.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KPACMANVIEW_H +#define KPACMANVIEW_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +//include files for Qt +#include <qwidget.h> +#include <qregexp.h> + +// application specific includes +#include "score.h" +#include "referee.h" +#include "status.h" +#include "painter.h" + +/** The KpacmanView class provides the view widget for the KpacmanApp instance. + * The View instance inherits QWidget as a base class and represents the view object of a KTMainWindow. + */ +class KpacmanView : public QWidget +{ + Q_OBJECT +public: + /** Constructor for the main view */ + KpacmanView ( QWidget *parent = 0, const char *name = 0); + /** Destructor for the main view */ + virtual ~KpacmanView(); + + void setScheme(int scheme=-1, int mode=-1); + Score *score; + Referee *referee; + Status *status; + +protected: + void confScheme(); + void confMisc(bool defGroup=TRUE); + void resizeEvent( QResizeEvent * ); + +private: + Bitfont *bitfont; + uchar bitfontFirstChar; + uchar bitfontLastChar; + + QString fontName; + + int scheme; + int mode; +}; + +#endif // KPACMANVIEW_H diff --git a/kpacman/lo16-app-kpacman.png b/kpacman/lo16-app-kpacman.png Binary files differnew file mode 100644 index 0000000..7dc8172 --- /dev/null +++ b/kpacman/lo16-app-kpacman.png diff --git a/kpacman/lo32-app-kpacman.png b/kpacman/lo32-app-kpacman.png Binary files differnew file mode 100644 index 0000000..2c2d2e6 --- /dev/null +++ b/kpacman/lo32-app-kpacman.png diff --git a/kpacman/main.cpp b/kpacman/main.cpp new file mode 100644 index 0000000..48ebf48 --- /dev/null +++ b/kpacman/main.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Sam Jan 19 13:37:57 CET 2002 + copyright : (C) 1998-2003 by Jörg Thönnissen + email : joe@dsite.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <kcmdlineargs.h> +#include <kaboutdata.h> +#include <klocale.h> + +#include "kpacman.h" + +static const char *description = + I18N_NOOP("A pacman game for the KDE Desktop\n\n" + "The program based on the source of ksnake\n" + "by Michel Filippi (mfilippi@sade.rhein-main.de).\n" + "The design was strongly influenced by the pacman\n" + "(c) 1980 MIDWAY MFG.CO.\n\n" + "I like to thank my girlfriend Elke Krueers for\n" + "the last 14 years of her friendship\n" + "and Christine Nickel for the 'K' in my life."); + +static KCmdLineOptions options[] = +{ + { 0, 0, 0 } + // INSERT YOUR COMMANDLINE OPTIONS HERE +}; + +int main(int argc, char *argv[]) +{ + + KAboutData aboutData( "kpacman", I18N_NOOP("Kpacman"), + VERSION, description, KAboutData::License_GPL, + "(c) 1998-2003, Jörg Thönnissen", 0, 0, "joe@dsite.de"); + aboutData.addAuthor("Jörg Thönnissen",0, "joe@dsite.de"); + KCmdLineArgs::init( argc, argv, &aboutData ); + KCmdLineArgs::addCmdLineOptions( options ); // Add our own options. + + KApplication app; + + KpacmanApp *kpacman = new KpacmanApp(); + kpacman->show(); + + return app.exec(); +} diff --git a/kpacman/monster.cpp b/kpacman/monster.cpp new file mode 100644 index 0000000..2f402b4 --- /dev/null +++ b/kpacman/monster.cpp @@ -0,0 +1,262 @@ +#include "monster.h" +#include "board.h" + +Monster::Monster(Board *b, int mid) +{ + board = b; + ID = mid; + + setREM(0); + setHarmless(0, 0, 0); + setArrested(0, 0); + setFreedom(board->position(prisonexit)); + if (mid == 0) + setPrison(board->position(prisonentry)); + else + setPrison(board->position(monsterhome, mid)); + + actualPosition = lastPosition = OUT; + feetPosition = 0; + IQ = 0; + maxBodyPixmaps = 0; + maxEyesPixmaps = 0; +} + +void Monster::setMaxPixmaps(int maxBody, int maxEyes) +{ + if (feetPosition >= (maxBody/10)) + feetPosition = 0; + maxBodyPixmaps = maxBody; + maxEyesPixmaps = maxEyes; +} + +void Monster::setArrested(int ticks, int duration) +{ + actualState = dangerous; + pauseDuration = ticks; + pause = 0; + arrestDuration = arrestLeft = duration; + arrestPause = ticks; + harmlessLeft = 0; +} + +void Monster::setDangerous(int ticks, int iq) +{ + actualState = dangerous; + pauseDuration = ticks; + pause = 0; + dangerousPause = ticks; + harmlessLeft = 0; + IQ = iq; +} + +void Monster::setHarmless(int ticks, int hDuration, int wDuration) +{ + actualState = harmless; + pauseDuration = ticks; + pause = 0; + harmlessDuration = harmlessLeft = hDuration; + warningDuration = wDuration; +} + +void Monster::setREM(int ticks) +{ + actualState = rem; + pauseDuration = ticks; + pause = 0; +} + +void Monster::setPosition(int pos) +{ + board->reset(lastPosition, monster, ID); // reset old position on the board + actualPosition = lastPosition = pos; // set position of monster + board->set(actualPosition, monster, ID); + feetPosition = 0; +} + +void Monster::setPrison(int pos) +{ + prisonPosition = pos; +} + +void Monster::setFreedom(int pos) +{ + freedomPosition = pos; +} + +void Monster::setDirection(int dir) +{ + if (dir == X) + lastDirection = actualDirection; + actualDirection = dir; +} + +monsterState Monster::state() +{ + return actualState; +} + +int Monster::position() +{ + return actualPosition; +} + +int Monster::direction() +{ + return actualDirection; +} + +int Monster::id() +{ + return ID; +} + +bool Monster::move() +{ + if (arrestLeft > 1) + arrestLeft--; + + if (harmlessLeft > 0) { + harmlessLeft--; + if (harmlessLeft == 0 && actualState == harmless) { + actualState = dangerous; + pauseDuration = dangerousPause; + } + } + + if (pause-- > 0) + return FALSE; + else + pause = pauseDuration; + + if (actualPosition == OUT) + return FALSE; + + if (actualDirection == X) { + if (++feetPosition >= (maxBodyPixmaps/10)) + feetPosition = 0; + return TRUE; + } + + lastPosition = actualPosition; + int d = actualDirection; + + if (arrestLeft > 1) { // during the arrest, only up and down + if (!board->isWay(actualPosition, d, empty) && + !board->isWay(actualPosition, d, tunnel)) + d = board->turn(actualDirection); + } + + if (arrestLeft == 1) { // going out of the prison + if (((d == W || d == E) && + board->x(actualPosition) == board->x(freedomPosition)) || + ((d == S || d == N) && + board->y(actualPosition) == board->y(freedomPosition)) || + board->isWay(actualPosition, d, brick) || + board->isWay(actualPosition, d, prison)) { + d = board->closeup(actualPosition, d, freedomPosition); + } + while (board->isWay(actualPosition, d, brick) || + board->isWay(actualPosition, d, prison)) { + if (d == actualDirection) + d = rand() % 4; + else + d = actualDirection; + } + if (actualState == dangerous) + pauseDuration = dangerousPause; + + } + + if (arrestLeft == 0) + if (actualState == rem) { // on the way to prison + + d = board->closeup(actualPosition, d, prisonPosition); + + while (board->isWay(actualPosition, d, brick) || + board->isWay(actualPosition, d, prison)) { + if (d != actualDirection) // if new direction is not possible, + d = actualDirection; // try current direction first. + else + d = rand() % 4; + } + + } else { // dangerous or harmless movement + if (rand() % (int) ((190-IQ)/10) == 0) { + d = board->closeup(actualPosition, d, board->position(pacman)); + if (actualState == harmless) + d = board->turn(d); + } else + do // try new direction, but not the opposite + d = rand() % 4; // direction, to prevent hectic movement. + while (d == board->turn(actualDirection)); + + while ((!board->isWay(actualPosition, d, empty) && + !board->isWay(actualPosition, d, tunnel)) || + d == board->turn(actualDirection)) { + if (d != actualDirection) // if new direction is not possible, + d = actualDirection; // try current direction first. + else + d = rand() % 4; + } + } + + actualDirection = d; + actualPosition = board->move(actualPosition, actualDirection); + + if (arrestLeft == 1 && actualPosition == freedomPosition) + arrestLeft = 0; + + if (actualState == rem && actualPosition == prisonPosition) { + actualState = dangerous; + pauseDuration = arrestPause; + arrestLeft = arrestDuration+1; + actualDirection = S; + } + + if (actualPosition != lastPosition) { + board->reset(lastPosition, monster, ID); + board->set(actualPosition, monster, ID); + } + + if (++feetPosition >= (maxBodyPixmaps/10)) + feetPosition = 0; + + return TRUE; +} + +int Monster::body() +{ + if (actualState == rem || actualPosition == OUT) + return -1; + else + if (actualState == harmless) + if (harmlessLeft > warningDuration || + harmlessLeft % (int) (warningDuration/4.5) > (int) (warningDuration/9)) + return ((maxBodyPixmaps/10)*8)+feetPosition; + else + return ((maxBodyPixmaps/10)*9)+feetPosition; + else + return ((maxBodyPixmaps/10)*ID)+feetPosition; +} + +int Monster::eyes() +{ + if (actualState == harmless || actualPosition == OUT) + return -1; + else + switch (actualDirection) { + case N : return 0; + case E : return 1; + case S : return 2; + case W : return 3; + case X : switch (lastDirection) { + case N : return 0; + case E : return 1; + case S : return 2; + default : return 3; + } + default : return -1; + } +} + diff --git a/kpacman/monster.h b/kpacman/monster.h new file mode 100644 index 0000000..b5d7f36 --- /dev/null +++ b/kpacman/monster.h @@ -0,0 +1,62 @@ +#ifndef MONSTER_H +#define MONSTER_H + +#include <stdlib.h> +#include <qpixmap.h> +#include <qwidget.h> + +#include "board.h" + +enum monsterState { dangerous, harmless, rem, arrested }; + +class Monster { +public: + Monster(Board *b, int mid = 0); + void setMaxPixmaps(int maxBody, int maxEyes); + void setArrested(int ticks, int duration); + void setDangerous(int ticks, int IQ); + void setHarmless(int ticks, int hDuration, int wDuration); + void setREM(int ticks); + void setPosition(int pos); + void setPrison(int pos); + void setFreedom(int pos); + void setDirection(int dir); + monsterState state(); + int position(); + int direction(); + int id(); + bool move(); + int body(); + int eyes(); +private: + Board *board; + int ID; // ID of monster (0 = 1st, 1 = 2nd ... 7 = last) + int IQ; // Intelligence of movement (0 = dumb..180 = smart) + + monsterState actualState; // The state of the monster + + int pauseDuration; // Number of ticks before movement + int pause; // actual ticks before moevment (0 = move) + int dangerousPause; // pause in dangerous-state + + int harmlessDuration; // Length of harmless-time in ticks + int harmlessLeft; // rest of the time in harmless-state + int warningDuration; // warningtime before monster get dangerous again + + int arrestDuration; // Length of arrest in ticks + int arrestLeft; // time left of arrest + int arrestPause; // pause in arrest-state + + int actualDirection; // actual direction of monster + int lastDirection; // last direction, before no movement (X) + int actualPosition; // actual position on board + int lastPosition; // the last position of the monster + int feetPosition; // left, right, left, right, ... + int maxBodyPixmaps; + int maxEyesPixmaps; + int prisonPosition; // where to go, if arrested + int freedomPosition; // where to go, if released from prison +}; + +#endif // MONSTER_H + diff --git a/kpacman/pacman.cpp b/kpacman/pacman.cpp new file mode 100644 index 0000000..40f60a8 --- /dev/null +++ b/kpacman/pacman.cpp @@ -0,0 +1,147 @@ +#include "pacman.h" +#include "board.h" + +Pacman::Pacman(Board *b) +{ + board = b; + setDemo(FALSE); + setAlive(0); + actualPosition = lastPosition = OUT; + mouthPosition = 0; + lastPix = 0; + maxPixmaps = 0; +} + +void Pacman::setMaxPixmaps(int max) +{ + if (actualDirection == X && lastPix >= 0) { + actualDirection = lastPix / (maxPixmaps/4); + if (max < maxPixmaps) + mouthPosition = 0; + else + mouthPosition = lastPix % (maxPixmaps/4); + maxPixmaps = max; + + lastPix = pix(); + + actualDirection = X; + } else + maxPixmaps = max; +} + +void Pacman::setAlive(int ticks) +{ + actualState = alive; + pauseDuration = ticks; + pause = 0; +} + +void Pacman::setPosition(int pos) +{ + board->reset(lastPosition, pacman); + actualPosition = lastPosition = pos; + board->set(actualPosition, pacman); + mouthPosition = 0; +} + +void Pacman::setDirection(int dir, bool forced) +{ + if (forced || + board->isWay(actualPosition, dir, empty) || + board->isWay(actualPosition, dir, tunnel)) { + if (dir == X) + lastPix = pix(); + actualDirection = dir; + nextDirection = X; + } else + nextDirection = dir; +} + +void Pacman::setDemo(bool yes) +{ + demo = yes; +} + +pacmanState Pacman::state() +{ + return actualState; +} + +int Pacman::position() +{ + return actualPosition; +} + +int Pacman::direction() +{ + return actualDirection; +} + +bool Pacman::move() +{ + if (pause-- > 0) + return FALSE; + else + pause = pauseDuration; + + if (actualDirection == X || actualPosition == OUT) + return FALSE; + + lastPosition = actualPosition; + + if (demo) { + int d = actualDirection; + + do // try new direction, but not the opposite + d = rand() % 4; // direction, to prevent hectic movement. + while (d == board->turn(actualDirection)); + + while (!board->isWay(actualPosition, d, empty) && + !board->isWay(actualPosition, d, tunnel)) { + if (d != actualDirection) // if new actualDirection is not possible, + d = actualDirection; // try current actualDirection first. + else + d = rand() % 4; + } + + actualDirection = d; + actualPosition = board->move(actualPosition, actualDirection); + + } else { + + if (nextDirection != X) + if (board->isWay(actualPosition, nextDirection, empty) || + board->isWay(actualPosition, nextDirection, tunnel)) { + actualDirection = nextDirection; + nextDirection = X; + } + + if (board->isWay(actualPosition, actualDirection, empty) || + board->isWay(actualPosition, actualDirection, tunnel)) + actualPosition = board->move(actualPosition, actualDirection); + } + + if (actualPosition != lastPosition) { + board->reset(lastPosition, pacman); + board->set(actualPosition, pacman); + + if (++mouthPosition >= (maxPixmaps/4)) + mouthPosition = 0; + } + return TRUE; +} + +int Pacman::pix() +{ + if (actualPosition != OUT && maxPixmaps > 0) + switch (actualDirection) { + case N : return ((maxPixmaps/4)*0)+mouthPosition; + case E : return ((maxPixmaps/4)*1)+mouthPosition; + case S : return ((maxPixmaps/4)*2)+mouthPosition; + case W : return ((maxPixmaps/4)*3)+mouthPosition; + case X : return lastPix; + } + + return -1; +} + diff --git a/kpacman/pacman.h b/kpacman/pacman.h new file mode 100644 index 0000000..e81fdd2 --- /dev/null +++ b/kpacman/pacman.h @@ -0,0 +1,47 @@ +#ifndef PACMAN_H +#define PACMAN_H + +#include <stdlib.h> +#include <qpixmap.h> +#include <qwidget.h> + +#include "board.h" + +enum pacmanState { alive }; + +class Pacman { +public: + Pacman(Board *b); + void init(bool Demo = FALSE); + void setMaxPixmaps(int max); + void setAlive(int ticks); + void setPosition(int pos); + void setDirection(int dir, bool forced = FALSE); + void setDemo(bool yes); + pacmanState state(); + int position(); + int direction(); + bool move(); + int pix(); + +private: + Board *board; + + pacmanState actualState; // the state of pacman + bool demo; // real life or just demo + + int pauseDuration; // number of ticks before next movement + int pause; // actual ticks before movement (0=move) + + int actualDirection; // actual direction of pacman + int nextDirection; // where he wants to go + int lastPix; // last Pixmap-index before no movement + int maxPixmaps; // Number of Pixmaps (1..) + int actualPosition; // actual position on board + int lastPosition; // the last position of pacman + int mouthPosition; // eating + +}; + +#endif // PACMAN_H + diff --git a/kpacman/painter.cpp b/kpacman/painter.cpp new file mode 100644 index 0000000..93a3782 --- /dev/null +++ b/kpacman/painter.cpp @@ -0,0 +1,956 @@ +#include <kapp.h> +#include <kconfig.h> +#include <kstddirs.h> + +#include <qcolor.h> +#include <qpainter.h> +#include <qpixmap.h> +#include <qbitmap.h> +#include <qrect.h> +#include <qstring.h> + +#include <qmessagebox.h> +#include <qfileinfo.h> + +#include "painter.h" +#include "board.h" + +Painter::Painter( Board *b, QWidget *parent, int Scheme, int Mode, Bitfont *font) +{ + w = parent; + board = b; + + pointPix = NULL; + wallPix = NULL; + prisonPix = NULL; + energizerPix = NULL; + fruitPix = NULL; + pacmanPix = NULL; + dyingPix = NULL; + eyesPix = NULL; + monsterPix = NULL; + fruitScorePix = NULL; + monsterScorePix = NULL; + + lastPointPixmapName = ""; + lastWallPixmapName = ""; + lastPrisonPixmapName = ""; + lastEnergizerPixmapName = ""; + lastFruitPixmapName = ""; + lastPacmanPixmapName = ""; + lastDyingPixmapName = ""; + lastEyesPixmapName = ""; + lastMonsterPixmapName = ""; + lastFruitScorePixmapName = ""; + lastMonsterScorePixmapName = ""; + + bitfont = font; + + scheme = Scheme; + mode = Mode; + level = 0; + + confScheme(); +} + +QList<QPixmap> *Painter::loadPixmap(QWidget *parent, QString pixmapName, + QList<QPixmap> *pixmaps) +{ + if (pixmaps == NULL) { + pixmaps = new QList<QPixmap>; + pixmaps->setAutoDelete(TRUE); + } + + if (!pixmaps->isEmpty()) + pixmaps->clear(); + + QPixmap PIXMAP(pixmapName); + if (PIXMAP.isNull() || PIXMAP.mask() == NULL) { + QString msg = i18n("The pixmap could not be contructed.\n\n" + "The file '@PIXMAPNAME@' does not exist,\n" + "or is of an unknown format."); + msg.replace(QRegExp("@PIXMAPNAME@"), pixmapName); + // QMessageBox::critical(parent, i18n("Initialization Error"), msg); + printf("%s\n", msg.data()); + return 0; + } + + int height = PIXMAP.height(); + int width = (height == 0) ? 0 : PIXMAP.width()/(PIXMAP.width()/height); + + QBitmap BITMAP; + QBitmap MASK; + + BITMAP = *PIXMAP.mask(); + MASK.resize(width, height); + + for (int x = 0; x < PIXMAP.width()/width; x++) { + QPixmap *pixmap = new QPixmap(width, height); + pixmaps->append(pixmap); + bitBlt(pixmap, 0, 0, &PIXMAP, x*width, 0, width, height, QPixmap::CopyROP, TRUE); + bitBlt(&MASK, 0, 0, &BITMAP, x*width, 0, width, height, QPixmap::CopyROP, TRUE); + pixmap->setMask(MASK); + } + + return pixmaps; +} + +QList<QPixmap> *Painter::textPixmap(QStrList &str, QList<QPixmap> *pixmaps, + QColor fg, QColor bg) +{ + if (pixmaps == NULL) { + pixmaps = new QList<QPixmap>; + pixmaps->setAutoDelete(TRUE); + } + + if (!pixmaps->isEmpty()) + pixmaps->clear(); + + for (uint s = 0; s < str.count(); s++) { + QPixmap *pixmap = new QPixmap(bitfont->text(str.at(s), fg, bg)); + pixmaps->append(pixmap); + } + + return pixmaps; +} + +QList<QPixmap> *Painter::textPixmap(QString str, QList<QPixmap> *pixmaps, + QColor fg, QColor bg) +{ + if (pixmaps == NULL) { + pixmaps = new QList<QPixmap>; + pixmaps->setAutoDelete(TRUE); + } + + if (!pixmaps->isEmpty()) + pixmaps->clear(); + + QPixmap *pixmap = new QPixmap(bitfont->text(str, fg, bg)); + pixmaps->append(pixmap); + + return pixmaps; +} + +/* Return the point of the upperleft pixel of the block representing that position + * on the board. + */ +QPoint Painter::point(int pos) +{ + return QPoint((board->x(pos)-1)*BlockWidth, (board->y(pos)-1)*BlockHeight); +} + + +QRect Painter::rect(int pos, PixMap pix, uint i) +{ + if (pos == OUT) + return QRect(); + + QPixmap *PIXMAP = NULL; + switch (pix) { + case PacmanPix : PIXMAP = pacmanPix-> + at(checkRange(i, pacmanPix->count()-1)); + break; + case DyingPix : PIXMAP = dyingPix-> + at(checkRange(i, dyingPix->count()-1)); + break; + case MonsterPix : PIXMAP = monsterPix-> + at(checkRange(i, monsterPix->count()-1)); + break; + case EyesPix : PIXMAP = eyesPix-> + at(checkRange(i, eyesPix->count()-1)); + break; + case FruitPix : PIXMAP = fruitPix-> + at(checkRange(i, fruitPix->count()-1)); + break; + case PointPix : PIXMAP = pointPix-> + at(checkRange(i, pointPix->count()-1)); + break; + case EnergizerPix : PIXMAP = energizerPix-> + at(checkRange(i, energizerPix->count()-1)); + break; + case FruitScorePix : PIXMAP = fruitScorePix-> + at(checkRange(i, fruitScorePix->count()-1)); + break; + case MonsterScorePix : PIXMAP = monsterScorePix-> + at(checkRange(i,monsterScorePix->count()-1)); + break; + default : PIXMAP = wallPix-> + at(checkRange(i, wallPix->count()-1)); + } + if (PIXMAP == NULL) + return QRect(); + + QRect rect = PIXMAP->rect(); + QPoint point = this->point(pos); + rect.moveCenter(QPoint(point.x()-1, point.y()-1)); + + return rect; +} + +QRect Painter::rect(int pos, QString str, int align) +{ + if (pos == OUT) // return an empty rect if the position + return QRect(); // is invalid + QPoint point = this->point(pos); + QRect rect = bitfont->rect(str); + + rect.moveCenter(QPoint(point.x()-1, point.y()-1)); + + int dx = 0; + int dy = 0; + + if (align & QLabel::AlignLeft || align & QLabel::AlignRight) { + dx = (str.length()-1) * (bitfont->width()/2); + if (align & QLabel::AlignRight) + dx *= -1; + } + + if (align & QLabel::AlignTop || align & QLabel::AlignBottom) { + dy = bitfont->height()/2; + if (align & QLabel::AlignBottom) + dy *= -1; + } + + if (dx != 0 || dy != 0) + rect.moveBy(dx, dy); + + return rect; +} + +QRect Painter::rect(QRect r1, QRect r2) +{ + QRect rect; + rect.setLeft(r1.left() < r2.left() ? r1.left() : r2.left()); + rect.setTop(r1.top() < r2.top() ? r1.top() : r2.top()); + rect.setRight(r1.right() > r2.right() ? r1.right() : r2.right()); + rect.setBottom(r1.bottom() > r2.bottom() ? r1.bottom() : r2.bottom()); + + return rect; +} + +void Painter::erase(int pos, PixMap pix, uint i) +{ + if (pos == OUT) + return; + QRect rect = this->rect(pos, pix, i); + bitBlt(&roomPix, rect.x(), rect.y(), &backPix, + rect.x(), rect.y(), rect.width(), rect.height()); +} + +int Painter::maxPixmaps(PixMap pix) +{ + switch (pix) { + case WallPix : return (int) wallPix->count(); + case PrisonPix : return (int) prisonPix->count(); + case PointPix : return (int) pointPix->count(); + case EnergizerPix : return (int) energizerPix->count(); + case FruitPix : return (int) fruitPix->count(); + case PacmanPix : return (int) pacmanPix->count(); + case DyingPix : return (int) dyingPix->count(); + case EyesPix : return (int) eyesPix->count(); + case MonsterPix : return (int) monsterPix->count(); + case FruitScorePix : return (int) fruitScorePix->count(); + case MonsterScorePix : return (int) monsterScorePix->count(); + default : return 0; + } +} + +void Painter::draw(QPoint point, DrawWidget where, QPixmap pix) +{ + switch (where) { + case Widget : bitBlt(w, point.x(), point.y(), &pix); + break; + case RoomPix : bitBlt(&roomPix, point.x(), point.y(), &pix); + break; + case BackPix : bitBlt(&backPix, point.x(), point.y(), &pix); + break; + } +} + +void Painter::draw(QRect rect, DrawWidget where, QPixmap pix) +{ + draw(QPoint(rect.x(), rect.y()), where, pix); +} + +void Painter::draw(int pos, DrawWidget where, PixMap pix, uint i) +{ + QPixmap *PIXMAP = NULL; + switch (pix) { + case PacmanPix : PIXMAP = pacmanPix-> + at(checkRange(i, pacmanPix->count()-1)); + break; + case DyingPix : PIXMAP = dyingPix-> + at(checkRange(i, dyingPix->count()-1)); + break; + case MonsterPix : PIXMAP = monsterPix-> + at(checkRange(i, monsterPix->count()-1)); + break; + case EyesPix : PIXMAP = eyesPix-> + at(checkRange(i, eyesPix->count()-1)); + break; + case FruitPix : PIXMAP = fruitPix-> + at(checkRange(i, fruitPix->count()-1)); + break; + case EnergizerPix : PIXMAP = energizerPix-> + at(checkRange(i, energizerPix->count()-1)); + break; + case FruitScorePix : PIXMAP = fruitScorePix-> + at(checkRange(i, fruitScorePix->count()-1)); + break; + case MonsterScorePix : PIXMAP = monsterScorePix-> + at(checkRange(i,monsterScorePix->count()-1)); + break; + default : ; + } + + if (PIXMAP == NULL) + return; + + QRect rect = PIXMAP->rect(); + QPoint point = this->point(pos); + rect.moveCenter(QPoint(point.x()-1, point.y()-1)); + + switch (where) { + case Widget : bitBlt(w, rect.x(), rect.y(), PIXMAP); + break; + case RoomPix : bitBlt(&roomPix, rect.x(), rect.y(), PIXMAP); + break; + case BackPix : bitBlt(&backPix, rect.x(), rect.y(), PIXMAP); + break; + } +} + +QPixmap Painter::draw(int pos, DrawWidget where, + QString str, QColor fg, QColor bg, int align) +{ + QPixmap TEXT = bitfont->text(str, fg, bg); + + QRect rect = this->rect(pos, str, align); + QPixmap SAVE = QPixmap(rect.width(), rect.height()); + + switch (where) { + case Widget : bitBlt(&SAVE, 0, 0, w, rect.x(), rect.y()); + bitBlt(w, rect.x(), rect.y(), &TEXT); + break; + case RoomPix : bitBlt(&SAVE, 0, 0, &roomPix, rect.x(), rect.y()); + bitBlt(&roomPix, rect.x(), rect.y(), &TEXT); + break; + case BackPix : bitBlt(&SAVE, 0, 0, &backPix, rect.x(), rect.y()); + bitBlt(&backPix, rect.x(), rect.y(), &TEXT); + break; + } + + return SAVE; +} + +QRect Painter::draw(int col, int row, DrawWidget where, + QString str, QColor fg, QColor bg, int align) +{ + QPixmap TEXT = bitfont->text(str, fg, bg); + + QRect rect = this->rect(row*BoardWidth+col, str, align); + draw(rect, where, TEXT); + + return rect; +} + +void Painter::initPixmaps() +{ + if (lastPointPixmapName != pointPixmapName.at(level)) { + pointPix = loadPixmap(w, pointPixmapName.at(level), pointPix); + lastPointPixmapName = pointPixmapName.at(level); + } + if (lastPrisonPixmapName != prisonPixmapName.at(level)) { + prisonPix = loadPixmap(w, prisonPixmapName.at(level), prisonPix); + lastPrisonPixmapName = prisonPixmapName.at(level); + } + if (lastEnergizerPixmapName != energizerPixmapName.at(level)) { + energizerPix = loadPixmap(w, energizerPixmapName.at(level), energizerPix); + lastEnergizerPixmapName = energizerPixmapName.at(level); + } + if (lastFruitPixmapName != fruitPixmapName.at(level)) { + fruitPix = loadPixmap(w, fruitPixmapName.at(level), fruitPix); + lastFruitPixmapName = fruitPixmapName.at(level); + } + if (lastPacmanPixmapName != pacmanPixmapName.at(level)) { + pacmanPix = loadPixmap(w, pacmanPixmapName.at(level), pacmanPix); + lastPacmanPixmapName = pacmanPixmapName.at(level); + } + if (lastDyingPixmapName != dyingPixmapName.at(level)) { + dyingPix = loadPixmap(w, dyingPixmapName.at(level), dyingPix); + lastDyingPixmapName = dyingPixmapName.at(level); + } + if (lastEyesPixmapName != eyesPixmapName.at(level)) { + eyesPix = loadPixmap(w, eyesPixmapName.at(level), eyesPix); + lastEyesPixmapName = eyesPixmapName.at(level); + } + if (lastMonsterPixmapName != monsterPixmapName.at(level)) { + monsterPix = loadPixmap(w, monsterPixmapName.at(level), monsterPix); + lastMonsterPixmapName = monsterPixmapName.at(level); + } + + if (lastFruitScorePixmapName != fruitScorePixmapName.at(level) || + (const char *) *fruitScorePixmapName.at(level) == '\0') { + if ((const char *) *fruitScorePixmapName.at(level) == '\0') { + fruitScorePix = textPixmap(fruitScoreString, fruitScorePix, PINK); + } else { + fruitScorePix = loadPixmap(w, fruitScorePixmapName.at(level), + fruitScorePix); + lastFruitScorePixmapName = fruitScorePixmapName.at(level); + } + } + + if (lastMonsterScorePixmapName != monsterScorePixmapName.at(level) || + (const char *) *monsterScorePixmapName.at(level) == '\0') { + if ((const char *) *monsterScorePixmapName.at(level) == '\0') { + monsterScorePix = textPixmap(monsterScoreString, monsterScorePix, CYAN); + } else { + monsterScorePix = loadPixmap(w, monsterScorePixmapName.at(level), + monsterScorePix); + lastMonsterScorePixmapName = monsterScorePixmapName.at(level); + } + } + + if (lastWallPixmapName != wallPixmapName.at(level)) { + wallPix = loadPixmap(w, wallPixmapName.at(level), wallPix); + if (wallPix->isEmpty()) { + BlockWidth = 0; + BlockHeight = 0; + } else { + BlockWidth = wallPix->at(0)->width(); + BlockHeight = wallPix->at(0)->height(); + } + lastWallPixmapName = wallPixmapName.at(level); + } +} + +void Painter::initbackPixmaps() +{ + backgroundColor = BLACK; + + backPix.resize((BoardWidth-3)*BlockWidth, (BoardHeight-3)*BlockHeight ); + backPix.fill(backgroundColor); +} + +void Painter::initRoomPixmap() +{ + roomPix.resize((BoardWidth-3)*BlockWidth, (BoardHeight-3)*BlockHeight ); + bitBlt(&roomPix,0,0, &backPix); + + for (unsigned int x = 0; x < board->size(); x++) { + if (board->isBrick(x)) + drawBrick(x); + if (board->isPrison(x) || board->isGate(x)) + drawPrison(x); + if (board->isPoint(x)) + drawPoint(x); + } +} + +void Painter::drawBrick(int pos) +{ + int border = 0; + if (board->isBrick(board->move(pos, N ))) border |= (1 << 0); + if (board->isBrick(board->move(pos, NE))) border |= (1 << 1); + if (board->isBrick(board->move(pos, E ))) border |= (1 << 2); + if (board->isBrick(board->move(pos, SE))) border |= (1 << 3); + if (board->isBrick(board->move(pos, S ))) border |= (1 << 4); + if (board->isBrick(board->move(pos, SW))) border |= (1 << 5); + if (board->isBrick(board->move(pos, W ))) border |= (1 << 6); + if (board->isBrick(board->move(pos, NW))) border |= (1 << 7); + + if (board->isOut(board->move(pos, N ))) border |= (1 << 8); + if (board->isOut(board->move(pos, NE))) border |= (1 << 9); + if (board->isOut(board->move(pos, E ))) border |= (1 << 10); + if (board->isOut(board->move(pos, SE))) border |= (1 << 11); + if (board->isOut(board->move(pos, S ))) border |= (1 << 12); + if (board->isOut(board->move(pos, SW))) border |= (1 << 13); + if (board->isOut(board->move(pos, W ))) border |= (1 << 14); + if (board->isOut(board->move(pos, NW))) border |= (1 << 15); + + switch (border & 0xFF) { + case 31 : border = 0; break; + case 159 : border = 0; break; + case 63 : border = 0; break; + case 191 : border = 0; break; + case 241 : border = 1; break; + case 249 : border = 1; break; + case 243 : border = 1; break; + case 251 : border = 1; break; + case 124 : border = 2; break; + case 252 : border = 2; break; + case 126 : border = 2; break; + case 199 : border = 3; break; + case 231 : border = 3; break; + case 207 : border = 3; break; + case 28 : if ((border >> 8) > 0) + border = 24; + else + border = 4; + break; + case 112 : if ((border >> 8) > 0) + border = 27; + else + border = 5; + break; + case 7 : if ((border >> 8) > 0) + border = 25; + else + border = 6; + break; + case 193 : if ((border >> 8) > 0) + border = 26; + else + border = 7; + break; + case 247 : if ((border & (1 << 11)) > 0) + border = 23; + else + border = 8; + break; + case 119 : if ((border & (1 << 15)) > 0) + border = 8; + if ((border & (1 << 11)) > 0) + border = 11; + break; + case 223 : if ((border & (1 << 13)) > 0) + border = 20; + else + border = 9; + break; + case 221 : if ((border & (1 << 13)) > 0) + border = 10; + if ((border & (1 << 9)) > 0) + border = 9; + break; + case 253 : if ((border & (1 << 9)) > 0) + border = 21; + else + border = 10; + break; + case 127 : if ((border & (1 << 15)) > 0) + border = 22; + else + border = 11; + break; + case 30 : border = 12; break; + case 240 : border = 13; break; + case 15 : border = 14; break; + case 225 : border = 15; break; + case 135 : border = 16; break; + case 195 : border = 17; break; + case 60 : border = 18; break; + case 120 : border = 19; break; + case 255 : border = 28; break; + default : border = -1; + } + if (border != -1 && border < (int) wallPix->count()) { + QRect rect = this->rect(pos, WallPix); + bitBlt(&roomPix, rect.x(), rect.y(), wallPix->at((uint) border)); + } +} + +void Painter::drawPrison(int pos) +{ + int border = 0; + if (board->isPrison(board->move(pos, N ))) border |= (1 << 0); + if (board->isPrison(board->move(pos, NE))) border |= (1 << 1); + if (board->isPrison(board->move(pos, E ))) border |= (1 << 2); + if (board->isPrison(board->move(pos, SE))) border |= (1 << 3); + if (board->isPrison(board->move(pos, S ))) border |= (1 << 4); + if (board->isPrison(board->move(pos, SW))) border |= (1 << 5); + if (board->isPrison(board->move(pos, W ))) border |= (1 << 6); + if (board->isPrison(board->move(pos, NW))) border |= (1 << 7); + + if (board->isGate(board->move(pos, N ))) border |= (1 << 8); + if (board->isGate(board->move(pos, NE))) border |= (1 << 9); + if (board->isGate(board->move(pos, E ))) border |= (1 << 10); + if (board->isGate(board->move(pos, SE))) border |= (1 << 11); + if (board->isGate(board->move(pos, S ))) border |= (1 << 12); + if (board->isGate(board->move(pos, SW))) border |= (1 << 13); + if (board->isGate(board->move(pos, W ))) border |= (1 << 14); + if (board->isGate(board->move(pos, NW))) border |= (1 << 15); + + switch (border & 0xFF) { + case 31 : border = 0; break; + case 159 : border = 0; break; + case 63 : border = 0; break; + case 241 : border = 1; break; + case 249 : border = 1; break; + case 243 : border = 1; break; + case 124 : border = 2; break; + case 252 : border = 2; break; + case 126 : border = 2; break; + case 199 : border = 3; break; + case 231 : border = 3; break; + case 207 : border = 3; break; + case 28 : if ((border >> 8) != 0) + border = 12; + else + border = 4; + break; + case 112 : if ((border >> 8) != 0) + border = 13; + else + border = 5; + break; + case 7 : if ((border >> 8) != 0) + border = 14; + else + border = 6; + break; + case 193 : if ((border >> 8) != 0) + border = 15; + else + border = 7; + break; + case 247 : border = 8; break; + case 223 : border = 9; break; + case 253 : border = 10; break; + case 127 : border = 11; break; + default : border = -1; + } + if (board->isGate(pos)) { + if (board->isGate(board->move(pos, N))) + border = 17; + else + border = 16; + } + + if (border != -1 && border < (int) prisonPix->count()) { + QRect rect = this->rect(pos, PrisonPix); + bitBlt(&roomPix, rect.x(), rect.y(), prisonPix->at((uint) border)); + } +} + +void Painter::drawPoint(int pos) +{ + if (!pointPix->isEmpty()) { + QRect rect = this->rect(pos, PointPix); + bitBlt(&roomPix, rect.x(), rect.y(), pointPix->at(0)); + } +} + +QString Painter::decodeHexOctString(QString s) +{ + QString value; + QString valids; + int pos, xpos = 0, opos = 0; + int v, len, leadin; + const char *ptr; + uchar c; + + while (((xpos = s.find(QRegExp("\\\\x[0-9a-fA-F]+"), xpos)) != -1) || + ((opos = s.find(QRegExp("\\\\[0-7]+"), opos)) != -1)) { + if (xpos != -1) { + valids = "0123456789abcdef"; + leadin = 2; + pos = xpos; + } else { + valids = "01234567"; + leadin = 1; + pos = opos; + } + + c = '\0'; + len = 0; + value = s.mid(pos+leadin, 3); + ptr = (const char *) value; + + while (*ptr != '\0' && (v = valids.find(*ptr++, 0, FALSE)) != -1) { + c = (c * valids.length()) + v; + len++; + } + + value.fill(c, 1); + s.replace(pos, len+leadin, value); + } + + return s; +} + +void Painter::fillScoreString(QStrList &list, QArray<int> &values) +{ + if( !list.isEmpty()) + list.clear(); + + QString s; + + for (uint i = 0; i < values.size(); i++) { + + if (values[i] < 10 || values[i] > 10000) + s = "?"; + else if (values[i] == 1600) + s = "\x1a\x1b"; + else if (values[i] < 100) { + s = "\x0e"; + s.insert(0, char (values[i] / 10 + 0x10)); + } else if (values[i] < 1000) { + s = "\x0f"; + s.insert(0, char (values[i] / 100 + 0x10)); + } else { + s = "\x0f\x10"; + s.insert(0, char (values[i] / 1000 + 0x10)); + } + + list.append(s.data()); + } +} + +void Painter::fillArray(QArray<int> &array, QString values, int max) +{ + array.resize(max); + int last = 0; + bool ok; + QString value; + + for (uint i = 0; i < array.size(); i++) { + if (values.find(',') < 0 && values.length() > 0) { + value = values; + values = ""; + } + if (values.find(',') >= 0) { + value = values.left(values.find(',')); + values.remove(0,values.find(',')+1); + } + array[i] = value.toInt(&ok); + if (ok) + last = array[i]; + else + array[i] = last; + } +} + +void Painter::fillStrList(QStrList &list, QString values, int max) +{ + if (!list.isEmpty()) + list.clear(); + + QString last = ""; + QString value; + + for (uint i = 0; i < (uint) max; i++) { + if (values.find(',') < 0 && values.length() > 0) { + value = values; + values = ""; + } + if (values.find(',') >= 0) { + value = values.left(values.find(',')); + values.remove(0,values.find(',')+1); + } + if (!value.isEmpty()) + last = decodeHexOctString(value); + list.append(last); + } +} + +void Painter::fillPixmapName(QStrList &pixmapName) +{ + QStrList list = pixmapName; + + if (!pixmapName.isEmpty()) + pixmapName.clear(); + + QString pixmap; + + QFileInfo fileInfo; + + for (uint i = 0; i < list.count(); i++) { + pixmap = list.at(i); + + if (pixmap.left(1) != "/" && pixmap.left(1) != "~") + pixmap = KGlobal::dirs()->findResource("appdata", pixmapDirectory+pixmap); + + fileInfo.setFile(pixmap); + if (!fileInfo.isReadable() || !fileInfo.isFile()) + pixmap = ""; + + pixmapName.append(pixmap); + } +} + +void Painter::confLevels(bool defGroup) +{ + if (defGroup || kapp->config()->hasKey("Levels")) + maxLevel = kapp->config()->readNumEntry("Levels", 13); +} + +void Painter::confMisc(bool defGroup) +{ + if (defGroup || kapp->config()->hasKey("PixmapDirectory")) { + pixmapDirectory = kapp->config()->readEntry("PixmapDirectory"); + + if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~") + pixmapDirectory.insert(0, "pics/"); + if (pixmapDirectory.right(1) != "/") + pixmapDirectory.append("/"); + } + + if (defGroup || kapp->config()->hasKey("PointPixmapName")) + fillStrList(pointPixmapName, + kapp->config()->readEntry("PointPixmapName", "point.xpm"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("WallPixmapName")) + fillStrList(wallPixmapName, + kapp->config()->readEntry("WallPixmapName", "wall.xpm"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("PrisonPixmapName")) + fillStrList(prisonPixmapName, + kapp->config()->readEntry("PrisonPixmapName", "prison.xpm"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("EnergizerPixmapName")) + fillStrList(energizerPixmapName, + kapp->config()->readEntry("EnergizerPixmapName", "switch.xpm"),maxLevel+1); + if (defGroup || kapp->config()->hasKey("FruitPixmapName")) + fillStrList(fruitPixmapName, + kapp->config()->readEntry("FruitPixmapName", "fruit.xpm"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("PacmanPixmapName")) + fillStrList(pacmanPixmapName, + kapp->config()->readEntry("PacmanPixmapName", "pacman.xpm"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("DyingPixmapName")) + fillStrList(dyingPixmapName, + kapp->config()->readEntry("DyingPixmapName", "dying.xpm"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("EyesPixmapName")) + fillStrList(eyesPixmapName, + kapp->config()->readEntry("EyesPixmapName", "eyes.xpm"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("MonsterPixmapName")) + fillStrList(monsterPixmapName, + kapp->config()->readEntry("MonsterPixmapName", "monster.xpm"), maxLevel+1); + + if (defGroup || kapp->config()->hasKey("FruitScorePixmapName")) + fillStrList(fruitScorePixmapName, + kapp->config()->readEntry("FruitScorePixmapName"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("MonsterScorePixmapName")) + fillStrList(monsterScorePixmapName, + kapp->config()->readEntry("MonsterScorePixmapName"), maxLevel+1); +} + +void Painter::confScoring(bool defGroup) +{ + if (defGroup || kapp->config()->hasKey("FruitScore")) + fillArray(fruitScore, + kapp->config()->readEntry("FruitScore", + "100,300,500,,700,,1000,,2000,,3000,,5000"), + maxLevel+1); + if (defGroup || kapp->config()->hasKey("MonsterScore")) + fillArray(monsterScore, + kapp->config()->readEntry("MonsterScore", "200,400,800,1600"), 4); + + if (defGroup || kapp->config()->hasKey("FruitScoreString")) + fillStrList(fruitScoreString, + kapp->config()->readEntry("FruitScoreString"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("MonsterScoreString")) + fillStrList(monsterScoreString, + kapp->config()->readEntry("MonsterScoreString"), 4); +} + +void Painter::confScheme() +{ + QString oldgroup = kapp->config()->group(); + QString newgroup; + + // if not set, read mode and scheme from the configfile + if (mode == -1 && scheme == -1) { + scheme = kapp->config()->readNumEntry("Scheme", -1); + mode = kapp->config()->readNumEntry("Mode", -1); + + // if mode is not set in the defGroup-group, lookup the scheme group + if (scheme != -1 || mode == -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + mode = kapp->config()->readNumEntry("Mode", -1); + kapp->config()->setGroup(oldgroup); + } + } + + confLevels(); + + if (mode != -1) { + newgroup.sprintf("Mode %d", mode); + kapp->config()->setGroup(newgroup); + + confLevels(FALSE); + } + + if (scheme != -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + confLevels(FALSE); + } + + kapp->config()->setGroup(oldgroup); + + confMisc(); + confScoring(); + + if (mode != -1) { + newgroup.sprintf("Mode %d", mode); + kapp->config()->setGroup(newgroup); + + confMisc(FALSE); + confScoring(FALSE); + } + + if (scheme != -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + confMisc(FALSE); + confScoring(FALSE); + } + + if ((const char *) *fruitScoreString.at(0) == '\0') + fillScoreString(fruitScoreString, fruitScore); + if ((const char *) *monsterScoreString.at(0) == '\0') + fillScoreString(monsterScoreString, monsterScore); + + fillPixmapName(pointPixmapName); + fillPixmapName(wallPixmapName); + fillPixmapName(prisonPixmapName); + fillPixmapName(energizerPixmapName); + fillPixmapName(fruitPixmapName); + fillPixmapName(pacmanPixmapName); + fillPixmapName(dyingPixmapName); + fillPixmapName(eyesPixmapName); + fillPixmapName(monsterPixmapName); + fillPixmapName(fruitScorePixmapName); + fillPixmapName(monsterScorePixmapName); + + initPixmaps(); + initbackPixmaps(); + initRoomPixmap(); + + kapp->config()->setGroup(oldgroup); +} + +void Painter::setScheme(int Scheme, int Mode, Bitfont *font) +{ + bitfont = font; + + mode = Mode; + scheme = Scheme; + + confScheme(); +} + +void Painter::setLevel(int Level) +{ + level = Level; + + initPixmaps(); + initbackPixmaps(); + initRoomPixmap(); +} + +int Painter::checkRange(int value, int max, int min) +{ + if (value < min) { + printf("Painter::checkRange (value = %d, max = %d, min = %d)\n", + value, max, min); + return min; + } else if (value > max) { + printf("Painter::checkRange (value = %d, max = %d, min = %d)\n", + value, max, min); + return max; + } else + return value; +} diff --git a/kpacman/painter.h b/kpacman/painter.h new file mode 100644 index 0000000..7e63b96 --- /dev/null +++ b/kpacman/painter.h @@ -0,0 +1,144 @@ +#ifndef PAINTER_H +#define PAINTER_H + +#include <kapp.h> +#include <klocale.h> + +#include <qpixmap.h> +#include <qbitmap.h> +#include <qlabel.h> +#include <qcolor.h> +#include <qlist.h> +#include <qstrlist.h> +#include <qregexp.h> + +#include "board.h" +#include "bitfont.h" +#include "colors.h" + +enum PixMap { PacmanPix, DyingPix, MonsterPix, EyesPix, FruitPix, + PointPix, EnergizerPix, WallPix, PrisonPix, + FruitScorePix, MonsterScorePix }; +enum DrawWidget { Widget, RoomPix, BackPix }; + +class Painter +{ +public: + Painter (Board *, QWidget *parent=0, int scheme=-1, int mode=-1,Bitfont *font=0); + QPixmap levelPix() { return roomPix; } + + void setScheme(int scheme=-1, int mode=-1, Bitfont *font=0); + void setLevel(int level=0); + + QRect rect(int pos, PixMap pix, uint i = 0); + QRect rect(int pos, QString str, int align = QLabel::AlignCenter ); + QRect rect(QRect r1, QRect r2); + + void draw(QPoint point, DrawWidget where, QPixmap pix); + void draw(QRect rect, DrawWidget where, QPixmap pix); + void draw(int pos, DrawWidget where, PixMap pix, uint i = 0); + QPixmap draw(int pos, DrawWidget where, QString str, + QColor fg, QColor bg = QColor(), int align = QLabel::AlignCenter); + QRect draw(int col, int row, DrawWidget where, QString str, + QColor fg, QColor bg = QColor(), int align = QLabel::AlignCenter); + + void drawBrick(int pos); + void drawPrison(int pos); + void drawPoint(int pos); + + void erase(int pos, PixMap pix, uint i = 0); + + int maxPixmaps(PixMap pix); + +protected: + QString decodeHexOctString(QString str); + + void fillScoreString(QStrList &, QArray<int> &); + void fillArray(QArray<int> &, QString, int); + void fillStrList(QStrList &, QString, int); + void fillPixmapName(QStrList &); + + void confScheme(); + void confLevels(bool defGroup=TRUE); + void confMisc(bool defGroup=TRUE); + void confScoring(bool defGroup=TRUE); + + void initPixmaps(); + void initRoomPixmap(); + void initbackPixmaps(); + +private: + QWidget *w; + Board *board; + Bitfont *bitfont; + + int BlockWidth; + int BlockHeight; + + QArray<int> fruitScore; + QStrList fruitScoreString; + QArray<int> monsterScore; + QStrList monsterScoreString; + + QString pixmapDirectory; + + QStrList pointPixmapName; + QStrList wallPixmapName; + QStrList prisonPixmapName; + QStrList energizerPixmapName; + QStrList fruitPixmapName; + QStrList pacmanPixmapName; + QStrList dyingPixmapName; + QStrList eyesPixmapName; + QStrList monsterPixmapName; + QStrList fruitScorePixmapName; + QStrList monsterScorePixmapName; + + QString lastPointPixmapName; + QString lastWallPixmapName; + QString lastPrisonPixmapName; + QString lastEnergizerPixmapName; + QString lastFruitPixmapName; + QString lastPacmanPixmapName; + QString lastDyingPixmapName; + QString lastEyesPixmapName; + QString lastMonsterPixmapName; + QString lastFruitScorePixmapName; + QString lastMonsterScorePixmapName; + + QList<QPixmap> *loadPixmap(QWidget *parent, QString pixmapName, + QList<QPixmap> *pixmaps=0); + QList<QPixmap> *textPixmap(QStrList &, QList<QPixmap> *pixmaps=0, + QColor fg = BLACK, QColor bg = QColor()); + QList<QPixmap> *textPixmap(QString str, QList<QPixmap> *pixmaps=0, + QColor fg = BLACK, QColor bg = QColor()); + + QPoint point(int pos); + int checkRange(int value, int max, int min=0); + + QList<QPixmap> *wallPix; + QList<QPixmap> *prisonPix; + QList<QPixmap> *pointPix; + QList<QPixmap> *energizerPix; + QList<QPixmap> *fruitPix; + QList<QPixmap> *pacmanPix; + QList<QPixmap> *dyingPix; + QList<QPixmap> *eyesPix; + QList<QPixmap> *monsterPix; + QList<QPixmap> *fruitScorePix; + QList<QPixmap> *monsterScorePix; + + QPixmap roomPix; + QPixmap backPix; + + bool plainColor; + QColor backgroundColor; + + int maxLevel; + int level; + + int scheme; + int mode; +}; + +#endif // PAINTER_H diff --git a/kpacman/referee.cpp b/kpacman/referee.cpp new file mode 100644 index 0000000..55f03f8 --- /dev/null +++ b/kpacman/referee.cpp @@ -0,0 +1,1391 @@ +#include <kapp.h> +#include <kconfig.h> +#include <kstddirs.h> + +#include <referee.h> + +#include <qdatetm.h> +#include <stdlib.h> +#include <qtimer.h> +#include <qevent.h> +#include <qcolor.h> +#include <qkeycode.h> +#include <qfileinfo.h> +#include <kaccel.h> + +#include "board.h" +#include "pacman.h" +#include "monster.h" +#include "fruit.h" +#include "painter.h" + +Referee::Referee( QWidget *parent, const char *name, int Scheme, int Mode, Bitfont *font) + : QWidget( parent, name ) +{ + gameState.resize(12); + gameTimer = 0; + energizerTimer = 0; + + focusedPause = false; + setFocusPolicy(QWidget::StrongFocus); + + initKeys(); + + scheme = Scheme; + mode = Mode; + confScheme(); + + board = new Board(BoardWidth*BoardHeight); + + pix = new Painter(board, this, scheme, mode, font); + setFixedSize(pix->levelPix().size()); + + pacman = new Pacman(board); + + fruit = new Fruit(board); + + monsters = new QList<Monster>; + monsters->setAutoDelete(TRUE); + + monsterRect = new QList<QRect>; + monsterRect->setAutoDelete(TRUE); + + energizers = new QList<Energizer>; + energizers->setAutoDelete(TRUE); + + energizerRect = new QList<QRect>; + energizerRect->setAutoDelete(TRUE); + + pacmanRect.setRect(0, 0, 0, 0); + fruitRect.setRect(0, 0, 0, 0); + + QTime midnight( 0, 0, 0 ); + srand( midnight.secsTo(QTime::currentTime()) ); + + lifes = 0; + points = 0; + + emit setLifes(lifes); + emit setPoints(points); + + intro(); +} + +void Referee::paintEvent( QPaintEvent *e) +{ + if (gameState.testBit(HallOfFame)) + return; + + QRect rect = e->rect(); + + if (!rect.isEmpty()) { + QPixmap p = pix->levelPix(); + bitBlt(this, rect.x(), rect.y(), + &p, rect.x(), rect.y(), rect.width(), rect.height()); + } + + if ((gameState.testBit(GameOver) || gameState.testBit(Demonstration)) && + rect.intersects(pix->rect(board->position(fruithome), i18n("GAME OVER")))) + pix->draw(board->position(fruithome), Widget, i18n("GAME OVER"), RED); + + for (Energizer *e = energizers->first(); e != 0; e = energizers->next()) { + if (e && e->state() == on && + rect.intersects(pix->rect(e->position(), EnergizerPix)) && + !(e->position() == pacman->position() && gameState.testBit(Scoring))) { + if (e->pix() != -1) + pix->draw(e->position(), Widget, EnergizerPix, e->pix()); + } + } + + if (!gameState.testBit(Init)) { + + if (!gameState.testBit(Dying) && (fruit->pix() != -1)) + if (fruit->state() != active) { + if (rect.intersects(pix->rect(fruit->position(), FruitScorePix, fruit->pix()))) + pix->draw(fruit->position(), Widget, FruitScorePix, fruit->pix()); + } else { + if (rect.intersects(pix->rect(fruit->position(), FruitPix, fruit->pix()))) + pix->draw(fruit->position(), Widget, FruitPix, fruit->pix()); + } + + for (Monster *m = monsters->first(); m != 0; m = monsters->next()) + if (m && m->state() == harmless && + rect.intersects(pix->rect(m->position(), MonsterPix)) && + !(m->position() == pacman->position() && gameState.testBit(Scoring))) { + if (m->body() != -1) + pix->draw(m->position(), Widget, MonsterPix, m->body()); + if (m->eyes() != -1) + pix->draw(m->position(), Widget, EyesPix, m->eyes()); + } + + if (!gameState.testBit(Scoring) && !gameState.testBit(LevelDone) && + rect.intersects(pix->rect(pacman->position(), PacmanPix)) && pacman->pix() != -1) + pix->draw(pacman->position(), Widget, PacmanPix, pacman->pix()); + + for (Monster *m = monsters->first(); m != 0; m = monsters->next()) + if (m && m->state() != harmless && + rect.intersects(pix->rect(m->position(), MonsterPix)) && + !(m->position() == pacman->position() && gameState.testBit(Scoring))) { + if (m->body() != -1) + pix->draw(m->position(), Widget, MonsterPix, m->body()); + if (m->eyes() != -1) + pix->draw(m->position(), Widget, EyesPix, m->eyes()); + } + } + + if (gameState.testBit(Scoring) && + rect.intersects(pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1))) + pix->draw(pacman->position(), Widget, MonsterScorePix, monstersEaten-1); + + if (gameState.testBit(Init) && gameState.testBit(Dying) && + timerCount < pix->maxPixmaps(DyingPix) && + rect.intersects(pix->rect(pacman->position(), PacmanPix))) + pix->draw(pacman->position(), Widget, DyingPix, timerCount); + + if (gameState.testBit(LevelDone) && + rect.intersects(pix->rect(pacman->position(), PacmanPix))) + pix->draw(pacman->position(), Widget, PacmanPix, pacman->pix()); + + if (gameState.testBit(Player) && + rect.intersects(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE")))) + pix->draw(board->position(monsterhome, 0), Widget, i18n("PLAYER ONE"), CYAN); + + if (gameState.testBit(Ready) && + rect.intersects(pix->rect(board->position(fruithome), i18n("READY!")))) + pix->draw(board->position(fruithome), Widget, i18n("READY!"), YELLOW); + + if (gameState.testBit(Paused) && + rect.intersects(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED")))) + pix->draw((BoardWidth*BoardHeight)/2-BoardWidth, Widget, i18n("PAUSED"), RED, BLACK); +} + +void Referee::timerEvent( QTimerEvent *e ) +{ + if (gameState.testBit(HallOfFame)) + return; + + QRect lastRect; + int lastPix; + bool moved = FALSE; + int eated = 0; + + if (e->timerId() == energizerTimer) { + for (int e = 0; e < board->energizers(); e++) { + lastRect = pix->rect(energizers->at(e)->position(), EnergizerPix); + lastPix = energizers->at(e)->pix(); + if (energizers->at(e)->move()) { + moved = TRUE; + *energizerRect->at(e) = pix->rect(energizers->at(e)->position(), EnergizerPix); + if (lastPix == energizers->at(e)->pix() && + lastRect == pix->rect(energizers->at(e)->position(), EnergizerPix)) + energizerRect->at(e)->setRect(0, 0, 0, 0); + else + *energizerRect->at(e) = pix->rect(*energizerRect->at(e), lastRect); + } + } + + for (int e = 0; e < board->energizers(); e++) + if (!energizerRect->at(e)->isNull()) + repaint(*energizerRect->at(e), FALSE); + + return; + } + + timerCount++; + + lastRect = pix->rect(pacman->position(), PacmanPix); + lastPix = pacman->pix(); + + if (moved = pacman->move()) { // pacman really moved + pacmanRect = pix->rect(pacman->position(), PacmanPix); + if (lastPix == pacman->pix() && + lastRect == pix->rect(pacman->position(), PacmanPix)) + pacmanRect.setRect(0, 0, 0, 0); // nothing to do, because the pixmap + else // and the position isn't changed. + pacmanRect = pix->rect(pacmanRect, lastRect); + } else + pacmanRect.setRect(0, 0, 0, 0); + + int pos = pacman->position(); + + if (moved && board->isMonster(pos) && !gameState.testBit(Dying)) { + for (Monster *m = monsters->first(); m != 0; m = monsters->next()) + if (m && m->position() == pos) { + if (m->state() == harmless && !gameState.testBit(Dying)) { + m->setREM(remTicks[level]); + m->setDirection(X); // prevent movement before eaten() + eated++; + if (gameState.testBit(Introducing)) + m->setPosition(OUT); + } + if (m->state() == dangerous && !gameState.testBit(Dying)) + killed(); + } + } + + if (moved && !gameState.testBit(Dying)) { + if (board->isPoint(pos)) { + board->reset(pos, Point); + score(pointScore); + pix->erase(pos, PointPix); + } + if (board->isEnergizer(pos)) { + for (int e = 0; e < board->energizers();e++) { + if (energizers->at(e)->position() == pos) { + energizers->at(e)->setOff(); + energizers->remove(e); + energizerRect->remove(e); + e = board->energizers(); + } + } + board->reset(pos, energizer); + score(energizerScore); + monstersEaten = 0; + for (Monster *m = monsters->first(); m != 0; m = monsters->next()) + if (m && m->state() != rem) { + m->setHarmless(harmlessTicks[level], harmlessDurTicks[level], + harmlessWarnTicks[level]); + if (gameState.testBit(Introducing)) + m->setDirection(board->turn(m->direction())); + } + } + if (pos == fruit->position() && fruit->state() == active) { + fruit->setEaten(fruitScoreDurTicks[level]); + initFruit(FALSE); + score(fruitScore[fruit->pix()]); + } + } + + if (!gameState.testBit(Introducing)) { + if (fruit->state() != active && fruit->pix() >= 0) + lastRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix()); + else + lastRect = pix->rect(fruit->position(), FruitPix, fruit->pix()); + + lastPix = fruit->pix(); + if (fruit->move()) { + if (pos == fruit->position() && fruit->state() == active) { + fruit->setEaten(fruitScoreDurTicks[level]); + initFruit(FALSE); + score(fruitScore[fruit->pix()]); + } + if (fruit->state() != active && fruit->pix() >= 0) + fruitRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix()); + else + fruitRect = pix->rect(fruit->position(), FruitPix, fruit->pix()); + if (lastPix == fruit->pix() && lastRect == fruitRect) + fruitRect.setRect(0, 0, 0, 0); + else + fruitRect = pix->rect(fruitRect, lastRect); + } else + fruitRect.setRect(0, 0, 0, 0); + } else + fruitRect.setRect(0, 0, 0, 0); + + int lastBodyPix; + int lastEyesPix; + + for (Monster *m = monsters->first(); m != 0; m = monsters->next()) + if (m) { + lastRect = pix->rect(m->position(), MonsterPix); + lastBodyPix = m->body(); + lastEyesPix = m->eyes(); + if (m->move()) { + moved = TRUE; + *monsterRect->at(m->id()) = pix->rect(m->position(), MonsterPix); + if (lastBodyPix == m->body() && lastEyesPix == m->eyes() && + lastRect == pix->rect(m->position(), MonsterPix)) + monsterRect->at(m->id())->setRect(0, 0, 0, 0); + else + *monsterRect->at(m->id()) = pix->rect(*monsterRect->at(m->id()), lastRect); + if (m->position() == pos && !gameState.testBit(Dying)) { + if (m->state() == harmless && !gameState.testBit(Dying)) { + m->setREM(remTicks[level]); + eated++; + if (gameState.testBit(Introducing)) { + m->setPosition(OUT); + m->setDirection(X); + } + } + if (m->state() == dangerous && !gameState.testBit(Dying)) + killed(); + } + } else + monsterRect->at(m->id())->setRect(0, 0, 0, 0); + } + + for (int m = 0; m < board->monsters(); m++) + if (pacmanRect.intersects(*monsterRect->at(m))) { + pacmanRect = pix->rect(pacmanRect, *monsterRect->at(m)); + monsterRect->at(m)->setRect(0, 0, 0, 0); + } else + for (int im = m+1; im < board->monsters(); im++) + if (monsterRect->at(m)->intersects(*monsterRect->at(im))) { + *monsterRect->at(m) = pix->rect(*monsterRect->at(m), *monsterRect->at(im)); + monsterRect->at(im)->setRect(0, 0, 0, 0); + } + + if (!pacmanRect.isNull()) + repaint(pacmanRect, FALSE); + + if (!fruitRect.isNull()) + repaint(fruitRect, FALSE); + + for (int m = 0; m < board->monsters(); m++) + if (!monsterRect->at(m)->isNull()) + repaint(*monsterRect->at(m), FALSE); + + if (board->points() == 0 && !gameState.testBit(Dying)) + levelUp(); + + if (eated > 0 && !gameState.testBit(Dying)) { + timerCount = eated; + eaten(); + } + + if (gameState.testBit(Introducing) && moved) + introPlay(); +} + +void Referee::repaintFigures() +{ + pacmanRect = pix->rect(pacman->position(), PacmanPix); + + for (int e = 0; e < board->energizers(); e++) { + *energizerRect->at(e) = pix->rect(board->position(energizer, e), EnergizerPix); + + if (pacmanRect.intersects(*energizerRect->at(e))) { + pacmanRect = pix->rect(pacmanRect, *energizerRect->at(e)); + energizerRect->at(e)->setRect(0, 0, 0, 0); + } else + for (int ie = e+1; ie < board->energizers(); ie++) + if (energizerRect->at(e)->intersects(*energizerRect->at(ie))) { + *energizerRect->at(e) = pix->rect(*energizerRect->at(e), *energizerRect->at(ie)); + energizerRect->at(ie)->setRect(0, 0, 0, 0); + } + } + + if (fruit->pix() != -1 && fruit->state() != active) + fruitRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix()); + else + fruitRect = pix->rect(fruit->position(), FruitPix, fruit->pix()); + + if (pacmanRect.intersects(fruitRect)) { + pacmanRect = pix->rect(pacmanRect, fruitRect); + fruitRect.setRect(0, 0, 0, 0); + } + + for (int m = 0; m < board->monsters(); m++) { + *monsterRect->at(m) = pix->rect(board->position(monster, m), MonsterPix); + + if (pacmanRect.intersects(*monsterRect->at(m))) { + pacmanRect = pix->rect(pacmanRect, *monsterRect->at(m)); + monsterRect->at(m)->setRect(0, 0, 0, 0); + } else + for (int im = m+1; im < board->monsters(); im++) + if (monsterRect->at(m)->intersects(*monsterRect->at(im))) { + *monsterRect->at(m) = pix->rect(*monsterRect->at(m), *monsterRect->at(im)); + monsterRect->at(im)->setRect(0, 0, 0, 0); + } + } + + if (!pacmanRect.isNull()) + repaint(pacmanRect, FALSE); + + if (!fruitRect.isNull()) + repaint(fruitRect, FALSE); + + for (int m = 0; m < board->monsters(); m++) + if (!monsterRect->at(m)->isNull()) + repaint(*monsterRect->at(m), FALSE); + + for (int e = 0; e < board->energizers(); e++) + if (!energizerRect->at(e)->isNull()) + repaint(*energizerRect->at(e), FALSE); + +} + +void Referee::initKeys() +{ + QString up("Up"); + up = kapp->config()->readEntry("upKey", (const char*) up); + UpKey = KAccel::stringToKey(up); + + QString down("Down"); + down = kapp->config()->readEntry("downKey", (const char*) down); + DownKey = KAccel::stringToKey(down); + + QString left("Left"); + left = kapp->config()->readEntry("leftKey", (const char*) left); + LeftKey = KAccel::stringToKey(left); + + QString right("Right"); + right = kapp->config()->readEntry("rightKey", (const char*) right); + RightKey = KAccel::stringToKey(right); +} + +void Referee::fillArray(QArray<int> &array, QString values, int max) +{ + if (max < 0) + max = values.contains(',')+1; + + array.resize(max); + int last = 0; + bool ok; + QString value; + + for (uint i = 0; i < array.size(); i++) { + if (values.find(',') < 0 && values.length() > 0) { + value = values; + values = ""; + } + if (values.find(',') >= 0) { + value = values.left(values.find(',')); + values.remove(0,values.find(',')+1); + } + array[i] = value.toInt(&ok); + if (ok) + last = array[i]; + else + array[i] = last; + } +} + +void Referee::fillStrList(QStrList &list, QString values, int max) +{ + if (!list.isEmpty()) + list.clear(); + + QString last = ""; + QString value; + + for (uint i = 0; i < (uint) max; i++) { + if (values.find(',') < 0 && values.length() > 0) { + value = values; + values = ""; + } + if (values.find(',') >= 0) { + value = values.left(values.find(',')); + values.remove(0,values.find(',')+1); + } + if (!value.isEmpty()) + last = value; + + list.append(last); + } +} + +void Referee::fillMapName() +{ + QStrList list = mapName; + + if (!mapName.isEmpty()) + mapName.clear(); + + QString map; + + QFileInfo fileInfo; + + for (uint i = 0; i < list.count(); i++) { + map = list.at(i); + + if (map.left(1) != "/" && map.left(1) != "~") + map = KGlobal::dirs()->findResource("appdata", mapDirectory+map); + + fileInfo.setFile(map); + if (!fileInfo.isReadable()) + map = ""; + + mapName.append(map); + } +} + +void Referee::confLevels(bool defGroup) +{ + if (defGroup || kapp->config()->hasKey("Levels")) + maxLevel = kapp->config()->readNumEntry("Levels", 13); +} + +void Referee::confMisc(bool defGroup) +{ + if (defGroup || kapp->config()->hasKey("PixmapDirectory")) { + pixmapDirectory = kapp->config()->readEntry("PixmapDirectory"); + + if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~") + pixmapDirectory.insert(0, "pics/"); + if (pixmapDirectory.right(1) != "/") + pixmapDirectory.append("/"); + } + + if (defGroup || kapp->config()->hasKey("MapDirectory")) { + mapDirectory = kapp->config()->readEntry("MapDirectory"); + + if (mapDirectory.left(1) != "/" && mapDirectory.left(1) != "~") + mapDirectory.insert(0, "maps/"); + if (mapDirectory.right(1) != "/") + mapDirectory.append("/"); + } + + if (defGroup || kapp->config()->hasKey("MapName")) + fillStrList(mapName, kapp->config()->readEntry("MapName", "map"), maxLevel+1); + + if (defGroup || kapp->config()->hasKey("MonsterIQ")) + fillArray(monsterIQ, kapp->config()->readEntry("MonsterIQ", "0,170,180,170,180,170,180"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("FruitIQ")) + fillArray(fruitIQ, kapp->config()->readEntry("FruitIQ", "0,170,180,170,180,170,180"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("FruitIndex")) + fillArray(fruitIndex, kapp->config()->readEntry("FruitIndex", "0"), maxLevel+1); +} + +void Referee::confTiming(bool defGroup) +{ + if (defGroup || kapp->config()->hasKey("SpeedMS")) + fillArray(speed, kapp->config()->readEntry("SpeedMS", "20"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("PacmanTicks")) + fillArray(pacmanTicks,kapp->config()->readEntry("PacmanTicks", "3"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("RemTicks")) + fillArray(remTicks, kapp->config()->readEntry("RemTicks", "1"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("DangerousTicks")) + fillArray(dangerousTicks, kapp->config()->readEntry("DangerousTicks", "3"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("HarmlessTicks")) + fillArray(harmlessTicks, kapp->config()->readEntry("HarmlessTicks", "7,6,,5,,4"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("HarmlessDurationTicks")) + fillArray(harmlessDurTicks, kapp->config()->readEntry("HarmlessDurationTicks", "375,,,300,,250,200,150"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("HarmlessWarningTicks")) + fillArray(harmlessWarnTicks, kapp->config()->readEntry("HarmlessWarningTicks", "135"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("ArrestTicks")) + fillArray(arrestTicks, kapp->config()->readEntry("ArrestTicks", "6"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("ArrestDurationTicks")) + fillArray(arrestDurTicks, kapp->config()->readEntry("ArrestDurationTicks", "200,,,150"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("FruitTicks")) + fillArray(fruitTicks, kapp->config()->readEntry("FruitTicks", "7,6,,5,,4"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("FruitAppearsTicks")) + fillArray(fruitAppearsTicks, kapp->config()->readEntry("FruitAppearsTicks", "1000,,1500,2000,2500,3000,3500,4000"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("FruitDurationTicks")) + fillArray(fruitDurTicks, kapp->config()->readEntry("FruitDurationTicks", "500,,,400,350,300,,250,200,150"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("FruitScoreDurationTicks")) + fillArray(fruitScoreDurTicks, kapp->config()->readEntry("FruitScoreDurationTicks", "150"), maxLevel+1); + + if (defGroup || kapp->config()->hasKey("MonsterScoreDurationMS")) + monsterScoreDurMS = kapp->config()->readNumEntry("MonsterScoreDurationMS", 1000); + if (defGroup || kapp->config()->hasKey("PlayerDurationMS")) + playerDurMS = kapp->config()->readNumEntry("PlayerDurationMS", 3000); + if (defGroup || kapp->config()->hasKey("ReadyDurationMS")) + readyDurMS = kapp->config()->readNumEntry("ReadyDurationMS", 2000); + if (defGroup || kapp->config()->hasKey("GameOverDurationMS")) + gameOverDurMS = kapp->config()->readNumEntry("GameOverDurationMS", 3000); + if (defGroup || kapp->config()->hasKey("AfterPauseMS")) + afterPauseMS = kapp->config()->readNumEntry("AfterPauseMS", 1000); + if (defGroup || kapp->config()->hasKey("DyingPreAnimationMS")) + dyingPreAnimationMS = kapp->config()->readNumEntry("DyingPreAnimationMS", 1000); + if (defGroup || kapp->config()->hasKey("DyingAnimationMS")) + dyingAnimationMS = kapp->config()->readNumEntry("DyingAnimationMS", 100); + if (defGroup || kapp->config()->hasKey("DyingPostAnimationMS")) + dyingPostAnimationMS = kapp->config()->readNumEntry("DyingPostAnimationMS", 500); + if (defGroup || kapp->config()->hasKey("IntroAnimationMS")) + introAnimationMS = kapp->config()->readNumEntry("IntroAnimationMS", 800); + if (defGroup || kapp->config()->hasKey("IntroPostAnimationMS")) + introPostAnimationMS = kapp->config()->readNumEntry("IntroPostAnimationMS", 1000); + if (defGroup || kapp->config()->hasKey("LevelUpPreAnimationMS")) + levelUpPreAnimationMS = kapp->config()->readNumEntry("LevelUpPreAnimationMS", 2000); + if (defGroup || kapp->config()->hasKey("LevelUpAnimationMS")) + levelUpAnimationMS = kapp->config()->readNumEntry("LevelUpAnimationMS", 2000); + if (defGroup || kapp->config()->hasKey("EnergizerAnimationMS")) + energizerAnimationMS = kapp->config()->readNumEntry("EnergizerAnimationMS", 200); +} + +void Referee::confScoring(bool defGroup) +{ + if (defGroup || kapp->config()->hasKey("PointScore")) + pointScore = kapp->config()->readNumEntry("PointScore", 10); + if (defGroup || kapp->config()->hasKey("EnergizerScore")) + energizerScore = kapp->config()->readNumEntry("EnergizerScore", 50); + if (defGroup || kapp->config()->hasKey("FruitScore")) + fillArray(fruitScore, kapp->config()->readEntry("FruitScore", "100,300,500,,700,,1000,,2000,,3000,,5000"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("MonsterScore")) + fillArray(monsterScore, kapp->config()->readEntry("MonsterScore", "200,400,800,1600"), 4); + if (defGroup || kapp->config()->hasKey("ExtraLifeScore")) + fillArray(extraLifeScore, kapp->config()->readEntry("ExtraLifeScore", "10000"), -1); +} + +void Referee::confScheme() +{ + QString oldgroup = kapp->config()->group(); + QString newgroup; + + // if not set, read mode and scheme from the configfile + if (mode == -1 && scheme == -1) { + scheme = kapp->config()->readNumEntry("Scheme", -1); + mode = kapp->config()->readNumEntry("Mode", -1); + + // if mode is not set in the defGroup-group, lookup the scheme group + if (scheme != -1 || mode == -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + mode = kapp->config()->readNumEntry("Mode", -1); + kapp->config()->setGroup(oldgroup); + } + } + + confLevels(); + + if (mode != -1) { + newgroup.sprintf("Mode %d", mode); + kapp->config()->setGroup(newgroup); + + confLevels(FALSE); + } + + if (scheme != -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + confLevels(FALSE); + } + + kapp->config()->setGroup(oldgroup); + + confMisc(); + confTiming(); + confScoring(); + + if (mode != -1) { + newgroup.sprintf("Mode %d", mode); + kapp->config()->setGroup(newgroup); + + confMisc(FALSE); + confTiming(FALSE); + confScoring(FALSE); + } + + if (scheme != -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + confMisc(FALSE); + confTiming(FALSE); + confScoring(FALSE); + } + + fillMapName(); + + kapp->config()->setGroup(oldgroup); +} + +void Referee::setScheme(int Scheme, int Mode, Bitfont *font) +{ + mode = Mode; + scheme = Scheme; + + confScheme(); + + pix->setScheme(scheme, mode, font); + + pacman->setMaxPixmaps(pix->maxPixmaps(PacmanPix)); + fruit->setMaxPixmaps(pix->maxPixmaps(FruitPix)); + + for (Monster *m = monsters->first(); m != 0; m = monsters->next()) + if (m) + m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix)); + + for (Energizer *e = energizers->first(); e != 0; e = energizers->next()) + if (e) + e->setMaxPixmaps(pix->maxPixmaps(EnergizerPix)); + + if (gameState.testBit(Introducing)) + for (int i = 0; i < (gameState.testBit(Init) ? timerCount : 15); i++) + introPaint(i); + + setFixedSize(pix->levelPix().size()); + repaint(); +} + +void Referee::keyPressEvent( QKeyEvent *k ) +{ + if (gameState.testBit(Paused) || gameState.testBit(HallOfFame) || + gameState.testBit(Demonstration) || gameState.testBit(Dying) || + gameState.testBit(Ready) || gameState.testBit(LevelDone) || + !gameState.testBit(Playing)) + return; + + uint key = k->key(); + if (key == UpKey) + pacman->setDirection(N); + else if (key == DownKey) + pacman->setDirection(S); + else if (key == RightKey) + pacman->setDirection(E); + else if (key == LeftKey) + pacman->setDirection(W); + +#ifdef CHEATS + else if (key == Key_L) { printf("levelUp()\n"); levelUp(); } + else if (key == Key_F) { printf("fruit->move(TRUE)\n"); fruit->move(TRUE); repaint(FALSE); } + else if (key == Key_E) { printf("setLifes(++lifes)\n"); emit setLifes(++lifes); } +#endif + + else { + k->ignore(); + return; + } + k->accept(); +} + +void Referee::score(int p) +{ + if (!gameState.testBit(Playing)) + return; + + if ((points += p) < 0) + points = 0; + + emit setPoints(points); + + if (points >= nextExtraLifeScore) { + emit setLifes(++lifes); + if (extraLifeScoreIndex < (int) extraLifeScore.size()-1) + extraLifeScoreIndex++; + if (extraLifeScore[extraLifeScoreIndex] < 0) + nextExtraLifeScore = extraLifeScore[extraLifeScoreIndex] * -1; + else + nextExtraLifeScore += extraLifeScore[extraLifeScoreIndex]; + } +} + +void Referee::eaten() +{ + if (gameState.testBit(Ready)) + return; + + stop(); + + if (monstersEaten < 4) + monstersEaten++; + + gameState.setBit(Scoring); + score(monsterScore[monstersEaten-1]); + + repaint(pix->rect(pix->rect(pacman->position(), MonsterPix), + pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1))); + + if (--timerCount > 0) + QTimer::singleShot( monsterScoreDurMS, this, SLOT(eaten())); + else { + for (Monster *m = monsters->first(); m != 0; m = monsters->next()) + if (m && m->direction() == X && !gameState.testBit(Introducing)) + m->setDirection(N); + if (monstersEaten != 4 || !gameState.testBit(Introducing)) + QTimer::singleShot( monsterScoreDurMS, this, SLOT(start())); + } +} + +void Referee::toggleHallOfFame() +{ + gameState.toggleBit(HallOfFame); +} + +void Referee::hallOfFame() +{ + if (gameState.testBit(HallOfFame)) // If the HallOfFame is switched on manually, toggle the + toggleHallOfFame(); // bit twice. + + emit setLevel(0); // Clear status display for hall of fame + emit setScore(level, 0); + emit forcedGameHighscores(); +} + +void Referee::pause() +{ + static int pausedTimer = 0; + + if (!gameState.testBit(Paused)) { + pausedTimer = gameTimer; + stop(); + stopEnergizer(); + gameState.setBit(Paused); + repaint(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED")), FALSE); + } else { + gameState.clearBit(Paused); + repaint(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED")), FALSE); + if (pausedTimer) { + pausedTimer = 0; + start(); + } + // manual pause deactivating (also) deactivates a focusedPause + focusedPause = false; + } + //0.3.2 emit gamePause(); +} + +void Referee::intro() +{ + stop(); + stopEnergizer(); + bool paused = gameState.testBit(Paused); + + gameState.fill(FALSE); + gameState.setBit(Introducing); + gameState.setBit(Init); + + if (paused) + gameState.setBit(Paused); + + level = 0; + emit setLevel(level); + + board->init(Intro); + pix->setLevel(level); + + initPacman(); + initFruit(); + initMonsters(); + initEnergizers(); + + repaint(); + + monstersEaten = 0; + timerCount = 0; + introPlay(); +} + +void Referee::introMonster(int id) +{ + Monster *m = new Monster(board, id); + + m->setPosition((10+id*6)*BoardWidth+10); + m->setDirection(E); + m->setDangerous(dangerousTicks[level], monsterIQ[level]); + m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix)); + + if (m->body() != -1) + pix->draw(m->position(), RoomPix, MonsterPix, m->body()); + if (m->eyes() != -1) + pix->draw(m->position(), RoomPix, EyesPix, m->eyes()); + + repaint(pix->rect(m->position(), MonsterPix), FALSE); + m->setPosition(OUT); +} + +void Referee::introPaint(int t) +{ + QString pts; + + switch (t) { + case 0 : repaint(pix->draw(16, 6, RoomPix, i18n("CHARACTER"), WHITE, QColor(), AlignLeft), FALSE); + repaint(pix->draw(36, 6, RoomPix, i18n("/"), WHITE, QColor(), AlignLeft), FALSE); + repaint(pix->draw(40, 6, RoomPix, i18n("NICKNAME"), WHITE, QColor(), AlignLeft), FALSE); + break; + case 1 : introMonster(0); + break; + case 2 : repaint(pix->draw(16, 10, RoomPix, i18n("-SHADOW"), RED, QColor(), AlignLeft), FALSE); + break; + case 3 : repaint(pix->draw(38, 10, RoomPix, i18n("\"BLINKY\""), RED, QColor(), AlignLeft), FALSE); + break; + case 4 : introMonster(1); + break; + case 5 : repaint(pix->draw(16, 16, RoomPix, i18n("-SPEEDY"), PINK, QColor(), AlignLeft), FALSE); + break; + case 6 : repaint(pix->draw(38, 16, RoomPix, i18n("\"PINKY\""), PINK, QColor(), AlignLeft), FALSE); + break; + case 7 : introMonster(2); + break; + case 8 : repaint(pix->draw(16, 22, RoomPix, i18n("-BASHFUL"), CYAN, QColor(), AlignLeft), FALSE); + break; + case 9 : repaint(pix->draw(38, 22, RoomPix, i18n("\"INKY\""), CYAN, QColor(), AlignLeft), FALSE); + break; + case 10 : introMonster(3); + break; + case 11 : repaint(pix->draw(16, 28, RoomPix, i18n("-POKEY"), ORANGE, QColor(), AlignLeft), FALSE); + break; + case 12 : repaint(pix->draw(38, 28, RoomPix, i18n("\"CLYDE\""), ORANGE, QColor(), AlignLeft), FALSE); + break; + case 13 : pts.sprintf("%d", pointScore); + repaint(pix->draw(28, 44, RoomPix, pts.data(), WHITE, QColor(), AlignRight), FALSE); + repaint(pix->draw(31, 44, RoomPix, "\x1C\x1D\x1E", WHITE, QColor(), AlignLeft), FALSE); + pts.sprintf("%d", energizerScore); + repaint(pix->draw(28, 48, RoomPix, pts.data(), WHITE, QColor(), AlignRight), FALSE); + repaint(pix->draw(31, 48, RoomPix, "\x1C\x1D\x1E", WHITE, QColor(), AlignLeft), FALSE); + break; + case 14 : // "@ 1980 MIDWAY MFG.CO." + repaint(pix->draw(30, 58, RoomPix, "© 1998-2003 J.THÖNNISSEN", PINK), FALSE); + break; + } +} + +void Referee::introPlay() +{ + if (!gameState.testBit(Introducing) || gameState.testBit(Ready)) + return; + if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) { + QTimer::singleShot(afterPauseMS, this, SLOT(introPlay())); + return; + } + + if (!gameState.testBit(Init)) { + if (monstersEaten == 4) { + stop(); + QTimer::singleShot(introPostAnimationMS, this, SLOT(demo())); + } + if (pacman->direction() == W) { + int id = -1; + if (pacman->position() == 37*BoardWidth-6) + id = 0; + else + if (board->isMonster(37*BoardWidth-6)) + for (Monster *m = monsters->first(); m != 0; m = monsters->next()) + if (m && m->position() == 37*BoardWidth-6) { + id = m->id(); + id++; + break; + } + + if (id >= 0 && id <= 4) + for (Monster *m = monsters->first(); m != 0; m = monsters->next()) + if (m && m->id() == id && m->position() == OUT) { + m->setPosition(37*BoardWidth-1); + m->setDirection(W); + m->setDangerous(dangerousTicks[level], monsterIQ[level]); + board->set(37*BoardWidth-1, monsterhome, id); + repaint(pix->rect(m->position(), MonsterPix)); + break; + } + } + return; + } + + if (timerCount < 15) + introPaint(timerCount); + + switch (timerCount) { + case 13 : board->set(44*BoardWidth+22, Point); + pix->drawPoint(44*BoardWidth+22); + repaint(pix->rect(44*BoardWidth+22, PointPix), FALSE); + energizers->at(0)->setPosition(48*BoardWidth+22); + energizers->at(0)->setOn(); + repaint(pix->rect(48*BoardWidth+22, EnergizerPix), FALSE); + break; + case 14 : energizers->at(1)->setPosition(36*BoardWidth+10); + energizers->at(1)->setOn(); + repaint(pix->rect(36*BoardWidth+10, EnergizerPix), FALSE); + for (int pos = 8; pos < BoardWidth; pos++) { + board->set(34*BoardWidth+pos, out); + board->set(38*BoardWidth+pos, out); + } + board->set(36*BoardWidth+8, out); + break; + case 15 : gameState.clearBit(Init); + initPacman(); + pacman->setDemo(TRUE); + pacman->setPosition(37*BoardWidth-1); + repaintFigures(); + start(); + return; + } + + if (timerCount++ < 15) + QTimer::singleShot(introAnimationMS, this, SLOT(introPlay())); +} + +void Referee::demo() +{ + if (gameState.testBit(Ready)) + return; + + if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) { + QTimer::singleShot(afterPauseMS, this, SLOT(demo())); + return; + } + + stop(); + stopEnergizer(); + + gameState.fill(FALSE); + gameState.setBit(Init); + gameState.setBit(Demonstration); + + level = 0; + emit setLevel(level); + + board->init(Demo, mapName.at(0)); + pix->setLevel(level); + + initPacman(); + initFruit(); + initMonsters(); + initEnergizers(); + + gameState.clearBit(Init); + + repaint(); + + timerCount = 0; + QTimer::singleShot(playerDurMS, this, SLOT(start())); +} + +void Referee::play() +{ + stop(); + stopEnergizer(); + + gameState.fill(FALSE); + gameState.setBit(Init); + gameState.setBit(Playing); + gameState.setBit(Player); + gameState.setBit(Ready); + + lifes = 3; + level = 1; + points = 0; + + extraLifeScoreIndex = 0; + nextExtraLifeScore = extraLifeScore[extraLifeScoreIndex]; + if (nextExtraLifeScore < 0) + nextExtraLifeScore *= -1; + + board->init(Level, mapName.at(level)); + pix->setLevel(level); + + initPacman(); + initFruit(); + initMonsters(); + initEnergizers(); + + repaint(); + //0.3.2 emit toggleNew(); + emit setLifes(lifes); + emit setLevel(level); + emit setPoints(points); + + repaint(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE")), FALSE); + repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE); + + timerCount = 0; + QTimer::singleShot(playerDurMS, this, SLOT(ready())); +} + +void Referee::ready() +{ + if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) { + QTimer::singleShot(afterPauseMS, this, SLOT(ready())); + return; + } + + if (gameState.testBit(Player)) { + emit setLifes(--lifes); + gameState.clearBit(Player); + gameState.clearBit(Init); + repaint(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE")), FALSE); + repaintFigures(); + QTimer::singleShot(playerDurMS, this, SLOT(ready())); + return; + } + + if (gameState.testBit(Ready)) { + gameState.clearBit(Ready); + repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE); + start(); + } else { + gameState.setBit(Ready); + gameState.clearBit(Init); + repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE); + QTimer::singleShot(readyDurMS, this, SLOT(ready())); + } +} + + +void Referee::levelUp() +{ + stop(); + stopEnergizer(); + + gameState.setBit(LevelDone); + pacman->setPosition(pacman->position()); // set mouthPosition to "0" + repaint(pix->rect(pacman->position(), PacmanPix)); + + timerCount = 0; + QTimer::singleShot(levelUpPreAnimationMS, this, SLOT(levelUpPlay())); +} + +void Referee::levelUpPlay() +{ + if (gameState.testBit(Ready)) + return; + + if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) { + QTimer::singleShot(afterPauseMS, this, SLOT(levelUpPlay())); + return; + } + + switch (timerCount) { + case 0 : gameState.setBit(Init); + setOnEnergizers(); + repaintFigures(); + break; + case 1 : gameState.clearBit(LevelDone); + repaint(pix->rect(pacman->position(), PacmanPix)); + break; + } + + if (timerCount++ < 2) { + QTimer::singleShot(levelUpAnimationMS, this, SLOT(levelUpPlay())); + return; + } + + gameState.clearBit(Init); + + if (gameState.testBit(Demonstration)) { + hallOfFame(); + return; + } + + if (level < maxLevel) + level++; + + board->init(Level, mapName.at(level)); + pix->setLevel(level); + + initPacman(); + initFruit(); + initMonsters(); + initEnergizers(); + + repaint(); + emit setLevel(level); + + ready(); +} + +void Referee::start() +{ + if (gameState.testBit(Ready)) + return; + + if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) { + QTimer::singleShot(afterPauseMS, this, SLOT(start())); + return; + } + + if (gameState.testBit(Scoring)) { + gameState.clearBit(Scoring); + repaint(pix->rect(pix->rect(pacman->position(), MonsterPix), + pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1))); + } + + if (!gameTimer) + gameTimer = startTimer( speed [level] ); + + if (!energizerTimer) + energizerTimer = startTimer( energizerAnimationMS ); +} + +void Referee::start(int t) +{ + gameTimer = startTimer(t); +} + +void Referee::stop() +{ + if (gameTimer) { + killTimer (gameTimer); + gameTimer = 0; + } +} + +void Referee::stopEnergizer() +{ + if (energizerTimer) { + killTimer (energizerTimer); + energizerTimer = 0; + } +} + +void Referee::killed() +{ + if (gameState.testBit(Ready)) + return; + + if (!gameState.testBit(Dying)) { + gameState.setBit(Dying); + + pacman->setDirection(X, TRUE); + for (Monster *m = monsters->first(); m != 0; m = monsters->next()) + if (m) + m->setDirection(X); + QTimer::singleShot(dyingPreAnimationMS, this, SLOT(killed())); + } else { + stop(); + if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) { + QTimer::singleShot(afterPauseMS, this, SLOT(killed())); + return; + } + + gameState.setBit(Init); + + repaintFigures(); + + timerCount = 0; + killedPlay(); + } +} + +void Referee::killedPlay() +{ + if (!gameState.testBit(Dying) || gameState.testBit(Ready)) + return; + if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) { + QTimer::singleShot(afterPauseMS, this, SLOT(killedPlay())); + return; + } + + if (timerCount <= pix->maxPixmaps(DyingPix)) { + repaint(pix->rect(pacman->position(), PacmanPix), FALSE); + if (timerCount >= pix->maxPixmaps(DyingPix)-1 || timerCount == 0) + QTimer::singleShot(dyingPostAnimationMS, this, SLOT(killedPlay())); + else + QTimer::singleShot(dyingAnimationMS, this, SLOT(killedPlay())); + timerCount++; + } else { + gameState.clearBit(Dying); + stopEnergizer(); + if (lifes == 0) { + gameState.setBit(GameOver); + gameState.clearBit(Playing); + for (int e = 0; e < board->energizers(); e++) { + energizers->at(e)->setOff(); + repaint(pix->rect(board->position(energizer, e), EnergizerPix), FALSE); + } + repaint(pix->rect(board->position(fruithome), i18n("GAME OVER")), FALSE); + QTimer::singleShot(gameOverDurMS, this, SLOT(hallOfFame())); + } else { + gameState.clearBit(Init); + initPacman(); + initFruit(); + initMonsters(); + initEnergizers(); + emit setLifes(--lifes); + repaintFigures(); + ready(); + } + } +} + +void Referee::initPacman() +{ + pacman->setMaxPixmaps(pix->maxPixmaps(PacmanPix)); + pacman->setDemo(gameState.testBit(Demonstration)); + pacman->setPosition(board->position(pacmanhome)); + pacman->setDirection(W, TRUE); + pacman->setAlive(pacmanTicks[level]); +} + +void Referee::initFruit(bool fullInitialization) +{ + if (fullInitialization) { + fruit->setMaxPixmaps(pix->maxPixmaps(FruitPix)); + if (fruitIndex[level] == 0) + fruit->setLevel(level, fruitAppearsTicks[level], + fruitDurTicks[level], fruitTicks[level]); + else if (fruitIndex[level] < 0) + fruit->setLevel(pix->maxPixmaps(FruitPix)+1, + fruitAppearsTicks[level], + fruitDurTicks[level], fruitTicks[level]); + else + fruit->setLevel(fruitIndex[level], fruitAppearsTicks[level], + fruitDurTicks[level], fruitTicks[level]); + } + + if (board->tunnels() > 0) + fruit->setMovement(board->position(tunnel, rand() % board->tunnels()), + board->position(tunnel, rand() % board->tunnels()), + fruitIQ[level]); +} + +void Referee::initMonsters() +{ + if( !monsters->isEmpty()) + monsters->clear(); + if( !monsterRect->isEmpty()) + monsterRect->clear(); + + for (int id = 0; id < (gameState.testBit(Introducing) ? 4 : board->monsters()); id++) { + Monster *m = new Monster(board, id); + monsters->append(m); + QRect *r = new QRect(); + monsterRect->append(r); + if (!gameState.testBit(Introducing)) { + m->setFreedom(board->position(prisonexit)); + m->setDangerous(dangerousTicks[level], monsterIQ[level]); + if (id == 0) + m->setPrison(board->position(prisonentry)); + else { + m->setPrison(board->position(monsterhome, id)); + m->setArrested(arrestTicks[level], arrestDurTicks[level]*id); + } + m->setPosition(board->position(monsterhome, id)); + switch(id) { + case 0 : m->setDirection(W); break; + case 1 : m->setDirection(N); break; + default : m->setDirection(S); + } + } + m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix)); + } +} + +void Referee::initEnergizers() +{ + if( !energizers->isEmpty()) + energizers->clear(); + if( !energizerRect->isEmpty()) + energizerRect->clear(); + + for (int id = 0; id < (gameState.testBit(Introducing) ? 2 : board->energizers()); id++) { + Energizer *e = new Energizer(board); + energizers->append(e); + QRect *r = new QRect(); + energizerRect->append(r); + if (!gameState.testBit(Introducing)) { + e->setPosition(board->position(energizer, id)); + e->setOn(); + } + e->setMaxPixmaps(pix->maxPixmaps(EnergizerPix)); + } +} + +void Referee::setOnEnergizers() +{ + for (int e = 0; e < board->energizers(); e++) { + energizers->at(e)->setOn(); + } +} + +void Referee::setFocusOutPause(bool FocusOutPause) +{ + focusOutPause = FocusOutPause; +} + +void Referee::setFocusInContinue(bool FocusInContinue) +{ + focusInContinue = FocusInContinue; +} + +void Referee::focusInEvent(QFocusEvent *) +{ + if (focusInContinue && focusedPause && + gameState.testBit(Paused) && gameState.testBit(Playing)) { + focusedPause = false; + // this also calls the Referee::pause() function + emit focusedGamePause(); + } +} + +void Referee::focusOutEvent(QFocusEvent *) +{ + if (focusOutPause && !focusedPause && + !gameState.testBit(Paused) && gameState.testBit(Playing)) { + focusedPause = true; + // this also calls the Referee::pause() function + emit focusedGamePause(); + } +} diff --git a/kpacman/referee.h b/kpacman/referee.h new file mode 100644 index 0000000..376b5c2 --- /dev/null +++ b/kpacman/referee.h @@ -0,0 +1,190 @@ +#ifndef REFEREE_H +#define REFEREE_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kapp.h> +#include <qwidget.h> +#include <qlist.h> +#include <qstrlist.h> +#include <qarray.h> +#include <qbitarry.h> + +#include "board.h" +#include "pacman.h" +#include "monster.h" +#include "fruit.h" +#include "energizer.h" +#include "bitfont.h" +#include "painter.h" + +enum { Init, Introducing, Playing, Demonstration, Paused, Player, Ready, + Scoring, LevelDone, Dying, GameOver, HallOfFame }; + + +class Referee : public QWidget +{ + Q_OBJECT +public: + Referee (QWidget *parent=0, const char *name=0, int scheme=-1, int mode=-1, Bitfont *font=0); + + void setSkill(int); + void setRoom(int); + +public slots: + void setScheme(int scheme, int mode, Bitfont *font=0); + + void levelUp(); + void levelUpPlay(); + + void pause(); + void ready(); + void intro(); + void introPlay(); + void hallOfFame(); + void demo(); + void play(); + void killed(); + void killedPlay(); + void eaten(); + void toggleHallOfFame(); + + void setFocusOutPause(bool focusOutPause); + void setFocusInContinue(bool focusInContinue); + void initKeys(); + + void repaintFigures(); + +private slots: + void start(); + void stop(); + void stopEnergizer(); + +signals: + void setScore(int, int); + void setPoints(int); + void setLevel(int); + void setLifes(int); + + void focusedGamePause(); + void forcedGameHighscores(); + +protected: + void timerEvent(QTimerEvent *); + void paintEvent(QPaintEvent *); + void keyPressEvent(QKeyEvent *); + + void focusOutEvent(QFocusEvent *); + void focusInEvent(QFocusEvent *); + + void fillArray(QArray<int> &, QString, int); + void fillStrList(QStrList &, QString, int); + void fillMapName(); + + void confScheme(); + void confLevels(bool defGroup=TRUE); + void confMisc(bool defGroup=TRUE); + void confTiming(bool defGroup=TRUE); + void confScoring(bool defGroup=TRUE); + +private: + QBitArray gameState; + int timerCount; + int maxLevel; + + int scheme; + int mode; + + QString pixmapDirectory; + QString mapDirectory; + QStrList mapName; + + QArray<int> speed; + QArray<int> monsterIQ; + QArray<int> fruitIQ; + QArray<int> fruitIndex; + QArray<int> pacmanTicks; + QArray<int> remTicks; + QArray<int> dangerousTicks; + QArray<int> harmlessTicks; + QArray<int> harmlessDurTicks; + QArray<int> harmlessWarnTicks; + QArray<int> arrestTicks; + QArray<int> arrestDurTicks; + QArray<int> fruitTicks; + QArray<int> fruitAppearsTicks; + QArray<int> fruitDurTicks; + QArray<int> fruitScoreDurTicks; + + int monsterScoreDurMS; + int playerDurMS; + int readyDurMS; + int gameOverDurMS; + int afterPauseMS; + int dyingPreAnimationMS; + int dyingAnimationMS; + int dyingPostAnimationMS; + int introAnimationMS; + int introPostAnimationMS; + int levelUpPreAnimationMS; + int levelUpAnimationMS; + int energizerAnimationMS; + + int pointScore; + int energizerScore; + QArray<int> fruitScore; + QArray<int> monsterScore; + QArray<int> extraLifeScore; + + int extraLifeScoreIndex; + int nextExtraLifeScore; + + int monstersEaten; + int points; + int lifes; + int level; + + bool focusedPause; + bool focusOutPause; + bool focusInContinue; + + Board *board; + Painter *pix; + Pacman *pacman; + Fruit *fruit; + + QList<Monster> *monsters; + QList<QRect> *monsterRect; + + QList<Energizer> *energizers; + QList<QRect> *energizerRect; + + QRect pacmanRect; + QRect fruitRect; + + void introMonster(int id); + void introPaint(int t); + + void initMonsters(); + void initPacman(); + void initFruit(bool fullInitialization=TRUE); + void initEnergizers(); + + void setOnEnergizers(); + + int gameTimer; + int energizerTimer; + void start(int); + void init(bool); + + void score(int); + + uint UpKey; + uint DownKey; + uint RightKey; + uint LeftKey; +}; + +#endif // REFEREE_H diff --git a/kpacman/score.cpp b/kpacman/score.cpp new file mode 100644 index 0000000..1bbd427 --- /dev/null +++ b/kpacman/score.cpp @@ -0,0 +1,627 @@ +#include <score.h> + +#include <stdlib.h> +#include <ctype.h> + +#include <kaccel.h> + +#include <kapp.h> +#include <kconfig.h> +#include <kstddirs.h> +#include <kmessagebox.h> +#include <qpixmap.h> +#include <qstring.h> +#include <qdstream.h> +#include <qkeycode.h> +#include <qtimer.h> +#include <qfileinfo.h> + +#include "bitfont.h" + +Score::Score(QWidget *parent, const char *name, int Scheme, int Mode, Bitfont *font) : QWidget(parent, name) +{ + setFocusPolicy(QWidget::StrongFocus); + + paused = FALSE; + + lastScore = -1; + lastPlayer = -1; + + cursorBlinkTimer = 0; + cursorBlinkMS = -1; + cursor.x = -1; + cursor.y = -1; + cursor.on = FALSE; + cursor.chr = QChar('?'); + + initKeys(); + + scheme = Scheme; + mode = Mode; + confScheme(); + + bitfont = font; + + highscoreFile.setName(locateHighscoreFilePath().filePath()); + read(); + + for (int p = 0; p < maxPlayer; p++) { + playerScore[p] = 0; + playerName[p] = getenv("LOGNAME"); + if (playerName[p].length() < minPlayerNameLength) + playerName[p].setExpand(minPlayerNameLength-1, ' '); + + for (uint i = 0; i < playerName[p].length(); i++) + if (playerName[p].at(i) < bitfont->firstChar() || + playerName[p].at(i) > bitfont->lastChar()) + playerName[p].at(i) = playerName[p].at(i).upper(); + } +} + +Score::~Score() +{ + // write(); +} + +void Score::paintEvent( QPaintEvent *e) +{ + if (rect(1, 0, i18n(" 1UP ")).intersects(e->rect())) { + QPixmap pix; + QColor fg = BLACK; + if (cursor.on || paused || lastPlayer != 0) + fg = WHITE; + pix = bitfont->text(i18n(" 1UP "), fg, BLACK); + bitBlt(this, x(1), y(0), &pix); + } + + if (rect(8, 0, i18n(" HIGH SCORE ")).intersects(e->rect())) { + QPixmap pix = bitfont->text(i18n(" HIGH SCORE "), WHITE, BLACK); + bitBlt(this, x(8), y(0), &pix); + } + + if (maxPlayer > 1 && rect(21, 0, i18n(" 2UP ")).intersects(e->rect())) { + QPixmap pix; + QColor fg = BLACK; + if (cursor.on || paused || lastPlayer != 1) + fg = WHITE; + pix = bitfont->text(i18n(" 2UP "), fg, BLACK); + bitBlt(this, x(21), y(0), &pix); + } + + QString s; + + s.sprintf("%6d0", playerScore[0]/10); + if (rect(0, 1, s).intersects(e->rect())) { + QPixmap pix = bitfont->text(s, WHITE, BLACK); + bitBlt(this, x(0), y(1), &pix); + } + + s.sprintf("%8d0", HighScore/10); + if (rect(8, 1, s).intersects(e->rect())) { + QPixmap pix = bitfont->text(s, WHITE, BLACK); + bitBlt(this, x(8), y(1), &pix); + } + + if (lastScore >= 0) { + if (rect(1, 4*1.25, i18n(" CONGRATULATIONS ")).intersects(e->rect())) { + QPixmap pix = bitfont->text(i18n(" CONGRATULATIONS "), YELLOW, BLACK); + bitBlt(this, x(1), y(4*1.25), &pix); + } + if (rect(1, 6*1.25, i18n(" YOU HAVE ARCHIEVED ")).intersects(e->rect())) { + QPixmap pix = bitfont->text(i18n(" YOU HAVE ARCHIEVED "), CYAN, BLACK); + bitBlt(this, x(1), y(6*1.25), &pix); + } + if (rect(1, 7*1.25, i18n(" A SCORE IN THE TOP 10. ")).intersects(e->rect())) { + QPixmap pix = bitfont->text(i18n(" A SCORE IN THE TOP 10. "), CYAN, BLACK); + bitBlt(this, x(1), y(7*1.25), &pix); + } + if (rect(1, 8*1.25, i18n(" ")).intersects(e->rect())) { + QPixmap pix = bitfont->text(i18n(" "), CYAN, BLACK); + bitBlt(this, x(1), y(8*1.25), &pix); + } + } + + if (rect(1, 9.5*1.25, i18n("RNK SCORE NAME DATE")).intersects(e->rect())) { + QPixmap pix = bitfont->text(i18n("RNK SCORE NAME DATE"), WHITE, BLACK); + bitBlt(this, x(1), y(9.5*1.25), &pix); + } + + for (int i = 0; i < 10; i++) { + s.sprintf("%2d%9d %-3.3s %-8.8s", + i+1, hallOfFame[i].points, hallOfFame[i].name.utf8().data(), + formatDate(hallOfFame[i].moment.date()).data()); + if (rect(1, (11+i)*1.25, s).intersects(e->rect())) { + QPixmap pix = bitfont->text(s, (i == lastScore) ? YELLOW : WHITE, BLACK); + bitBlt(this, x(1), y((11+i)*1.25), &pix); + } + } + + if (cursor.x != -1 && cursor.y != -1 && cursor.on) { + if (rect(cursor.x, (cursor.y*1.25), cursor.chr).intersects(e->rect())) { + QPixmap pix = bitfont->text(cursor.chr, BLACK, YELLOW); + bitBlt(this, x(cursor.x), y(cursor.y*1.25), &pix); + } + } + + if (paused) { + + QPixmap pix = bitfont->text(i18n("PAUSED"), RED, BLACK); + QRect r = bitfont->rect(i18n("PAUSED")); + r.moveCenter(QPoint(this->width()/2, this->height()/2)); + + bitBlt(this, r.x(), r.y(), &pix); + } +} + +void Score::timerEvent(QTimerEvent *e) +{ + cursor.on = !cursor.on; + + if (paused) + return; + + if (cursor.x != -1 && cursor.y != -1) + repaint(rect(cursor.x, cursor.y*1.25, cursor.chr), FALSE); + scrollRepeat = FALSE; + + if (lastPlayer == 0) + repaint(rect(1, 0, i18n(" 1UP ")), FALSE); + + if (lastPlayer == 1) + repaint(rect(21, 0, i18n(" 2UP ")), FALSE); +} + +void Score::keyPressEvent(QKeyEvent *k) +{ + if (lastScore < 0 || lastPlayer < 0 || lastPlayer >= maxPlayer || paused) { + k->ignore(); + return; + } + + int x = cursor.x; + int y = cursor.y; + + uint key = k->key(); + + if (scrollRepeat && (key == UpKey || key == Key_Up || key == DownKey || key == Key_Down)) { + k->ignore(); + return; + } + + if (key != Key_Return) { + if (key == RightKey || key == Key_Right) + if (++cursor.x > 16) + cursor.x = 14; + if (key == LeftKey || key == Key_Left) + if (--cursor.x < 14) + cursor.x = 16; + if (key == UpKey || key == Key_Up) + if (cursor.chr.unicode() < bitfont->lastChar()) + cursor.chr = cursor.chr.unicode()+1; + else + cursor.chr = bitfont->firstChar(); + if (key == DownKey || key == Key_Down) + if (cursor.chr.unicode() > bitfont->firstChar()) + cursor.chr = cursor.chr.unicode()-1; + else + cursor.chr = bitfont->lastChar(); + + if (cursor.x == x && cursor.y == y && + cursor.chr == hallOfFame[lastScore].name.at(cursor.x-14)) { + uint ascii = k->ascii(); + + if (ascii < bitfont->firstChar() || ascii > bitfont->lastChar()) + ascii = toupper(ascii); + + if (ascii >= bitfont->firstChar() && ascii <= bitfont->lastChar()) { + cursor.chr = ascii; + hallOfFame[lastScore].name.at(cursor.x-14) = cursor.chr; + if (++cursor.x > 16) + cursor.x = 14; + } + } + } + + if (key == Key_Return) { + playerName[lastPlayer] = hallOfFame[lastScore].name; + write(); + read(); + lastScore = -1; + lastPlayer = -1; + cursor.x = -1; + cursor.y = -1; + emit gameFinished(); + end(); + } + + if (x != cursor.x || y != cursor.y) { + if (cursor.x != -1) + cursor.chr = hallOfFame[lastScore].name.at(cursor.x-14); + scrollRepeat = FALSE; + repaint(rect(x, y*1.25, cursor.chr), FALSE); + } else + hallOfFame[lastScore].name.at(cursor.x-14) = cursor.chr; + + if (key == UpKey || key == Key_Up || key == DownKey || key == Key_Down) + scrollRepeat = TRUE; + else + repaint(rect(cursor.x, cursor.y*1.25, cursor.chr), FALSE); +} + +void Score::initKeys() +{ + QString up("Up"); + up = kapp->config()->readEntry("upKey", (const char*) up); + UpKey = KAccel::stringToKey(up); + + QString down("Down"); + down = kapp->config()->readEntry("downKey", (const char*) down); + DownKey = KAccel::stringToKey(down); + + QString left("Left"); + left = kapp->config()->readEntry("leftKey", (const char*) left); + LeftKey = KAccel::stringToKey(left); + + QString right("Right"); + right = kapp->config()->readEntry("rightKey", (const char*) right); + RightKey = KAccel::stringToKey(right); +} + +void Score::confTiming(bool defGroup) +{ + if (defGroup || kapp->config()->hasKey("CursorBlinkMS")) + cursorBlinkMS = kapp->config()->readNumEntry("CursorBlinkMS", 250); + if (defGroup || kapp->config()->hasKey("HallOfFameMS")) + hallOfFameMS = kapp->config()->readNumEntry("HallOfFameMS", 7000); + if (defGroup || kapp->config()->hasKey("AfterPauseMS")) + afterPauseMS = kapp->config()->readNumEntry("AfterPauseMS", 1000); +} + +void Score::confScheme() +{ + QString oldgroup = kapp->config()->group(); + QString newgroup; + + // if not set, read mode and scheme from the configfile + if (mode == -1 && scheme == -1) { + scheme = kapp->config()->readNumEntry("Scheme", -1); + mode = kapp->config()->readNumEntry("Mode", -1); + + // if mode is not set in the defGroup-group, lookup the scheme group + if (scheme != -1 || mode == -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + mode = kapp->config()->readNumEntry("Mode", -1); + kapp->config()->setGroup(oldgroup); + } + } + + int oldCursorBlinkMS = cursorBlinkMS; + + confTiming(); + + if (mode != -1) { + newgroup.sprintf("Mode %d", mode); + kapp->config()->setGroup(newgroup); + + confTiming(FALSE); + } + + if (scheme != -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + confTiming(FALSE); + } + + if (cursorBlinkMS != oldCursorBlinkMS) { + if (cursorBlinkTimer) + killTimer(cursorBlinkTimer); + cursorBlinkTimer = startTimer(cursorBlinkMS); + } + + kapp->config()->setGroup(oldgroup); +} + +void Score::setScheme(int Scheme, int Mode, Bitfont *font) +{ + mode = Mode; + scheme = Scheme; + + confScheme(); + + bitfont = font; + + for (int p = 0; p < maxPlayer; p++) + for (uint i = 0; i < playerName[p].length(); i++) + if (playerName[p].at(i) < bitfont->firstChar() || + playerName[p].at(i) > bitfont->lastChar()) + playerName[p].at(i) = playerName[p].at(i).upper(); + + for (int i = 0; i < 10; i++) + for (uint j = 0; j < hallOfFame[i].name.length(); j++) + if (hallOfFame[i].name.at(j) < bitfont->firstChar() || + hallOfFame[i].name.at(j) > bitfont->lastChar()) + hallOfFame[i].name.at(j) = hallOfFame[i].name.at(j).upper(); + + if (cursor.chr.unicode() < bitfont->firstChar() || + cursor.chr.unicode() > bitfont->lastChar()) + cursor.chr = cursor.chr.upper(); +} + +void Score::set(int score) +{ + set(score, 0); +} + +void Score::set(int score, int player) +{ + if (player < 0 || player >= maxPlayer) + return; + + lastPlayer = player; + playerScore[lastPlayer] = score; + + QString s; + + s.sprintf("%6d0", playerScore[lastPlayer]/10); + repaint(rect(0, 1, s), FALSE); + + if (score > HighScore) { + HighScore = score; + s.sprintf("%8d0", HighScore/10); + repaint(rect(8, 1, s), FALSE); + } +} + +/* + * Set the score for player after the game if over. If the score is in the + * high scores then the hall of fame is updated (shifted) and the scoreboard + * is shown. + */ + +void Score::setScore(int level, int player) +{ + // pointer to the array-position of a new archived top score + lastScore = -1; + + // was it a real game or just a demo (level == 0) + if (player >= 0 && player < maxPlayer && level != 0) { + + lastPlayer = player; + + for (int i = 0; i < 10; i++) + if ( playerScore[lastPlayer] > hallOfFame[i].points) { + lastScore = i; + break; + } + } + + // no new highscore archived, finish after specified time + if (lastScore < 0) { + // enable gameNew directly for an immediate next try + emit gameFinished(); + lastPlayer = -1; + QTimer::singleShot(hallOfFameMS, this, SLOT(end())); + return; + } + + // shift old (lower) scores to make place for the new one + for (int i = 9; i > lastScore && i > 0; i--) + hallOfFame[i] = hallOfFame[i-1]; + + hallOfFame[lastScore].points = playerScore[lastPlayer]; + hallOfFame[lastScore].levels = level; + hallOfFame[lastScore].moment = QDateTime::currentDateTime(); + hallOfFame[lastScore].name = playerName[lastPlayer]; + + cursor.x = 14; + cursor.y = 11+lastScore; + cursor.chr = hallOfFame[lastScore].name.at(cursor.x-14); + +// startTimer(cursorBlinkMS); + setFocus(); +} + +/* + * Read the highscores, if no file or a file shorter than 4 bytes (versions before 0.2.4 stores only + * the points of one highscore) exists - the highscores were initialized with default values. + */ +void Score::read() +{ + if (highscoreFile.exists() && highscoreFile.size() > 4) { + if (highscoreFile.open(IO_ReadOnly)) { + QDataStream s(&highscoreFile); + char *name; + for (int i = 0; i < 10; i++) { + s >> hallOfFame[i].points >> hallOfFame[i].levels >> hallOfFame[i].duration >> + hallOfFame[i].moment >> name; + hallOfFame[i].name = QString::fromLatin1(name); + delete(name); + } + highscoreFile.close(); + } + } else { + for (int i = 0; i < 10; i++) { + hallOfFame[i].points = 5000; + hallOfFame[i].levels = 0; + hallOfFame[i].duration = QTime(); + hallOfFame[i].moment = QDateTime(); + hallOfFame[i].name = "???"; + } + // write(); + } + + for (int i = 0; i < 10; i++) + for (uint j = 0; j < hallOfFame[i].name.length(); j++) + if (hallOfFame[i].name.at(j) < bitfont->firstChar() || + hallOfFame[i].name.at(j) > bitfont->lastChar()) + hallOfFame[i].name.at(j) = hallOfFame[i].name.at(j).upper(); + + HighScore = hallOfFame[0].points; +} + +void Score::write() +{ + if (!highscoreFile.exists() && highscoreFile.name() == systemHighscoreFileInfo.filePath()) + KMessageBox::information(0, + i18n("You're going to create the highscore-file\n" + "'%1'\n" + "for your maschine, that should be used systemwide.\n" + "\n" + "To grant access to the other users, set the appropriate rights (a+w)\n" + "on that file or ask your systemadministator for that favor.\n" + "\n" + "To use a different directory or filename for the highscores," + "specify them in the configfile (kpacmanrc:highscoreFilePath)." + ).arg(systemHighscoreFileInfo.filePath())); + + if (highscoreFile.name() == privateHighscoreFileInfo.filePath()) + KMessageBox::information(0, + i18n("You're using a private highscore-file, that's mostly because of\n" + "missing write-access to the systemwide file\n" + "'%1' .\n" + "\n" + "Ask your systemadministrator for granting you access to that file,\n" + "by setting the appropriate rights (a+w) on it.\n" + "\n" + "To use a different directory or filename for the highscores," + "specify them in the configfile (kpacmanrc:highscoreFilePath)." + ).arg(systemHighscoreFileInfo.filePath()), + QString::null, "PrivateHighscore"); + + if (highscoreFile.open(IO_WriteOnly)) { + QDataStream s(&highscoreFile); + for (int i = 0; i < 10; i++) + s << hallOfFame[i].points << hallOfFame[i].levels << hallOfFame[i].duration << + hallOfFame[i].moment << hallOfFame[i].name.latin1(); + highscoreFile.close(); + } +} + +void Score::setPause(bool Paused) +{ + paused = Paused; + + QRect r = bitfont->rect(i18n("PAUSED")); + r.moveCenter(QPoint(this->width()/2, this->height()/2)); + repaint(r, TRUE); + + // repaint 1UP or 2UP + repaint(FALSE); +} + +void Score::end() +{ + if (paused) { + QTimer::singleShot(afterPauseMS, this, SLOT(end())); + return; + } + + // repaint 1UP or 2UP + repaint(FALSE); + + // if lastPlayer != -1 we're already in playing mode + if (lastPlayer == -1) + emit gameHighscores(); +} + +/* + * Return the date in a formatted QString. The format can be changed using internationalization + * of the string "YY/MM/DD". Invalid QDate's where returned as "00/00/00". + */ +QString Score::formatDate(QDate date) +{ + QString s = i18n("@YY@/@MM@/@DD@"); + + QString dd; + dd.sprintf("%02d", date.isValid() ? date.year() % 100 : 0); + s.replace(QRegExp("@YY@"), dd); + dd.sprintf("%02d", date.isValid() ? date.month() : 0); + s.replace(QRegExp("@MM@"), dd); + dd.sprintf("%02d", date.isValid() ? date.day() : 0); + s.replace(QRegExp("@DD@"), dd); + + return s; +} + +QRect Score::rect(int col, float row, QString str, int align) +{ + QRect r = bitfont->rect(str); + r.moveBy(x(col), y(row)); + + int dx = 0; + int dy = 0; + + if (align & AlignLeft || align & AlignRight) { + dx = (str.length()-1) * (bitfont->width()/2); + if (align & AlignRight) + dx *= -1; + } + + if (align & AlignTop || align & AlignBottom) { + dy = bitfont->height()/2; + if (align & AlignBottom) + dy *= -1; + } + + if (dx != 0 || dy != 0) + r.moveBy(dx, dy); + + return r; +} + +int Score::x(int col) +{ + return col*bitfont->width(); +} + +int Score::y(float row) +{ + return (int) (row*(bitfont->height()+bitfont->height()/4)); +} + +/** + * Ermittelt die zu benutzende "highscore"-Datei, in die auch geschrieben werden kann. + * Über den "highscoreFilePath"-KConfig-Eintrag, kann abweichend von der Standardlokation + * der Standort der "highscore"-Datei spezifiziert werden. + * Wenn die systemweite "highscore"-Datei nicht beschrieben werden kann, wird mit einer + * privaten Datei gearbeitet. + */ +QFileInfo Score::locateHighscoreFilePath() +{ + QFileInfo systemHighscoreDirPath; + QStringList systemHighscoreDirs; + + // Schreibfähige "private" highscore-Datei ermitteln für den fallback. + privateHighscoreFileInfo.setFile(KGlobal::dirs()->saveLocation("appdata")+highscoreName); + + // FilePath aus der Konfigurationsdatei benutzen + systemHighscoreFileInfo.setFile(kapp->config()->readEntry("HighscoreFilePath")); + + // Kein Wert aus der Konfiguration erhalten, dann die "system"-Datei suchen. + if (systemHighscoreFileInfo.filePath().isEmpty()) + systemHighscoreDirs = KGlobal::dirs()->resourceDirs("appdata"); + else + systemHighscoreDirs = QStringList(systemHighscoreFileInfo.filePath()); + + for (QStringList::Iterator i = systemHighscoreDirs.begin(); i != systemHighscoreDirs.end(); ++i) { + + systemHighscoreFileInfo.setFile(*i); + if (systemHighscoreFileInfo.fileName().isEmpty()) + systemHighscoreFileInfo.setFile(systemHighscoreFileInfo.dirPath()+"/"+highscoreName); + + // privateHighscoreFileInfo für die "system" Suche ignorieren + if (systemHighscoreFileInfo.filePath() != privateHighscoreFileInfo.filePath()) + if (!systemHighscoreFileInfo.exists()) { + systemHighscoreDirPath.setFile(systemHighscoreFileInfo.dirPath()); + if (systemHighscoreDirPath.exists() && systemHighscoreDirPath.isWritable()) + return systemHighscoreFileInfo; + } else + if (systemHighscoreFileInfo.isWritable()) + return systemHighscoreFileInfo; + } + + return privateHighscoreFileInfo; +} diff --git a/kpacman/score.h b/kpacman/score.h new file mode 100644 index 0000000..8f6a644 --- /dev/null +++ b/kpacman/score.h @@ -0,0 +1,124 @@ +#ifndef SCORE_H +#define SCORE_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kapp.h> +#include <qwidget.h> +#include <qstring.h> +#include <qpoint.h> +#include <qrect.h> +#include <qfile.h> + +#include <qfileinfo.h> +#include <qdatetime.h> + +#include "painter.h" +#include "bitfont.h" + +#define maxPlayer 1 +#define minPlayerNameLength 3 +#define highscoreName "highscore" + +class Score : public QWidget +{ + Q_OBJECT +public: + Score (QWidget *parent=0, const char *name=0, int scheme=-1, int mode=-1, Bitfont *font=0); + ~Score(); + +public slots: + void setScheme(int scheme, int mode, Bitfont *font=0); + + void set(int score); + void set(int score, int player); + void setScore(int level, int player); + void setPause(bool paused); + + void initKeys(); + +private slots: + void read(); + void write(); + void end(); + +signals: + void gameFinished(); + void gameHighscores(); + +protected: + void timerEvent(QTimerEvent *); + void paintEvent(QPaintEvent *); + void keyPressEvent(QKeyEvent *); + + void focusInEvent(QFocusEvent *) { ; } + void focusOutEvent(QFocusEvent *) { ; } + + void confScheme(); + void confTiming(bool defGroup=TRUE); + +private: + Bitfont *bitfont; + + QRect rect(int col, float row, QString str, int align = AlignCenter); + int x(int col); + int y(float row); + + QString formatDate(QDate date); + + /** + * Ermittelt die zu benutzende "highscore"-Datei, in die auch geschrieben werden kann. + * Über den "highscoreFilePath"-KConfig-Eintrag, kann abweichend von der Standardlokation + * der Standort der "highscore"-Datei spezifiziert werden. + * Wenn die systemweite "globale" Datei nicht beschrieben werden kann, wird mit einer + * privaten Datei gearbeitet. + */ + QFileInfo locateHighscoreFilePath(); + + int cursorBlinkMS; + int hallOfFameMS; + int afterPauseMS; + + bool paused; + + uint UpKey; + uint DownKey; + uint RightKey; + uint LeftKey; + + int lastScore; + int lastPlayer; + int HighScore; + int playerScore[maxPlayer]; + QString playerName[maxPlayer]; + + struct { + int x; + int y; + QChar chr; + bool on; + } cursor; + + int cursorBlinkTimer; + bool scrollRepeat; + + struct { + int points; + int levels; + QTime duration; + QDateTime moment; + QString name; + } hallOfFame[10]; + + QFileInfo systemHighscoreFileInfo; + QFileInfo privateHighscoreFileInfo; + + QFile highscoreFile; + + int scheme; + int mode; +}; + +#endif // SCORE_H diff --git a/kpacman/status.cpp b/kpacman/status.cpp new file mode 100644 index 0000000..e93111b --- /dev/null +++ b/kpacman/status.cpp @@ -0,0 +1,353 @@ +#include <kapp.h> +#include <klocale.h> +#include <kstddirs.h> + +#include <status.h> + +#include <qpixmap.h> +#include <qbitmap.h> +#include <qstring.h> +#include <qmsgbox.h> +#include <qfileinfo.h> + +Status::Status( QWidget *parent, const char *name, int Scheme, int Mode ) : + QWidget( parent, name ) +{ + actualLifes = 0; + actualLevel = 0; + + lifesPix = NULL; + levelPix = NULL; + + scheme = Scheme; + mode = Mode; + level = 0; + + confScheme(); +} + +QList<QPixmap> *Status::loadPixmap(QWidget *parent, QString pixmapName, + QList<QPixmap> *pixmaps) +{ + if (pixmaps == NULL) { + pixmaps = new QList<QPixmap>; + pixmaps->setAutoDelete(TRUE); + } + + if (!pixmaps->isEmpty()) + pixmaps->clear(); + + QPixmap PIXMAP(pixmapName); + if (PIXMAP.isNull() || PIXMAP.mask() == NULL) { + QString msg = i18n("The pixmap could not be contructed.\n\n" + "The file '@PIXMAPNAME@' does not exist,\n" + "or is of an unknown format."); + msg.replace(QRegExp("@PIXMAPNAME@"), pixmapName); + QMessageBox::information(parent, i18n("Initialization Error"), + (const char *) msg); + return 0; + } + + int height = PIXMAP.height(); + int width = (height == 0) ? 0 : PIXMAP.width()/(PIXMAP.width()/height); + + QBitmap BITMAP; + QBitmap MASK; + + BITMAP = *PIXMAP.mask(); + MASK.resize(width, height); + + for (int x = 0; x < PIXMAP.width()/width; x++) { + QPixmap *pixmap = new QPixmap(width, height); + pixmaps->append(pixmap); + bitBlt(pixmap, 0, 0, &PIXMAP, x*width, 0, width, height, CopyROP, TRUE); + bitBlt(&MASK, 0, 0, &BITMAP, x*width, 0, width, height, CopyROP, TRUE); + pixmap->setMask(MASK); + } + + return pixmaps; +} + +void Status::paintEvent( QPaintEvent *) +{ + for (int x = 0; x < actualLifes && !lifesPix->isEmpty(); x++) + bitBlt(this, lifesPix->at(0)->width()+(lifesPix->at(0)->width()*x), + (height()-lifesPix->at(0)->height())/2, + lifesPix->at(0), 0, 0, + lifesPix->at(0)->width(), lifesPix->at(0)->height()); + + for (int x = 0; x < actualLevel && !levelPix->isEmpty(); x++) { + erase((width()-levelPix->at(x)->width()*2)-(levelPix->at(x)->width()*levelPos[x]), + (height()-levelPix->at(x)->height())/2, + levelPix->at(x)->width(), levelPix->at(x)->height()); + bitBlt(this, (width()-levelPix->at(x)->width()*2)-(levelPix->at(x)->width()*levelPos[x]), + (height()-levelPix->at(x)->height())/2, + levelPix->at(x), 0, 0, + levelPix->at(x)->width(), levelPix->at(x)->height()); + } +} + +void Status::initPixmaps() +{ + if (lastLifesPixmapName != lifesPixmapName.at(level)) { + lifesPix = loadPixmap(this, lifesPixmapName.at(level), lifesPix); + lastLifesPixmapName = lifesPixmapName.at(level); + } + if (lastLevelPixmapName != levelPixmapName.at(level)) { + levelPix = loadPixmap(this, levelPixmapName.at(level), levelPix); + lastLevelPixmapName = levelPixmapName.at(level); + } +} + +QString Status::decodeHexOctString(QString s) +{ + QString value; + QString valids; + int pos, xpos = 0, opos = 0; + int v, len, leadin; + const char *ptr; + uchar c; + + while (((xpos = s.find(QRegExp("\\\\x[0-9a-fA-F]+"), xpos)) != -1) || + ((opos = s.find(QRegExp("\\\\[0-7]+"), opos)) != -1)) { + if (xpos != -1) { + valids = "0123456789abcdef"; + leadin = 2; + pos = xpos; + } else { + valids = "01234567"; + leadin = 1; + pos = opos; + } + + c = '\0'; + len = 0; + value = s.mid(pos+leadin, 3); + ptr = (const char *) value; + + while (*ptr != '\0' && (v = valids.find(*ptr++, 0, FALSE)) != -1) { + c = (c * valids.length()) + v; + len++; + } + + value.fill(c, 1); + s.replace(pos, len+leadin, value); + } + + return s; +} + +void Status::fillArray(QArray<int> &array, QString values, int max) +{ + array.resize(max); + int last = 0; + bool ok; + QString value; + + for (uint i = 0; i < array.size(); i++) { + if (values.find(',') < 0 && values.length() > 0) { + value = values; + values = ""; + } + if (values.find(',') >= 0) { + value = values.left(values.find(',')); + values.remove(0,values.find(',')+1); + } + array[i] = value.toInt(&ok); + if (ok) + last = array[i]; + else + array[i] = last; + } +} + +void Status::fillStrList(QStrList &list, QString values, int max) +{ + if (!list.isEmpty()) + list.clear(); + + QString last = ""; + QString value; + + for (uint i = 0; i < (uint) max; i++) { + if (values.find(',') < 0 && values.length() > 0) { + value = values; + values = ""; + } + if (values.find(',') >= 0) { + value = values.left(values.find(',')); + values.remove(0,values.find(',')+1); + } + if (!value.isEmpty()) + last = decodeHexOctString(value); + list.append(last); + } +} + +void Status::fillPixmapName(QStrList &pixmapName) +{ + QStrList list = pixmapName; + + if (!pixmapName.isEmpty()) + pixmapName.clear(); + + QString pixmap; + + QFileInfo fileInfo; + + for (uint i = 0; i < list.count(); i++) { + pixmap = list.at(i); + + if (pixmap.left(1) != "/" && pixmap.left(1) != "~") + pixmap = KGlobal::dirs()->findResource("appdata", pixmapDirectory+pixmap); + + fileInfo.setFile(pixmap); + if (!fileInfo.isReadable() || !fileInfo.isFile()) + pixmap = ""; + + pixmapName.append(pixmap); + } +} + +void Status::confLevels(bool defGroup) +{ + if (defGroup || kapp->config()->hasKey("Levels")) + maxLevel = kapp->config()->readNumEntry("Levels", 13); +} + +void Status::confMisc(bool defGroup) +{ + if (defGroup || kapp->config()->hasKey("LevelPosition")) + fillArray(levelPos, kapp->config()->readEntry("LevelPosition", "0,1,2,3,,4,,5,,6,,7"), maxLevel); + + if (defGroup || kapp->config()->hasKey("PixmapDirectory")) { + pixmapDirectory = kapp->config()->readEntry("PixmapDirectory"); + + if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~") + pixmapDirectory.insert(0, "pics/"); + if (pixmapDirectory.right(1) != "/") + pixmapDirectory.append("/"); + } + + if (defGroup || kapp->config()->hasKey("LifesPixmapName")) + fillStrList(lifesPixmapName, + kapp->config()->readEntry("LifesPixmapName", "lifes.xpm"), maxLevel+1); + if (defGroup || kapp->config()->hasKey("LevelPixmapName")) + fillStrList(levelPixmapName, + kapp->config()->readEntry("LevelPixmapName", "level.xpm"), maxLevel+1); + +} + +void Status::confScheme() +{ + QString oldgroup = kapp->config()->group(); + QString newgroup; + + // if not set, read mode and scheme from the configfile + if (mode == -1 && scheme == -1) { + scheme = kapp->config()->readNumEntry("Scheme", -1); + mode = kapp->config()->readNumEntry("Mode", -1); + + // if mode is not set in the defGroup-group, lookup the scheme group + if (scheme != -1 || mode == -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + mode = kapp->config()->readNumEntry("Mode", -1); + kapp->config()->setGroup(oldgroup); + } + } + + confLevels(); + + if (mode != -1) { + newgroup.sprintf("Mode %d", mode); + kapp->config()->setGroup(newgroup); + + confLevels(FALSE); + } + + if (scheme != -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + confLevels(FALSE); + } + + kapp->config()->setGroup(oldgroup); + + confMisc(); + + if (mode != -1) { + newgroup.sprintf("Mode %d", mode); + kapp->config()->setGroup(newgroup); + + confMisc(FALSE); + } + + if (scheme != -1) { + newgroup.sprintf("Scheme %d", scheme); + kapp->config()->setGroup(newgroup); + + confMisc(FALSE); + } + + fillPixmapName(lifesPixmapName); + fillPixmapName(levelPixmapName); + + initPixmaps(); + + setFixedHeight(minHeight()); + + kapp->config()->setGroup(oldgroup); +} + +void Status::setScheme(int Scheme, int Mode) +{ + mode = Mode; + scheme = Scheme; + + confScheme(); + + repaint(); +} + +int Status::minHeight() +{ + if (lifesPix->isEmpty() && levelPix->isEmpty()) + return 0; + if (levelPix->isEmpty()) + return lifesPix->at(0)->height(); + if (lifesPix->isEmpty()) + return levelPix->at(0)->height(); + return (lifesPix->at(0)->height() > levelPix->at(0)->height()) ? + lifesPix->at(0)->height() : levelPix->at(0)->height(); +} + +int Status::minWidth() +{ + if (lifesPix->isEmpty() && levelPix->isEmpty()) + return 0; + if (levelPix->isEmpty()) + return lifesPix->at(0)->width(); + if (lifesPix->isEmpty()) + return levelPix->at(0)->width(); + return (lifesPix->at(0)->width() > levelPix->at(0)->width()) ? + lifesPix->at(0)->width() : levelPix->at(0)->width(); +} + +void Status::setLifes(int lifes) +{ + actualLifes = lifes; + repaint(); +} + +void Status::setLevel(int Level) +{ + level = Level; + + initPixmaps(); + + actualLevel = (level > (int) levelPix->count()) ? (int) levelPix->count() : level; + repaint(); +} diff --git a/kpacman/status.h b/kpacman/status.h new file mode 100644 index 0000000..c749f69 --- /dev/null +++ b/kpacman/status.h @@ -0,0 +1,74 @@ +#ifndef STATUS_H +#define STATUS_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kapp.h> +#include <kconfig.h> + +#include <qwidget.h> +#include <qpixmap.h> +#include <qstring.h> +#include <qarray.h> +#include <qlist.h> +#include <qstrlist.h> +#include <qregexp.h> + +class Status : public QWidget +{ + Q_OBJECT +public: + Status(QWidget *parent=0, const char *name=0, int scheme=-1, int mode=-1); + ~Status() {}; + +public slots: + void setScheme(int scheme, int mode); + void setLevel(int level); + void setLifes(int lifes); + +protected: + void paintEvent(QPaintEvent *); + int minHeight(); + int minWidth(); + + QString decodeHexOctString(QString str); + + void fillArray(QArray<int> &, QString, int); + void fillStrList(QStrList &, QString, int); + void fillPixmapName(QStrList &); + + void confScheme(); + void confLevels(bool defGroup=TRUE); + void confMisc(bool defGroup=TRUE); + + void initPixmaps(); + +private: + QArray<int> levelPos; + int actualLifes; + int actualLevel; + + QString pixmapDirectory; + + QStrList lifesPixmapName; + QStrList levelPixmapName; + + QString lastLifesPixmapName; + QString lastLevelPixmapName; + + QList<QPixmap> *loadPixmap(QWidget *parent, QString pixmapName, + QList<QPixmap> *pixmaps=0); + + QList<QPixmap> *lifesPix; + QList<QPixmap> *levelPix; + + int maxLevel; + int level; + + int scheme; + int mode; +}; + +#endif // STATUS_H diff --git a/kpacman/templates/cpp_template b/kpacman/templates/cpp_template new file mode 100644 index 0000000..6afef5d --- /dev/null +++ b/kpacman/templates/cpp_template @@ -0,0 +1,16 @@ +/*************************************************************************** + |FILENAME| - description + ------------------- + begin : |DATE| + copyright : (C) |YEAR| by |AUTHOR| + email : |EMAIL| + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ diff --git a/kpacman/templates/header_template b/kpacman/templates/header_template new file mode 100644 index 0000000..6afef5d --- /dev/null +++ b/kpacman/templates/header_template @@ -0,0 +1,16 @@ +/*************************************************************************** + |FILENAME| - description + ------------------- + begin : |DATE| + copyright : (C) |YEAR| by |AUTHOR| + email : |EMAIL| + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ |