diff options
author | gregory guy <gregory-tde@laposte.net> | 2021-04-26 18:43:25 +0200 |
---|---|---|
committer | gregory guy <gregory-tde@laposte.net> | 2021-05-20 20:16:35 +0200 |
commit | 749694a3f2fecddf44633067c24851d8719b181e (patch) | |
tree | 27c58f5c28223c8ae9aa5a01409a5e12ff0c52ca /tdescreensaver/kdesavers/tdeasciiquarium/aasaver.cpp | |
parent | b0ef1b76e6bc94f5a8a35b9a43573eab81bca459 (diff) | |
download | tdeartwork-749694a3f2fecddf44633067c24851d8719b181e.tar.gz tdeartwork-749694a3f2fecddf44633067c24851d8719b181e.zip |
asciiquarium: Add cmake build support, app is renamed tdeasciiquarium.
Signed-off-by: gregory guy <gregory-tde@laposte.net>
Diffstat (limited to 'tdescreensaver/kdesavers/tdeasciiquarium/aasaver.cpp')
-rw-r--r-- | tdescreensaver/kdesavers/tdeasciiquarium/aasaver.cpp | 1220 |
1 files changed, 1220 insertions, 0 deletions
diff --git a/tdescreensaver/kdesavers/tdeasciiquarium/aasaver.cpp b/tdescreensaver/kdesavers/tdeasciiquarium/aasaver.cpp new file mode 100644 index 00000000..daf09d97 --- /dev/null +++ b/tdescreensaver/kdesavers/tdeasciiquarium/aasaver.cpp @@ -0,0 +1,1220 @@ +//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; + } +} |