summaryrefslogtreecommitdiffstats
path: root/ksnake
diff options
context:
space:
mode:
Diffstat (limited to 'ksnake')
-rw-r--r--ksnake/ChangeLog21
-rw-r--r--ksnake/Makefile.am34
-rw-r--r--ksnake/appearance.ui87
-rw-r--r--ksnake/ball.cpp128
-rw-r--r--ksnake/ball.h62
-rw-r--r--ksnake/basket.cpp118
-rw-r--r--ksnake/basket.h70
-rw-r--r--ksnake/bitmaps.h106
-rw-r--r--ksnake/board.cpp330
-rw-r--r--ksnake/board.h100
-rw-r--r--ksnake/data/Makefile.am9
-rw-r--r--ksnake/data/backgrounds/Bark.pngbin0 -> 29349 bytes
-rw-r--r--ksnake/data/backgrounds/Blue_Carpet.pngbin0 -> 67082 bytes
-rw-r--r--ksnake/data/backgrounds/Dark_Wood.pngbin0 -> 8630 bytes
-rw-r--r--ksnake/data/backgrounds/Granite.pngbin0 -> 5679 bytes
-rw-r--r--ksnake/data/backgrounds/Green_Carpet.pngbin0 -> 30829 bytes
-rw-r--r--ksnake/data/backgrounds/Makefile.am8
-rw-r--r--ksnake/data/backgrounds/Mystique.pngbin0 -> 6242 bytes
-rw-r--r--ksnake/data/backgrounds/Rope_Weave.pngbin0 -> 9455 bytes
-rw-r--r--ksnake/data/backgrounds/Volcanic.pngbin0 -> 8248 bytes
-rw-r--r--ksnake/data/backgrounds/Wood.pngbin0 -> 27667 bytes
-rw-r--r--ksnake/data/highScoresbin0 -> 130 bytes
-rw-r--r--ksnake/data/levels/Makefile.am9
-rw-r--r--ksnake/data/levels/room0118
-rw-r--r--ksnake/data/levels/room0218
-rw-r--r--ksnake/data/levels/room0318
-rw-r--r--ksnake/data/levels/room0418
-rw-r--r--ksnake/data/levels/room0518
-rw-r--r--ksnake/data/levels/room0618
-rw-r--r--ksnake/data/levels/room0718
-rw-r--r--ksnake/data/levels/room0818
-rw-r--r--ksnake/data/levels/room0918
-rw-r--r--ksnake/data/levels/room1018
-rw-r--r--ksnake/data/levels/room1118
-rw-r--r--ksnake/data/levels/room1218
-rw-r--r--ksnake/data/levels/room1318
-rw-r--r--ksnake/data/levels/room1418
-rw-r--r--ksnake/data/levels/room1518
-rw-r--r--ksnake/data/levels/room1618
-rw-r--r--ksnake/data/levels/room1718
-rw-r--r--ksnake/data/levels/room1818
-rw-r--r--ksnake/data/levels/room1918
-rw-r--r--ksnake/data/levels/room2018
-rw-r--r--ksnake/data/levels/room2118
-rw-r--r--ksnake/data/levels/room2218
-rw-r--r--ksnake/data/levels/room2318
-rw-r--r--ksnake/data/levels/room2418
-rw-r--r--ksnake/data/levels/room2518
-rw-r--r--ksnake/data/pixmaps/Makefile.am5
-rw-r--r--ksnake/data/pixmaps/apples.pngbin0 -> 284 bytes
-rw-r--r--ksnake/data/pixmaps/ball.pngbin0 -> 295 bytes
-rw-r--r--ksnake/data/pixmaps/brick.pngbin0 -> 25582 bytes
-rw-r--r--ksnake/data/pixmaps/snake1.pngbin0 -> 483 bytes
-rw-r--r--ksnake/data/pixmaps/snake2.pngbin0 -> 468 bytes
-rw-r--r--ksnake/game.cpp180
-rw-r--r--ksnake/game.h64
-rw-r--r--ksnake/general.ui202
-rw-r--r--ksnake/hi128-app-ksnake.pngbin0 -> 17498 bytes
-rw-r--r--ksnake/hi16-app-ksnake.pngbin0 -> 695 bytes
-rw-r--r--ksnake/hi22-app-ksnake.pngbin0 -> 3755 bytes
-rw-r--r--ksnake/hi32-app-ksnake.pngbin0 -> 1862 bytes
-rw-r--r--ksnake/hi48-app-ksnake.pngbin0 -> 3453 bytes
-rw-r--r--ksnake/hi64-app-ksnake.pngbin0 -> 5522 bytes
-rw-r--r--ksnake/ksnake.desktop82
-rw-r--r--ksnake/ksnake.kcfg50
-rw-r--r--ksnake/ksnakeui.rc5
-rw-r--r--ksnake/level.cpp152
-rw-r--r--ksnake/level.h55
-rw-r--r--ksnake/levels.cpp58
-rw-r--r--ksnake/levels.h45
-rw-r--r--ksnake/main.cpp54
-rw-r--r--ksnake/pixServer.cpp245
-rw-r--r--ksnake/pixServer.h76
-rw-r--r--ksnake/progress.cpp54
-rw-r--r--ksnake/progress.h47
-rw-r--r--ksnake/rattler.cpp692
-rw-r--r--ksnake/rattler.h155
-rw-r--r--ksnake/settings.kcfgc5
-rw-r--r--ksnake/snake.cpp557
-rw-r--r--ksnake/snake.h140
-rw-r--r--ksnake/startroom.cpp81
-rw-r--r--ksnake/startroom.h50
-rw-r--r--ksnake/version.h1
-rw-r--r--ksnake/view.cpp59
-rw-r--r--ksnake/view.h48
85 files changed, 4694 insertions, 0 deletions
diff --git a/ksnake/ChangeLog b/ksnake/ChangeLog
new file mode 100644
index 00000000..58991c06
--- /dev/null
+++ b/ksnake/ChangeLog
@@ -0,0 +1,21 @@
+Version 0.4.0:
+ * [Benjamin Meyer] Changed to use KDE highscore widget.
+ * [Benjamin Meyer] Changed to use KConfigXT and a configure dialog.
+ * [Benjamin Meyer] Removed unnecessary classes.
+ * [Benjamin Meyer] Lots of general code cleanup (headers/indentation/variable naming).
+ * [Benjamin Meyer] Added copyright headers to all of the source files.
+
+Version 0.3.1:
+ * [Andrew Chant] Cleaned up a lot of code
+ Fixed Start new game dialogue behavior
+ Fixed fonts on High Scores list.
+ Made 'Beginner' mode actually somewhat Easy!!
+Version 0.3.0:
+ * [Andrew Chant] Added Window Resizing capability, so now works on
+ almost all resoloutions!
+Version 0.2.1:
+ * [Robert Williams] Added -caption "%c" to ksnake.kdelnk
+ * [Robert Williams] Added getCaption()
+ * [Robert Williams] Added version.h
+ * [Robert Williams] Added getHelpMenu()
+
diff --git a/ksnake/Makefile.am b/ksnake/Makefile.am
new file mode 100644
index 00000000..b46794a6
--- /dev/null
+++ b/ksnake/Makefile.am
@@ -0,0 +1,34 @@
+
+INCLUDES = -I$(top_srcdir)/libkdegames -I$(top_srcdir)/libkdegames/highscore/ $(all_includes)
+
+noinst_HEADERS = game.h rattler.h board.h bitmaps.h \
+ level.h ball.h snake.h basket.h startroom.h \
+ pixServer.h progress.h levels.h view.h version.h
+
+ksnake_SOURCES = game.cpp rattler.cpp board.cpp level.cpp ball.cpp \
+ snake.cpp basket.cpp startroom.cpp \
+ pixServer.cpp progress.cpp levels.cpp\
+ view.cpp main.cpp settings.kcfgc appearance.ui general.ui
+
+ksnake_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+ksnake_LDADD = $(LIB_KDEUI) $(LIB_KDEGAMES) -lm
+ksnake_DEPENDENCIES = $(LIB_KDEGAMES_DEP)
+
+METASOURCES = AUTO
+
+bin_PROGRAMS = ksnake
+
+######### build rules ################
+
+xdg_apps_DATA = ksnake.desktop
+kde_kcfg_DATA = ksnake.kcfg
+
+KDE_ICON = ksnake
+
+SUBDIRS = data
+
+rcdir = $(kde_datadir)/ksnake
+rc_DATA = ksnakeui.rc
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/ksnake.pot
diff --git a/ksnake/appearance.ui b/ksnake/appearance.ui
new file mode 100644
index 00000000..0f328f04
--- /dev/null
+++ b/ksnake/appearance.ui
@@ -0,0 +1,87 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>Appearance</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Appearance</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>334</width>
+ <height>285</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Background</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QComboBox" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_bgimage</cstring>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_bgcolor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>kcfg_bgcolor_enabled</cstring>
+ </property>
+ <property name="text">
+ <string>Color:</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>kcfg_bgimage_enabled</cstring>
+ </property>
+ <property name="text">
+ <string>Image:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcolorbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/ksnake/ball.cpp b/ksnake/ball.cpp
new file mode 100644
index 00000000..2881beb9
--- /dev/null
+++ b/ksnake/ball.cpp
@@ -0,0 +1,128 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "ball.h"
+#include "board.h"
+
+int bounce[8][8]={
+ { NE, NW, SE, SW, N, E, S, W },
+ { SE, SW, NE, NW, S, E, N, W },
+ { NW, NE, SW, SE, N, W, S, E },
+ { SW, SE, NW, NE, S, W, N, E },
+ { NE, NW, SE, SW, N, E, S, W },
+ { SE, SW, NE, NW, S, E, N, W },
+ { NW, NE, SW, SE, N, W, S, E },
+ { SW, SE, NW, NE, S, W, N, E }
+};
+
+Ball::Ball(Board *b, PixServer *p)
+{
+ board = b;
+ pixServer = p;
+
+ int i = BoardWidth+1;
+ while( !board->isEmpty(i) ) i++;
+ hold = index = i;
+ board->set(index, Balle);
+ next = SE;
+}
+
+void Ball::zero()
+{
+ board->set(index, empty);
+ pixServer->erase(index);
+}
+
+void Ball::nextMove()
+{
+ hold = index;
+ board->set(hold, empty);
+
+ for ( int x = 0; x < 8 ; x++) {
+ int d = bounce[next][x];
+ int nextSq = board->getNext(d, index);
+
+ if (board->isHead(nextSq) || board->isEmpty(nextSq)) {
+ next = d;
+ index = nextSq;
+ board->set(index, Balle);
+ break;
+ }
+ }
+}
+
+void Ball::repaint()
+{
+ static int i = 0;
+ static bool rotate = true;
+
+ pixServer->erase(hold);
+ pixServer->draw(index, BallPix, i);
+
+ if (rotate)
+ if (++i > 3) i=0;
+
+ rotate = !rotate;
+}
+
+void KillerBall::nextMove()
+{
+ hold = index;
+ board->set(hold, empty);
+
+ // Find the snake.
+ int sn = board->samyHeadIndex();
+ if(board->isHead(sn)) {
+ int nextSq = getNextSquare();
+ if(nextSq != -1) {
+ next = board->direction(index, nextSq);
+ index = nextSq;
+ board->set(index, Balle);
+ return;
+ }
+ }
+
+ for ( int x = 0; x < 8 ; x++) {
+ int d = bounce[next][x];
+ int nextSq = board->getNext(d, index);
+
+ if (board->isHead(nextSq) || board->isEmpty(nextSq)) {
+ next = d;
+ index = nextSq;
+ board->set(index, Balle);
+ break;
+ }
+ }
+}
+
+int KillerBall::getNextSquare()
+{
+ return board->getNextCloseTo(index, board->samyHeadIndex(), true);
+}
+
+int DumbKillerBall::getNextSquare()
+{
+ return board->getNextCloseToDumb(index, board->samyHeadIndex());
+}
diff --git a/ksnake/ball.h b/ksnake/ball.h
new file mode 100644
index 00000000..e7796354
--- /dev/null
+++ b/ksnake/ball.h
@@ -0,0 +1,62 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef BALL_H
+#define BALL_H
+
+#include "pixServer.h"
+
+class Ball {
+public:
+ Ball(Board *b, PixServer *p);
+ virtual ~Ball(){}
+ virtual void nextMove();
+ void repaint();
+ void zero();
+protected:
+ Board *board;
+ PixServer *pixServer;
+ int index;
+ int hold;
+ int next;
+};
+
+class KillerBall : public Ball {
+public:
+ KillerBall(Board *b, PixServer *p) : Ball(b, p) {}
+ virtual ~KillerBall(){}
+ void nextMove();
+protected:
+ virtual int getNextSquare();
+};
+
+class DumbKillerBall : public KillerBall {
+public:
+ DumbKillerBall(Board *b, PixServer *p) : KillerBall(b, p) {}
+protected:
+ int getNextSquare();
+};
+
+#endif // BALL_H
diff --git a/ksnake/basket.cpp b/ksnake/basket.cpp
new file mode 100644
index 00000000..c03b1deb
--- /dev/null
+++ b/ksnake/basket.cpp
@@ -0,0 +1,118 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qtimer.h>
+#include <qptrlist.h>
+
+#include "board.h"
+#include "basket.h"
+#include "pixServer.h"
+
+Kaffee::Kaffee(int pos, int r1, int r2)
+{
+ p = pos;
+ t = Red;
+ r = r2;
+ QTimer::singleShot( r1, this, SLOT(golden()) );
+ dirty = true;
+}
+
+void Kaffee::golden()
+{
+ dirty = true;
+ t = (t == Red ? Golden : Red);
+ QTimer::singleShot( r, this, SLOT(golden()) );
+}
+
+Basket::Basket(Board *b, PixServer *p)
+{
+ board = b;
+ pixServer = p;
+ list = new QPtrList<Kaffee>;
+ list->setAutoDelete( true );
+}
+
+Basket::~Basket()
+{
+ delete list;
+}
+
+void Basket::clear()
+{
+ if( !list->isEmpty())
+ list->clear();
+}
+
+void Basket::newApples()
+{
+ int x;
+ int i = 0;
+
+ while(i < 10) {
+ x = random.getLong(board->size());
+ if ((unsigned)x < board->size() && board->isEmpty(x) && x > BoardWidth+4) {
+ Kaffee *g = new Kaffee(x, random.getLong(40000), random.getLong(40000));
+ board->set(x, Apple);
+ list->append(g);
+ i++;
+ }
+ }
+}
+
+void Basket::repaint(bool dirty )
+{
+ Kaffee *g;
+ for ( g = list->first(); g != 0; g = list->next()) {
+ if (dirty) {
+ pixServer->draw(g->position(), ApplePix, (int)g->type());
+ g->dirty = false;
+ }
+ else if (g->dirty) {
+ pixServer->draw(g->position(), ApplePix, (int)g->type());
+ g->dirty = false;
+ }
+ }
+}
+
+Fruits Basket::eaten(int i)
+{
+ Kaffee *g;
+ Fruits f = Red;
+
+ for (g = list->first(); g != 0; g = list->next() )
+ {
+ if (g->position() == i) {
+ f = g->type();
+ list->remove(g);
+ break;
+ }
+ }
+ if (list->isEmpty())
+ emit openGate();
+
+ return f;
+}
+
+#include "basket.moc"
diff --git a/ksnake/basket.h b/ksnake/basket.h
new file mode 100644
index 00000000..eb965e4a
--- /dev/null
+++ b/ksnake/basket.h
@@ -0,0 +1,70 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef BASKET_H
+#define BASKET_H
+
+#include <krandomsequence.h>
+
+class PixServer;
+
+enum Fruits { Red, Golden };
+
+class Kaffee : public QObject
+{
+ Q_OBJECT
+public:
+ Kaffee(int pos, int r1, int r2);
+ int position() { return p;}
+ Fruits type() { return t;}
+ bool dirty;
+private slots:
+ void golden();
+private:
+ int p;
+ int r;
+ Fruits t;
+};
+
+class Basket : public QObject
+{
+ Q_OBJECT
+public:
+ Basket(Board *b, PixServer *p);
+ ~Basket();
+ void repaint(bool);
+ void newApples();
+ void clear();
+ Fruits eaten( int i);
+signals:
+ void openGate();
+private:
+ Board *board;
+ PixServer *pixServer;
+ QPtrList<Kaffee> *list;
+ KRandomSequence random;
+};
+
+#endif // BASKET_H
diff --git a/ksnake/bitmaps.h b/ksnake/bitmaps.h
new file mode 100644
index 00000000..95b17ed4
--- /dev/null
+++ b/ksnake/bitmaps.h
@@ -0,0 +1,106 @@
+#define zero_width 7
+#define zero_height 9
+static unsigned char zero_bits[] = {
+ 0x1e, 0x33, 0x3b, 0x3b, 0x33, 0x37, 0x37, 0x33, 0x1e};
+
+#define one_width 7
+#define one_height 9
+static unsigned char one_bits[] = {
+ 0x18, 0x1c, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18};
+
+#define two_width 7
+#define two_height 9
+static unsigned char two_bits[] = {
+ 0x1e, 0x3f, 0x33, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x3f};
+
+#define three_width 7
+#define three_height 9
+static unsigned char three_bits[] = {
+ 0x1e, 0x3f, 0x33, 0x30, 0x1c, 0x30, 0x33, 0x33, 0x1e};
+
+#define four_width 7
+#define four_height 9
+static unsigned char four_bits[] = {
+ 0x06, 0x06, 0x36, 0x36, 0x36, 0x33, 0x7f, 0x30, 0x30};
+
+#define five_width 7
+#define five_height 9
+static unsigned char five_bits[] = {
+ 0x3f, 0x03, 0x03, 0x03, 0x1f, 0x30, 0x30, 0x18, 0x0f};
+
+#define six_width 7
+#define six_height 9
+static unsigned char six_bits[] = {
+ 0x1c, 0x0c, 0x06, 0x1f, 0x33, 0x33, 0x33, 0x33, 0x1e};
+
+#define seven_width 7
+#define seven_height 9
+static unsigned char seven_bits[] = {
+ 0x7f, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x0c};
+
+#define eight_width 7
+#define eight_height 9
+static unsigned char eight_bits[] = {
+ 0x1e, 0x33, 0x33, 0x37, 0x1e, 0x3b, 0x33, 0x33, 0x1e};
+
+#define nine_width 7
+#define nine_height 9
+static unsigned char nine_bits[] = {
+ 0x1e, 0x33, 0x33, 0x33, 0x33, 0x3e, 0x18, 0x0c, 0x0e};
+
+#define intro_width 35
+#define intro_height 35
+static unsigned char intro_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x71, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x00, 0xc0, 0x00,
+ 0x04, 0x8d, 0x01, 0xc0, 0x00, 0x04, 0x8d, 0x01, 0xc0, 0xe4, 0x04, 0x8d,
+ 0x0d, 0xce, 0xf2, 0x05, 0x0d, 0x7c, 0xdb, 0x9a, 0x05, 0x19, 0x6c, 0xdb,
+ 0x99, 0x05, 0x31, 0x6c, 0xd8, 0x98, 0x05, 0x61, 0x6c, 0xde, 0xf9, 0x05,
+ 0xc1, 0x6c, 0xdb, 0x12, 0x04, 0x8d, 0x6d, 0xdf, 0xe6, 0x05, 0xf9, 0x00,
+ 0xd8, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf9,
+ 0x00, 0x00, 0x00, 0x04, 0x19, 0x03, 0x00, 0x00, 0x04, 0x19, 0x02, 0x00,
+ 0x00, 0x04, 0x19, 0x06, 0x00, 0x38, 0x04, 0x19, 0x06, 0x00, 0x7c, 0x04,
+ 0x19, 0xe3, 0x70, 0x66, 0x04, 0x99, 0xb1, 0xd9, 0x66, 0x04, 0xf9, 0xb0,
+ 0xd9, 0x66, 0x04, 0x99, 0x81, 0xd9, 0x7e, 0x04, 0x19, 0xe1, 0x19, 0x04,
+ 0x04, 0x19, 0xb2, 0x99, 0x78, 0x04, 0x19, 0xf0, 0x71, 0x00, 0x04, 0x01,
+ 0x80, 0x01, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
+
+#define level_width 35
+#define level_height 35
+static unsigned char level_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x0d, 0x00, 0x00, 0xf0,
+ 0x04, 0x0d, 0x00, 0x00, 0xc0, 0x04, 0x0d, 0x00, 0x00, 0xc0, 0x04, 0x0d,
+ 0x9e, 0x99, 0xc7, 0x04, 0x0d, 0xb3, 0xd9, 0xcc, 0x04, 0x0d, 0xb3, 0xd9,
+ 0xcc, 0x04, 0x0d, 0xbf, 0xd9, 0xcf, 0x04, 0x0d, 0x83, 0xd9, 0xc0, 0x04,
+ 0x0d, 0x03, 0xcf, 0xc0, 0x04, 0x7d, 0x1e, 0x86, 0xf7, 0x05, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
+
+#define gameover_width 35
+#define gameover_height 35
+static unsigned char gameover_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x79, 0x00, 0x00, 0x00, 0x04, 0xcd,
+ 0x00, 0x00, 0x00, 0x04, 0xcd, 0x78, 0xfc, 0x78, 0x04, 0x0d, 0xc0, 0xac,
+ 0xcd, 0x04, 0x0d, 0xc0, 0xac, 0xcd, 0x04, 0xed, 0xf8, 0xac, 0xfd, 0x04,
+ 0xcd, 0xcc, 0xac, 0x0d, 0x04, 0xcd, 0xcc, 0xac, 0x0d, 0x04, 0xf9, 0xf8,
+ 0x8c, 0x79, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1,
+ 0x00, 0x00, 0x00, 0x04, 0x99, 0x01, 0x00, 0x00, 0x04, 0x99, 0x99, 0xf1,
+ 0x98, 0x05, 0x99, 0x99, 0x99, 0xd9, 0x05, 0x99, 0x99, 0x99, 0x39, 0x04,
+ 0x99, 0x99, 0xf9, 0x19, 0x04, 0x99, 0x99, 0x19, 0x18, 0x04, 0x99, 0xf1,
+ 0x18, 0x18, 0x04, 0xf1, 0x60, 0xf0, 0x18, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/board.cpp b/ksnake/board.cpp
new file mode 100644
index 00000000..9179dfb1
--- /dev/null
+++ b/ksnake/board.cpp
@@ -0,0 +1,330 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qrect.h>
+#include "board.h"
+
+Pos::Pos(Pos *p, int i, int r) {
+ _parent = p;
+ _index = i;
+ _price = r;
+ left = right = next = fnext = 0;
+ inList = false;
+}
+Pos::~Pos() {
+ delete fnext;
+}
+int Pos::index() const {
+ return(_index);
+}
+void Pos::setPrice(int p) {
+ _price = p;
+}
+int Pos::price() const {
+ return(_price);
+}
+void Pos::setParent(Pos *p) {
+ _parent = p;
+}
+Pos *Pos::parent() const {
+ return(_parent);
+}
+Pos *Pos::listNext() {
+ inList = false;
+ return(next);
+}
+void Pos::addBTree(Pos *np) {
+ // Check direction np is going to.
+ Pos **p = 0;
+ if(np->index() < index())
+ p = &left;
+ else if(np->index() > index())
+ p = &right;
+ else {
+ qFatal("Repeated nodes on btree should never happens");
+ }
+
+ if(! *p) {
+ *p = np;
+ }
+ else {
+ (*p)->addBTree(np);
+ }
+}
+Pos *Pos::searchBTree(int i) {
+ if(i == index()) {
+ return(this);
+ }
+ else if(i < index() && left) {
+ return(left->searchBTree(i));
+ }
+ else if(right) {
+ return(right->searchBTree(i));
+ }
+ // Node not found.
+ return(0);
+}
+void Pos::addFList(Pos *np) {
+ np->fnext = fnext;
+ fnext = np;
+}
+void Pos::addList(Pos *np) {
+ if(np->inList)
+ return; // We're already in list.
+
+ np->inList = true;
+ Pos *p, *n;
+ for(p = this; p; p = n) {
+ // Check if the node next to p has a higher price.
+ n = p->next;
+ if(! n) {
+ // The new node go to tail.
+ np->next = 0;
+ p->next = np;
+ return;
+ }
+
+ if(np->price() <= n->price()) {
+ // Add new node after p.
+ np->next = p->next;
+ p->next = np;
+ return;
+ }
+ }
+ qFatal("Shouldn't reach this point");
+}
+
+Board::Board(int s)
+ :QMemArray<int> (s)
+{
+ sz = s;
+ samyIndex = -1;
+}
+
+void Board::index(int i)
+{
+ row = i/BoardWidth;
+ col = i-(row*BoardWidth);
+}
+
+bool Board::inBounds(int i)
+{
+ return ( i < 0 || i > sz-1 ? false : true);
+}
+
+void Board::set(int i, Square sq)
+{
+ if (inBounds(i))
+ at(i) = sq;
+ if(sq == head)
+ samyIndex = i;
+}
+
+QRect Board::rect(int i)
+{
+ index(i);
+ return (QRect(col*BRICKSIZE, row*BRICKSIZE, BRICKSIZE, BRICKSIZE));
+}
+
+bool Board::isEmpty(int i)
+{
+ if (inBounds(i))
+ return (at(i) == empty ? true : false);
+ return true;
+}
+
+bool Board::isBrick(int i)
+{
+ if (inBounds(i))
+ return (at(i) == brick ? true : false);
+ return false;
+}
+
+bool Board::isApple(int i)
+{
+ if (inBounds(i))
+ return (at(i) == Apple ? true : false);
+ return false;
+}
+
+bool Board::isHead(int i)
+{
+ if (inBounds(i))
+ return (at(i) == head ? true : false);
+ return false;
+}
+
+bool Board::isSnake(int i)
+{
+ if (inBounds(i))
+ return (at(i) == snake ? true : false);
+ return false;
+}
+
+int Board::getNext(int n, int i)
+{
+ index(i);
+
+ switch(n)
+ {
+ case NW:
+ return( i >= BoardWidth && col > 0 ? (i-BoardWidth)-1 : OUT);
+ case N:
+ return( i >= BoardWidth ? i-BoardWidth : OUT );
+ case NE:
+ return( i >= BoardWidth && col < BoardWidth-1 ? (i-BoardWidth)+1 : OUT);
+ case W:
+ return(col > 0 ? i-1 : OUT );
+ case E:
+ return(col < BoardWidth-1 ? i+1 : OUT );
+ case SW:
+ return( row < sz-BoardWidth && col > 0 ? (i+BoardWidth)-1 : OUT);
+ case S:
+ return( row < sz-BoardWidth ? i+BoardWidth : OUT );
+ case SE:
+ return( row < sz-BoardWidth && col < BoardWidth-1 ? (i+BoardWidth)+1 : OUT);
+ default:
+ return OUT;
+ }
+}
+
+int Board::getNextCloseToDumb(int s, int d)
+{
+ if(s == d)
+ return(-1); // What can I say, we're here! ;o)
+
+ int nextSq = getNext(direction(s, d), s);
+
+ if(! isEmpty(nextSq))
+ return(-1);
+
+ return(nextSq);
+}
+
+int Board::getNextCloseTo(int s, int d, bool diag, int lastIndex)
+{
+ if(s == d)
+ return(-1); // What can I say, we're here! ;o)
+
+ const int firstN = diag ? 4 : 0;
+ const int lastN = diag ? 8 : 4;
+
+ Pos *root = new Pos(0, s, 0), *list = root;
+
+ // List of indexes.
+ for(; list; list = list->listNext()) {
+ Pos *p;
+
+ // Check if current list node is the destination position.
+ if(list->index() == d) {
+ // Find first movement after root.
+ for(; ; list = p) {
+ p = list->parent();
+ if(p == root) {
+ // This is our move.
+ int nextSq = list->index();
+ delete root;
+ index(nextSq);
+ return(nextSq);
+ }
+ }
+ qFatal("Never here");
+ }
+
+ // Make possible moves.
+ for(int n = firstN; n < lastN; n ++) {
+ int i = getNext(n, list->index());
+ int pri = list->price() + 1;
+
+ // getNext returned valid place?
+ if(! inBounds(i) || (! isEmpty(i) && i != d)) {
+ // Or place is out of map or it's not empty,
+ // so go to the next possible move.
+ continue;
+ }
+
+ int pi = list->parent() ? list->parent()->index() : lastIndex;
+ if(pi != -1 && direction(pi, list->index()) !=
+ direction(list->index(), i)) {
+ pri += 10;
+ }
+
+ // Check if position wasn't processed yet.
+ if( (p = root->searchBTree(i))) {
+ // Position already processed.
+ // Check price of found position with current one.
+ if(p->price() > pri) {
+ // We found a cheapear way to reach the same
+ // place, so let's change the parent and price of p.
+ p->setPrice(list->price() + 1);
+ p->setParent(list);
+ list->addList(p);
+ }
+ continue;
+ }
+
+ // Create new Pos class instance.
+ p = new Pos(list, i, pri);
+
+ // Add.
+ list->addList(p);
+ root->addFList(p);
+ root->addBTree(p);
+ }
+ }
+
+ // Solution not found.
+ delete root;
+ return(-1);
+}
+
+int Board::direction(int s, int d)
+{
+ index(s);
+ int scol = col, srow = row;
+ index(d);
+ if(scol > col) { // Left.
+ if(srow < row)
+ return(SW);
+ else if(srow > row)
+ return(NW);
+ else
+ return(W);
+ }
+ else if(scol < col) { // Right.
+ if(srow < row)
+ return(SE);
+ else if(srow > row)
+ return(NE);
+ else
+ return(E);
+ }
+ else { // X's the same.
+ if(srow < row)
+ return(S);
+ else
+ return(N);
+ }
+}
diff --git a/ksnake/board.h b/ksnake/board.h
new file mode 100644
index 00000000..0fa43d7e
--- /dev/null
+++ b/ksnake/board.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef BOARD_H
+#define BOARD_H
+
+enum Square {empty, brick, Apple, Balle, snake, head};
+enum Directions {N=0,E=2,S=1,W=3,NE,SE,NW,SW};
+
+#define BoardWidth 35
+extern int BRICKSIZE;
+extern int MAPWIDTH;
+extern int MAPHEIGHT;
+#define OUT -1
+
+typedef int Gate;
+const int NORTH_GATE = BoardWidth/2;
+const int SOUTH_GATE =(BoardWidth*BoardWidth)-(NORTH_GATE+1);
+
+class Pos {
+public:
+ Pos(Pos *p, int i, int r);
+ ~Pos();
+ int index() const;
+ void setPrice(int p);
+ int price() const;
+ void setParent(Pos *p);
+ Pos *parent() const;
+ Pos *listNext();
+ void addBTree(Pos *np);
+ Pos *searchBTree(int i);
+ void addFList(Pos *);
+ void addList(Pos *np);
+private:
+ int _index;
+ int _price; // Price to reach this position.
+ Pos *_parent; // Way to reach destination.
+ Pos *next; // Single linked list.
+ Pos *fnext; // Link all Pos instances, so we can delete them all.
+ Pos *left, *right; // BTree.
+ bool inList;
+};
+
+class Board : public QMemArray<int>
+{
+public:
+ Board (int s);
+ ~Board() {}
+ QRect rect(int i);
+
+ void set(int i, Square sq);
+
+ bool isBrick(int i);
+ bool isEmpty(int i);
+ bool isApple(int i);
+ bool isHead(int i);
+ bool isSnake(int i);
+
+ int getNext(int, int);
+ int getNextCloseToDumb(int, int);
+ int getNextCloseTo(int, int, bool, int = -1);
+ int direction(int, int);
+
+ int samyHeadIndex() const {
+ return(samyIndex);
+ }
+
+private:
+ void index(int i);
+ bool inBounds(int i);
+ int row;
+ int col;
+ int sz;
+
+ int samyIndex;
+};
+
+#endif // BOARD_H
diff --git a/ksnake/data/Makefile.am b/ksnake/data/Makefile.am
new file mode 100644
index 00000000..42d15ec2
--- /dev/null
+++ b/ksnake/data/Makefile.am
@@ -0,0 +1,9 @@
+
+
+highscoredir = $(kde_datadir)/ksnake
+highscore_DATA = highScores
+
+SUBDIRS = levels pixmaps backgrounds
+
+EXTRA_DIST = $(highscore_DATA)
+
diff --git a/ksnake/data/backgrounds/Bark.png b/ksnake/data/backgrounds/Bark.png
new file mode 100644
index 00000000..68180cdd
--- /dev/null
+++ b/ksnake/data/backgrounds/Bark.png
Binary files differ
diff --git a/ksnake/data/backgrounds/Blue_Carpet.png b/ksnake/data/backgrounds/Blue_Carpet.png
new file mode 100644
index 00000000..92c8c8f2
--- /dev/null
+++ b/ksnake/data/backgrounds/Blue_Carpet.png
Binary files differ
diff --git a/ksnake/data/backgrounds/Dark_Wood.png b/ksnake/data/backgrounds/Dark_Wood.png
new file mode 100644
index 00000000..9767ec63
--- /dev/null
+++ b/ksnake/data/backgrounds/Dark_Wood.png
Binary files differ
diff --git a/ksnake/data/backgrounds/Granite.png b/ksnake/data/backgrounds/Granite.png
new file mode 100644
index 00000000..2dc1c2a9
--- /dev/null
+++ b/ksnake/data/backgrounds/Granite.png
Binary files differ
diff --git a/ksnake/data/backgrounds/Green_Carpet.png b/ksnake/data/backgrounds/Green_Carpet.png
new file mode 100644
index 00000000..ba18e54c
--- /dev/null
+++ b/ksnake/data/backgrounds/Green_Carpet.png
Binary files differ
diff --git a/ksnake/data/backgrounds/Makefile.am b/ksnake/data/backgrounds/Makefile.am
new file mode 100644
index 00000000..597ab5a8
--- /dev/null
+++ b/ksnake/data/backgrounds/Makefile.am
@@ -0,0 +1,8 @@
+
+bgdir = $(kde_datadir)/ksnake/backgrounds
+
+bg_DATA = Bark.png Blue_Carpet.png Dark_Wood.png Granite.png \
+ Green_Carpet.png Mystique.png Rope_Weave.png Volcanic.png \
+ Wood.png
+
+EXTRA_DIST = $(bg_DATA)
diff --git a/ksnake/data/backgrounds/Mystique.png b/ksnake/data/backgrounds/Mystique.png
new file mode 100644
index 00000000..92f59620
--- /dev/null
+++ b/ksnake/data/backgrounds/Mystique.png
Binary files differ
diff --git a/ksnake/data/backgrounds/Rope_Weave.png b/ksnake/data/backgrounds/Rope_Weave.png
new file mode 100644
index 00000000..70903bbc
--- /dev/null
+++ b/ksnake/data/backgrounds/Rope_Weave.png
Binary files differ
diff --git a/ksnake/data/backgrounds/Volcanic.png b/ksnake/data/backgrounds/Volcanic.png
new file mode 100644
index 00000000..90d185fc
--- /dev/null
+++ b/ksnake/data/backgrounds/Volcanic.png
Binary files differ
diff --git a/ksnake/data/backgrounds/Wood.png b/ksnake/data/backgrounds/Wood.png
new file mode 100644
index 00000000..c317f8df
--- /dev/null
+++ b/ksnake/data/backgrounds/Wood.png
Binary files differ
diff --git a/ksnake/data/highScores b/ksnake/data/highScores
new file mode 100644
index 00000000..41c812e8
--- /dev/null
+++ b/ksnake/data/highScores
Binary files differ
diff --git a/ksnake/data/levels/Makefile.am b/ksnake/data/levels/Makefile.am
new file mode 100644
index 00000000..6918477d
--- /dev/null
+++ b/ksnake/data/levels/Makefile.am
@@ -0,0 +1,9 @@
+
+room_DATA = room01 room02 room03 room04 room05 room06 room07 \
+ room08 room09 room10 room11 room12 room13 room14 room15 \
+ room16 room17 room18 room19 room20 room21 room22 room23 \
+ room24 room25
+
+roomdir = $(kde_datadir)/ksnake/levels
+
+EXTRA_DIST = $(room_DATA)
diff --git a/ksnake/data/levels/room01 b/ksnake/data/levels/room01
new file mode 100644
index 00000000..de31fc6a
--- /dev/null
+++ b/ksnake/data/levels/room01
@@ -0,0 +1,18 @@
+#define room01_width 35
+#define room01_height 35
+static unsigned char room01_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01,
+ 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00,
+ 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04,
+ 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01,
+ 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04,
+ 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01,
+ 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00,
+ 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04,
+ 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01,
+ 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x01, 0x00, 0x04,
+ 0x04, 0x01, 0x01, 0x00, 0x04, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room02 b/ksnake/data/levels/room02
new file mode 100644
index 00000000..4c73afef
--- /dev/null
+++ b/ksnake/data/levels/room02
@@ -0,0 +1,18 @@
+#define room2_width 35
+#define room2_height 35
+static unsigned char room2_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xc1, 0xff, 0xff, 0x1f, 0x04, 0x01,
+ 0x00, 0x02, 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x04, 0x01, 0x00, 0x02,
+ 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x04,
+ 0x01, 0x00, 0x02, 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x04, 0x01, 0x00,
+ 0x02, 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x04, 0x01, 0x00, 0x02, 0x00,
+ 0x04, 0x01, 0x00, 0x02, 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x04, 0x01,
+ 0x00, 0x02, 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x04, 0x01, 0x00, 0x02,
+ 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x04,
+ 0x01, 0x00, 0x02, 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x04, 0x01, 0x00,
+ 0x02, 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room03 b/ksnake/data/levels/room03
new file mode 100644
index 00000000..c7738cc8
--- /dev/null
+++ b/ksnake/data/levels/room03
@@ -0,0 +1,18 @@
+#define room3_width 35
+#define room3_height 35
+static unsigned char room3_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xc1, 0xff, 0xff, 0x1f, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04,
+ 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00,
+ 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10,
+ 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41,
+ 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00,
+ 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04,
+ 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00,
+ 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10,
+ 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41,
+ 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00,
+ 0x10, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room04 b/ksnake/data/levels/room04
new file mode 100644
index 00000000..0085400a
--- /dev/null
+++ b/ksnake/data/levels/room04
@@ -0,0 +1,18 @@
+#define room4_width 35
+#define room4_height 35
+static unsigned char room4_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xc1, 0x1f, 0xc0, 0x1f, 0x04, 0x41,
+ 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00,
+ 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04,
+ 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00,
+ 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10,
+ 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41,
+ 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00,
+ 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04,
+ 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00,
+ 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0xc1, 0x1f, 0xc0, 0x1f,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room05 b/ksnake/data/levels/room05
new file mode 100644
index 00000000..814e56d9
--- /dev/null
+++ b/ksnake/data/levels/room05
@@ -0,0 +1,18 @@
+#define room5_width 35
+#define room5_height 35
+static unsigned char room5_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x41, 0x00, 0xfe, 0x1f, 0x04, 0x41,
+ 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00,
+ 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04,
+ 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00,
+ 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10,
+ 0x04, 0x41, 0x00, 0x02, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41,
+ 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00,
+ 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04,
+ 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0x41, 0x00,
+ 0x00, 0x10, 0x04, 0x41, 0x00, 0x00, 0x10, 0x04, 0xc1, 0xff, 0x03, 0x10,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room06 b/ksnake/data/levels/room06
new file mode 100644
index 00000000..bd5c36f8
--- /dev/null
+++ b/ksnake/data/levels/room06
@@ -0,0 +1,18 @@
+#define room6_width 35
+#define room6_height 35
+static unsigned char room6_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04, 0x41,
+ 0x04, 0x00, 0x11, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04, 0x41, 0x04, 0x00,
+ 0x11, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04,
+ 0x41, 0x04, 0x00, 0x11, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04, 0x41, 0x04,
+ 0x00, 0x11, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04, 0x41, 0x04, 0x00, 0x11,
+ 0x04, 0x41, 0x04, 0x00, 0x11, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04, 0x41,
+ 0x04, 0x00, 0x11, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04, 0x41, 0x04, 0x00,
+ 0x11, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04,
+ 0x41, 0x04, 0x00, 0x11, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04, 0x41, 0x04,
+ 0x00, 0x11, 0x04, 0x41, 0x04, 0x00, 0x11, 0x04, 0x41, 0x04, 0x00, 0x11,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room07 b/ksnake/data/levels/room07
new file mode 100644
index 00000000..3330a24b
--- /dev/null
+++ b/ksnake/data/levels/room07
@@ -0,0 +1,18 @@
+#define room7_width 35
+#define room7_height 35
+static unsigned char room7_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0xe1, 0xff, 0xff, 0x3f, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0xe1, 0xff, 0xf8, 0x3f, 0x04, 0x01, 0x80, 0x08,
+ 0x00, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04,
+ 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80,
+ 0x08, 0x00, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08, 0x00,
+ 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01,
+ 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08,
+ 0x00, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04,
+ 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80,
+ 0x08, 0x00, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08, 0x00,
+ 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room08 b/ksnake/data/levels/room08
new file mode 100644
index 00000000..00ae3b91
--- /dev/null
+++ b/ksnake/data/levels/room08
@@ -0,0 +1,18 @@
+#define room8_width 35
+#define room8_height 35
+static unsigned char room8_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0xe1, 0xff, 0xff, 0x3f, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0xe1, 0xff, 0xff, 0x3f, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x21, 0x01, 0x00, 0x24, 0x04,
+ 0x21, 0x01, 0x00, 0x24, 0x04, 0x21, 0x01, 0x00, 0x24, 0x04, 0x21, 0x01,
+ 0x00, 0x24, 0x04, 0x21, 0x01, 0x00, 0x24, 0x04, 0x21, 0x01, 0x00, 0x24,
+ 0x04, 0x21, 0x01, 0x00, 0x24, 0x04, 0x21, 0x01, 0x00, 0x24, 0x04, 0x21,
+ 0x01, 0x00, 0x24, 0x04, 0x21, 0x01, 0x00, 0x24, 0x04, 0x21, 0x01, 0x00,
+ 0x24, 0x04, 0x21, 0x01, 0x00, 0x24, 0x04, 0x21, 0x01, 0x00, 0x24, 0x04,
+ 0x21, 0x01, 0x00, 0x24, 0x04, 0x21, 0x01, 0x00, 0x24, 0x04, 0x21, 0x01,
+ 0x00, 0x24, 0x04, 0x21, 0x01, 0x00, 0x24, 0x04, 0x21, 0x01, 0x00, 0x24,
+ 0x04, 0x21, 0x01, 0x00, 0x24, 0x04, 0x21, 0x01, 0x00, 0x24, 0x04, 0x21,
+ 0x01, 0x00, 0x24, 0x04, 0x21, 0x01, 0x00, 0x24, 0x04, 0x21, 0x01, 0x00,
+ 0x24, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room09 b/ksnake/data/levels/room09
new file mode 100644
index 00000000..8fe76e00
--- /dev/null
+++ b/ksnake/data/levels/room09
@@ -0,0 +1,18 @@
+#define room9_width 35
+#define room9_height 35
+static unsigned char room9_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1, 0x7f, 0xf0, 0x7f,
+ 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11,
+ 0x00, 0x00, 0x40, 0x04, 0x11, 0x7f, 0xf0, 0x47, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01,
+ 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44,
+ 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11,
+ 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x7f,
+ 0xf0, 0x47, 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11, 0x00, 0x00, 0x40,
+ 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0xf1, 0x7f, 0xf0, 0x7f, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room10 b/ksnake/data/levels/room10
new file mode 100644
index 00000000..a50f3f39
--- /dev/null
+++ b/ksnake/data/levels/room10
@@ -0,0 +1,18 @@
+#define room10_width 35
+#define room10_height 35
+static unsigned char room10_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x11, 0x01, 0xfe, 0x7f,
+ 0x04, 0x11, 0x01, 0x00, 0x40, 0x04, 0x11, 0x01, 0x00, 0x40, 0x04, 0x11,
+ 0x01, 0x00, 0x40, 0x04, 0x11, 0x01, 0xfe, 0x47, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01,
+ 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x05, 0x44,
+ 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x05, 0x44, 0x04, 0x11,
+ 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x7f,
+ 0x00, 0x44, 0x04, 0x11, 0x00, 0x00, 0x44, 0x04, 0x11, 0x00, 0x00, 0x44,
+ 0x04, 0x11, 0x00, 0x00, 0x44, 0x04, 0xf1, 0x7f, 0x00, 0x44, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room11 b/ksnake/data/levels/room11
new file mode 100644
index 00000000..6a0c1a1d
--- /dev/null
+++ b/ksnake/data/levels/room11
@@ -0,0 +1,18 @@
+#define room11_width 35
+#define room11_height 35
+static unsigned char room11_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x91, 0x04, 0x00, 0x49,
+ 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91,
+ 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00,
+ 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04,
+ 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04,
+ 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49,
+ 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91,
+ 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00,
+ 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04,
+ 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04,
+ 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49,
+ 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x91, 0x04, 0x00, 0x49, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room12 b/ksnake/data/levels/room12
new file mode 100644
index 00000000..ce609936
--- /dev/null
+++ b/ksnake/data/levels/room12
@@ -0,0 +1,18 @@
+#define room12_width 35
+#define room12_height 35
+static unsigned char room12_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1, 0xff, 0xff, 0x7f,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1,
+ 0xff, 0xf8, 0x7f, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08,
+ 0x00, 0x04, 0xf1, 0x8f, 0x88, 0x7f, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04,
+ 0x01, 0x88, 0x88, 0x00, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04, 0x01, 0x88,
+ 0x88, 0x00, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04, 0x01, 0x88, 0x88, 0x00,
+ 0x04, 0x01, 0x88, 0x88, 0x00, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04, 0x01,
+ 0x88, 0x88, 0x00, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04, 0x01, 0x88, 0x88,
+ 0x00, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04,
+ 0x01, 0x88, 0x88, 0x00, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04, 0x01, 0x88,
+ 0x88, 0x00, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04, 0x01, 0x88, 0x88, 0x00,
+ 0x04, 0x01, 0x88, 0x88, 0x00, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room13 b/ksnake/data/levels/room13
new file mode 100644
index 00000000..ad3b3879
--- /dev/null
+++ b/ksnake/data/levels/room13
@@ -0,0 +1,18 @@
+#define room13_width 35
+#define room13_height 35
+static unsigned char room13_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1, 0xff, 0xff, 0x7f,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1,
+ 0xff, 0xff, 0x7f, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x51, 0x01, 0x00, 0x54, 0x04, 0x51, 0x01, 0x00, 0x54, 0x04, 0x51, 0x01,
+ 0x00, 0x54, 0x04, 0x51, 0x01, 0x00, 0x54, 0x04, 0x51, 0x01, 0x00, 0x54,
+ 0x04, 0x51, 0x01, 0x00, 0x54, 0x04, 0x51, 0x01, 0x00, 0x54, 0x04, 0x51,
+ 0x01, 0x00, 0x54, 0x04, 0x51, 0x01, 0x00, 0x54, 0x04, 0x51, 0x01, 0x00,
+ 0x54, 0x04, 0x51, 0x01, 0x00, 0x54, 0x04, 0x51, 0x01, 0x00, 0x54, 0x04,
+ 0x51, 0x01, 0x00, 0x54, 0x04, 0x51, 0x01, 0x00, 0x54, 0x04, 0x51, 0x01,
+ 0x00, 0x54, 0x04, 0x51, 0x01, 0x00, 0x54, 0x04, 0x51, 0x01, 0x00, 0x54,
+ 0x04, 0x51, 0x01, 0x00, 0x54, 0x04, 0x51, 0x01, 0x00, 0x54, 0x04, 0x11,
+ 0x01, 0x00, 0x44, 0x04, 0x51, 0x01, 0x00, 0x54, 0x04, 0x51, 0x01, 0x00,
+ 0x54, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room14 b/ksnake/data/levels/room14
new file mode 100644
index 00000000..7d682c7e
--- /dev/null
+++ b/ksnake/data/levels/room14
@@ -0,0 +1,18 @@
+#define room14_width 35
+#define room14_height 35
+static unsigned char room14_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1, 0xff, 0xf8, 0x7f,
+ 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11,
+ 0x00, 0x00, 0x40, 0x04, 0x11, 0xff, 0xf8, 0x47, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0xf1, 0x7f, 0x44, 0x04, 0x11, 0x11, 0x40, 0x44, 0x04, 0x11, 0x11,
+ 0x40, 0x44, 0x04, 0x11, 0x11, 0x40, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44,
+ 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11,
+ 0x11, 0x40, 0x44, 0x04, 0x11, 0x11, 0x40, 0x44, 0x04, 0x11, 0x11, 0x40,
+ 0x44, 0x04, 0x11, 0xf1, 0x7f, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0xff,
+ 0xf8, 0x47, 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11, 0x00, 0x00, 0x40,
+ 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0xf1, 0xff, 0xf8, 0x7f, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room15 b/ksnake/data/levels/room15
new file mode 100644
index 00000000..004ad67e
--- /dev/null
+++ b/ksnake/data/levels/room15
@@ -0,0 +1,18 @@
+#define room15_width 35
+#define room15_height 35
+static unsigned char room15_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x11, 0xf1, 0xff, 0x7f,
+ 0x04, 0x11, 0x01, 0x00, 0x40, 0x04, 0x11, 0x01, 0x00, 0x40, 0x04, 0x11,
+ 0x01, 0x00, 0x40, 0x04, 0x11, 0xf1, 0xff, 0x47, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0xc1,
+ 0x1d, 0x44, 0x04, 0x11, 0xc1, 0x1d, 0x44, 0x04, 0x11, 0xc1, 0x18, 0x44,
+ 0x04, 0x11, 0x01, 0x02, 0x44, 0x04, 0x11, 0xc1, 0x18, 0x44, 0x04, 0x11,
+ 0xc1, 0x1d, 0x44, 0x04, 0x11, 0xc1, 0x1d, 0x44, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0xff,
+ 0x7f, 0x44, 0x04, 0x11, 0x00, 0x00, 0x44, 0x04, 0x11, 0x00, 0x00, 0x44,
+ 0x04, 0x11, 0x00, 0x00, 0x44, 0x04, 0xf1, 0xff, 0x7f, 0x44, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room16 b/ksnake/data/levels/room16
new file mode 100644
index 00000000..59dde122
--- /dev/null
+++ b/ksnake/data/levels/room16
@@ -0,0 +1,18 @@
+#define room16_width 35
+#define room16_height 35
+static unsigned char room16_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92,
+ 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91,
+ 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40,
+ 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04,
+ 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24,
+ 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92,
+ 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91,
+ 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40,
+ 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04,
+ 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24,
+ 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92,
+ 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91, 0x24, 0x40, 0x92, 0x04, 0x91,
+ 0x24, 0x40, 0x92, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room17 b/ksnake/data/levels/room17
new file mode 100644
index 00000000..1237cfb7
--- /dev/null
+++ b/ksnake/data/levels/room17
@@ -0,0 +1,18 @@
+#define room17_width 35
+#define room17_height 35
+static unsigned char room17_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1, 0xff, 0xff, 0x7f,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1,
+ 0xff, 0xf8, 0x7f, 0x04, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08,
+ 0x00, 0x04, 0xf1, 0x8f, 0x88, 0x7f, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04,
+ 0x01, 0x88, 0x88, 0x00, 0x04, 0xf1, 0x88, 0x88, 0x78, 0x04, 0x81, 0x88,
+ 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08,
+ 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81,
+ 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88,
+ 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04,
+ 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88,
+ 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08,
+ 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room18 b/ksnake/data/levels/room18
new file mode 100644
index 00000000..2c1949f5
--- /dev/null
+++ b/ksnake/data/levels/room18
@@ -0,0 +1,18 @@
+#define room18_width 35
+#define room18_height 35
+static unsigned char room18_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1, 0xff, 0xff, 0x7f,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1,
+ 0xff, 0xff, 0x7f, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0x11, 0xe1, 0x3f, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x55, 0x01, 0x00, 0x54, 0x05, 0x55, 0xe1, 0x3f, 0x54, 0x05, 0x55, 0x01,
+ 0x00, 0x54, 0x05, 0x55, 0x01, 0x00, 0x54, 0x05, 0x55, 0xe1, 0x3f, 0x54,
+ 0x05, 0x55, 0x01, 0x00, 0x54, 0x05, 0x55, 0x01, 0x00, 0x54, 0x05, 0x55,
+ 0xe1, 0x3f, 0x54, 0x05, 0x55, 0x01, 0x00, 0x54, 0x05, 0x55, 0x01, 0x00,
+ 0x54, 0x05, 0x55, 0x01, 0x00, 0x54, 0x05, 0x55, 0x01, 0x00, 0x54, 0x05,
+ 0x55, 0x01, 0x00, 0x54, 0x05, 0x55, 0x01, 0x00, 0x54, 0x05, 0x55, 0x01,
+ 0x00, 0x54, 0x05, 0x55, 0x01, 0x00, 0x54, 0x05, 0x55, 0x01, 0x00, 0x54,
+ 0x05, 0x55, 0x01, 0x00, 0x54, 0x05, 0x55, 0x01, 0x00, 0x54, 0x05, 0x55,
+ 0x01, 0x00, 0x54, 0x05, 0x11, 0x01, 0x00, 0x44, 0x04, 0x55, 0x01, 0x00,
+ 0x54, 0x05, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room19 b/ksnake/data/levels/room19
new file mode 100644
index 00000000..39a1d698
--- /dev/null
+++ b/ksnake/data/levels/room19
@@ -0,0 +1,18 @@
+#define room19_width 35
+#define room19_height 35
+static unsigned char room19_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1, 0xff, 0xf8, 0x7f,
+ 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11,
+ 0x00, 0x00, 0x40, 0x04, 0x11, 0xff, 0xff, 0x47, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0xf1, 0x78, 0x44, 0x04, 0x11, 0x11, 0x40, 0x44, 0x04, 0x11, 0x11,
+ 0x40, 0x44, 0x04, 0x11, 0x11, 0x42, 0x44, 0x04, 0x11, 0x10, 0x40, 0x40,
+ 0x04, 0x11, 0x90, 0x48, 0x40, 0x04, 0x11, 0x10, 0x40, 0x40, 0x04, 0x11,
+ 0x11, 0x42, 0x44, 0x04, 0x11, 0x11, 0x40, 0x44, 0x04, 0x11, 0x11, 0x40,
+ 0x44, 0x04, 0x11, 0xf1, 0x78, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0xff,
+ 0xff, 0x47, 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11, 0x00, 0x00, 0x40,
+ 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0xf1, 0xff, 0xf8, 0x7f, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room20 b/ksnake/data/levels/room20
new file mode 100644
index 00000000..11765e1c
--- /dev/null
+++ b/ksnake/data/levels/room20
@@ -0,0 +1,18 @@
+#define room20_width 35
+#define room20_height 35
+static unsigned char room20_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x01, 0x00, 0x00, 0x04, 0x01, 0x01,
+ 0x00, 0x00, 0x04, 0x01, 0x01, 0x00, 0x00, 0x04, 0x11, 0xf1, 0xff, 0x7f,
+ 0x04, 0x11, 0x01, 0x00, 0x40, 0x04, 0x11, 0x01, 0x00, 0x40, 0x04, 0x11,
+ 0x01, 0x00, 0x40, 0x04, 0x11, 0xf1, 0xff, 0x47, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0xc1,
+ 0x15, 0x44, 0x04, 0x11, 0x01, 0x14, 0x44, 0x04, 0x11, 0xc1, 0x10, 0x44,
+ 0x04, 0x11, 0x01, 0x02, 0x44, 0x04, 0x11, 0x41, 0x18, 0x44, 0x04, 0x11,
+ 0x41, 0x01, 0x44, 0x04, 0x11, 0x41, 0x1d, 0x44, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0xff,
+ 0x0f, 0x44, 0x04, 0x11, 0x00, 0x00, 0x44, 0x04, 0x11, 0x00, 0x00, 0x44,
+ 0x04, 0x11, 0x00, 0x00, 0x44, 0x04, 0xf1, 0xff, 0x0f, 0x44, 0x04, 0x01,
+ 0x00, 0x00, 0x04, 0x04, 0x01, 0x00, 0x00, 0x04, 0x04, 0x01, 0x00, 0x00,
+ 0x04, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room21 b/ksnake/data/levels/room21
new file mode 100644
index 00000000..3ce582b6
--- /dev/null
+++ b/ksnake/data/levels/room21
@@ -0,0 +1,18 @@
+#define room21_width 35
+#define room21_height 35
+static unsigned char room21_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92,
+ 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49,
+ 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48,
+ 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04,
+ 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92,
+ 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92,
+ 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49,
+ 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48,
+ 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04,
+ 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92,
+ 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92,
+ 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49, 0x92, 0x48, 0x92, 0x04, 0x49,
+ 0x92, 0x48, 0x92, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room22 b/ksnake/data/levels/room22
new file mode 100644
index 00000000..104557c9
--- /dev/null
+++ b/ksnake/data/levels/room22
@@ -0,0 +1,18 @@
+#define room22_width 35
+#define room22_height 35
+static unsigned char room22_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1, 0xff, 0xff, 0x7f,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xff,
+ 0xff, 0xf8, 0xff, 0x07, 0x01, 0x80, 0x08, 0x00, 0x04, 0x01, 0x80, 0x08,
+ 0x00, 0x04, 0xf1, 0x8f, 0x88, 0x7f, 0x04, 0x01, 0x88, 0x88, 0x00, 0x04,
+ 0x01, 0x88, 0x88, 0x00, 0x04, 0xf1, 0x88, 0x88, 0x78, 0x04, 0x81, 0x88,
+ 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08,
+ 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81,
+ 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88,
+ 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04,
+ 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88,
+ 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08,
+ 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81, 0x88, 0x88, 0x08, 0x04, 0x81,
+ 0x80, 0x08, 0x08, 0x04, 0x81, 0x00, 0x00, 0x08, 0x04, 0x81, 0x00, 0x00,
+ 0x08, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room23 b/ksnake/data/levels/room23
new file mode 100644
index 00000000..e3091764
--- /dev/null
+++ b/ksnake/data/levels/room23
@@ -0,0 +1,18 @@
+#define room23_width 35
+#define room23_height 35
+static unsigned char room23_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0xf1, 0xff, 0xff, 0x7f, 0x04, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0xc1, 0xff, 0xff, 0x1f, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1,
+ 0xff, 0xff, 0x7f, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0x11, 0xe1, 0x3f, 0x44, 0x04, 0x11, 0x01, 0x02, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x55, 0xe5, 0x3f, 0x55, 0x05, 0x55, 0x05,
+ 0x02, 0x55, 0x05, 0x55, 0x05, 0x00, 0x55, 0x05, 0x55, 0xe5, 0x3f, 0x55,
+ 0x05, 0x55, 0x05, 0x02, 0x55, 0x05, 0x55, 0x05, 0x00, 0x55, 0x05, 0x55,
+ 0xe5, 0x3f, 0x55, 0x05, 0x55, 0x05, 0x02, 0x55, 0x05, 0x55, 0x05, 0x00,
+ 0x55, 0x05, 0x11, 0xe1, 0x3f, 0x44, 0x04, 0x55, 0x05, 0x02, 0x55, 0x05,
+ 0x55, 0x05, 0x00, 0x55, 0x05, 0x55, 0x05, 0x00, 0x55, 0x05, 0x55, 0x05,
+ 0x00, 0x55, 0x05, 0x55, 0x05, 0x00, 0x55, 0x05, 0x55, 0x05, 0x00, 0x55,
+ 0x05, 0x55, 0x05, 0x00, 0x55, 0x05, 0x55, 0x05, 0x00, 0x55, 0x05, 0x55,
+ 0x05, 0x00, 0x55, 0x05, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room24 b/ksnake/data/levels/room24
new file mode 100644
index 00000000..29d5e2a1
--- /dev/null
+++ b/ksnake/data/levels/room24
@@ -0,0 +1,18 @@
+#define room24_width 35
+#define room24_height 35
+static unsigned char room24_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xc1, 0xff, 0xff, 0x1f,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11,
+ 0x00, 0x00, 0x40, 0x04, 0x11, 0xfc, 0xff, 0x41, 0x04, 0x11, 0x00, 0x00,
+ 0x40, 0x04, 0x11, 0x01, 0x00, 0x40, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0xc1, 0x1f, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x11,
+ 0x40, 0x44, 0x04, 0x11, 0x91, 0x4d, 0x44, 0x04, 0x11, 0x91, 0x4d, 0x44,
+ 0x04, 0x11, 0x11, 0x40, 0x44, 0x04, 0x11, 0x91, 0x4d, 0x44, 0x04, 0x11,
+ 0x91, 0x4d, 0x44, 0x04, 0x11, 0x11, 0x40, 0x44, 0x04, 0x11, 0x01, 0x00,
+ 0x44, 0x04, 0x11, 0xc1, 0x1f, 0x44, 0x04, 0x11, 0x01, 0x00, 0x44, 0x04,
+ 0x11, 0x01, 0x00, 0x44, 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11, 0xfc,
+ 0xff, 0x41, 0x04, 0x11, 0x00, 0x00, 0x40, 0x04, 0x11, 0x00, 0x00, 0x40,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xc1, 0xff, 0xff, 0x1f, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/levels/room25 b/ksnake/data/levels/room25
new file mode 100644
index 00000000..e52f722a
--- /dev/null
+++ b/ksnake/data/levels/room25
@@ -0,0 +1,18 @@
+#define room25_width 35
+#define room25_height 35
+static unsigned char room25_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf1, 0xff, 0xff, 0x47,
+ 0x04, 0x11, 0x00, 0x00, 0x44, 0x04, 0x11, 0x00, 0x00, 0x44, 0x04, 0x11,
+ 0xff, 0x03, 0x44, 0x04, 0x11, 0x01, 0x02, 0x44, 0x04, 0x11, 0x01, 0x02,
+ 0x44, 0x04, 0x11, 0x49, 0x02, 0x44, 0x04, 0x11, 0x91, 0x02, 0x44, 0x04,
+ 0x11, 0x01, 0x02, 0x44, 0x04, 0x11, 0x01, 0x02, 0x44, 0x04, 0x11, 0x01,
+ 0x02, 0x44, 0x04, 0x11, 0x01, 0x02, 0x44, 0x04, 0x11, 0x01, 0x02, 0x44,
+ 0x04, 0x11, 0x01, 0x02, 0x44, 0x04, 0x11, 0x01, 0x02, 0x44, 0x04, 0x11,
+ 0x01, 0x02, 0x44, 0x04, 0x11, 0x01, 0x02, 0x44, 0x04, 0x11, 0x01, 0x02,
+ 0x44, 0x04, 0x11, 0x01, 0x02, 0x44, 0x04, 0x11, 0x01, 0x02, 0x44, 0x04,
+ 0x11, 0x01, 0x92, 0x44, 0x04, 0x11, 0x01, 0x22, 0x45, 0x04, 0x11, 0x01,
+ 0x02, 0x44, 0x04, 0x11, 0x01, 0xfe, 0x47, 0x04, 0x11, 0x01, 0x00, 0x40,
+ 0x04, 0x11, 0x01, 0x00, 0x40, 0x04, 0x11, 0xff, 0xff, 0x7f, 0x04, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x07};
diff --git a/ksnake/data/pixmaps/Makefile.am b/ksnake/data/pixmaps/Makefile.am
new file mode 100644
index 00000000..67ea560b
--- /dev/null
+++ b/ksnake/data/pixmaps/Makefile.am
@@ -0,0 +1,5 @@
+
+pixmapsdir = $(kde_datadir)/ksnake/pics
+pixmaps_DATA = apples.png ball.png brick.png snake1.png snake2.png
+
+EXTRA_DIST = $(pixmaps_DATA)
diff --git a/ksnake/data/pixmaps/apples.png b/ksnake/data/pixmaps/apples.png
new file mode 100644
index 00000000..f90552a7
--- /dev/null
+++ b/ksnake/data/pixmaps/apples.png
Binary files differ
diff --git a/ksnake/data/pixmaps/ball.png b/ksnake/data/pixmaps/ball.png
new file mode 100644
index 00000000..98ecc115
--- /dev/null
+++ b/ksnake/data/pixmaps/ball.png
Binary files differ
diff --git a/ksnake/data/pixmaps/brick.png b/ksnake/data/pixmaps/brick.png
new file mode 100644
index 00000000..a2b264af
--- /dev/null
+++ b/ksnake/data/pixmaps/brick.png
Binary files differ
diff --git a/ksnake/data/pixmaps/snake1.png b/ksnake/data/pixmaps/snake1.png
new file mode 100644
index 00000000..c95367ef
--- /dev/null
+++ b/ksnake/data/pixmaps/snake1.png
Binary files differ
diff --git a/ksnake/data/pixmaps/snake2.png b/ksnake/data/pixmaps/snake2.png
new file mode 100644
index 00000000..154b889a
--- /dev/null
+++ b/ksnake/data/pixmaps/snake2.png
Binary files differ
diff --git a/ksnake/game.cpp b/ksnake/game.cpp
new file mode 100644
index 00000000..0fa18df2
--- /dev/null
+++ b/ksnake/game.cpp
@@ -0,0 +1,180 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ note: the code to lookup and insert the pixmaps
+ into the Options menu was copied and adapted
+ from KReversi.
+ thanks.
+ */
+#include <qdir.h>
+#include <qregexp.h>
+
+
+#include <klocale.h>
+#include <kconfigdialog.h>
+
+#include <kstdgameaction.h>
+#include <kscoredialog.h>
+#include <kstatusbar.h>
+#include <kmenubar.h>
+
+#include "rattler.h"
+#include "game.h"
+#include "startroom.h"
+#include "levels.h"
+#include "progress.h"
+#include "view.h"
+#include "general.h"
+#include "appearance.h"
+#include "settings.h"
+
+#define SCORE 1
+#define LIVES 2
+
+Game::Game(QWidget *parent, const char *name) : KMainWindow(parent,name)
+{
+ // create statusbar
+ statusBar()->insertItem(i18n("Score: 0"), SCORE);
+ statusBar()->insertItem(i18n("Lives: 0"), LIVES);
+
+ levels = new Levels();
+
+ view = new View(this, "View");
+ rattler = view->rattler;
+ rattler->reloadRoomPixmap();
+ rattler->setFocus();
+
+ connect(rattler, SIGNAL(setPoints(int)), this, SLOT(scoreChanged(int)));
+ connect(rattler, SIGNAL(setTrys(int)), this, SLOT(setTrys(int)));
+ connect(rattler, SIGNAL(rewind()), view->progress, SLOT(rewind()));
+ connect(rattler, SIGNAL(advance()), view->progress, SLOT(advance()));
+ connect(view->progress, SIGNAL(restart()), rattler, SLOT(restartTimer()));
+
+ connect(rattler, SIGNAL(togglePaused()), this, SLOT(togglePaused()));
+ connect(rattler, SIGNAL(setScore(int)), this, SLOT(gameEnd(int)));
+
+ setCentralWidget(view);
+
+ createMenu();
+ setupGUI(KMainWindow::Save | StatusBar | Create );
+}
+
+Game::~Game()
+{
+ delete levels;
+}
+
+void Game::scoreChanged(int score){
+ statusBar()->changeItem(i18n("Score: %1").arg(score), SCORE);
+}
+
+void Game::setTrys(int tries){
+ statusBar()->changeItem(i18n("Lives: %1").arg(tries), LIVES);
+}
+
+void Game::gameEnd(int score){
+ KScoreDialog di(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Date, this);
+ KScoreDialog::FieldInfo scoreInfo;
+ QString date = QDateTime::currentDateTime().toString();
+ scoreInfo.insert(KScoreDialog::Date, date);
+ if (di.addScore(score, scoreInfo, true))
+ di.exec();
+}
+
+void Game::showHighScores()
+{
+ KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Date, this);
+ d.exec();
+}
+
+void Game::createMenu()
+{
+ actionCollection()->setAutoConnectShortcuts(false);
+ (void)new KAction(i18n("Move Up"), Key_Up, 0, 0, actionCollection(), "Pl1Up");
+ (void)new KAction(i18n("Move Down"), Key_Down, 0, 0, actionCollection(), "Pl1Down");
+ (void)new KAction(i18n("Move Right"), Key_Right, 0, 0, actionCollection(), "Pl1Right");
+ (void)new KAction(i18n("Move Left"), Key_Left, 0, 0, actionCollection(), "Pl1Left");
+ actionCollection()->setAutoConnectShortcuts(true);
+ rattler->setActionCollection(actionCollection());
+
+ KStdGameAction::gameNew(rattler, SLOT(restart()), actionCollection());
+ pause = KStdGameAction::pause(rattler, SLOT(pause()), actionCollection());
+ KStdGameAction::highscores(this, SLOT(showHighScores()), actionCollection());
+ KStdGameAction::quit( this, SLOT(close()), actionCollection());
+
+ KStdAction::preferences(this, SLOT(showSettings()), actionCollection());
+
+ // TODO change and make custom function that pauses game or
+ // modify widget to pause when loosing focus and remove this
+ KStdAction::keyBindings(guiFactory(), SLOT(configureShortcuts()),
+actionCollection());
+}
+
+void Game::togglePaused()
+{
+ static bool checked = false;
+ checked = !checked;
+ pause->setEnabled(checked);
+}
+
+/**
+ * Show Settings dialog.
+ */
+void Game::showSettings(){
+ if(KConfigDialog::showDialog("settings"))
+ return;
+
+ KConfigDialog *dialog = new KConfigDialog(this, "settings", Settings::self());
+ dialog->addPage(new General(0, "General"), i18n("General"), "package_settings");
+
+ Appearance *a = new Appearance(0, "Appearance");
+
+
+ QStringList list;
+
+ if (rattler->backgroundPixmaps.count() == 0) {
+ list.append(i18n("none"));
+ } else {
+ QStringList::ConstIterator it = rattler->backgroundPixmaps.begin();
+ for(unsigned i = 0; it != rattler->backgroundPixmaps.end(); i++, it++) {
+ // since the filename may contain underscore, they
+ // are replaced with spaces in the menu entry
+ QString s = QFileInfo( *it ).baseName();
+ s = s.replace(QRegExp("_"), " ");
+ list.append(s);
+ }
+ }
+
+ a->kcfg_bgimage->insertStringList(list);
+
+ dialog->addPage(a, i18n("Appearance"), "style");
+
+ dialog->addPage(new StartRoom(0, "StartRoom"), i18n("First Level"), "folder_home");
+ connect(dialog, SIGNAL(settingsChanged()), rattler, SLOT(loadSettings()));
+ dialog->show();
+}
+
+#include "game.moc"
diff --git a/ksnake/game.h b/ksnake/game.h
new file mode 100644
index 00000000..f25ef127
--- /dev/null
+++ b/ksnake/game.h
@@ -0,0 +1,64 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santo <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef GAME_H
+#define GAME_H
+
+#include <kmainwindow.h>
+
+class KAction;
+class Rattler;
+class Levels;
+class View;
+
+class Game : public KMainWindow {
+
+Q_OBJECT
+
+public:
+ Game(QWidget *parent=0, const char *name=0);
+ ~Game();
+
+private slots:
+ void gameEnd(int score);
+ void showHighScores();
+
+ void showSettings();
+
+ void togglePaused();
+ void scoreChanged(int newScore);
+ void setTrys(int);
+
+private:
+ View *view;
+ Rattler *rattler;
+ Levels *levels;
+ KAction *pause;
+
+ void createMenu();
+};
+
+#endif // GAME_H
+
diff --git a/ksnake/general.ui b/ksnake/general.ui
new file mode 100644
index 00000000..de9ef8cb
--- /dev/null
+++ b/ksnake/general.ui
@@ -0,0 +1,202 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>General</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>General</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>333</width>
+ <height>409</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>Speed</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSlider" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kcfg_Skill</cstring>
+ </property>
+ <property name="maxValue">
+ <number>3</number>
+ </property>
+ <property name="pageStep">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel10</cstring>
+ </property>
+ <property name="text">
+ <string>Slow</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>textLabel12</cstring>
+ </property>
+ <property name="text">
+ <string>Fast</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox6</cstring>
+ </property>
+ <property name="title">
+ <string>Snakes</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel7</cstring>
+ </property>
+ <property name="text">
+ <string>Snake behavior:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="1">
+ <item>
+ <property name="text">
+ <string>Random</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Eater</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Killer</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>kcfg_SnakesAI</cstring>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_ComputerSnakes</cstring>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel8</cstring>
+ </property>
+ <property name="text">
+ <string>Number of snakes:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox5</cstring>
+ </property>
+ <property name="title">
+ <string>Balls</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel9</cstring>
+ </property>
+ <property name="text">
+ <string>Number of balls:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_Balls</cstring>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="1">
+ <item>
+ <property name="text">
+ <string>Dumb</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Average</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Killer</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>kcfg_BallsAI</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel13</cstring>
+ </property>
+ <property name="text">
+ <string>Ball behavior:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>70</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/ksnake/hi128-app-ksnake.png b/ksnake/hi128-app-ksnake.png
new file mode 100644
index 00000000..f0031391
--- /dev/null
+++ b/ksnake/hi128-app-ksnake.png
Binary files differ
diff --git a/ksnake/hi16-app-ksnake.png b/ksnake/hi16-app-ksnake.png
new file mode 100644
index 00000000..ab14f946
--- /dev/null
+++ b/ksnake/hi16-app-ksnake.png
Binary files differ
diff --git a/ksnake/hi22-app-ksnake.png b/ksnake/hi22-app-ksnake.png
new file mode 100644
index 00000000..ee9e6756
--- /dev/null
+++ b/ksnake/hi22-app-ksnake.png
Binary files differ
diff --git a/ksnake/hi32-app-ksnake.png b/ksnake/hi32-app-ksnake.png
new file mode 100644
index 00000000..1c68c053
--- /dev/null
+++ b/ksnake/hi32-app-ksnake.png
Binary files differ
diff --git a/ksnake/hi48-app-ksnake.png b/ksnake/hi48-app-ksnake.png
new file mode 100644
index 00000000..89e65255
--- /dev/null
+++ b/ksnake/hi48-app-ksnake.png
Binary files differ
diff --git a/ksnake/hi64-app-ksnake.png b/ksnake/hi64-app-ksnake.png
new file mode 100644
index 00000000..b7d4fdc0
--- /dev/null
+++ b/ksnake/hi64-app-ksnake.png
Binary files differ
diff --git a/ksnake/ksnake.desktop b/ksnake/ksnake.desktop
new file mode 100644
index 00000000..89cc2e05
--- /dev/null
+++ b/ksnake/ksnake.desktop
@@ -0,0 +1,82 @@
+[Desktop Entry]
+Name=KSnakeRace
+Name[af]=K-slang-resies
+Name[ar]=لعبة سباق الأفعى (KSnakeRace)
+Name[be]=Змяіныя гонкі
+Name[bn]=কে-স্নেকরেস
+Name[ca]=Cursa de serps
+Name[eo]=Serpentkurado
+Name[fi]=KSnake
+Name[hi]=के-स्नेक-रेस
+Name[hr]=KUtrka zmija
+Name[hu]=Kígyóverseny
+Name[is]=Slönguleikurinn
+Name[nb]=Slangeløp
+Name[ne]=केडीई सर्प दौड
+Name[nn]=Slangeløp
+Name[pa]=ਕੇ-ਸੱਪ ਦੌੜ
+Name[pl]=Wyścig węży
+Name[pt_BR]=KCorrida de Cobras
+Name[se]=Gearpmašgilvu
+Name[sv]=Ksnakerace
+Name[ta]=Kபாம்பு பந்தயம்
+Name[tg]=KМусобиқаи Морчаҳо
+Name[th]=แข่งวิ่งงู - K
+Name[tr]=Yılan Yarışı
+Name[zh_TW]=KSnakeRace 貪食蛇
+Name[zu]=I-KSnakeRace
+Icon=ksnake
+Exec=ksnake %i %m -caption "%c"
+DocPath=ksnake/index.html
+GenericName=Snake Race Game
+GenericName[be]=Змяіныя гонкі
+GenericName[bg]=Змии и ябълки
+GenericName[bn]=স্নেক রেস খেলা
+GenericName[bs]=Igra utrke zmija
+GenericName[ca]=Joc de cursa de serps
+GenericName[cs]=Závod hadů
+GenericName[cy]=Gêm Ras Nadredd
+GenericName[da]=Slangevæddeløb spil
+GenericName[de]=Schlangenrennen
+GenericName[el]=Παιχνίδι αγώνα φιδιών
+GenericName[eo]=Serpent-vetkura ludo
+GenericName[es]=Juego de la carrera de la serpiente
+GenericName[et]=Ussiralli
+GenericName[eu]=Snake Race jokoa
+GenericName[fa]=بازی مسابقۀ مار
+GenericName[fi]=Matokilpailupeli
+GenericName[fr]=Jeu de course de serpent
+GenericName[he]=משחק מירוץ נחשים
+GenericName[hr]=Igra utrke zmija
+GenericName[hu]=Ügyességi
+GenericName[is]=Snákakapphlaup
+GenericName[it]=Gioco del Snake Race
+GenericName[ja]=蛇のレースゲーム
+GenericName[km]=ល្បែង​ប្រណាំង​ពស់
+GenericName[lv]=Čūsku skriešanās spēle
+GenericName[mk]=Игра со трки на змии
+GenericName[nb]=Slangespill
+GenericName[nds]=Schlangenwettloop
+GenericName[ne]=सर्प दौड खेल
+GenericName[nl]=Slangenracespel
+GenericName[nn]=Slangespel
+GenericName[pa]=ਸੱਪ ਦੌੜ ਖੇਡ
+GenericName[pl]=Wyścig węży
+GenericName[pt]=Jogo de Corrida de Cobras
+GenericName[pt_BR]=Jogo de corrida de cobras
+GenericName[ru]=Змеиные гонки
+GenericName[se]=Gearpmášspeallu
+GenericName[sk]=Hra Snake Race
+GenericName[sl]=Igra dirke kač
+GenericName[sr]=Игра змијица
+GenericName[sr@Latn]=Igra zmijica
+GenericName[sv]=Orm-racespel
+GenericName[ta]=பாம்பு ஓட்ட விளையாட்டு
+GenericName[uk]=Гра схожа на перегони пітонів
+GenericName[zh_CN]=贪食蛇
+GenericName[zh_TW]=吞食蛇遊戲
+Terminal=false
+Type=Application
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Multi
+Categories=Qt;KDE;Game;ArcadeGame;
diff --git a/ksnake/ksnake.kcfg b/ksnake/ksnake.kcfg
new file mode 100644
index 00000000..087be291
--- /dev/null
+++ b/ksnake/ksnake.kcfg
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile name="ksnakerc"/>
+ <group name="Game">
+ <entry name="bgcolor_enabled" type="Bool">
+ <default>false</default>
+ </entry>
+ <entry name="bgcolor" type="Color">
+ <label>The background color of the game.</label>
+ <default>white</default>
+ </entry>
+ <entry name="bgimage_enabled" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry name="bgimage" type="Int">
+ <label>Background Image</label>
+ <default>4</default>
+ </entry>
+
+ <entry name="Skill" type="Int">
+ <label>Snake speed</label>
+ <default>0</default>
+ </entry>
+ <entry name="ComputerSnakes" type="Int">
+ <label>Number of Snakes in the game</label>
+ <default>1</default>
+ </entry>
+ <entry name="SnakesAI" type="Int">
+ <label>Snake Behavior</label>
+ <default>0</default>
+ </entry>
+
+ <entry name="Balls" type="Int">
+ <label>Number of Balls in the game</label>
+ <default>1</default>
+ </entry>
+ <entry name="BallsAI" type="Int">
+ <label>Ball Behavior</label>
+ <default>0</default>
+ </entry>
+
+ <entry name="StartingRoom" type="Int">
+ <default>1</default>
+ </entry>
+
+ </group>
+</kcfg>
diff --git a/ksnake/ksnakeui.rc b/ksnake/ksnakeui.rc
new file mode 100644
index 00000000..cb3a2023
--- /dev/null
+++ b/ksnake/ksnakeui.rc
@@ -0,0 +1,5 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="ksnake" version="6">
+<MenuBar>
+</MenuBar>
+</kpartgui>
diff --git a/ksnake/level.cpp b/ksnake/level.cpp
new file mode 100644
index 00000000..86360818
--- /dev/null
+++ b/ksnake/level.cpp
@@ -0,0 +1,152 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qbitmap.h>
+#include <qimage.h>
+
+#include "level.h"
+#include "board.h"
+#include "bitmaps.h"
+#include "levels.h"
+
+const uchar *numbers[10] = { zero_bits, one_bits, two_bits,
+ three_bits, four_bits, five_bits,
+ six_bits, seven_bits, eight_bits, nine_bits
+};
+
+Level::Level(Board *b)
+{
+ board = b;
+ create(Intro);
+}
+
+void Level::nextLevel()
+{
+ if (level < leV->max())
+ level++;
+}
+
+void Level::create(Img img)
+{
+ switch(img){
+ case Banner:
+ createBanner();
+ break;
+ case Room:
+ createRoom();
+ break;
+ case Intro:
+ makeImageFromData(intro_bits);
+ break;
+ case GameOver:
+ makeImageFromData(gameover_bits);
+ break;
+ }
+}
+
+void Level::createRoom()
+{
+ QImage image = leV->getImage(level);
+ initBoard(image);
+}
+
+void Level::makeImageFromData(const uchar *buf)
+{
+ QBitmap bitmap(BoardWidth, BoardWidth, buf, true);
+ QImage image = bitmap.convertToImage();
+ initBoard (image);
+}
+
+void Level::initBoard(const QImage &image)
+{
+ int index = 0;
+ uchar *b;
+
+ for ( int y = 0;y < image.height();y++ ) {
+ b = image.scanLine(y);
+ for ( int x = 0;x < image.width();x++ ) {
+
+ if ( image.bitOrder() == QImage::BigEndian ) {
+ if (((*b >> (7 - (x & 7))) & 1) == 1)
+ board->set(index, brick);
+ else board->set(index, empty);
+ } else {
+ if (((*b >> (x & 7)) & 1) == 1)
+ board->set(index, brick);
+ else board->set(index, empty);
+ }
+
+ if ( (x & 7) == 7 )
+ b++;
+ index++;
+ }
+ }
+}
+
+void Level::createBanner()
+{
+ makeImageFromData(level_bits);
+
+ QString num;
+ num.setNum(level);
+ if(level < 10)
+ num.insert(0,'0');
+
+ QString left = num.left(1);
+ QString right = num.right(1);
+
+ drawNumber ( 606, numbers[left.toInt()] );
+ drawNumber ( 614, numbers[right.toInt()] );
+}
+
+void Level::drawNumber(int beginAt, const uchar *buf)
+{
+ QBitmap bitmap(7, 9, buf, true);
+ QImage image = bitmap.convertToImage();
+
+ int index = beginAt;
+ uchar *b;
+
+ for ( int y = 0;y < image.height();y++ )
+ {
+ b = image.scanLine(y);
+ for ( int x = 0;x < image.width();x++ )
+ {
+ if ( image.bitOrder() == QImage::BigEndian )
+ {
+ if (((*b >> (7 - (x & 7))) & 1) == 1)
+ board->set(index, brick);
+ } else {
+ if (((*b >> (x & 7)) & 1) == 1)
+ board->set(index, brick);
+ }
+ if ( (x & 7) == 7 )
+ b++;
+ index++;
+ }
+ index += 28;
+ }
+}
+
diff --git a/ksnake/level.h b/ksnake/level.h
new file mode 100644
index 00000000..51c86dc6
--- /dev/null
+++ b/ksnake/level.h
@@ -0,0 +1,55 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LEVEL_H
+#define LEVEL_H
+
+class Board;
+
+enum Img {Banner, Room, Intro, GameOver};
+
+class Level {
+
+public:
+ Level (Board *);
+ void nextLevel();
+ void setLevel(int level) { this->level = level; }
+ int getLevel() const { return level; }
+ void create(Img boardType);
+
+private:
+ Board *board;
+ QImage makeImage(char *);
+ void makeImageFromData(const uchar *buf);
+ void drawNumber(int beginAt, const uchar *buf);
+ void initBoard(const QImage &image);
+ void createRoom();
+ void createBanner();
+
+ // Can level be negative?
+ int level;
+};
+
+#endif // LEVEL_H
diff --git a/ksnake/levels.cpp b/ksnake/levels.cpp
new file mode 100644
index 00000000..c58aa895
--- /dev/null
+++ b/ksnake/levels.cpp
@@ -0,0 +1,58 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qimage.h>
+#include <qbitmap.h>
+
+#include <kstandarddirs.h>
+
+#include "levels.h"
+
+Levels *leV = 0;
+
+Levels::Levels()
+{
+ leV = this;
+ list = KGlobal::dirs()->findAllResources("appdata", "levels/*");
+ list.prepend( "dummy" );
+}
+
+int Levels::max()
+{
+ return ( list.count() -1 );
+}
+
+QImage Levels::getImage(int at)
+{
+ QBitmap bitmap(*list.at(at));
+ QImage image = bitmap.convertToImage();
+ return image;
+}
+
+QPixmap Levels::getPixmap(int at)
+{
+ return QPixmap(*list.at(at));
+}
+
diff --git a/ksnake/levels.h b/ksnake/levels.h
new file mode 100644
index 00000000..e40f5602
--- /dev/null
+++ b/ksnake/levels.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LEVELS_H
+#define LEVELS_H
+
+class Levels
+{
+public:
+ Levels ();
+ QImage getImage(int);
+ QPixmap getPixmap(int);
+ int max();
+
+private:
+ QStringList list;
+
+};
+
+extern Levels *leV;
+
+#endif // LEVELS_H
+
diff --git a/ksnake/main.cpp b/ksnake/main.cpp
new file mode 100644
index 00000000..0ff21c66
--- /dev/null
+++ b/ksnake/main.cpp
@@ -0,0 +1,54 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "game.h"
+#include "version.h"
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+
+static const char description[] = I18N_NOOP("KDE Snake Race Game");
+
+int main( int argc, char **argv )
+{
+ KAboutData aboutData( "ksnake", I18N_NOOP("KSnakeRace"),
+ KSNAKE_VERSION, description, KAboutData::License_GPL,
+ I18N_NOOP("(c) 1997-2000, Your Friendly KSnake Developers"));
+ aboutData.addAuthor("Michel Filippi",0, "mfilippi@sade.rhein-main.de");
+ aboutData.addAuthor("Robert Williams");
+ aboutData.addAuthor("Andrew Chant",0, "andrew.chant@utoronto.ca");
+ aboutData.addCredit("André Luiz dos Santos", I18N_NOOP("AI stuff"), "andre@netvision.com.br");
+ aboutData.addCredit("Benjamin Meyer", I18N_NOOP("Improvements"), "ben+ksnake@meyerhome.net");
+ KCmdLineArgs::init( argc, argv, &aboutData );
+
+ KApplication app;
+ KGlobal::locale()->insertCatalogue("libkdegames");
+
+ Game *ksnake = new Game();
+ app.setMainWidget( ksnake );
+ ksnake->show();
+ return app.exec();
+}
+
diff --git a/ksnake/pixServer.cpp b/ksnake/pixServer.cpp
new file mode 100644
index 00000000..bdc281ea
--- /dev/null
+++ b/ksnake/pixServer.cpp
@@ -0,0 +1,245 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "pixServer.h"
+
+#include <qimage.h>
+#include <qpainter.h>
+#include <qbitmap.h>
+
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+#include "board.h"
+#include "settings.h"
+
+PixServer::PixServer( Board *b)
+{
+ board = b;
+ initPixmaps();
+ initBrickPixmap();
+ initbackPixmaps();
+ initRoomPixmap();
+}
+
+void PixServer::erase(int pos)
+{
+ if (!board->isEmpty(pos))
+ return;
+
+ QRect rect = board->rect(pos);
+ bitBlt( &cachePix, rect.x(), rect.y(), &backPix,
+ rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+void PixServer::restore(int pos)
+{
+ QRect rect = board->rect(pos);
+ bitBlt( &cachePix, rect.x(), rect.y(), &roomPix,
+ rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+void PixServer::draw(int pos, PixMap pix, int i)
+{
+ QPixmap p;
+ p.resize(BRICKSIZE, BRICKSIZE);
+
+ QRect rect = board->rect(pos);
+
+ if (! plainColor)
+ bitBlt( &p, 0, 0, &backPix,
+ rect.x(), rect.y(), rect.width(), rect.height());
+ else
+ p.fill(backgroundColor);
+
+ switch (pix) {
+ case SamyPix: bitBlt(&p ,0,0, &samyPix[i]);
+ break;
+ case CompuSnakePix: bitBlt(&p ,0,0, &compuSnakePix[i]);
+ break;
+ case ApplePix: bitBlt(&p ,0,0, &applePix[i]);
+ break;
+ case BallPix: bitBlt(&p ,0,0, &ballPix[i]);
+ break;
+ default:
+ break;
+ }
+
+ bitBlt(&cachePix, rect.x(), rect.y(), &p);
+}
+
+void PixServer::initPixmaps()
+{
+
+ QPixmap pm = QPixmap(locate("appdata", "pics/snake1.png"));
+ QImage qi = pm.convertToImage();
+ qi=qi.smoothScale(BRICKSIZE*18,BRICKSIZE);
+ pm.convertFromImage(qi,QPixmap::AvoidDither);
+ for (int x = 0 ; x < 18; x++){
+ compuSnakePix[x].resize(BRICKSIZE, BRICKSIZE);
+ bitBlt(&compuSnakePix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, true);
+ compuSnakePix[x].setMask(compuSnakePix[x].createHeuristicMask());
+ }
+
+ pm = QPixmap(locate("appdata", "pics/snake2.png"));
+ qi = pm.convertToImage();
+ qi=qi.smoothScale(BRICKSIZE*18,BRICKSIZE);
+ pm.convertFromImage(qi,QPixmap::AvoidDither);
+ for (int x = 0 ; x < 18; x++){
+ samyPix[x].resize(BRICKSIZE, BRICKSIZE);
+ bitBlt(&samyPix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, true);
+ samyPix[x].setMask(samyPix[x].createHeuristicMask());
+ }
+
+ pm = QPixmap(locate("appdata", "pics/ball.png"));
+ qi = pm.convertToImage();
+ qi=qi.smoothScale(BRICKSIZE*4,BRICKSIZE);
+ pm.convertFromImage(qi,QPixmap::AvoidDither);
+ for (int x = 0 ; x < 4; x++){
+ ballPix[x].resize(BRICKSIZE, BRICKSIZE);
+ bitBlt(&ballPix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, true);
+ ballPix[x].setMask(ballPix[x].createHeuristicMask());
+ }
+
+ pm = QPixmap(locate("appdata", "pics/apples.png"));
+ qi = pm.convertToImage();
+ qi=qi.smoothScale(BRICKSIZE*2,BRICKSIZE);
+ pm.convertFromImage(qi,QPixmap::AvoidDither);
+ for (int x = 0 ; x < 2; x++){
+ applePix[x].resize(BRICKSIZE, BRICKSIZE);
+ bitBlt(&applePix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, true);
+ applePix[x].setMask(applePix[x].createHeuristicMask());
+ }
+}
+
+void PixServer::initbackPixmaps()
+{
+ QString path;
+ plainColor = false;
+
+ if(Settings::bgcolor_enabled()){
+ backgroundColor = Settings::bgcolor();
+ plainColor = true;
+ } else if(Settings::bgimage_enabled()) {
+ // A bit of a hack.
+ QStringList backgroundPixmaps =
+ KGlobal::dirs()->findAllResources("appdata", "backgrounds/*.png");
+ path = backgroundPixmaps[(Settings::bgimage())];
+ }
+
+ QPixmap PIXMAP;
+ int pw, ph;
+
+ backPix.resize(MAPWIDTH, MAPHEIGHT);
+
+ if (! plainColor) {
+
+ PIXMAP = QPixmap(path);
+
+ if (!PIXMAP.isNull()) {
+ pw = PIXMAP.width();
+ ph = PIXMAP.height();
+
+ for (int x = 0; x <= MAPWIDTH; x+=pw) //Tile BG Pixmap onto backPix
+ for (int y = 0; y <= MAPHEIGHT; y+=ph)
+ bitBlt(&backPix, x, y, &PIXMAP);
+ }
+ else {
+ kdDebug() << "error loading background image :" << path << endl;
+ backgroundColor = (QColor("black"));
+ plainColor = true;
+ }
+ }
+ if ( plainColor)
+ backPix.fill(backgroundColor);
+}
+
+void PixServer::initBrickPixmap()
+{
+ QPixmap pm = QPixmap(locate("appdata", "pics/brick.png"));
+ if (pm.isNull()) {
+ kdFatal() << i18n("error loading %1, aborting\n").arg("brick.png");
+ }
+ int pw = pm.width();
+ int ph = pm.height();
+
+ offPix.resize(MAPWIDTH, MAPHEIGHT);
+ for (int x = 0; x <= MAPWIDTH; x+=pw)
+ for (int y = 0; y <= MAPHEIGHT; y+=ph)
+ bitBlt(&offPix, x, y, &pm);
+}
+
+void PixServer::initRoomPixmap()
+{
+ QPainter paint;
+
+ roomPix.resize(MAPWIDTH, MAPHEIGHT);
+ bitBlt(&roomPix,0,0, &backPix);
+ paint.begin(&roomPix);
+
+ for (unsigned int x = 0; x < board->size(); x++) {
+ if (board->isBrick(x))
+ drawBrick(&paint, x);
+ }
+ paint.end();
+
+ cachePix.resize(MAPWIDTH, MAPHEIGHT);
+ bitBlt(&cachePix,0,0, &roomPix);
+}
+
+void PixServer::drawBrick(QPainter *p ,int i)
+{
+ //Note, ROOMPIC IS OUR 'TARGET'
+ QColor light(180,180,180);
+ QColor dark(100,100,100);
+
+ int topSq = board->getNext(N, i); //find 'address' of neighbouring squares
+ int botSq = board->getNext(S, i);
+ int rightSq = board->getNext(E ,i);
+ int leftSq = board->getNext(W, i);
+
+ QRect rect = board->rect(i); //get our square's rect
+
+ int x = rect.x();
+ int y = rect.y(); //Get x,y location of square???
+
+ int width, height;
+
+ int highlight = 2; //Highlighting Distance (pixels)?
+
+ width = height = rect.width();
+
+ p->fillRect(x, y, width, height, light); //By default, fill square w/ Light? no. use dark!!!!
+
+ bitBlt(&roomPix, x, y, &offPix, x, y, width, height ); //Copy the brick pattern onto the brick
+
+ if (!board->isBrick(rightSq)) p->fillRect(x + width - highlight, y, highlight, height, dark); //highlight if its an end-brick.
+ if (!board->isBrick(leftSq)) p->fillRect(x, y, highlight, height, light);
+ if (!board->isBrick(botSq)) p->fillRect(x, y + height - highlight, width, highlight, dark);
+ if (!board->isBrick(topSq)) p->fillRect(x, y, width, highlight, light);
+
+}
+
diff --git a/ksnake/pixServer.h b/ksnake/pixServer.h
new file mode 100644
index 00000000..783f7efa
--- /dev/null
+++ b/ksnake/pixServer.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PIXSERVER_H
+#define PIXSERVER_H
+
+#include <qpixmap.h>
+
+class Board;
+enum SnakePix {TailUp, TailDown, TailRight, TailLeft,
+ HeadUp, HeadDown, HeadRight, HeadLeft,
+ AngleSw, AngleSe, AngleNw, AngleNe,
+ BodyHz, BodyVt,
+ HtailUp, HtailDown, HtailRight, HtailLeft };
+enum PixMap { SamyPix, CompuSnakePix, ApplePix, BallPix };
+enum Image {Snake, ComputerSnake};
+
+class PixServer
+{
+public:
+ PixServer (Board *);
+ QPixmap levelPix() const { return cachePix; }
+
+ void initRoomPixmap();
+ void initBrickPixmap();
+ void initPixmaps();
+ void initbackPixmaps();
+
+ void draw(int pos, PixMap pix, int i = 0);
+ void erase(int pos);
+ void restore(int pos);
+
+private:
+ Board *board;
+
+ void drawBrick(QPainter *, int);
+
+ QPixmap samyPix[18];
+ QPixmap compuSnakePix[18];
+ QPixmap ballPix[4];
+ QPixmap applePix[2];
+
+ QPixmap roomPix;
+ QPixmap cachePix;
+ QPixmap offPix;
+ QPixmap backPix;
+
+ bool plainColor;
+ QColor backgroundColor;
+
+};
+
+#endif // PIXSERVER_H
+
diff --git a/ksnake/progress.cpp b/ksnake/progress.cpp
new file mode 100644
index 00000000..d6d88823
--- /dev/null
+++ b/ksnake/progress.cpp
@@ -0,0 +1,54 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "progress.h"
+
+Progress::Progress(QWidget *parent, const char *name)
+ : KGameProgress(0, 300, 300, KGameProgress::Horizontal, parent, name)
+{
+ setBarColor("green1");
+ setTextEnabled(false);
+}
+
+void Progress::advance()
+{
+ if (value() == 0) {
+ emit restart();
+ return;
+ }
+
+ if (value() == 80)
+ setBarColor("red1");
+
+ KGameProgress::advance(-1);
+}
+
+void Progress::rewind()
+{
+ setBarColor("green1");
+ KGameProgress::setValue(300);
+}
+
+#include "progress.moc"
diff --git a/ksnake/progress.h b/ksnake/progress.h
new file mode 100644
index 00000000..4b902f26
--- /dev/null
+++ b/ksnake/progress.h
@@ -0,0 +1,47 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PROGRESS_H
+#define PROGRESS_H
+
+#include <kgameprogress.h>
+
+class Progress : public KGameProgress
+{
+ Q_OBJECT
+public:
+ Progress( QWidget *parent=0, const char *name=0 );
+
+public slots:
+ void advance();
+ void rewind();
+
+signals:
+ void restart();
+
+};
+
+#endif // PROGRESS_H
+
diff --git a/ksnake/rattler.cpp b/ksnake/rattler.cpp
new file mode 100644
index 00000000..8bea1c0c
--- /dev/null
+++ b/ksnake/rattler.cpp
@@ -0,0 +1,692 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "rattler.h"
+
+#include <qtimer.h>
+#include <qlabel.h>
+#include <kapplication.h>
+#include <kstdgameaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <qbitarray.h>
+#include <kstandarddirs.h>
+
+#include "level.h"
+#include "basket.h"
+#include "settings.h"
+
+QBitArray gameState(5);
+QLabel *label = 0;
+int speed[4] = { 130, 95, 55, 40 };
+
+Rattler::Rattler( QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ setFocusPolicy(QWidget::StrongFocus);
+
+ numBalls = Settings::balls();
+ ballsAI = Settings::ballsAI();
+ numSnakes = Settings::computerSnakes();
+ snakesAI = Settings::snakesAI();
+ skill = Settings::skill();
+ room = Settings::startingRoom();
+
+ board = new Board(35*35);
+ level = new Level(board);
+ pix = new PixServer(board);
+ basket = new Basket(board, pix);
+ samy = new SamySnake(board, pix);
+
+ computerSnakes = new QPtrList<CompuSnake>;
+ computerSnakes->setAutoDelete( true );
+
+ balls = new QPtrList<Ball>;
+ balls->setAutoDelete( true );
+
+ connect( samy, SIGNAL(closeGate(int)), this, SLOT(closeGate(int)));
+ connect( samy, SIGNAL(score(bool, int)), this, SLOT(scoring(bool,int)));
+ connect( samy, SIGNAL(goingOut()), this, SLOT(speedUp()));
+ connect( basket, SIGNAL(openGate()), this, SLOT(openGate()));
+
+ gameState.fill(false);
+ gameState.setBit(Demo);
+
+ timerCount = 0;
+ QTimer::singleShot( 2000, this, SLOT(demo()) ); // Why wait?
+
+ backgroundPixmaps =
+ KGlobal::dirs()->findAllResources("appdata", "backgrounds/*.png");
+}
+
+Rattler::~Rattler()
+{
+ delete level;
+ delete balls;
+ delete computerSnakes;
+ delete basket;
+ delete samy;
+ delete pix;
+ delete board;
+}
+
+/**
+ * One of the settings changed, load our settings
+ */
+void Rattler::loadSettings(){
+ setBalls(Settings::balls());
+ setBallsAI(Settings::ballsAI());
+ setCompuSnakes(Settings::computerSnakes());
+ setSnakesAI(Settings::snakesAI());
+ setSkill(Settings::skill());
+ setRoom(Settings::startingRoom());
+ reloadRoomPixmap();
+}
+
+void Rattler::paintEvent( QPaintEvent *e)
+{
+ QRect rect = e->rect();
+
+ if (rect.isEmpty())
+ return;
+ QPixmap levelPix = pix->levelPix();
+
+ basket->repaint(true);
+
+ bitBlt(this, rect.x(), rect.y(),
+ &levelPix, rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+void Rattler::timerEvent( QTimerEvent * )
+{
+ timerCount++;
+
+ if ( !leaving ) // advance progressBar unless Samy
+ emit advance(); // is going out
+
+ for (CompuSnake *c = computerSnakes->first(); c != 0; c = computerSnakes->next()){
+ if(c) {
+ c->nextMove();
+ c->repaint(false);
+ }
+ }
+
+ for (Ball *b = balls->first(); b != 0; b = balls->next()){
+ if (b) {
+ b->nextMove();
+ b->repaint();
+ }
+ }
+
+
+ samyState state = ok;
+
+ if(!gameState.testBit(Demo))
+ {
+ state = samy->nextMove(direction);
+ samy->repaint( false );
+ }
+
+ basket->repaint( false);
+
+ if (state == ko)
+ newTry();
+ else if (state == out)
+ levelUp();
+
+ QPixmap levelPix = pix->levelPix();
+ bitBlt(this, 0, 0, &levelPix, 0, 0, rect().width(), rect().height());
+}
+
+void Rattler::keyPressEvent( QKeyEvent *k )
+{
+ if (gameState.testBit(Paused))
+ return;
+
+ KKey key(k);
+ if(actionCollection->action("Pl1Up")->shortcut().contains(key))
+ direction = N;
+ else if(actionCollection->action("Pl1Down")->shortcut().contains(key))
+ direction = S;
+ else if(actionCollection->action("Pl1Right")->shortcut().contains(key))
+ direction = E;
+ else if(actionCollection->action("Pl1Left")->shortcut().contains(key))
+ direction = W;
+ else if ((k->key() == Key_Return) ||
+ (k->key() == Key_Enter) || (k->key() == Key_Space)) {
+ if (!gameState.testBit(Demo)) {
+ k->ignore();
+ return;
+ }
+ restart();
+ }
+ else {
+ k->ignore();
+ return;
+ }
+ k->accept();
+}
+
+void Rattler::mousePressEvent( QMouseEvent *e )
+{
+ if (gameState.testBit(Paused))
+ return;
+
+ uint button = e->button();
+ if (button == Qt::RightButton)
+ {
+ switch (direction)
+ {
+ case N: direction=E;
+ break;
+ case E: direction=S;
+ break;
+ case S: direction=W;
+ break;
+ case W: direction=N;
+ break;
+ }
+ e->accept();
+ }
+ else if (button == Qt::LeftButton)
+ {
+ switch (direction)
+ {
+ case N: direction=W;
+ break;
+ case E: direction=N;
+ break;
+ case S: direction=E;
+ break;
+ case W: direction=S;
+ break;
+ }
+ e->accept();
+ }
+ else
+ e->ignore();
+}
+
+void Rattler::closeGate(int i)
+{
+ board->set(i, brick);
+ pix->restore(i);
+}
+
+void Rattler::openGate()
+{
+ board->set(NORTH_GATE, empty);
+ pix->erase(NORTH_GATE);
+}
+
+void Rattler::scoring(bool win, int i)
+{
+ Fruits fruit = basket->eaten(i);
+
+ if (gameState.testBit(Demo))
+ win = true;
+
+ int p = 0;
+
+ switch (fruit) {
+
+ case Red:
+ if (win) {
+ if (!timerHasRunOut)
+ p = 1 + skill*2;
+ else p = 1;
+ }
+ else p = -2;
+ break;
+
+ case Golden:
+ if (win) {
+ if (!timerHasRunOut)
+ p = 2 + (skill*2) + (numSnakes*2) + (numBalls+2);
+ else p = 2;
+ }
+ else p = -5;
+ break;
+
+ default:
+ break;
+
+ }
+ score(p);
+}
+
+void Rattler::score(int p)
+{
+ points += p;
+ points = (points < 0 ? 0 : points);
+ emit setPoints(points);
+
+ while (points > check*50) {
+ check++;
+ if (trys < 7 && !gameState.testBit(Demo))
+ emit setTrys(++trys);
+ }
+}
+
+void Rattler::killedComputerSnake()
+{
+ if (!gameState.testBit(Demo))
+ score(20);
+}
+
+void Rattler::pause()
+{
+ if (gameState.testBit(Init))
+ return;
+
+ if (gameState.testBit(Playing)) {
+
+ gameState.toggleBit(Playing);
+ gameState.setBit(Paused);
+ stop();
+
+ KAction* tempPauseAction = KStdGameAction::pause();
+
+ label = new QLabel(this);
+ label->setFont( QFont( "Times", 14, QFont::Bold ) );
+ label->setText(i18n("Game Paused\n Press %1 to resume\n")
+ .arg(tempPauseAction->shortcutText()));
+ label->setAlignment( AlignCenter );
+ label->setFrameStyle( QFrame::Panel | QFrame::Raised );
+ label->setGeometry(182, 206, 198, 80);
+ label->show();
+
+ delete tempPauseAction;
+ //emit togglePaused();
+ }
+ else if (gameState.testBit(Paused)) {
+ gameState.toggleBit(Paused);
+ gameState.setBit(Playing);
+ start();
+ cleanLabel();
+ //emit togglePaused();
+ }
+}
+
+void Rattler::cleanLabel()
+{
+ if (label) {
+ delete label;
+ label = 0;
+ }
+}
+
+void Rattler::restartDemo()
+{
+ if (!gameState.testBit(Demo))
+ return;
+
+ int r = 50000+ (kapp->random() % 30000);
+ QTimer::singleShot( r, this, SLOT(restartDemo()) );
+
+ stop();
+ level->create(Intro);
+ pix->initRoomPixmap();
+ init(false);
+ repaint();
+ start();
+}
+
+void Rattler::demo()
+{
+ static bool first_time = true;
+
+ if(gameState.testBit(Init) || gameState.testBit(Playing))
+ return;
+
+ stop();
+
+ QTimer::singleShot( 60000, this, SLOT(restartDemo()) );
+ gameState.fill(false);
+ gameState.setBit(Init);
+ gameState.setBit(Demo);
+ resetFlags();
+
+ if(!first_time) {
+ level->create(Intro);
+ pix->initRoomPixmap();
+ }
+ repaint(rect(), false);
+ init(false);
+ run();
+ first_time = false;
+}
+
+void Rattler::restart()
+{
+ if (gameState.testBit(Init))
+ return;
+ stop();
+
+ if (gameState.testBit(Paused) || gameState.testBit(Playing)) {
+
+ switch( KMessageBox::questionYesNo( this,
+ i18n("A game is already started.\n"
+ "Start a new one?\n"), i18n("Snake Race"), i18n("Start New"), i18n("Keep Playing"))) {
+ case KMessageBox::No:
+ if (!gameState.testBit(Paused))
+ start();
+ return;
+ break;
+ case KMessageBox::Yes:
+ ;
+ }
+ }
+
+ gameState.fill(false);
+ gameState.setBit(Init);
+ gameState.setBit(Playing);
+
+ resetFlags();
+
+ level->setLevel(room);
+ level->create(Banner);
+ pix->initRoomPixmap();
+
+ cleanLabel();
+
+ repaint();
+ QTimer::singleShot( 2000, this, SLOT(showRoom()) );
+}
+
+void Rattler::newTry()
+{
+ stop();
+
+ if(trys==0) {
+ gameState.fill(false);
+ gameState.setBit(Over);
+ level->create(GameOver);
+ pix->initRoomPixmap();
+ repaint();
+ QTimer::singleShot( 5000, this, SLOT(demo()) );
+ emit setScore(points);
+ return;
+ }
+ --trys;
+ gameState.fill(false);
+ gameState.setBit(Init);
+ gameState.setBit(Playing);
+
+ level->create(Room);
+ pix->initRoomPixmap();
+ init(true);
+ repaint();
+ QTimer::singleShot( 1000, this, SLOT(run()) );
+}
+
+void Rattler::levelUp()
+{
+ stop();
+
+ gameState.fill(false);
+ gameState.setBit(Init);
+ gameState.setBit(Playing);
+
+ score (2*(level->getLevel())+(2*numSnakes)+(2*numBalls)+(2*skill));
+
+ level->nextLevel();
+ level->create(Banner);
+ pix->initRoomPixmap();
+ repaint();
+
+ QTimer::singleShot( 2000, this, SLOT(showRoom()) );
+}
+
+/* this slot is called by the progressBar when value() == 0
+or by a compuSnake wich manages to exit */
+void Rattler::restartTimer()
+{
+ timerHasRunOut = true;
+ timerCount = 0;
+ emit rewind();
+
+ if ( board->isEmpty(NORTH_GATE) )
+ closeGate(NORTH_GATE);
+ basket->newApples();
+}
+
+void Rattler::speedUp()
+{
+ leaving = true;
+ stop();
+ start( 30 );
+}
+
+void Rattler::resetFlags()
+{
+ trys = 2;
+ check = 1;
+ points = 0;
+}
+
+void Rattler::showRoom()
+{
+ level->create(Room);
+ pix->initRoomPixmap();
+ init(true);
+ repaint();
+ QTimer::singleShot( 1000, this, SLOT(run()) );
+}
+
+void Rattler::init(bool play)
+{
+ leaving = false;
+ timerHasRunOut = false;
+ timerCount = 0;
+ emit rewind();
+
+ emit setTrys(trys);
+ emit setPoints(points);
+
+ basket->clear();
+ basket->newApples();
+ restartBalls(play);
+ restartComputerSnakes(play);
+ if(play)
+ samy->init();
+}
+
+void Rattler::run()
+{
+ direction = N;
+ gameState.toggleBit(Init);
+ start();
+}
+
+void Rattler::start()
+{
+ gameTimer = startTimer( speed [skill] );
+}
+
+void Rattler::start(int t)
+{
+ gameTimer = startTimer(t);
+}
+
+void Rattler::stop()
+{
+ killTimers();
+}
+
+void Rattler::restartComputerSnakes(bool play)
+{
+ if( !computerSnakes->isEmpty())
+ computerSnakes->clear();
+
+ int i = (play == false && numSnakes == 0 ? 1 : numSnakes);
+
+ for (int x = 0; x < i; x++) {
+ CompuSnake *as;
+ switch(snakesAI) {
+ default: // random.
+ as = new CompuSnake(board, pix);
+ break;
+ case 1: // eater.
+ as = new EaterCompuSnake(board, pix);
+ break;
+ case 2: // killer.
+ as = new KillerCompuSnake(board, pix);
+ break;
+ }
+ connect( as, SIGNAL(closeGate(int)), this, SLOT(closeGate(int)));
+ connect( as, SIGNAL(restartTimer()), this, SLOT(restartTimer()));
+ connect( as, SIGNAL(score(bool, int)), this, SLOT(scoring(bool,int)));
+ connect( as, SIGNAL(killed()), this, SLOT(killedComputerSnake()));
+ computerSnakes->append(as);
+ }
+}
+
+void Rattler::restartBalls(bool play)
+{
+ if( !balls->isEmpty())
+ balls->clear();
+
+ int i = (play == false && numBalls == 0 ? 1 : numBalls);
+
+ for (int x = 0; x < i; x++) {
+ Ball *b;
+ switch(ballsAI) {
+ default: // default.
+ b = new Ball(board, pix);
+ break;
+ case 1: // dumb.
+ b = new DumbKillerBall(board, pix);
+ break;
+ case 2: // smart.
+ b = new KillerBall(board, pix);
+ break;
+ }
+ balls->append(b);
+ }
+}
+
+void Rattler::setBalls(int newNumBalls)
+{
+ numBalls = balls->count();
+
+ if (!(gameState.testBit(Playing) || gameState.testBit(Demo)) || numBalls == newNumBalls)
+ return;
+
+ while ( newNumBalls > numBalls) {
+ Ball *b = new Ball(board, pix);
+ balls->append(b);
+ numBalls++;
+ }
+ while (newNumBalls < numBalls) {
+ Ball *b = balls->getLast();
+ b->zero();
+ balls->removeLast();
+ numBalls--;
+ }
+}
+
+void Rattler::setBallsAI(int i)
+{
+ ballsAI = i;
+}
+
+void Rattler::resizeEvent( QResizeEvent * )
+{
+ pix->initPixmaps();
+ pix->initBrickPixmap();
+ pix->initbackPixmaps();
+ pix->initRoomPixmap();
+}
+
+void Rattler::setCompuSnakes(int i)
+{
+ CompuSnake *cs;
+ numSnakes = i;
+ int count = computerSnakes->count();
+
+ if (gameState.testBit(Playing) || gameState.testBit(Demo)) {
+ if ( i > count) {
+ while ( i > count) {
+ CompuSnake *as;
+ switch(snakesAI) {
+ default: // random.
+ as = new CompuSnake(board, pix);
+ break;
+ case 1: // eater.
+ as = new EaterCompuSnake(board, pix);
+ break;
+ case 2: // killer.
+ as = new KillerCompuSnake(board, pix);
+ break;
+ }
+ connect( as, SIGNAL(closeGate(int)), this, SLOT(closeGate(int)));
+ connect( as, SIGNAL(restartTimer()), this, SLOT(restartTimer()));
+ connect( as, SIGNAL(score(bool, int)), this, SLOT(scoring(bool,int)));
+ connect( as, SIGNAL(killed()), this, SLOT(killedComputerSnake()));
+ computerSnakes->append(as);
+ i--;
+ }
+ }
+ else if (i < count) {
+ while (i < count) {
+ cs = computerSnakes->getLast();
+ cs->zero();
+ computerSnakes->removeLast();
+ i++;
+ }
+ }
+ }
+}
+
+void Rattler::setSnakesAI(int i)
+{
+ snakesAI = i;
+}
+
+void Rattler::setSkill(int i)
+{
+ skill = i;
+ if (gameState.testBit(Playing) || gameState.testBit(Demo)) {
+ stop();
+ start();
+ }
+}
+
+void Rattler::setRoom(int i)
+{
+ room = i;
+}
+
+void Rattler::reloadRoomPixmap()
+{
+ pix->initbackPixmaps();
+ pix->initRoomPixmap();
+ demo();
+}
+
+#include "rattler.moc"
+
diff --git a/ksnake/rattler.h b/ksnake/rattler.h
new file mode 100644
index 00000000..2922dfe6
--- /dev/null
+++ b/ksnake/rattler.h
@@ -0,0 +1,155 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef RATTLER_H
+#define RATTLER_H
+
+#include <qwidget.h>
+#include <kaction.h>
+#include "ball.h"
+#include "snake.h"
+
+class Board;
+class PixServer;
+class Level;
+class Basket;
+class SamySnake;
+
+
+enum { Init, Playing, Demo, Paused, Over };
+
+class Rattler : public QWidget
+{
+ Q_OBJECT
+
+public:
+ Rattler ( QWidget *parent=0, const char *name=0 );
+ ~Rattler();
+ void setActionCollection(KActionCollection *a){ actionCollection = a;}
+
+
+ void setBalls(int);
+ void setBallsAI(int);
+ void setCompuSnakes(int);
+ void setSnakesAI(int);
+ void setSkill(int);
+ void setRoom(int);
+
+ void reloadRoomPixmap();
+
+ QStringList backgroundPixmaps;
+
+public slots:
+ void closeGate(int);
+ void openGate();
+ void loadSettings();
+
+ void scoring(bool, int);
+
+ void restart();
+ void newTry();
+ void levelUp();
+
+ void pause();
+ void restartTimer();
+
+ void speedUp();
+
+ void run();
+ void demo();
+
+ void killedComputerSnake();
+
+private slots:
+ void start();
+ void stop();
+ void showRoom();
+ void restartDemo();
+
+signals:
+ void setPoints(int);
+ void setTrys(int);
+
+ void setScore(int);
+ // Is this used? Maybe remove?
+ void togglePaused();
+
+ // progress
+ void rewind();
+ void advance();
+
+protected:
+ void timerEvent( QTimerEvent * );
+ void paintEvent( QPaintEvent * );
+ void keyPressEvent( QKeyEvent * );
+ void mousePressEvent( QMouseEvent * );
+ void focusOutEvent( QFocusEvent * ) { ; }
+ void focusInEvent( QFocusEvent * ) { ; }
+ KActionCollection *actionCollection;
+
+private:
+ Board *board;
+ PixServer *pix;
+ Level *level;
+ Basket *basket;
+ SamySnake *samy;
+
+ int timerCount;
+ bool leaving;
+
+ int check;
+ int points;
+ int trys;
+
+ int direction;
+
+ QPtrList<Ball> *balls;
+ void restartBalls(bool);
+ int numBalls;
+ int ballsAI;
+
+ QPtrList<CompuSnake> *computerSnakes;
+ void restartComputerSnakes(bool);
+ int numSnakes;
+ int snakesAI;
+
+ int room;
+ int skill;
+
+ int gameTimer;
+ bool timerHasRunOut;
+ void start(int);
+ void resetFlags();
+ void init(bool);
+
+ void score(int);
+ void cleanLabel();
+
+ void resizeEvent( QResizeEvent * );
+};
+
+
+#endif // RATTLER_H
+
diff --git a/ksnake/settings.kcfgc b/ksnake/settings.kcfgc
new file mode 100644
index 00000000..cf8ee5e6
--- /dev/null
+++ b/ksnake/settings.kcfgc
@@ -0,0 +1,5 @@
+# Code generation options for kconfig_compiler
+File=ksnake.kcfg
+ClassName=Settings
+Singleton=true
+Mutators=false
diff --git a/ksnake/snake.cpp b/ksnake/snake.cpp
new file mode 100644
index 00000000..33b3f027
--- /dev/null
+++ b/ksnake/snake.cpp
@@ -0,0 +1,557 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qwidget.h>
+
+#include "snake.h"
+
+int opposite[4] = { S, N , W, E };
+
+int emptySq[4][4]={
+ { N, E, W, N },
+ { S, W, E, S },
+ { E, N, S, E },
+ { W, S, N, W }
+};
+
+Snake::Snake(Board *b, PixServer *p, Gate g, PixMap x)
+{
+ list.setAutoDelete( true );
+ pixServer = p;
+ board = b;
+ gate = g;
+ pixmap = x;
+ random.setSeed(0);
+}
+
+void Snake::updateSamy()
+{
+ int x = tail();
+ while ( x > 0) {
+ *list.at(x) = *list.at(x-1);
+ --x;
+ }
+}
+
+void Snake::zero()
+{
+ for ( Samy *sam = list.first(); sam != 0; sam = list.next() ) {
+ board->set(sam->index, empty);
+ pixServer->erase(sam->index);
+ }
+}
+
+void Snake::appendSamy()
+{
+ Samy *sam = new Samy;
+ list.append(sam);
+
+ updateSamy();
+ grow--;
+}
+
+void Snake::reset(int index, int border)
+{
+ Samy *sam = list.first();
+
+ switch (border) {
+ case N:
+ sam->pixmap = (tail() == 0 ? HtailUp : HeadUp);
+ break;
+ case S:
+ sam->pixmap = (tail() == 0 ? HtailDown : HeadDown);
+ break;
+ case E:
+ sam->pixmap = (tail() == 0 ? HtailRight : HeadRight);
+ break;
+ case W:
+ sam->pixmap = (tail() == 0 ? HtailLeft : HeadLeft);
+ break;
+ }
+
+ sam->index = index;
+ sam->direction = border;
+
+ if (tail() > 1) {
+
+ sam = list.next();
+
+ if (sam->direction == border) {
+ if (border == N || border == S)
+ sam->pixmap = BodyVt;
+ else
+ sam->pixmap = BodyHz;
+ }
+ else {
+ if (border == W && sam->direction == S
+ || border == N && sam->direction == E)
+ sam->pixmap = AngleNw;
+ if (border == E && sam->direction == S
+ || border == N && sam->direction == W)
+ sam->pixmap = AngleNe;
+ if(border == W && sam->direction == N
+ || border == S && sam->direction == E)
+ sam->pixmap = AngleSw;
+ if(border == E && sam->direction == N
+ || border == S && sam->direction == W)
+ sam->pixmap = AngleSe;
+ }
+
+
+ } //end if (tail() > 1)
+
+ if (tail() > 0) {
+
+ sam = list.last();
+
+ switch (list.at(tail()-1)->direction) {
+ case N:
+ sam->pixmap = TailUp;
+ break;
+ case S:
+ sam->pixmap = TailDown;
+ break;
+ case E:
+ sam->pixmap = TailRight;
+ break;
+ case W:
+ sam->pixmap = TailLeft;
+ break;
+ }
+ }
+}
+
+void Snake::repaint( bool dirty)
+{
+ int x = 0;
+ for ( Samy *sam = list.first(); sam != 0; sam = list.next(), x++) {
+ if (sam->index != OUT ) {
+ if(!dirty && x > 1 && x < tail())
+ continue;
+ pixServer->draw(sam->index, pixmap, sam->pixmap);
+ }
+ }
+ if (!growing() && hold != OUT && hold != gate) {
+ pixServer->erase(hold);
+ }
+}
+
+
+CompuSnake::CompuSnake( Board *b, PixServer *p)
+ : Snake( b, p, NORTH_GATE, CompuSnakePix )
+{
+ init();
+}
+
+bool CompuSnake::init()
+{
+ if( !list.isEmpty()) {
+ list.clear();
+ }
+
+ int index = NORTH_GATE;
+ int length = 12;
+ grow = 0;
+ hold = OUT;
+
+ if ( !board->isBrick(gate) ) return false;
+
+ Samy *sam;
+ for ( int x = 0; x < length; x++) {
+ board->set(index, snake);
+ sam = new Samy;
+ sam->direction = S;
+ sam->index = index;
+ sam->pixmap = (x == 0 ? HeadDown : BodyVt);
+ list.append(sam);
+ index = -1;
+ }
+ return true;
+}
+
+bool CompuSnake::permission()
+{
+ if( list.isEmpty() ){
+
+ if ( hold != OUT) {
+ emit killed();
+ hold = OUT;
+ }
+
+ if(board->isBrick(gate)){
+ static int skip = 12;
+ if (skip < 12) {
+ skip++;
+ return false;
+ } else {
+ skip = 0;
+ return init();
+ }
+ }
+ else return false;
+ }
+ else return true;
+}
+
+void CompuSnake::nextMove()
+{
+ if (!permission())
+ return;
+
+ Samy *sam = list.first();
+ int index = sam->index;
+ int dir = sam->direction;
+ static bool varies = false;
+
+
+ bool found = false;
+
+ for ( int x = 0; x < 4 ; x++) {
+ int next = board->getNext(x, sam->index);
+ if (board->isApple(next)){
+ index = next;
+ dir = x;
+ found = true;
+ grow+=6;
+ emit score(false, index);
+ break;
+ }
+ }
+
+ if(!found)
+ for ( int x = 0; x < 4 ; x++) {
+ int sq = emptySq[sam->direction][x];
+ if (varies && (x > 0 && x < 3))
+ sq = opposite[sq];
+ int next = board->getNext(sq, sam->index);
+ if (findEmpty(next, x)) {
+ index = next;
+ dir = sq;
+ found = true;
+ break;
+ }
+ }
+ varies = !varies;
+
+ if(!found) {
+ hold = list.last()->index;
+ if (board->isSnake(hold)) board->set(hold, empty);
+ removeSamy();
+ }
+ else
+ if(growing())
+ appendSamy();
+ else
+ if (!growing() && found) {
+ hold = list.last()->index;
+ if (board->isSnake(hold)) board->set(hold, empty);
+ updateSamy();
+ }
+
+ if( !list.isEmpty()) {
+ board->set(index, snake);
+ reset(index, dir);
+ }
+
+ if ( hold == gate)
+ out();
+}
+
+void KillerCompuSnake::nextMove()
+{
+ if (!permission()) return;
+
+ Samy *sam = list.first();
+ int index = sam->index;
+ int dir = sam->direction;
+ static bool varies = false;
+
+
+ bool found = false;
+
+ if(!found) {
+ int sn = board->samyHeadIndex();
+ if(sn != -1 && board->isHead(sn)) {
+ int nextSq = board->getNextCloseTo(index, sn, false, lastIndex);
+ if(nextSq != -1) {
+ dir = board->direction(index, nextSq);
+ index = nextSq;
+ found = true;
+ }
+ }
+ }
+
+ if(!found)
+ for ( int x = 0; x < 4 ; x++) {
+ int sq = emptySq[sam->direction][x];
+ if (varies && (x > 0 && x < 3))
+ sq = opposite[sq];
+ int next = board->getNext(sq, sam->index);
+ if (findEmpty(next, x)) {
+ index = next;
+ dir = sq;
+ found = true;
+ break;
+ }
+ }
+ varies = !varies;
+
+ if(!found) {
+ hold = list.last()->index;
+ if (board->isSnake(hold)) board->set(hold, empty);
+ removeSamy();
+ }
+ else {
+ lastIndex = index;
+
+ if(growing())
+ appendSamy();
+ else
+ if (!growing() && found) {
+ hold = list.last()->index;
+ if (board->isSnake(hold)) board->set(hold, empty);
+ updateSamy();
+ }
+ }
+
+ if( !list.isEmpty()) {
+ board->set(index, snake);
+ reset(index, dir);
+ }
+
+ if ( hold == gate)
+ out();
+}
+
+void EaterCompuSnake::nextMove()
+{
+ if (!permission()) return;
+
+ Samy *sam = list.first();
+ int index = sam->index;
+ int dir = sam->direction;
+ static bool varies = false;
+
+
+ bool found = false;
+
+ for ( int x = 0; x < 4 ; x++) {
+ int next = board->getNext(x, sam->index);
+ if (board->isApple(next)){
+ index = next;
+ dir = x;
+ found = true;
+ grow+=6;
+ emit score(false, index);
+ break;
+ }
+ }
+
+ if(!found) {
+ int sn;
+ bool apple = false;
+ for(sn = board->count() - 1; sn > 0; sn --) {
+ if(board->isApple(sn)) {
+ apple = true;
+ int nextSq = board->getNextCloseTo(index, sn, false);
+ if(nextSq != -1) {
+ dir = board->direction(index, nextSq);
+ index = nextSq;
+ found = true;
+ break;
+ }
+ }
+ }
+ if(!found && !apple) {
+ // No more apples, move snake to gate.
+ int nextSq = board->getNextCloseTo(index, gate, false, lastIndex);
+ if(nextSq != -1) {
+ dir = board->direction(index, nextSq);
+ index = nextSq;
+ found = true;
+ }
+ }
+ }
+
+ if(!found)
+ for ( int x = 0; x < 4 ; x++) {
+ int sq = emptySq[sam->direction][x];
+ if (varies && (x > 0 && x < 3))
+ sq = opposite[sq];
+ int next = board->getNext(sq, sam->index);
+ if (findEmpty(next, x)) {
+ index = next;
+ dir = sq;
+ found = true;
+ break;
+ }
+ }
+ varies = !varies;
+
+ if(!found) {
+ hold = list.last()->index;
+ if (board->isSnake(hold)) board->set(hold, empty);
+ removeSamy();
+ }
+ else {
+ lastIndex = index;
+
+ if(growing())
+ appendSamy();
+ else
+ if (!growing() && found) {
+ hold = list.last()->index;
+ if (board->isSnake(hold)) board->set(hold, empty);
+ updateSamy();
+ }
+ }
+
+ if( !list.isEmpty()) {
+ board->set(index, snake);
+ reset(index, dir);
+ }
+
+ if ( hold == gate)
+ out();
+}
+
+bool CompuSnake::findEmpty(int i, int it)
+{
+ bool found = false;
+ bool change = false;
+ static int s_random = random.getLong(BoardWidth/2);
+ static int moves = 0;
+
+ if (moves > s_random) {
+ s_random = random.getLong(BoardWidth/2);
+ moves = 0;
+ change = true;
+ }
+
+ found = ( ( board->isEmpty(i) && it > 0)
+ || ( board->isEmpty(i) && !change && it == 0) );
+
+ moves++;
+ change = false;
+ return found;
+}
+
+void CompuSnake::removeSamy()
+{
+ list.remove();
+ grow = 0;
+}
+
+void CompuSnake::out()
+{
+ emit closeGate( gate );
+
+ if( list.isEmpty() )
+ return;
+
+ if(list.first()->index == OUT) {
+ emit restartTimer();
+ list.clear();
+ }
+}
+
+SamySnake::SamySnake( Board *b, PixServer *p)
+ : Snake( b, p, SOUTH_GATE, SamyPix )
+{
+
+}
+
+void SamySnake::init()
+{
+ if( !list.isEmpty()) {
+ list.clear();
+ }
+ Samy *sam;
+
+ int index = SOUTH_GATE;
+ int length = 12;
+ grow = 0;
+ hold = 0;
+
+ for ( int x = 0; x < length; x++) {
+ board->set(index, head);
+ sam = new Samy;
+ sam->direction = N;
+ sam->index = index;
+ sam->pixmap = (x == 0 ? HeadUp : BodyVt);
+ list.append(sam);
+ index = -1;
+ }
+}
+
+samyState SamySnake::nextMove(int direction)
+{
+ Samy *sam = list.first();
+
+ if(!board->isHead(sam->index) && sam->index != OUT)
+ return ko;
+
+ if ( direction == opposite[sam->direction])
+ direction = sam->direction;
+
+ if(sam->index == gate || sam->index == OUT )
+ direction = N;
+
+ if (sam->index == NORTH_GATE) {
+ emit goingOut();
+ direction = N;
+ }
+
+ int index = board->getNext(direction, sam->index);
+
+ if (board->isApple(index)) {
+ grow+=6;
+ emit score(true, index);
+ }
+ else if (!board->isEmpty(index))
+ return ko;
+
+ if(growing())
+ appendSamy();
+ else {
+ hold = list.last()->index;
+ board->set(hold, empty);
+ updateSamy();
+ }
+
+ board->set(sam->index, snake);
+ reset(index, direction);
+ board->set(index, head);
+
+ if ( hold == gate)
+ emit closeGate( gate );
+ else if ( hold == NORTH_GATE)
+ return out;
+
+ return ok;
+}
+
+#include "snake.moc"
+
diff --git a/ksnake/snake.h b/ksnake/snake.h
new file mode 100644
index 00000000..863ec593
--- /dev/null
+++ b/ksnake/snake.h
@@ -0,0 +1,140 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SAMY_H
+#define SAMY_H
+
+#include <krandomsequence.h>
+#include "pixServer.h"
+#include "board.h"
+
+class Snake : public QObject
+{
+
+ Q_OBJECT
+
+signals:
+ void score(bool, int);
+ void killed();
+ void closeGate(int);
+ void restartTimer();
+ void goingOut();
+
+public:
+ Snake(Board *b, PixServer *p, Gate g, PixMap x);
+ ~Snake() {}
+ void repaint( bool );
+ void zero();
+
+protected:
+ Board *board;
+ PixServer *pixServer;
+ Gate gate;
+ PixMap pixmap;
+
+ struct Samy {
+ int direction;
+ SnakePix pixmap;
+ int index;
+ };
+
+ QPtrList<Samy> list;
+
+ KRandomSequence random;
+
+ void reset(int index, int border);
+ void appendSamy();
+ void updateSamy();
+ int tail() const { return (list.count() -1 ); }
+ bool growing() const { return (grow > 0 ? TRUE : FALSE); }
+
+ int hold;
+ int grow;
+};
+
+class CompuSnake : public Snake
+{
+
+public:
+ CompuSnake(Board *b, PixServer *p);
+ virtual ~CompuSnake() {}
+ virtual void nextMove();
+
+protected:
+ bool init();
+ void removeSamy();
+ bool findEmpty(int i, int it);
+ bool permission();
+ void out();
+
+};
+
+/**
+ * Don't eat any apples.
+ * Try to hit samy's head.
+ */
+class KillerCompuSnake : public CompuSnake
+{
+
+public:
+ KillerCompuSnake(Board *b, PixServer *p) : CompuSnake(b, p) {}
+ virtual ~KillerCompuSnake() {}
+ virtual void nextMove();
+
+private:
+ int lastIndex;
+
+};
+
+/**
+ * Eat as much apples as it can, from down to up.
+ * When all apples are eaten, try to reach the gate.
+ */
+class EaterCompuSnake : public CompuSnake
+{
+
+public:
+ EaterCompuSnake(Board *b, PixServer *p) : CompuSnake(b, p) {}
+ virtual ~EaterCompuSnake() {}
+ virtual void nextMove();
+
+private:
+ int lastIndex;
+
+};
+
+enum samyState { ok, ko, out };
+
+class SamySnake : public Snake
+{
+
+public:
+ SamySnake(Board *, PixServer *);
+ samyState nextMove(int direction);
+ void init();
+
+};
+
+#endif // SAMY_H
diff --git a/ksnake/startroom.cpp b/ksnake/startroom.cpp
new file mode 100644
index 00000000..5bb4d989
--- /dev/null
+++ b/ksnake/startroom.cpp
@@ -0,0 +1,81 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "startroom.h"
+
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qwmatrix.h>
+#include <qspinbox.h>
+#include <klocale.h>
+#include <qlayout.h>
+
+#include "levels.h"
+
+StartRoom::StartRoom( QWidget *parent, const char *name)
+ : QWidget( parent, name )
+{
+ QGridLayout *Form1Layout = new QGridLayout( this, 1, 1, 11, 6, "Form1Layout");
+ QSpacerItem* spacer = new QSpacerItem( 20, 61, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ Form1Layout->addItem( spacer, 2, 1 );
+
+ QHBoxLayout *layout1 = new QHBoxLayout( 0, 0, 6, "layout1");
+ QSpacerItem* spacer_2 = new QSpacerItem( 91, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ layout1->addItem( spacer_2 );
+
+ picture = new QLabel( this, "picture" );
+ layout1->addWidget( picture );
+ QSpacerItem* spacer_3 = new QSpacerItem( 41, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ layout1->addItem( spacer_3 );
+
+ Form1Layout->addMultiCellLayout( layout1, 0, 0, 0, 1 );
+
+ roomRange = new QSpinBox( this, "kcfg_StartingRoom" );
+ roomRange->setMaxValue( 25 );
+ roomRange->setMinValue( 1 );
+
+ Form1Layout->addWidget( roomRange, 1, 1 );
+
+ QLabel *textLabel = new QLabel( this, "textLabel" );
+ textLabel->setText(i18n("First level:"));
+ Form1Layout->addWidget( textLabel, 1, 0 );
+
+ connect( roomRange, SIGNAL(valueChanged(int)), SLOT(loadLevel(int)));
+ loadLevel(1);
+}
+
+void StartRoom::loadLevel(int level)
+{
+ if(level < 1 || level > leV->max())
+ return;
+
+ QPixmap pixmap = leV->getPixmap(level);
+ QWMatrix m;
+ m.scale( (double)7, (double)7 );
+ pixmap = pixmap.xForm( m );
+ picture->setPixmap(pixmap);
+}
+
+#include "startroom.moc"
+
diff --git a/ksnake/startroom.h b/ksnake/startroom.h
new file mode 100644
index 00000000..ef8cbbe0
--- /dev/null
+++ b/ksnake/startroom.h
@@ -0,0 +1,50 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef STARTROOM_H
+#define STARTROOM_H
+
+#include <qwidget.h>
+
+class QLabel;
+class QSpinBox;
+
+class StartRoom : public QWidget
+{
+ Q_OBJECT
+public:
+ StartRoom( QWidget *parent=0, const char *name=0 );
+
+private slots:
+ void loadLevel(int level);
+
+private:
+ QLabel *picture;
+ QSpinBox *roomRange;
+
+};
+
+#endif // STARTROOM_H
+
diff --git a/ksnake/version.h b/ksnake/version.h
new file mode 100644
index 00000000..0fc13a82
--- /dev/null
+++ b/ksnake/version.h
@@ -0,0 +1 @@
+#define KSNAKE_VERSION "0.4.0"
diff --git a/ksnake/view.cpp b/ksnake/view.cpp
new file mode 100644
index 00000000..3db7d34f
--- /dev/null
+++ b/ksnake/view.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "view.h"
+
+#include "progress.h"
+#include "rattler.h"
+
+int BRICKSIZE = 16;
+int MAPWIDTH = BRICKSIZE * 35;
+int MAPHEIGHT = MAPWIDTH;
+
+#define BAR_HEIGHT 12
+View::View( QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ progress = new Progress(this);
+ rattler = new Rattler( this);
+ setMinimumSize(145,145+BAR_HEIGHT);
+}
+
+void View::resizeEvent( QResizeEvent * )
+{
+ // These hard coded number really need to be documented
+ BRICKSIZE= (int)16* ((width() < height() - BAR_HEIGHT) ? width() : height() - BAR_HEIGHT)/ 560;
+ MAPWIDTH=BRICKSIZE * BoardWidth;
+ MAPHEIGHT=MAPWIDTH;
+
+ progress->setGeometry(5, 0, width()-5, BAR_HEIGHT);
+ rattler->setGeometry(0, BAR_HEIGHT, width(), height()-BAR_HEIGHT);
+}
+
+QSize View::sizeHint() const
+{
+ return QSize(490,502);
+}
+
+#include "view.moc"
diff --git a/ksnake/view.h b/ksnake/view.h
new file mode 100644
index 00000000..3dff2dbb
--- /dev/null
+++ b/ksnake/view.h
@@ -0,0 +1,48 @@
+/**
+ * Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
+ * Robert Williams
+ * Andrew Chant <andrew.chant@utoronto.ca>
+ * André Luiz dos Santos <andre@netvision.com.br>
+ * Benjamin Meyer <ben+ksnake@meyerhome.net>
+ *
+ * This file is part of the ksnake package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef VIEW_H
+#define VIEW_H
+
+#include <qwidget.h>
+
+class Progress;
+class Rattler;
+
+class View : public QWidget
+{
+ Q_OBJECT
+public:
+ View ( QWidget *parent=0, const char *name=0 );
+
+ Progress *progress;
+ Rattler *rattler;
+
+protected:
+ void resizeEvent( QResizeEvent * );
+ virtual QSize sizeHint() const;
+};
+
+#endif // VIEW_H
+