summaryrefslogtreecommitdiffstats
path: root/kfouleggs
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitc90c389a8a8d9d8661e9772ec4144c5cf2039f23 (patch)
tree6d8391395bce9eaea4ad78958617edb20c6a7573 /kfouleggs
downloadtdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.tar.gz
tdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdegames@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kfouleggs')
-rw-r--r--kfouleggs/CHANGELOG1
-rw-r--r--kfouleggs/LICENSE18
-rw-r--r--kfouleggs/Makefile.am75
-rw-r--r--kfouleggs/README14
-rw-r--r--kfouleggs/TODO3
-rw-r--r--kfouleggs/ai.cpp40
-rw-r--r--kfouleggs/ai.h21
-rw-r--r--kfouleggs/board.cpp161
-rw-r--r--kfouleggs/board.h44
-rw-r--r--kfouleggs/eventsrc358
-rw-r--r--kfouleggs/field.cpp61
-rw-r--r--kfouleggs/field.h19
-rw-r--r--kfouleggs/kfouleggs.desktop69
-rw-r--r--kfouleggs/kfouleggs.kcfg60
-rw-r--r--kfouleggs/kfouleggsui.rc27
-rw-r--r--kfouleggs/main.cpp92
-rw-r--r--kfouleggs/main.h34
-rw-r--r--kfouleggs/pics/Makefile.am3
-rw-r--r--kfouleggs/pics/hi128-app-kfouleggs.pngbin0 -> 17630 bytes
-rw-r--r--kfouleggs/pics/hi16-app-kfouleggs.pngbin0 -> 824 bytes
-rw-r--r--kfouleggs/pics/hi22-app-kfouleggs.pngbin0 -> 3971 bytes
-rw-r--r--kfouleggs/pics/hi32-app-kfouleggs.pngbin0 -> 2233 bytes
-rw-r--r--kfouleggs/pics/hi48-app-kfouleggs.pngbin0 -> 4003 bytes
-rw-r--r--kfouleggs/pics/hi64-app-kfouleggs.pngbin0 -> 6222 bytes
-rw-r--r--kfouleggs/piece.cpp90
-rw-r--r--kfouleggs/piece.h50
-rw-r--r--kfouleggs/prefs.kcfgc9
27 files changed, 1249 insertions, 0 deletions
diff --git a/kfouleggs/CHANGELOG b/kfouleggs/CHANGELOG
new file mode 100644
index 00000000..d7e56fd2
--- /dev/null
+++ b/kfouleggs/CHANGELOG
@@ -0,0 +1 @@
+see "ksirtet" CHANGELOG
diff --git a/kfouleggs/LICENSE b/kfouleggs/LICENSE
new file mode 100644
index 00000000..621e9325
--- /dev/null
+++ b/kfouleggs/LICENSE
@@ -0,0 +1,18 @@
+KFOULEGGS
+---------
+Copyright (c) 1999-2004 Nicolas HADACEK ([email protected])
+
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
diff --git a/kfouleggs/Makefile.am b/kfouleggs/Makefile.am
new file mode 100644
index 00000000..a47789a4
--- /dev/null
+++ b/kfouleggs/Makefile.am
@@ -0,0 +1,75 @@
+INCLUDES = -I$(top_builddir)/libksirtet -I$(top_srcdir)/libksirtet -I$(top_srcdir)/libksirtet/base -I$(top_srcdir)/libkdegames -I$(top_srcdir)/libkdegames/highscore $(all_includes)
+
+SUBDIRS = pics
+
+KDE_CXXFLAGS = $(KDE_USE_FPIE)
+
+bin_PROGRAMS = kfouleggs
+kfouleggs_LDADD = $(top_builddir)/libksirtet/common/libksirtetcommon.la
+kfouleggs_LDFLAGS = $(KDE_USE_PIE) $(all_libraries) $(KDE_RPATH)
+kfouleggs_SOURCES = piece.cpp board.cpp ai.cpp field.cpp main.cpp prefs.kcfgc
+METASOURCES = board.moc ai.moc field.moc main.moc
+
+rcdir = $(kde_datadir)/kfouleggs
+rc_DATA = kfouleggsui.rc
+
+xdg_apps_DATA = kfouleggs.desktop
+kde_kcfg_DATA = kfouleggs.kcfg
+
+appdatadir = $(kde_datadir)/kfouleggs
+appdata_DATA = eventsrc
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kfouleggs.pot
+
+# for system-wide highscore file
+DESTBIN = $(DESTDIR)$(bindir)/$(bin_PROGRAMS)
+DESTHIGHSCORES = $(DESTDIR)$(HIGHSCORE_DIRECTORY)
+DESTSCORES = $(DESTDIR)$(HIGHSCORE_DIRECTORY)/$(bin_PROGRAMS).scores
+
+install-data-local:
+ @(test x$(HIGHSCORE_DIRECTORY) != x \
+ && echo "********************************************************" \
+ && echo "" \
+ && echo "This game is installed sgid \"games\" to use the" \
+ && echo "system-wide highscore file (in "$(HIGHSCORE_DIRECTORY)")." \
+ && echo "" \
+ && echo "If the system-wide highscore file does not exist, it is" \
+ && echo "created with the correct ownership and permissions. See the" \
+ && echo "INSTALL file in \"kdegames/libkdegames/highscore\" for details." \
+ && echo "" \
+ && echo "********************************************************" \
+ ) || true
+
+install-exec-hook:
+ @(test x$(HIGHSCORE_DIRECTORY) != x \
+ && ((chown $(highscore_user):$(highscore_group) $(DESTBIN)) \
+ || echo "Error: Could not install the game with correct permissions !!" \
+ )) || true
+
+ @(test x$(HIGHSCORE_DIRECTORY) != x \
+ && ((mkdir -p $(DESTHIGHSCORES) && chown $(highscore_user):$(highscore_group) $(DESTHIGHSCORES) \
+ && chmod 750 $(DESTHIGHSCORES)) \
+ || echo "Error: Could not create the highscore directory with correct permissions !!" \
+ )) || true
+
+ @(test x$(HIGHSCORE_DIRECTORY) != x \
+ && ((chown $(highscore_user):$(highscore_group) $(DESTBIN)) \
+ || echo "Error: Could not install the game with correct permissions !!" \
+ )) || true
+
+ @(test ${setgid} = true \
+ && ((chmod 2755 $(DESTBIN)) \
+ || echo "Error: Could not install the game with correct permissions !!" \
+ )) || true
+
+ @(test x$(HIGHSCORE_DIRECTORY) != x \
+ && ((touch $(DESTSCORES) && chown $(highscore_user):$(highscore_group) $(DESTSCORES) \
+ && chmod 0660 $(DESTSCORES)) \
+ || echo "Error: Could not create system-wide highscore file with correct permissions !!" \
+ )) || true
+
+field.o: ../libksirtet/common/commonprefs.h ../libksirtet/base/baseprefs.h
+main.o: ../libksirtet/common/commonprefs.h ../libksirtet/base/baseprefs.h
+prefs.o: ../libksirtet/common/commonprefs.h ../libksirtet/base/baseprefs.h
+
diff --git a/kfouleggs/README b/kfouleggs/README
new file mode 100644
index 00000000..46ffcb4c
--- /dev/null
+++ b/kfouleggs/README
@@ -0,0 +1,14 @@
+KFOULEGGS : a puyopuyo-alike game
+---------------------------------
+Copyright (c) 1999-2004 Nicolas HADACEK ([email protected])
+Distributed under the GNU General Public License
+
+
+KFoulEggs is an adaptation of the also well-known (at least in Japan)
+Puyo-Puyo game. It provides multiplayers functionality and "artificial
+intelligence" player.
+
+The code links to the ksirtet libraries.
+
+
+Enjoy !
diff --git a/kfouleggs/TODO b/kfouleggs/TODO
new file mode 100644
index 00000000..b999a6fe
--- /dev/null
+++ b/kfouleggs/TODO
@@ -0,0 +1,3 @@
+see also the TODO list for libksirtet
+
+ * better (a -very- simple AI is already quite annoying :) and varied AIs
diff --git a/kfouleggs/ai.cpp b/kfouleggs/ai.cpp
new file mode 100644
index 00000000..ee8a6c4b
--- /dev/null
+++ b/kfouleggs/ai.cpp
@@ -0,0 +1,40 @@
+#include "ai.h"
+#include "ai.moc"
+
+#include <klocale.h>
+
+#include "board.h"
+
+
+const AI::Data FEAI::DATA[] = {
+ { "OccupiedLines", I18N_NOOP("Occupied lines:"), 0,
+ false, nbOccupiedLines },
+ { "Spaces", I18N_NOOP("Number of spaces:"), I18N_NOOP("Number of spaces under mean height"),
+ false, nbSpaces },
+ { "Peak2Peak", I18N_NOOP("Peak-to-peak distance:"), 0,
+ false, peakToPeak },
+ { "MeanHeight", I18N_NOOP("Mean height:"), 0,
+ false, mean },
+ { "RemovedEggs", I18N_NOOP("Number of removed eggs:"), 0,
+ false, nbRemoved },
+ { "Puyos", I18N_NOOP("Number of puyos:"), 0,
+ true, nbPuyos },
+ { "ChainedPuyos", I18N_NOOP("Number of chained puyos:"), 0,
+ true, nbChained },
+ LastData
+};
+
+FEAI::FEAI()
+: AI(0, 200, DATA)
+{}
+
+double FEAI::nbPuyos(const Board &main, const Board &current)
+{
+ return static_cast<const FEBoard &>(current).nbPuyos()
+ - static_cast<const FEBoard &>(main).nbPuyos();
+}
+
+double FEAI::nbChained(const Board &, const Board &current)
+{
+ return static_cast<const FEBoard &>(current).chained();
+}
diff --git a/kfouleggs/ai.h b/kfouleggs/ai.h
new file mode 100644
index 00000000..86e8f5b2
--- /dev/null
+++ b/kfouleggs/ai.h
@@ -0,0 +1,21 @@
+#ifndef FE_AI_H
+#define FE_AI_H
+
+#include "common/ai.h"
+
+
+class FEAI : public AI
+{
+ Q_OBJECT
+
+ public:
+ FEAI();
+
+ private:
+ static const Data DATA[];
+
+ static double nbPuyos(const Board &, const Board &);
+ static double nbChained(const Board &, const Board &);
+};
+
+#endif
diff --git a/kfouleggs/board.cpp b/kfouleggs/board.cpp
new file mode 100644
index 00000000..836c7e1e
--- /dev/null
+++ b/kfouleggs/board.cpp
@@ -0,0 +1,161 @@
+#include "board.h"
+#include "board.moc"
+
+#include <kglobal.h>
+
+#include "common/misc_ui.h"
+#include "piece.h"
+
+
+using namespace KGrid2D;
+
+FEBoard::FEBoard(bool graphic, QWidget *parent)
+: Board(graphic, new GiftPool(parent), parent),
+ _field(matrix().width(), matrix().height()), _chainedPuyos(4)
+{
+ init();
+}
+
+void FEBoard::init()
+{
+ _nbPuyos = 0;
+ _chained = 0;
+ _giftRest = 0;
+ _lastChained = 0;
+ for (uint i=0; i<4; i++) {
+ _chainedPuyos[i] = 0;
+ _lastChained += (2<<i); // update
+ }
+}
+
+void FEBoard::copy(const GenericTetris &g)
+{
+ Board::copy(g);
+ _nbPuyos = static_cast<const FEBoard &>(g)._nbPuyos;
+}
+
+void FEBoard::start(const GTInitData &data)
+{
+ init();
+ Board::start(data);
+}
+
+void FEBoard::computeInfos()
+{
+ Board::computeInfos();
+ if ( graphic() ) computeNeighbours();
+}
+
+bool FEBoard::afterGlue(bool doAll, bool first)
+{
+ return !doFall(doAll, first, false);
+}
+
+void FEBoard::removeBlock(const Coord &c)
+{
+ Board::removeBlock(c);
+
+ // remove surrounding garbage
+ CoordList list = matrix().neighbours(c, true, true);
+ for (CoordList::const_iterator i = list.begin(); i!=list.end(); ++i)
+ if ( matrix()[*i]!=0 && matrix()[*i]->isGarbage() )
+ Board::removeBlock(*i);
+}
+
+bool FEBoard::toBeRemoved(const Coord &c) const
+{
+ return ( _field[c]>=4 );
+}
+
+bool FEBoard::toFall(const Coord &c) const
+{
+ Coord under = c - Coord(0, 1);
+ return ( matrix()[under]==0 );
+}
+
+void FEBoard::remove()
+{
+ Board::remove();
+
+ // score calculation from another game
+ // not sure it is the "official" way
+ uint nbPuyos = _groups.size(); // number of group detroyed
+ uint nbEggs = 0; // number of eggs destroyed
+ for (uint k=0; k<_groups.size(); k++) nbEggs += _groups[k];
+
+ uint bonus = nbEggs - 3; // more than 4 since we are here !
+ if ( nbEggs==11 ) bonus += 2;
+ if ( nbPuyos>=2 ) bonus += 3 * (1 << (nbPuyos-2)); // 3 * 2^(nb-2)
+ if ( _chained>=1 ) bonus += 1 << (_chained+2); // 2^(chained+2)
+ uint dscore = 10 * nbPuyos * bonus;
+
+ uint i = kMin(_chained, (uint)3);
+ _chainedPuyos[i] += nbPuyos;
+ _lastChained = 2 << i;
+ _chained++;
+ _giftRest += dscore;
+ _nbPuyos += nbPuyos;
+ updateRemoved(nbRemoved() + nbEggs);
+ updateScore(score() + dscore);
+
+ updateLevel();
+}
+
+Board::AfterRemoveResult FEBoard::afterRemove(bool doAll, bool first)
+{
+ Board::AfterRemoveResult res = Board::afterRemove(doAll, first);
+ if ( res==Done && needRemoving() ) return NeedRemoving;
+ return res;
+}
+
+bool FEBoard::needRemoving()
+{
+ _groups = findGroups(_field, 4);
+ if ( _groups.size()==0 ) _chained = 0;
+ return _groups.size();
+}
+
+/*****************************************************************************/
+// Multiplayers methods
+uint FEBoard::gift()
+{
+ uint n = _giftRest / 60;
+ _giftRest = _giftRest % 60;
+ return n;
+}
+
+bool FEBoard::putGift(uint n)
+{
+ QMemArray<bool> free(matrix().width());
+
+ // garbage blocks are put randomly on conlumns with more than 5 free lines.
+ uint nbFree = 0;
+ for (uint i=0; i<free.size(); i++) {
+ int f = firstColumnBlock(i);
+ if ( f==-1 || f>=(int)matrix().height()-5 ) free[i] = false;
+ else {
+ free[i] = true;
+ nbFree++;
+ }
+ }
+ uint nb = kMin(nbFree, n);
+ while (nbFree && nb) {
+ uint k = (uint)randomGarbage.getLong(nbFree);
+ uint l = 0;
+ for (uint i=0; i<free.size(); i++) {
+ if ( free[i]==false ) continue;
+ if ( k==l ) {
+ Block *gb = currentPiece()->garbageBlock();
+ gb->sprite()->show();
+ Coord c(i, matrix().height()-1);
+ setBlock(c, gb);
+ free[i] = false;
+ nbFree--;
+ nb--;
+ break;
+ }
+ l++;
+ }
+ }
+ return true;
+}
diff --git a/kfouleggs/board.h b/kfouleggs/board.h
new file mode 100644
index 00000000..e0889b3b
--- /dev/null
+++ b/kfouleggs/board.h
@@ -0,0 +1,44 @@
+#ifndef FE_BOARD_H
+#define FE_BOARD_H
+
+#include "common/board.h"
+
+
+class FEBoard : public Board
+{
+ Q_OBJECT
+ public:
+ FEBoard(bool graphic, QWidget *parent);
+ void copy(const GenericTetris &);
+
+ void start(const GTInitData &);
+
+ uint nbPuyos() const { return _nbPuyos; }
+ uint chained() const { return _chained; }
+ uint nbChainedPuyos(uint i) const { return _chainedPuyos[i]; }
+ uint lastChained() const { return _lastChained; }
+
+ private:
+ // standard methods
+ bool afterGlue(bool doAll, bool first);
+ AfterRemoveResult afterRemove(bool doAll, bool first);
+ bool afterGift(bool first) { return !doFall(false, first, true); }
+ void removeBlock(const KGrid2D::Coord &);
+ bool toBeRemoved(const KGrid2D::Coord &) const;
+ bool toFall(const KGrid2D::Coord &) const;
+ void remove();
+ bool needRemoving();
+ void computeInfos();
+
+ void init();
+
+ // Multiplayers methods
+ uint gift();
+ bool putGift(uint);
+
+ KGrid2D::Square<int> _field;
+ QMemArray<uint> _groups, _chainedPuyos;
+ uint _nbPuyos, _chained, _giftRest, _lastChained;
+};
+
+#endif
diff --git a/kfouleggs/eventsrc b/kfouleggs/eventsrc
new file mode 100644
index 00000000..11663f03
--- /dev/null
+++ b/kfouleggs/eventsrc
@@ -0,0 +1,358 @@
+[!Global!]
+IconName=kfouleggs
+Comment=KFoulEggs
+Comment[ar]=لعبة البيضات المعفنة (KFoulEggs)
+Comment[be]=Фатальныя яйкі
+Comment[bn]=কে-ফাউলএগ
+Comment[cs]=Zkažená vejce
+Comment[hi]=के-फाउलएग्स
+Comment[hr]=KPokvarena jaja
+Comment[is]=Fúlegg
+Comment[ne]=केडीई फल ऐग
+Comment[pt_BR]=KOvos Sujos
+Comment[sv]=Kfouleggs
+Comment[ta]=கேதவறான முட்டைகள்
+Comment[tg]=KТухмҳои Афтанда
+
+[removed]
+Name=Blocks removed
+Name[ar]=لقد أزيل الطوب
+Name[be]=Блокі выдаленыя
+Name[bg]=Премахнати са блокове
+Name[bn]=গুটি সরিয়ে ফেলা হয়েছে
+Name[bs]=Uklonjeni blokovi
+Name[ca]=Blocs eliminats
+Name[cs]=Bloky odstraněny
+Name[cy]=Gwaredwyd blociau
+Name[da]=Blokke fjernet
+Name[de]=Entfernte Klötzchen
+Name[el]=Οι γραμμές αφαιρέθηκαν
+Name[eo]=Blokoj forigitaj
+Name[es]=Bloques eliminados
+Name[et]=Eemaldatud blokid
+Name[eu]=Kendutako blokeak
+Name[fa]=بلوکها حذف شدند
+Name[fi]=Palikoita poistettu
+Name[fr]=Blocs supprimés
+Name[ga]=Bloic bainte
+Name[gl]=Bloques eliminados
+Name[he]=בלוקים שהוסרו
+Name[hi]=पिण्ड हटाए
+Name[hr]=Uklonjeni blokovi
+Name[hu]=Blokk eltávolítva
+Name[is]=Kubbar fjarlægðir
+Name[it]=Blocchi rimossi
+Name[ja]=ブロックを消した
+Name[km]=ដុំ​ដែល​បាន​យក​ចេញ
+Name[lt]=Blokai panaikinti
+Name[lv]=Noņemti bloki
+Name[mk]=Отстранети се блокови
+Name[nb]=Blokker fjernet
+Name[nds]=Wegdaan Steen
+Name[ne]=खण्ड हटाइयो
+Name[nl]=Blokken verwijderd
+Name[nn]=Blokker fjerna
+Name[pa]=ਬਲਾਕ ਹਟਾਏ
+Name[pl]=Usunięcie bloków
+Name[pt]=Blocos removidos
+Name[pt_BR]=Blocos removidos
+Name[ro]=Blocuri eliminate
+Name[ru]=Блок удалён
+Name[se]=Bihtát leat eretváldon
+Name[sk]=Bloky odstránené
+Name[sl]=Odstranjeni bloki
+Name[sr]=Уклоњени блокови
+Name[sr@Latn]=Uklonjeni blokovi
+Name[sv]=Block borttagna
+Name[ta]=கட்டங்கள் நீக்கப்பட்டது
+Name[tg]=Бастаҳо ҷойивазкарда шудаанд
+Name[tr]=Silinen bloklar
+Name[uk]=Блоків вилучено
+Name[zh_CN]=消去的块数
+Name[zh_TW]=移除的方塊
+Comment=Blocks removed
+Comment[be]=Блокі выдаленыя
+Comment[bg]=Премахнати са блокове
+Comment[bn]=গুটি সরিয়ে ফেলা হয়েছে
+Comment[bs]=Uklonjeni blokovi
+Comment[ca]=Blocs eliminats
+Comment[cs]=Bloky odstraněny
+Comment[cy]=Gwaredwyd blociau
+Comment[da]=Blokke fjernet
+Comment[de]=Entfernte Klötzchen
+Comment[el]=Οι γραμμές αφαιρέθηκαν
+Comment[eo]=Blokoj forigitaj
+Comment[es]=Bloques eliminados
+Comment[et]=Eemaldatud blokid
+Comment[eu]=Kendutako blokeak
+Comment[fa]=بلوکها حذف شدند
+Comment[fi]=Palikoita poistettu
+Comment[fr]=Blocs supprimés
+Comment[ga]=Bloic bainte
+Comment[gl]=Bloques eliminados
+Comment[he]=בלוקים שהוסרו
+Comment[hi]=पिण्ड हटाए
+Comment[hr]=Uklonjeni blokovi
+Comment[hu]=Blokk eltávolítva
+Comment[is]=Kubbar fjarlægðir
+Comment[it]=Blocchi rimossi
+Comment[ja]=ブロック消した
+Comment[km]=ដុំ​ដែល​បាន​យក​ចេញ
+Comment[lt]=Blokai panaikinti
+Comment[lv]=Noņemti bloki
+Comment[mk]=Отстранети се блокови
+Comment[nb]=Blokker fjernet
+Comment[nds]=Wegdaan Steen
+Comment[ne]=खण्ड हटाइयो
+Comment[nl]=Blokken verwijderd
+Comment[nn]=Blokker fjerna
+Comment[pa]=ਬਲਾਕ ਹਟਾਏ
+Comment[pl]=Usunięcie bloków
+Comment[pt]=Blocos removidos
+Comment[pt_BR]=Blocos removidos
+Comment[ro]=Blocuri eliminate
+Comment[ru]=Блок удалён
+Comment[se]=Bihtát leat eretváldon
+Comment[sk]=Bloky odstránené
+Comment[sl]=Odstranjeni bloki
+Comment[sr]=Уклоњени блокови
+Comment[sr@Latn]=Uklonjeni blokovi
+Comment[sv]=Block borttagna
+Comment[ta]=தடைகள் நீக்கப்பட்டது
+Comment[tg]=Бастаҳо ҷойивазкарда шудаанд
+Comment[tr]=Silinen bloklar
+Comment[uk]=Блоків вилучено
+Comment[zh_CN]=消去的块数
+Comment[zh_TW]=移除的方塊
+default_presentation=0
+
+[game over]
+Name=Game Over
+Name[af]=Speletjie Bo
+Name[ar]=اللعبة انتهت
+Name[az]=Oyun Qurtardı
+Name[be]=Канец гульні
+Name[bg]=Край на играта
+Name[bn]=খেল খতম
+Name[br]=Echu an abadenn
+Name[bs]=Igra završena
+Name[ca]=Fi de la partida
+Name[cs]=Konec hry
+Name[cy]=Gêm Drosodd
+Name[da]=Spillet forbi
+Name[de]=Spiel beendet
+Name[el]=Τέλος παιχνιδιού
+Name[eo]=Ludo finita
+Name[es]=Fin de la partida
+Name[et]=Mäng läbi
+Name[eu]=Jokoa amaitu da
+Name[fa]=بازی تمام شد
+Name[fi]=Peli loppu
+Name[fr]=Fin de la partie
+Name[ga]=Cluiche Thart
+Name[gl]=Fin do Xogo
+Name[he]=סיום משחק
+Name[hi]=खेल ख़त्म
+Name[hr]=Igra je završena
+Name[hu]=Vége a játéknak
+Name[id]=permainan berakhir
+Name[is]=Leik lokið
+Name[it]=Gioco terminato
+Name[ja]=ゲームオーバー
+Name[km]=ល្បែង​ចប់
+Name[ko]=SameGame
+Name[lt]=Žaidimas baigtas
+Name[lv]=Spēles beigas
+Name[mk]=Играта заврши
+Name[mt]=Il-Logħba Spiċċat
+Name[nb]=Spillet er slutt
+Name[nds]=Speel vörbi
+Name[ne]=खेल समाप्त
+Name[nl]=Spel is afgelopen
+Name[nn]=Spelet er slutt
+Name[nso]=Papadi e Fedile
+Name[pa]=ਖੇਡ ਖਤਮ
+Name[pl]=Koniec gry
+Name[pt]=Fim do jogo
+Name[pt_BR]=Fim do jogo
+Name[ro]=Joc terminat
+Name[ru]=Конец игры
+Name[se]=Speallu nogai
+Name[sk]=Koniec hry
+Name[sl]=Konec igre
+Name[sr]=Крај игре
+Name[sr@Latn]=Kraj igre
+Name[sv]=Spelet är slut
+Name[ta]=ஆட்டம் முடிந்தது
+Name[tg]=Бозӣ ба итмом расид
+Name[th]=จบเกม
+Name[tr]=Oyun Bitti
+Name[uk]=Гру завершено
+Name[uz]=Oʻyin tugadi
+Name[uz@cyrillic]=Ўйин тугади
+Name[ven]=Muthambo wo Fhela
+Name[vi]=Game kết thúc
+Name[wa]=Li djeu est houte
+Name[xh]=Uphelile Umdlalo
+Name[zh_CN]=游戏结束
+Name[zh_TW]=遊戲結束
+Name[zu]=Umdlalo uphelile
+Comment=Game over
+Comment[be]=Канец гульні
+Comment[bg]=Край на играта
+Comment[bn]=খেল খতম
+Comment[br]=Echu an abadenn
+Comment[bs]=Kraj igre
+Comment[ca]=Fi de la partida
+Comment[cs]=Hra skončena
+Comment[cy]=Gêm drosodd
+Comment[da]=Spil forbi
+Comment[de]=Das Spiel ist vorbei
+Comment[el]=Τέλος παιχνιδιού
+Comment[eo]=Ludo finita
+Comment[es]=Fin de la partida
+Comment[et]=Mäng läbi
+Comment[eu]=Jokoa amaitu da
+Comment[fa]=بازی تمام شد
+Comment[fi]=Peli loppui
+Comment[fr]=Fin de la partie
+Comment[ga]=Cluiche thart
+Comment[he]=סיום משחק
+Comment[hr]=Kraj igre
+Comment[hu]=Vége a játéknak
+Comment[is]=Leik lokið
+Comment[it]=Gioco terminato
+Comment[ja]=ゲームオーバー
+Comment[km]=ល្បែង​ចប់
+Comment[lt]=Žaidimas baigtas
+Comment[lv]=Spēle beigusies
+Comment[mk]=Играта заврши
+Comment[nb]=Spillet er slutt
+Comment[nds]=Speel vörbi
+Comment[ne]=खेल समाप्त
+Comment[nl]=Het spel is afgelopen
+Comment[nn]=Spelet er slutt
+Comment[pa]=ਖੇਡ ਖਤਮ
+Comment[pl]=Koniec gry
+Comment[pt]=Fim do jogo
+Comment[pt_BR]=Fim do Jogo
+Comment[ru]=Конец игры
+Comment[se]=Speallu nogai
+Comment[sk]=Koniec hry
+Comment[sl]=Konec igre
+Comment[sr]=Крај игре
+Comment[sr@Latn]=Kraj igre
+Comment[sv]=Spelet slut
+Comment[ta]=ஆட்டம் முடிந்தது
+Comment[tr]=Oyun bitti
+Comment[uk]=Кінець гри
+Comment[wa]=Li djeu est houte
+Comment[zh_CN]=游戏结束
+Comment[zh_TW]=遊戲結束
+default_presentation=0
+
+[glued]
+Name=Piece glued
+Name[ar]=لقد ألصقت القطعة
+Name[be]=Кавалачак зліпнуўся
+Name[bg]=Залепени са парчета
+Name[bn]=গুটি আটকে আছে
+Name[bs]=Komad spojen
+Name[ca]=Peça enganxada
+Name[cs]=Blok spojen
+Name[cy]=Darn wedi ei gludo
+Name[da]=Brik klæbet fast
+Name[de]=Zusammengefügte Klötzchen
+Name[el]=Το κομμάτι κολλήθηκε
+Name[eo]=Peco gluita
+Name[es]=Ficha pegada
+Name[et]=Kleepunud klots
+Name[eu]=Pieza itsatsita
+Name[fa]=قطعه چسبید
+Name[fi]=Pala liimattu
+Name[fr]=Morceau collé
+Name[gl]=Peza pegada
+Name[he]=חתיכה מודבקת
+Name[hi]=टुकड़े चिपकाए
+Name[hr]=Zalijepljeni dio
+Name[hu]=Elem lekötve
+Name[is]=Hlutur límdur
+Name[it]=Pezzo incollato
+Name[ja]=ピースをくっつけた
+Name[km]=បំណែក​បាន​បិទ
+Name[lt]=Dalis įklijuota
+Name[lv]=Pielīmēts gabals
+Name[mk]=Залепено е парче
+Name[nb]=Brikke festet
+Name[nds]=Steen tosamenbackt
+Name[ne]=टाँसिएको टुक्रा
+Name[nl]=Samengevoegde stukken
+Name[nn]=Brikke festa
+Name[pl]=Sklejenie elementów
+Name[pt]=Peça colada
+Name[pt_BR]=Peça colada
+Name[ru]=Слипание яиц
+Name[se]=Bihttá lea liibmejuvvon
+Name[sk]=Kus zlepený
+Name[sl]=Kos prilepljen
+Name[sr]=Залепљено парче
+Name[sr@Latn]=Zalepljeno parče
+Name[sv]=Pjäs fastsatt
+Name[ta]= துண்டு கிலூயிட்
+Name[tg]=Қисмҳои часбанда
+Name[tr]=Yapıştırılan parçalar
+Name[uk]=Фігура приклеєна
+Name[zh_CN]=粘连的块数
+Name[zh_TW]=黏著的小碎片
+Comment=Piece glued
+Comment[ar]=لقد ألصقت القطعة
+Comment[be]=Кавалачак зліпнуўся
+Comment[bg]=Залепени са парчета
+Comment[bn]=গুটি আটকে আছে
+Comment[bs]=Komad spojen
+Comment[ca]=Peça enganxada
+Comment[cs]=Blok spojen
+Comment[cy]=Darn wedi ei gludo
+Comment[da]=Brik klæbet fast
+Comment[de]=Zusammengefügte Klötzchen
+Comment[el]=Το κομμάτι κολλήθηκε
+Comment[eo]=Peco gluita
+Comment[es]=Ficha pegada
+Comment[et]=Paikapandud klots
+Comment[eu]=Pieza itsatsita
+Comment[fa]=قطعه چسبید
+Comment[fi]=Pala liimattu
+Comment[fr]=Morceau collé
+Comment[gl]=Peza pegada
+Comment[he]=חתיכה מודבקת
+Comment[hi]=टुकड़े चिपकाए
+Comment[hr]=Zalijepljeni dio
+Comment[hu]=Elem lekötve
+Comment[is]=Hlutur límdur
+Comment[it]=Pezzo incollato
+Comment[ja]=ピースをくっつけた
+Comment[km]=បំណែក​បាន​បិទ
+Comment[lt]=Dalis įklijuota
+Comment[lv]=Gabals ir pielīmēts
+Comment[mk]=Залепено е парче
+Comment[nb]=Brikke festet
+Comment[nds]=Steen tosamenbackt
+Comment[ne]=टाँसिएको टुक्रा
+Comment[nl]=Samengevoegde stukken
+Comment[nn]=Brikke festa
+Comment[pl]=Sklejenie elementu
+Comment[pt]=Peça colada
+Comment[pt_BR]=Peça colada
+Comment[ru]=Слипание яиц
+Comment[se]=Bihttá lea liibmejuvvon
+Comment[sk]=Kus zlepený
+Comment[sl]=Kos prilepljen
+Comment[sr]=Залепљено парче
+Comment[sr@Latn]=Zalepljeno parče
+Comment[sv]=Pjäs fastsatt
+Comment[ta]=துண்டு ஒட்டப்பட்டது
+Comment[tg]=Қисмҳои часбанда
+Comment[tr]=Parça yapıştırıldı
+Comment[uk]=Фігура приклеєна
+Comment[zh_CN]=粘连的块数
+default_presentation=0
diff --git a/kfouleggs/field.cpp b/kfouleggs/field.cpp
new file mode 100644
index 00000000..9d7abe85
--- /dev/null
+++ b/kfouleggs/field.cpp
@@ -0,0 +1,61 @@
+#include "field.h"
+#include "field.moc"
+
+#include <qwhatsthis.h>
+
+#include <klocale.h>
+#include <kgamelcd.h>
+
+#include "common/commonprefs.h"
+#include "board.h"
+
+
+FEField::FEField(QWidget *parent)
+ : Field(parent)
+{
+ Board *b = static_cast<Board *>(board);
+ QWhatsThis::add(b->giftPool(), i18n("Display the amount of foul eggs sent by your opponent."));
+}
+
+void FEField::removedUpdated()
+{
+ Field::removedUpdated();
+ const FEBoard *feb = static_cast<const FEBoard *>(board);
+ KGameLCD *lcd = static_cast<KGameLCD *>(removedList->lcd(0));
+ lcd->displayInt(feb->nbPuyos());
+ if ( feb->nbPuyos() ) lcd->highlight();
+ if ( CommonPrefs::showDetailedRemoved() )
+ for (uint i=0; i<4; i++) {
+ if ( !(feb->lastChained() & 2<<i) ) continue;
+ lcd = static_cast<KGameLCD *>(removedList->lcd(i+1));
+ lcd->displayInt(feb->nbChainedPuyos(i));
+ if ( feb->nbChainedPuyos(i) ) lcd->highlight();
+ }
+}
+
+void FEField::settingsChanged()
+{
+ Field::settingsChanged();
+
+ removedList->clear();
+ KGameLCD *lcd = new KGameLCD(6, removedList);
+ removedList->append(i18n("Total:"), lcd);
+ uint nb = static_cast<const FEBoard *>(board)->nbPuyos();
+ lcd->displayInt(nb);
+ lcd->show();
+
+ if ( CommonPrefs::showDetailedRemoved() ) {
+ QWhatsThis::add(removedList,
+ i18n("Display the number of removed groups (\"puyos\") classified by the number of chained removal."));
+ for (uint i=0; i<4; i++) {
+ KGameLCD *lcd = new KGameLCD(6, removedList);
+ QString s = (i==3 ? ">3" : QString::number(i));
+ removedList->append(s, lcd);
+ uint nb = static_cast<const FEBoard *>(board)->nbChainedPuyos(i);
+ lcd->displayInt(nb);
+ lcd->show();
+ }
+ } else
+ QWhatsThis::add(removedList,
+ i18n("Display the number of removed groups (\"puyos\")."));
+}
diff --git a/kfouleggs/field.h b/kfouleggs/field.h
new file mode 100644
index 00000000..df7812f2
--- /dev/null
+++ b/kfouleggs/field.h
@@ -0,0 +1,19 @@
+#ifndef FE_FIELD_H
+#define FE_FIELD_H
+
+#include "common/field.h"
+#include "common/misc_ui.h"
+
+
+class FEField : public Field
+{
+ Q_OBJECT
+ public:
+ FEField(QWidget *parent);
+
+ private slots:
+ virtual void removedUpdated();
+ void settingsChanged();
+};
+
+#endif
diff --git a/kfouleggs/kfouleggs.desktop b/kfouleggs/kfouleggs.desktop
new file mode 100644
index 00000000..d02296d3
--- /dev/null
+++ b/kfouleggs/kfouleggs.desktop
@@ -0,0 +1,69 @@
+[Desktop Entry]
+Name=KFoulEggs
+Name[af]=K-vrot-eier
+Name[ar]=لعبة البيضات المعفنة (KFoulEggs)
+Name[be]=Фатальныя яйкі
+Name[bn]=কে-ফাউলএগ
+Name[hi]=के-फाउलएग्स
+Name[hr]=KPokvarena jaja
+Name[is]=Fúlegg
+Name[ne]=के फल ऐग
+Name[pl]=Foul Eggs
+Name[pt_BR]=KOvos Sujos
+Name[sv]=Kfouleggs
+Name[ta]=கேதவறான முட்டைகள்
+Name[tg]=KТухмҳои Афтанда
+Name[tr]=Çürük Yumurtalar
+Icon=kfouleggs
+Exec=kfouleggs -caption "%c" %i %m
+Type=Application
+DocPath=kfouleggs/index.html
+GenericName=Japanese PuyoPuyo-like Game
+GenericName[be]=Японскі тэтрыс
+GenericName[bg]=Японски тетрис
+GenericName[bn]=জাপানি পুইয়োপুইয়ো-জাতীয় খেলা
+GenericName[br]=C'hoari doare PuyoPuyo japaneg
+GenericName[bs]=Japanska igra nalik na PuyoPuyo
+GenericName[ca]=Jocs similar al PuyoPuyo japonès
+GenericName[cs]=Japonská hra podobná PuyoPuyo
+GenericName[cy]=Gêm Fwrdd sy'n debyg i PuyoPuyo Siapanaidd
+GenericName[da]=Japansk PuyoPuyo-lignende spil
+GenericName[de]=Puyo-Puyo-ähnliches Brettspiel
+GenericName[el]=Ιαπωνικό παιχνίδι παρόμοιο με το PuyoPuyo
+GenericName[eo]=Japana PuyoPuyo-simila bretludo
+GenericName[es]=Juego japonés similar al PuyoPuyo
+GenericName[et]=Jaapani PuyoPuyo moodi mäng
+GenericName[eu]=PuyoPuyo bezalaeko joko japoniarra
+GenericName[fa]=بازی شبیه PuyoPuyo ژاپنی
+GenericName[fi]=Japanilainen PuyoPuyo-tyylinen peli
+GenericName[fr]=Jeu japonais dans le style de PuyoPuyo
+GenericName[he]=חיקוי PuyoPuyo יפני
+GenericName[hr]=Igra poput japanskog PuyoPuyo
+GenericName[hu]=PuyoPuyo-szerű játék
+GenericName[is]=Leikur sem líkist Japönskum PuyoPuyo leik
+GenericName[it]=Gioco simile al giapponese PuyoPuyo
+GenericName[ja]=プヨプヨのようなボードゲーム
+GenericName[km]=ល្បែង​ដូច PuyoPuyo របស់​ជប៉ុន
+GenericName[lv]=Spēle līdzīga Japāņu PuyoPuyo
+GenericName[mk]=Игри на слична на јапонската Пујо-пујо
+GenericName[nb]=Japansk PuyoPuyo-lignende spill
+GenericName[nds]=Japaansch Puyo-Puyo-liek Brettspeel
+GenericName[ne]=जापानी पुयोपुयो जस्तो खेल
+GenericName[nl]=Japans PuyoPuyo-achtig spel
+GenericName[nn]=Japansk PuyoPuyo-liknande spel
+GenericName[pl]=Gra typu PuyoPuyo
+GenericName[pt]=Jogo tipo PuyoPuyo
+GenericName[pt_BR]=Jogo parecido com PuyoPuyo japonês
+GenericName[ru]=Роковые яйца
+GenericName[se]=Japanalaš PuyoPuyo-lágan speallu
+GenericName[sk]=Japonská hra typu PuyoPuyo
+GenericName[sl]=Igra, podobna japonskemu PuyoPuyo
+GenericName[sr]=Игра налик на јапански PuyoPuyo
+GenericName[sr@Latn]=Igra nalik na japanski PuyoPuyo
+GenericName[sv]=Japanskt PuyoPuyo-liknande spel
+GenericName[ta]=ஜப்பானிய புயோ-புயோ போன்ற விளையாட்டு
+GenericName[uk]=Варіант тетрісу Пуйо-Пуйо
+GenericName[zh_TW]=類似日本 PuyoPuyo 遊戲
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Multi
+Categories=Qt;KDE;Game;ArcadeGame;
diff --git a/kfouleggs/kfouleggs.kcfg b/kfouleggs/kfouleggs.kcfg
new file mode 100644
index 00000000..685e29e1
--- /dev/null
+++ b/kfouleggs/kfouleggs.kcfg
@@ -0,0 +1,60 @@
+<?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" >
+ <group name="AI">
+ <entry name="Coefficient_OccupiedLines" type="Double" key="occupied lines COEF">
+ <label>Occupied lines</label>
+ <default>-2.0</default>
+ <min>-100.0</min>
+ <max>0.0</max>
+ </entry>
+ <entry name="Coefficient_Spaces" type="Double" key="spaces COEF">
+ <label>Number of spaces</label>
+ <default>0.0</default>
+ <min>-100.0</min>
+ <max>0.0</max>
+ </entry>
+ <entry name="Coefficient_Peak2Peak" type="Double" key="peak-to-peak COEF">
+ <label>Peak-to-peak distance</label>
+ <default>0.0</default>
+ <min>-100.0</min>
+ <max>0.0</max>
+ </entry>
+ <entry name="Coefficient_MeanHeight" type="Double" key="mean height COEF">
+ <label>Mean height</label>
+ <default>0.0</default>
+ <min>-100.0</min>
+ <max>0.0</max>
+ </entry>
+ <entry name="Coefficient_RemovedEggs" type="Double" key="removed eggs COEF">
+ <label>Number of removed eggs</label>
+ <default>20.0</default>
+ <min>0.0</min>
+ <max>100.0</max>
+ </entry>
+ <entry name="Coefficient_Puyos" type="Double" key="nb puyos COEF">
+ <label>Number of puyos</label>
+ <default>50.0</default>
+ <min>0.0</min>
+ <max>100.0</max>
+ </entry>
+ <entry name="Trigger_Puyos" type="Int" key="nb puyos TRIG">
+ <default>0</default>
+ <min>0</min>
+ <max>10</max>
+ </entry>
+ <entry name="Coefficient_ChainedPuyos" type="Double" key="nb chained COEF">
+ <label>Number of chained puyos</label>
+ <default>80.0</default>
+ <min>0.0</min>
+ <max>100.0</max>
+ </entry>
+ <entry name="Trigger_ChainedPuyos" type="Int" key="nb chained TRIG">
+ <default>0</default>
+ <min>0</min>
+ <max>10</max>
+ </entry>
+ </group>
+</kcfg>
diff --git a/kfouleggs/kfouleggsui.rc b/kfouleggs/kfouleggsui.rc
new file mode 100644
index 00000000..f4fb0d59
--- /dev/null
+++ b/kfouleggs/kfouleggsui.rc
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE kpartgui>
+<kpartgui name="kfouleggs" version="7">
+
+<MenuBar>
+ <Menu name="multiplayers"><text>&amp;Multiplayer</text>
+ <Action name="mp_single_human"/>
+ <Action name="mp_human_vs_human"/>
+ <Action name="mp_human_vs_computer"/>
+ <Separator/>
+ <Action name="mp_more"/>
+ </Menu>
+</MenuBar>
+
+<Menu name="popup">
+ <Action name="options_show_menubar"/>
+ <Separator/>
+ <Action name="game_new"/>
+ <Separator/>
+ <Action name="game_pause"/>
+ <Action name="game_highscores"/>
+ <Action name="game_print"/>
+ <Separator/>
+ <Action name="game_quit"/>
+</Menu>
+
+</kpartgui>
diff --git a/kfouleggs/main.cpp b/kfouleggs/main.cpp
new file mode 100644
index 00000000..4fbee4c7
--- /dev/null
+++ b/kfouleggs/main.cpp
@@ -0,0 +1,92 @@
+#include "main.h"
+#include "main.moc"
+
+#include <klocale.h>
+#include <kapplication.h>
+#include <khighscore.h>
+
+#include "common/inter.h"
+#include "common/highscores.h"
+#include "prefs.h"
+#include "piece.h"
+
+//-----------------------------------------------------------------------------
+const MPGameInfo MP_GAME_INFO = {
+ "004", // multiplayer id (increase when incompatible changes are made)
+ 4, // max nb local games
+ 500, // interval
+ true, // IA allowed
+ 0, 0 // no setting slots
+};
+
+const MainData MAIN_DATA = {
+ "kfouleggs",
+ I18N_NOOP("KFoulEggs"),
+ I18N_NOOP("KFoulEggs is an adaptation of the well-known\n(at least in "
+ "Japan) PuyoPuyo game"),
+ "http://kfouleggs.sourceforge.net/",
+ I18N_NOOP("Puyos"),
+ "2.1.11",
+ "2.1.11 (12 September 2004)"
+};
+
+const uint HISTOGRAM_SIZE = 8;
+const uint HISTOGRAM[HISTOGRAM_SIZE] = {
+ 1, 5000, 10000, 20000, 50000, 100000, 200000, 300000
+};
+
+const BaseBoardInfo BASE_BOARD_INFO = {
+ 6, 15, // width - height
+ true, // with pieces
+
+ 150, // before remove time
+ 10, // after removed time
+ 3, // nb toggles
+ 5, // nb partial fall stages
+
+ 0, // nb arcade stages
+
+ HISTOGRAM, HISTOGRAM_SIZE, false, // score is not bound
+};
+
+const CommonBoardInfo COMMON_BOARD_INFO = {
+ 1000, // base time
+ 10, // drop down time
+ 10, // before glue time
+ 10, // after glue time
+ 10, // after gift time
+ 3, // nb bump stages
+
+ 100, // nb removed to level
+ 5, 6, 800, 2000 // nb leds, max to send, shower timeout, pool timeout
+};
+
+FEFactory::FEFactory()
+ : CommonFactory(MAIN_DATA, BASE_BOARD_INFO, COMMON_BOARD_INFO)
+{}
+
+BaseInterface *FEFactory::createInterface(QWidget *parent)
+{
+ return new Interface(MP_GAME_INFO, parent);
+}
+
+
+//-----------------------------------------------------------------------------
+int main(int argc, char **argv)
+{
+ KHighscore::init(MAIN_DATA.appName);
+ FEFactory fef;
+ fef.init(argc, argv);
+
+ FEPieceInfo pieceInfo;
+ CommonHighscores highscores;
+ (void) Prefs::self(); // Create preferences
+
+ if ( kapp->isRestored() ) RESTORE(FEMainWindow)
+ else {
+ FEMainWindow *mw = new FEMainWindow;
+ kapp->setMainWidget(mw);
+ mw->show();
+ }
+ return kapp->exec();
+}
diff --git a/kfouleggs/main.h b/kfouleggs/main.h
new file mode 100644
index 00000000..5831d546
--- /dev/null
+++ b/kfouleggs/main.h
@@ -0,0 +1,34 @@
+#ifndef FE_MAIN_H
+#define FE_MAIN_H
+
+#include "common/main.h"
+#include "common/factory.h"
+#include "board.h"
+#include "ai.h"
+#include "field.h"
+
+
+//-----------------------------------------------------------------------------
+class FEFactory : public CommonFactory
+{
+ public:
+ FEFactory();
+
+ protected:
+ virtual BaseBoard *createBoard(bool graphic, QWidget *parent)
+ { return new FEBoard(graphic, parent); }
+ virtual BaseField *createField(QWidget *parent)
+ { return new FEField(parent); }
+ virtual BaseInterface *createInterface(QWidget *parent);
+ virtual AI *createAI() { return new FEAI; }
+};
+
+//-----------------------------------------------------------------------------
+class FEMainWindow : public MainWindow
+{
+ Q_OBJECT
+ public:
+ FEMainWindow() { init(); }
+};
+
+#endif
diff --git a/kfouleggs/pics/Makefile.am b/kfouleggs/pics/Makefile.am
new file mode 100644
index 00000000..c471f62b
--- /dev/null
+++ b/kfouleggs/pics/Makefile.am
@@ -0,0 +1,3 @@
+
+KDE_ICON= AUTO
+
diff --git a/kfouleggs/pics/hi128-app-kfouleggs.png b/kfouleggs/pics/hi128-app-kfouleggs.png
new file mode 100644
index 00000000..a9129858
--- /dev/null
+++ b/kfouleggs/pics/hi128-app-kfouleggs.png
Binary files differ
diff --git a/kfouleggs/pics/hi16-app-kfouleggs.png b/kfouleggs/pics/hi16-app-kfouleggs.png
new file mode 100644
index 00000000..ce66ca75
--- /dev/null
+++ b/kfouleggs/pics/hi16-app-kfouleggs.png
Binary files differ
diff --git a/kfouleggs/pics/hi22-app-kfouleggs.png b/kfouleggs/pics/hi22-app-kfouleggs.png
new file mode 100644
index 00000000..28713198
--- /dev/null
+++ b/kfouleggs/pics/hi22-app-kfouleggs.png
Binary files differ
diff --git a/kfouleggs/pics/hi32-app-kfouleggs.png b/kfouleggs/pics/hi32-app-kfouleggs.png
new file mode 100644
index 00000000..b7286d49
--- /dev/null
+++ b/kfouleggs/pics/hi32-app-kfouleggs.png
Binary files differ
diff --git a/kfouleggs/pics/hi48-app-kfouleggs.png b/kfouleggs/pics/hi48-app-kfouleggs.png
new file mode 100644
index 00000000..c6b5fc5a
--- /dev/null
+++ b/kfouleggs/pics/hi48-app-kfouleggs.png
Binary files differ
diff --git a/kfouleggs/pics/hi64-app-kfouleggs.png b/kfouleggs/pics/hi64-app-kfouleggs.png
new file mode 100644
index 00000000..5c4ff35a
--- /dev/null
+++ b/kfouleggs/pics/hi64-app-kfouleggs.png
Binary files differ
diff --git a/kfouleggs/piece.cpp b/kfouleggs/piece.cpp
new file mode 100644
index 00000000..3c676f1c
--- /dev/null
+++ b/kfouleggs/piece.cpp
@@ -0,0 +1,90 @@
+#include "piece.h"
+
+#include <math.h>
+
+#include <qpainter.h>
+#include <qbitmap.h>
+
+#include <klocale.h>
+
+#include "base/board.h"
+
+
+const FEPieceInfo::Form FEPieceInfo::FORM = {
+ {{ 0, 0}, {-1, 0}, { 0, 0}, { 0, -1}},
+ {{ 0, -1}, {-1, -1}, {-1, 0}, {-1, -1}}
+};
+
+const char *FEPieceInfo::DEFAULT_COLORS[NB_NORM_BLOCK_TYPES + 1] = {
+ "#64C864", "#64C8C8", "#C86464", "#C864C8", "#C8C8C8"
+};
+
+QColor FEPieceInfo::defaultColor(uint i) const
+{
+ if ( i>=nbColors() ) return QColor();
+ return QColor(DEFAULT_COLORS[i]);
+}
+
+QString FEPieceInfo::colorLabel(uint i) const
+{
+ return (i==NB_NORM_BLOCK_TYPES ? i18n("Garbage color:")
+ : i18n("Color #%1:").arg(i+1));
+}
+
+void FEPieceInfo::draw(QPixmap *pixmap, uint blockType, uint,
+ bool lighted) const
+{
+ QColor col = color(blockType);
+ if (lighted) col = col.light();
+ pixmap->fill(col);
+}
+
+void FEPieceInfo::setMask(QPixmap *pixmap, uint blockMode) const
+{
+ Q_ASSERT( pixmap->width()==pixmap->height() ); // drawing code assumes that
+ QBitmap bitmap(pixmap->size(), true);
+ QPainter p(&bitmap);
+ p.setBrush(Qt::color1);
+ p.setPen( QPen(Qt::NoPen) );
+
+ // base circle
+ int w = pixmap->width();
+ int d = (int)((sqrt(2)-2./3)*w);
+ QRect cr = QRect(0, 0, d, d);
+ cr.moveCenter(QPoint(w/2, w/2));
+ p.drawEllipse(cr);
+
+ if (blockMode) {
+ int a = (int)(w/(3.*sqrt(2)));
+ int ra = 2*w/3+1;
+ cr = QRect(0, 0, ra, ra);
+
+ // first drawing with color1
+ if ( blockMode & BaseBoard::Up ) p.drawRect( 0, 0, w, a);
+ if ( blockMode & BaseBoard::Right ) p.drawRect(w-a+1, 0, a, w);
+ if ( blockMode & BaseBoard::Down ) p.drawRect( 0, w-a+1, w, a);
+ if ( blockMode & BaseBoard::Left ) p.drawRect( 0, 0, a, w);
+
+ // second drawing with color0
+ p.setBrush(Qt::color0);
+ if ( (blockMode & BaseBoard::Up) || (blockMode & BaseBoard::Left) ) {
+ cr.moveCenter(QPoint(0, 0));
+ p.drawEllipse(cr);
+ }
+ if ( (blockMode & BaseBoard::Right) || (blockMode & BaseBoard::Up) ) {
+ cr.moveCenter(QPoint(w-1, 0));
+ p.drawEllipse(cr);
+ }
+ if ( (blockMode & BaseBoard::Down) || (blockMode & BaseBoard::Right) ){
+ cr.moveCenter(QPoint(w-1, w-1));
+ p.drawEllipse(cr);
+ }
+ if ( (blockMode & BaseBoard::Left) || (blockMode & BaseBoard::Down) ) {
+ cr.moveCenter(QPoint(0, w-1));
+ p.drawEllipse(cr);
+ }
+ }
+
+ p.end();
+ pixmap->setMask(bitmap);
+}
diff --git a/kfouleggs/piece.h b/kfouleggs/piece.h
new file mode 100644
index 00000000..ba90e902
--- /dev/null
+++ b/kfouleggs/piece.h
@@ -0,0 +1,50 @@
+#ifndef PIECE_H
+#define PIECE_H
+
+#include "base/piece.h"
+
+
+class FEPieceInfo : public GPieceInfo
+{
+ public:
+ FEPieceInfo() {}
+
+ virtual uint nbBlocks() const { return NB_BLOCKS; }
+ virtual uint nbForms() const { return 1; }
+ virtual uint nbTypes() const
+ { return NB_NORM_BLOCK_TYPES * NB_NORM_BLOCK_TYPES; }
+
+ virtual const int *i(uint, uint rot) const { return FORM.i[rot]; }
+ virtual const int *j(uint, uint rot) const { return FORM.j[rot]; }
+ virtual uint value(uint type, uint n) const
+ { return (n%2 ? type/4 : type%4); }
+ virtual uint form(uint) const { return 0; }
+ virtual uint nbConfigurations(uint type) const
+ { return ((type%4)==(type/4) ? 2 : 4);}
+
+ virtual uint nbNormalBlockTypes() const { return NB_NORM_BLOCK_TYPES; }
+ virtual uint nbGarbageBlockTypes() const { return 1; }
+ virtual uint nbBlockModes() const { return NB_BLOCK_MODES; }
+
+ virtual uint nbColors() const { return NB_NORM_BLOCK_TYPES + 1; }
+ virtual QString colorLabel(uint i) const;
+ virtual QColor defaultColor(uint i) const;
+
+ private:
+ void draw(QPixmap *, uint blockType, uint blockMode, bool lighted) const;
+ void setMask(QPixmap *, uint blockMode) const;
+
+ enum { NB_BLOCKS = 2,
+ NB_NORM_BLOCK_TYPES = 4,
+ NB_BLOCK_MODES = 1+4+6+4+1 }; // all possible connections
+
+ struct Form {
+ int i[4][NB_BLOCKS];
+ int j[4][NB_BLOCKS];
+ };
+ static const Form FORM;
+
+ static const char *DEFAULT_COLORS[NB_NORM_BLOCK_TYPES + 1];
+};
+
+#endif
diff --git a/kfouleggs/prefs.kcfgc b/kfouleggs/prefs.kcfgc
new file mode 100644
index 00000000..cf32e226
--- /dev/null
+++ b/kfouleggs/prefs.kcfgc
@@ -0,0 +1,9 @@
+# Code generation options for kconfig_compiler
+File=kfouleggs.kcfg
+IncludeFiles=common/commonprefs.h
+Inherits=CommonPrefs
+ClassName=Prefs
+Singleton=true
+#Mutators=true
+#CustomAdditions=true
+#Mutators=true