You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeartwork/tdescreensaver/kdesavers/tdeasciiquarium/aasaver.cpp

1221 lines
31 KiB

//Stub stolen from:
// klines 0.1.1 - Basic screen saver for KDE
// by Dirk Staneker 1997
#include <kdebug.h>
#include <tdelocale.h>
#include <tdeconfigdialog.h>
#include <tqdesktopwidget.h>
#include <tqpainter.h>
#include <tqbrush.h>
#include "screen.h"
#include "frame.h"
#include "sprite.h"
#include "aasaver.h"
#include "AASaverConfig.h"
#include "settingswidget.h"
#define ARRAY_SIZE(arr) sizeof(arr)/sizeof(arr[0])
AASaver::AASaver( WId id ): KScreenSaver(id)
{
screen = new Screen(this);
addEnvironment();
addCastle();
addAllSeaweed();
addAllFish();
addRandom(screen);
setBackgroundMode(NoBackground);
setWFlags(WNoAutoErase);
update(rect());
}
TQString AASaver::randColor(TQString color_mask)
{
char colors[] = {'c','C','r','R','y','Y','b','B','g','G','m','M'};
for (int i = 1; i <= 9; ++i)
{
char color = colors[intRand(ARRAY_SIZE(colors))];
color_mask.replace('0' + i, color);
}
return color_mask;
}
void AASaver::addCastle()
{
TQString castle_image =
" T~~\n"
" |\n"
" /^\\\n"
" / \\\n"
" _ _ _ / \\ _ _ _\n"
"[ ]_[ ]_[ ]/ _ _ \\[ ]_[ ]_[ ]\n"
"|_=__-_ =_|_[ ]_[ ]_|_=-___-__|\n"
" | _- = | =_ = _ |= _= |\n"
" |= -[] |- = _ = |_-=_[] |\n"
" | =_ |= - ___ | =_ = |\n"
" |= []- |- /| |\\ |=_ =[] |\n"
" |- =_ | =| | | | |- = - |\n"
" |_______|__|_|_|_|__|_______|\n";
TQString castle_mask =
" RR\n"
"\n"
" yyy\n"
" y y\n"
" y y\n"
" y y\n"
"\n"
"\n"
"\n"
" yyy\n"
" yy yy\n"
" y y y y\n"
" yyyyyyy\n";
Frame f(castle_image, castle_mask, 0x686868/* XXX: why grey? */ );
Sprite* castle = new Sprite(screen,
screen->width() - 32, screen->height() - 13, 22);
castle->addFrame(f);
screen->addSprite(castle);
}
void AASaver::addEnvironment()
{
TQString water_line_segment[] = {
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"^^^^ ^^^ ^^^ ^^^ ^^^^ ",
"^^^^ ^^^^ ^^^ ^^ ",
"^^ ^^^^ ^^^ ^^^^^^ "
};
// tile the segments so they stretch across the screen
int segment_size = water_line_segment[0].length();
int segment_repeat = int(screen->width()/segment_size) + 1;
for (unsigned i = 0; i < ARRAY_SIZE(water_line_segment); ++i) {
//do the tiling
TQString out;
for (int r = 0; r < segment_repeat; ++r)
out += water_line_segment[i];
//create a sprite.
Sprite* s = new Sprite(screen, 0, i + 5, 22);
s->addFrame(Frame(out, TQString::null, 0x149494));
screen->addSprite(s);
}
}
void AASaver::addAllSeaweed()
{
// figure out how many seaweed to add by the width of the screen
int seaweed_count = int(screen->width() / 15.0);
for (int i = 1; i <= seaweed_count; ++i)
addSeaweed(screen);
}
/**
* Special class to represent seaweed. Seaweed can disappear over time, and
* when this happens, this class will automatically spawn another one.
*/
class Seaweed: public Sprite
{
int m_ticks; ///< Number of animation ticks elapsed.
int m_lifeTimeMS; ///< Life time of seaweed in milliseconds.
public:
/**
* Constructor. The \p x, \p y, and \p z coordinates are all in logical
* coordinates.
*
* @param s The Screen to be created in.
* @param x The x coordinate to place the seaweed at.
* @param y The y coordinate to place the seaweed at.
* @param life The length of time in milliseconds the seaweed will live for.
*/
Seaweed(Screen* s, int x, int y, int life): Sprite(s, x, y, 21),
m_ticks(0), m_lifeTimeMS(life)
{
}
/**
* Reimplemented from Sprite::tickUpdate() to handle keeping track of
* Seaweed lifetime. Calls the inherited tickUpdate() as well.
*/
virtual bool tickUpdate()
{
++m_ticks;
if (m_ticks * m_screen->msPerTick() > m_lifeTimeMS)
{
kill();
AASaver::addSeaweed(m_screen);
}
return Sprite::tickUpdate();
}
};
void AASaver::addSeaweed(Screen* screen)
{
TQString seaweed_image[] = {"", ""};
int height = intRand(5) + 3;
for (int i = 1; i <= height; ++i)
{
int left_side = i % 2;
int right_side = !left_side;
seaweed_image[left_side] += "(\n";
seaweed_image[right_side] += " )\n";
}
int x = intRand(screen->width() - 2) + 1;
int y = screen->height() - height;
Seaweed* s = new Seaweed(screen, x, y,
intRand(4*60000) + (8*60000)); // seaweed lives for 8 to 12 minutes
s->addFrame(Frame(seaweed_image[0], TQString::null, 0x18AF18));
s->addFrame(Frame(seaweed_image[1], TQString::null, 0x18AF18));
s->setFrameDelay(intRand(50) + 250);
screen->addSprite(s);
}
/**
* Class to represent an AirBubble. The bubble will automatically float up,
* even though it is not descended from MovingSprite.
*/
class AirBubble : public Sprite
{
const int m_startY; ///< Y coordinate we started at, needed to choose a frame.
public:
/**
* Constructor. The \p x, \p y, and \p z coordinates are all in logical
* coordinates.
*
* @param screen The Screen to be created in.
* @param x The x coordinate to start at.
* @param y The y coordinate to start at.
* @param z The depth to start at.
*/
AirBubble(Screen *screen, int x, int y, int z) :
Sprite(screen, x, y, z), m_startY(y)
{
addFrame(Frame(".", TQString(), 0x18B2B2));
addFrame(Frame("o", TQString(), 0x18B2B2));
addFrame(Frame("O", TQString(), 0x18B2B2));
setFrameDelay(100);
}
/**
* Reimplemented from Sprite::tickUpdate() to handle moving the sprite and
* updating the current frame. The inherited tickUpdate() is not called.
*/
virtual bool tickUpdate()
{
if (!timerTick())
return false;
erase();
m_currentFrame = 0;
if(m_startY - m_y > 5)
m_currentFrame = 1;
if(m_startY - m_y > 11)
m_currentFrame = 2;
m_y--;
if(m_y < 9)
kill();
return true;
}
};
/**
* Moving sprite, will be killed when it moves off of the screen.
*/
class MovingSprite: public Sprite
{
protected:
int m_direct; ///< Direction to move in, -1 == left, 1 == right.
double m_speed; ///< Speed to move at (Currently m_speed per tick).
double m_realX; ///< Used for accuracy, holds fractional x position.
int m_ticksSinceLastChange; ///< Number of timer ticks since last frame change.
int m_frameTime; ///< Amount of time in milliseconds to show each frame.
public:
/**
* Constructor. The \p x, \p y, and \p z coordinates are all in logical
* coordinates.
*
* @param screen The Screen to be created in.
* @param direct The direction to move the sprite in along the X axis, either
* -1 for the left direction, or 1 for the right direction.
* @param speed The speed to move the sprite in along the X axis, in
* character cells per tick. Use Screen::msPerTick() to find
* out how long a tick takes. The speed can be fractional
* (e.g. 1.5 cells per tick).
* @param x The x coordinate to start at.
* @param y The y coordinate to start at.
* @param z The depth to start at.
*/
MovingSprite(Screen* screen, int direct, double speed, int x, int y, int z):
Sprite(screen, x, y, z), m_direct(direct), m_speed(speed), m_realX(x),
m_ticksSinceLastChange(0), m_frameTime(250)
{
}
/**
* Sets the amount of time a frame is shown. Use this function for
* MovingSprites that are also animated.
*
* @param milliseconds Amount of time to show a frame for in milliseconds.
*/
void setFrameTime(int milliseconds)
{
m_frameTime = milliseconds;
}
/// Returns the amount of time a frame lasts in milliseconds.
int frameTime() const { return m_frameTime; }
/// Returns the direction the sprite travels in.
int direction() const
{
return m_direct;
}
/// Returns the fractional speed of the sprite.
double realSpeed() const
{
return m_speed;
}
/// Returns the real (fractional) X position of the sprite.
double realX() const
{
return m_realX;
}
/**
* Reimplemented from Sprite::tickUpdate() to handle motion and frame
* animation. This function will automatically kill() this sprite when
* it moves off screen. The inherited tickUpdate() is not called.
*/
virtual bool tickUpdate()
{
if (!timerTick())
return false;
erase();
m_realX += (m_direct * m_speed);
m_x = (int) m_realX;
++m_ticksSinceLastChange;
if(m_ticksSinceLastChange * m_screen->msPerTick() > m_frameTime)
{
m_ticksSinceLastChange = 0;
++m_currentFrame;
if(m_currentFrame == m_frames.size())
m_currentFrame = 0;
}
if((m_x + m_frames[m_currentFrame].width() < 0) || (m_x > m_screen->width()))
kill();
return true;
}
};
/**
* Will spawn a random sprite when killed, otherwise behaves just like
* MovingSprite.
*/
class RandomMovingSprite : public MovingSprite
{
public:
RandomMovingSprite(Screen *screen, int direct, double speed, int x, int y, int z):
MovingSprite(screen, direct, speed, x, y, z)
{
}
/// Spawns another RandomMovingSprite before dying.
virtual void kill()
{
MovingSprite::kill();
AASaver::addRandom(m_screen);
}
};
/**
* Special subclass that represents a fish. Used so TeethSprite knows when it
* has caused a collision, and also to handle air bubble generation.
*/
class FishSprite : public MovingSprite
{
double m_spacesPerBubble; ///< Amount of spaces a fish moves for each bubble.
double m_lastBubbleRelease; ///< Amount of space traveled since the last bubble.
public:
FishSprite(Screen* screen, int direct, double speed, int x, int y, int z):
MovingSprite(screen, direct, speed, x, y, z), m_lastBubbleRelease(x)
{
m_spacesPerBubble = AASaver::doubleRand(screen->width()) + 12.0;
}
/// Spawns another fish before dying.
virtual void kill()
{
MovingSprite::kill();
AASaver::addFish(m_screen);
}
/**
* Reimplemented from MovingSprite::tickUpdate() to handle creating air
* bubbles. Inherited tickUpdate() is still called.
*/
virtual bool tickUpdate()
{
if(!MovingSprite::tickUpdate())
return false;
if(isKilled())
return true;
if(TQABS(realX() - m_lastBubbleRelease) >= m_spacesPerBubble)
{
m_lastBubbleRelease = realX();
int bubbleX = m_x;
TQRect geometry = geom();
if(m_direct > 0) // Moving right
bubbleX += geometry.width();
AASaver::addBubble(m_screen, bubbleX, m_y + geometry.height() / 2 - 1, m_z - 1);
}
return true;
}
};
void AASaver::addAllFish()
{
// Determine how many logical pixels we are dealing with, and find out how
// many we'd be dealing with in full screen, and then scale the user's
// number down to adjust so that we look about the same in a window as we
// do fullscreen. TODO: Xinerama issues?
TQRect fullScreenGeometry = kapp->desktop()->screenGeometry();
int full_width = fullScreenGeometry.width() / screen->cellWidth();
int full_height = fullScreenGeometry.height() / screen->cellHeight() - 9;
int full_size = full_width * full_height;
int screen_size = (screen->height() - 9) * screen->width();
int fish_count = AASaverConfig::fishCount() * screen_size / full_size;
if(fish_count < 5)
fish_count = 5;
for (int i = 1; i <= fish_count; ++ i)
addFish(screen);
}
Sprite *AASaver::newFish(Screen *screen)
{
TQString fish_image[] = {
" \\\n"
" ...\\..,\n"
"\\" "??" "/' \\\n" // trigraphs suck
" >= ( ' >\n"
"/??\\ / /\n"
" `\"'\"'/''\n",
" 2\n"
" 1112111\n"
"6 11 1\n"
" 66 7 4 5\n"
"6 1 3 1\n"
" 11111311\n",
//////////////////////////////
" /\n"
" ,../...\n"
" / '\\" "??" "/\n" // trigraphs suck
"< ' ) =<\n"
" \\ \\ /??\\\n"
" `'\\'\"'\"'\n",
" 2\n"
" 1112111\n"
" 1 11 6\n"
"5 4 7 66\n"
" 1 3 1 6\n"
" 11311111\n",
//////////////////////////////
" \\\n"
"\\?/--\\\n"
">= (o>\n"
"/?\\__/\n"
" /\n",
" 2\n"
"6 1111\n"
"66 745\n"
"6 1111\n"
" 3\n",
//////////////////////////////
" /\n"
" /--\\?/\n"
"<o) =<\n"
" \\__/?\\\n"
" \\\n",
" 2\n"
" 1111 6\n"
"547 66\n"
" 1111 6\n"
" 3\n",
//////////////////////////////
" \\:.\n"
"\\;,???,;\\\\\\\\\\,,\n"
" \\\\\\\\\\;;:::::o\n"
" ///;;::::::::<\n"
" /;`?``/////``\n",
" 222\n"
"666 1122211\n"
" 6661111111114\n"
" 66611111111115\n"
" 666 113333311\n",
//////////////////////////////
" .:/\n"
" ,,///;,???,;/\n"
" o:::::::;;///\n"
">::::::::;;\\\\\\\n"
" ''\\\\\\\\\\''?';\\\n",
" 222\n"
" 1122211 666\n"
" 4111111111666\n"
"51111111111666\n"
" 113333311 666\n",
//////////////////////////////
" __\n"
"><_'>\n"
" '\n",
" 11\n"
"61145\n"
" 3\n",
//////////////////////////////
" __\n"
"<'_><\n"
" `\n",
" 11\n"
"54116\n"
" 3\n",
//////////////////////////////
" ..\\,\n"
">=' ('>\n"
" '''/''\n",
" 1121\n"
"661 745\n"
" 111311\n",
//////////////////////////////
" ,/..\n"
"<') `=<\n"
" ``\\```\n",
" 1211\n"
"547 166\n"
" 113111\n",
//////////////////////////////
" \\\n"
" / \\\n"
">=_('>\n"
" \\_/\n"
" /\n",
" 2\n"
" 1 1\n"
"661745\n"
" 111\n"
" 3\n",
//////////////////////////////
" /\n"
" / \\\n"
"<')_=<\n"
" \\_/\n"
" \\\n",
" 2\n"
" 1 1\n"
"547166\n"
" 111\n"
" 3\n",
//////////////////////////////
" ,\\\n"
">=('>\n"
" '/\n",
" 12\n"
"66745\n"
" 13\n",
//////////////////////////////
" /,\n"
"<')=<\n"
" \\`\n",
" 21\n"
"54766\n"
" 31\n",
//////////////////////////////
" __\n"
"\\/ o\\\n"
"/\\__/\n",
" 11\n"
"61 41\n"
"61111\n",
//////////////////////////////
" __\n"
"/o \\/\n"
"\\__/\\\n",
" 11\n"
"14 16\n"
"11116\n"
};
// # 1: body
// # 2: dorsal fin
// # 3: flippers
// # 4: eye
// # 5: mouth
// # 6: tailfin
// # 7: gills*
int fish_num = intRand(ARRAY_SIZE(fish_image)/2);
int fish_index = fish_num * 2;
double speed = doubleRand(2) + 0.25;
int depth = 3 + intRand(18);
TQString color_mask = fish_image[fish_index+1];
color_mask.replace('4', 'W');
color_mask = randColor(color_mask);
Frame fishFrame(fish_image[fish_index], color_mask, 0);
int max_height = 9;
int min_height = screen->height() - fishFrame.height();
int x, y, dir;
y = max_height + intRand(min_height - max_height);
if (fish_num % 2)
{
x = screen->width() - 2;
dir = -1;
}
else
{
x = 1 - fishFrame.width();
dir = 1;
}
Sprite* fish = new FishSprite(screen, dir, speed, x, y, depth);
fish->addFrame(fishFrame);
return fish;
}
void AASaver::addFish(Screen* screen)
{
screen->addSprite(newFish(screen));
}
/**
* Sprite that represents a blood "splat" in the water.
*/
class Splat : public Sprite
{
public:
/**
* Constructor.
*
* @param screen The Screen to create the splat in.
* @param center The point to center the splat around.
* @param depth The depth to create the splat at.
*/
Splat(Screen *screen, TQPoint center, int depth) :
Sprite(screen, 0, 0, depth, 450 /* frame Delay */)
{
TQString splats[] = {
"\n"
" .\n"
" ***\n"
" '\n"
""
,
"\n"
" \",*;`\n"
" \"*,**\n"
" *\"'~'\n"
""
,
" , ,\n"
" \" \",\"'\n"
" *\" *'\"\n"
" \" ; .\n"
""
,
"* ' , ' `\n"
"' ` * . '\n"
" ' `' \",'\n"
"* ' \" * .\n"
"\" * ', '"
};
for(unsigned i = 0; i < ARRAY_SIZE(splats); ++i)
addFrame(Frame(splats[i], TQString(), 0xB21818, ' '));
TQRect r(center, TQSize(9, 5));
r.moveCenter(center);
m_x = r.x();
m_y = r.y();
setDieAfterLastFrame(true);
}
};
/**
* Invisible sprite which are created on a shark's teeth, to handle collisions
* with fish, creating splats and kill()'ing the fish.
*/
class TeethSprite : public MovingSprite
{
public:
/**
* Constructor. Copied parameters as appropriate from \p shark.
*
* @param shark The shark to create the teeth over.
*/
TeethSprite(MovingSprite *shark) : MovingSprite(shark->screen(), shark->direction(),
shark->realSpeed(), 2 + shark->geom().left(), shark->geom().top(), shark->depth())
{
m_y += 7;
m_z -= 1;
m_realX = 2 + shark->realX();
if(m_direct > 0) // Moving to right.
m_realX = -10;
addFrame(Frame("????????", TQString(), 0));
}
/// Returns true since we can collide.
bool canCollide() const { return true; }
/**
* Reimplemented in order to handle collisions. When colliding with a
* FishSprite, the fish is kill()'ed and a splat is created in its place.
* Otherwise, nothing is done.
*
* @param sprite The Sprite we collided with.
*/
void collision(Sprite *sprite)
{
if(dynamic_cast<FishSprite *>(sprite)) {
kdDebug() << "A fish just got killinated!\n";
sprite->erase();
sprite->kill();
screen()->addSprite(new Splat(screen(), sprite->geom().center(), depth() - 1));
}
}
};
void AASaver::addShark(Screen* screen)
{
TQString shark_image[] = {
" __\n"
" ( `\\\n"
" ,??????????????????????????" ") `\\\n" // trigraphs suck
";' `.????????????????????????" "( `\\__\n" // trigraphs suck
" ; `.?????????????__..---'' `~~~~-._\n"
" `. `.____...--'' (b `--._\n"
" > _.-' .(( ._ )\n"
" .`.-`--...__ .-' -.___.....-(|/|/|/|/'\n"
" ;.'?????????`. ...----`.___.',,,_______......---'\n"
" '???????????" "'-'\n", // trigraphs suck
" \n"
" \n"
" \n"
" \n"
" \n"
" cR \n"
" \n"
" cWWWWWWWW \n"
" \n"
" \n",
" __\n"
" /' )\n"
" /' (??????????????????????????,\n"
" __/' )????????????????????????.' `;\n"
" _.-~~~~' ``---..__?????????????.' ;\n"
" _.--' b) ``--...____.' .'\n"
"( _. )). `-._ <\n"
" `\\|\\|\\|\\|)-.....___.- `-. __...--'-.'.\n"
" `---......_______,,,`.___.'----... .'?????????`.;\n"
" `-`???????????`\n",
" \n"
" \n"
" \n"
" \n"
" \n"
" Rc \n"
" \n"
" WWWWWWWWc \n"
" \n"
" \n"
};
int shark_num = intRand(ARRAY_SIZE(shark_image)/2);
int shark_index = shark_num * 2;
TQString color_mask = randColor(shark_image[shark_index+1]);
Frame sharkFrame(shark_image[shark_index], color_mask, 0x18B2B2);
int x = -53;
int y = 9 + intRand(screen->height() - (10 + 9));
int dir = (shark_num % 2) ? -1 : 1;
if(dir < 0)
x = screen->width() - 2;
RandomMovingSprite* shark = new RandomMovingSprite(screen, dir, 2, x, y, 2 /* Always at 2 */);
shark->addFrame(sharkFrame);
screen->addSprite(shark);
TeethSprite *teeth = new TeethSprite(shark);
screen->addSprite(teeth);
}
void AASaver::addBubble(Screen *screen, int x, int y, int z)
{
screen->addSprite(new AirBubble(screen, x, y, z));
}
void AASaver::addShip(Screen* screen)
{
TQString ship_image[] = {
" | | |\n"
" )_) )_) )_)\n"
" )___))___))___)\\\n"
" )____)____)_____)\\\\\n"
"_____|____|____|____\\\\\\__\n"
"\\ /",
" y y y\n"
" \n"
" w\n"
" ww\n"
"yyyyyyyyyyyyyyyyyyyywwwyy\n"
"y y",
" | | |\n"
" (_( (_( (_(\n"
" /(___((___((___(\n"
" //(_____(____(____(\n"
"__///____|____|____|_____\n"
" \\ /",
" y y y\n"
" \n"
" w \n"
" ww \n"
"yywwwyyyyyyyyyyyyyyyyyyyy\n"
" y y"
};
int ship_num = intRand(17) % 2; // right == 0, left == 1
int x = -24, dir = 1;
if(ship_num == 1) {
x = screen->width() - 2;
dir = -1;
}
RandomMovingSprite *ship = new RandomMovingSprite(screen, dir, 1.0, x, 0, 2);
ship->addFrame(Frame(ship_image[2 * ship_num], ship_image[2 * ship_num + 1], 0xFFFFFF));
screen->addSprite(ship);
}
void AASaver::addWhale(Screen* screen)
{
TQString whale_image[] = {
" .-----:\n"
" .' `.\n"
",????/ (o) \\\n"
"\\`._/ ,__)",
" C C\n"
" CCCCCCC\n"
" C C C\n"
" BBBBBBB\n"
" BB BB\n"
"B B BWB B\n"
"BBBBB BBBB",
" :-----.\n"
" .' `.\n"
" / (o) \\????,\n"
"(__, \\_.'/",
" C C\n"
" CCCCCCC\n"
" C C C\n"
" BBBBBBB\n"
" BB BB\n"
" B BWB B B\n"
"BBBB BBBBB"
};
TQString spouty[] = {
"\n"
"\n"
" :",
"\n"
" :\n"
" :",
" . .\n"
" -:-\n"
" :",
" . .\n"
" .-:-.\n"
" :",
" . .\n"
"'.-:-.`\n"
"' : '",
"\n"
" .- -.\n"
"; : ;",
"\n"
"\n"
"; ;"
};
int whale_num = intRand(2); // 0 = right, 1 = left
int x = -18, spout_align = 11, dir = 1;
if (whale_num == 1)
{
x = screen->width() - 2;
spout_align = 1; // Waterspout closer to left side now.
dir = -1;
}
TQString mask = whale_image[2 * whale_num + 1];
RandomMovingSprite *whale = new RandomMovingSprite(screen, dir, 1.0, x, 0, 2);
whale->setFrameDelay(80);
whale->setFrameTime(40);
// We have to add some frames now. The first five will have no water spout.
TQString blankWhaleFrame = TQString("\n\n\n") + whale_image[2 * whale_num];
for(unsigned i = 0; i < 5; ++i)
whale->addFrame(Frame(blankWhaleFrame, mask, 0xFFFFFF));
// Now add frames for the animated water spout.
TQString whaleFrame = whale_image[2 * whale_num];
for (unsigned i = 0; i < ARRAY_SIZE(spouty); ++i)
{
TQStringList spoutLines = TQStringList::split("\n", spouty[i], true);
TQString spout;
TQString padding;
padding.fill(' ', spout_align);
// Move spout over an appropriate distance to line up right.
for(TQStringList::ConstIterator it = spoutLines.begin(); it != spoutLines.end(); ++it)
{
spout += padding;
spout += *it;
spout += "\n";
}
// Add spout to whale frame.
whale->addFrame(Frame(spout + whaleFrame, mask, 0xFFFFFF));
}
screen->addSprite(whale);
}
void AASaver::addBigFish(Screen* screen)
{
TQString big_fish_image[] = {
" ______\n"
"`\"\"-. `````-----.....__\n"
" `. . . `-.\n"
" : . . `.\n"
" ,?????: . . _ :\n"
": `.???: (@) `._\n"
" `. `..' . =`-. .__)\n"
" ; . = ~ : .-\"\n"
" .' .'`. . . =.-' `._ .'\n"
": .'???: . .'\n"
" '???.' . . . .-'\n"
" .'____....----''.'=.'\n"
" \"\"?????????????.'.'\n"
" ''\"'`",
" 111111\n"
"11111 11111111111111111\n"
" 11 2 2 111\n"
" 1 2 2 11\n"
" 1 1 2 2 1 1\n"
"1 11 1 1W1 111\n"
" 11 1111 2 1111 1111\n"
" 1 2 1 1 1 111\n"
" 11 1111 2 2 1111 111 11\n"
"1 11 1 2 11\n"
" 1 11 2 2 2 111\n"
" 111111111111111111111\n"
" 11 1111\n"
" 11111",
" ______\n"
" __.....-----''''' .-\"\"'\n"
" .-' . . .'\n"
" .' . . :\n"
" : _ . . :?????,\n"
" _.' (@) :???.' :\n"
"(__. .-'= . `..' .'\n"
" \"-. : ~ = . ;\n"
" `. _.' `-.= . . .'`. `.\n"
" `. . :???`. :\n"
" `-. . . . `.???`\n"
" `.=`.``----....____`.\n"
" `.`.?????????????\"\"\n"
" '`\"``",
" 111111\n"
" 11111111111111111 11111\n"
" 111 2 2 11\n"
" 11 2 2 1\n"
" 1 1 2 2 1 1\n"
" 111 1W1 1 11 1\n"
"1111 1111 2 1111 11\n"
" 111 1 1 1 2 1\n"
" 11 111 1111 2 2 1111 11\n"
" 11 2 1 11 1\n"
" 111 2 2 2 11 1\n"
" 111111111111111111111\n"
" 1111 11\n"
" 11111"
};
int big_fish_num = intRand(2); // right = 0, left = 1
int maxHeight = 9, minHeight = screen->height() - 15;
int y = intRand(minHeight - maxHeight) + maxHeight;
int x = -34, dir = 1;
if(big_fish_num == 1)
{
x = screen->width() - 1;
dir = -1;
}
TQString colors = randColor(big_fish_image[2 * big_fish_num + 1]);
RandomMovingSprite *bigFish = new RandomMovingSprite(screen, dir, 3.0, x, y, 2);
bigFish->addFrame(Frame(big_fish_image[2 * big_fish_num], colors, 0xFFFF54));
screen->addSprite(bigFish);
}
void AASaver::addNessie(Screen* screen)
{
TQString nessie_image[] = {
" ____\n"
" __??????????????????????????????????????????/ o \\\n"
" / \\????????_?????????????????????_???????/ ____ >\n"
" _??????| __ |?????/ \\????????_????????/ \\????| |\n"
" | \\?????| || |????| |?????/ \\?????| |???| |",
" ____\n"
" __?????????/ o \\\n"
" _?????????????????????_???????/ \\?????/ ____ >\n"
" _???????/ \\????????_????????/ \\????| __ |???| |\n"
" | \\?????| |?????/ \\?????| |???| || |???| |\n",
" ____\n"
" __????????????????????/ o \\\n"
" _??????????????????????_???????/ \\????????_???????/ ____ >\n"
"| \\??????????_????????/ \\????| __ |?????/ \\????| |\n"
" \\ \\???????/ \\?????| |???| || |????| |???| |",
" ____\n"
" __???????????????????????????????/ o \\\n"
" _??????????_???????/ \\????????_??????????????????/ ____ >\n"
" | \\???????/ \\????| __ |?????/ \\????????_??????| |\n"
" \\ \\?????| |???| || |????| |?????/ \\????| |",
" ____\n"
" / o \\??????????????????????????????????????????__\n"
"< ____ \\???????_?????????????????????_????????/ \\\n"
" | |????/ \\????????_????????/ \\?????| __ |??????_\n"
" | |???| |?????/ \\?????| |????| || |?????/ |",
" ____\n"
" / o \\?????????__\n"
"< ____ \\?????/ \\???????_?????????????????????_\n"
" | |???| __ |????/ \\????????_????????/ \\???????_\n"
" | |???| || |???| |?????/ \\?????| |?????/ |",
" ____\n"
" / o \\????????????????????__\n"
"< ____ \\???????_????????/ \\???????_??????????????????????_\n"
" | |????/ \\?????| __ |????/ \\????????_??????????/ |\n"
" | |???| |????| || |???| |?????/ \\???????/ /",
" ____\n"
" / o \\???????????????????????????????__\n"
"< ____ \\??????????????????_????????/ \\???????_??????????_\n"
" | |??????_????????/ \\?????| __ |????/ \\???????/ |\n"
" | |????/ \\?????| |????| || |???| |?????/ /"
};
TQString nessie_mask[] = {
"\n"
" W\n"
"\n"
"\n"
"\n"
"",
"\n"
" W\n"
"\n"
"\n"
"\n"
""
};
int nessie_num = intRand(2); // 0 = right, 1 = left.
int x = -64, dir = 1;
if(nessie_num == 1) {
x = screen->width() - 2;
dir = -1;
}
RandomMovingSprite *nessie = new RandomMovingSprite(screen, dir, 1.4, x, 2, 2);
nessie->setFrameDelay(75);
nessie->setFrameTime(400);
for(unsigned i = 0; i < 4; ++i)
nessie->addFrame(Frame(nessie_image[nessie_num * 4 + i], nessie_mask[nessie_num], 0x18B218));
screen->addSprite(nessie);
}
void AASaver::addRandom(Screen* screen)
{
const char *const cute_messages[] = {
"Quick, someone cue the ominous music!",
"Her continuing mission... to explore strange new seas...",
"I caught one that big once, but it got away. :(",
"Nessie, an Earthbound hero's best friend...",
"Thar be WHALES, Cap'n!!"
};
int choice = intRand(5);
if(intRand(45) < 7 && choice < ARRAY_SIZE(cute_messages))
kdDebug() << cute_messages[choice] << endl;
switch(choice)
{
case 0:
addShark(screen);
break;
case 1:
addShip(screen);
break;
case 2:
addBigFish(screen);
break;
case 3:
addNessie(screen);
break;
case 4:
addWhale(screen);
break;
}
}
void AASaver::paintEvent(TQPaintEvent* pe)
{
screen->paint(pe->region());
}
// libkscreensaver interface
extern "C"
{
KDE_EXPORT const char *kss_applicationName = "tdeasciiquarium.kss";
KDE_EXPORT const char *kss_description = I18N_NOOP( "TDEAsciiquarium" );
KDE_EXPORT const char *kss_version = "0.3.2";
KDE_EXPORT KScreenSaver *kss_create( WId id )
{
return new AASaver( id );
}
KDE_EXPORT TQDialog *kss_setup()
{
TDEConfigDialog *dialog = TDEConfigDialog::exists("settings");
if(dialog)
return dialog;
dialog = new TDEConfigDialog(0, "settings", AASaverConfig::self());
SettingsWidget *settings = new SettingsWidget(0, "settings_widget");
dialog->addPage(settings, i18n("TDEAsciiquarium Settings"), "tdescreensaver");
return dialog;
}
}