/xbmc/screensavers/rsxs-0.9/src/euphoria/euphoria.cc
http://github.com/xbmc/xbmc · C++ · 475 lines · 381 code · 58 blank · 36 comment · 19 complexity · 1ddb63e4a7bca23c695e3b4fd4aaa66c MD5 · raw file
- /*
- * Really Slick XScreenSavers
- * Copyright (C) 2002-2006 Michael Chapman
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *****************************************************************************
- *
- * This is a Linux port of the Really Slick Screensavers,
- * Copyright (C) 2002 Terence M. Welsh, available from www.reallyslick.com
- */
- #include <common.hh>
- #include <euphoria.hh>
- #include <hack.hh>
- #include <pngimage.hh>
- #include <wisp.hh>
- namespace Hack {
- unsigned int numWisps = 5;
- unsigned int numBackWisps = 0;
- unsigned int density = 25;
- float visibility = 35.0f;
- float speed = 15.0f;
- float feedback = 0.0f;
- float feedbackSpeed = 1.0f;
- unsigned int feedbackSize = 8;
- std::string texture;
- bool wireframe = false;
- };
- namespace Hack {
- enum Arguments {
- ARG_WISPS = 1,
- ARG_BACKWISPS,
- ARG_DENSITY,
- ARG_VISIBILITY,
- ARG_SPEED,
- ARG_FEEDBACK,
- ARG_FEEDBACKSPEED,
- ARG_FEEDBACKSIZE,
- ARG_TEXTURE,
- ARG_WIREFRAME = 0x100, ARG_NO_WIREFRAME,
- ARG_NO_TEXTURE = 0x200, ARG_PLASMA_TEXTURE, ARG_STRINGY_TEXTURE,
- ARG_LINES_TEXTURE, ARG_RANDOM_TEXTURE
- };
- float _fr[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
- float _fv[4];
- float _f[4];
- float _lr[3] = { 0.0f, 0.0f, 0.0f };
- float _lv[3];
- float _l[3];
- GLuint _tex;
- GLuint _feedbackTex;
- unsigned int _feedbackTexSize;
- stdx::dim3<GLubyte, 3> _feedbackMap;
- std::vector<Wisp> _backWisps;
- std::vector<Wisp> _wisps;
- error_t parse(int, char*, struct argp_state*);
- };
- error_t Hack::parse(int key, char* arg, struct argp_state* state) {
- retry:
- switch (key) {
- case ARG_WISPS:
- if (Common::parseArg(arg, numWisps, 0u, 100u))
- argp_failure(state, EXIT_FAILURE, 0,
- "number of wisps must be between 0 and 100");
- return 0;
- case ARG_BACKWISPS:
- if (Common::parseArg(arg, numBackWisps, 0u, 100u))
- argp_failure(state, EXIT_FAILURE, 0,
- "number of background layers must be between 0 and 100");
- return 0;
- case ARG_DENSITY:
- if (Common::parseArg(arg, density, 2u, 100u))
- argp_failure(state, EXIT_FAILURE, 0,
- "mesh density must be between 2 and 100");
- return 0;
- case ARG_VISIBILITY:
- if (Common::parseArg(arg, visibility, 1.0f, 100.0f))
- argp_failure(state, EXIT_FAILURE, 0,
- "mesh visibility must be between 1 and 100");
- return 0;
- case ARG_SPEED:
- if (Common::parseArg(arg, speed, 1.0f, 100.0f))
- argp_failure(state, EXIT_FAILURE, 0,
- "motion speed must be between 1 and 100");
- return 0;
- case ARG_FEEDBACK:
- if (Common::parseArg(arg, feedback, 0.0f, 100.0f))
- argp_failure(state, EXIT_FAILURE, 0,
- "feedback intensity must be between 0 and 100");
- return 0;
- case ARG_FEEDBACKSPEED:
- if (Common::parseArg(arg, feedbackSpeed, 1.0f, 100.0f))
- argp_failure(state, EXIT_FAILURE, 0,
- "feedback speed must be between 1 and 100");
- return 0;
- case ARG_FEEDBACKSIZE:
- if (Common::parseArg(arg, feedbackSize, 1u, 10u))
- argp_failure(state, EXIT_FAILURE, 0,
- "feedback speed must be between 1 and 10");
- return 0;
- case ARG_WIREFRAME:
- wireframe = true;
- return 0;
- case ARG_NO_WIREFRAME:
- wireframe = false;
- return 0;
- case ARG_TEXTURE:
- texture = arg;
- return 0;
- case ARG_NO_TEXTURE:
- texture = "";
- return 0;
- case ARG_PLASMA_TEXTURE:
- texture = "plasma.png";
- return 0;
- case ARG_STRINGY_TEXTURE:
- texture = "stringy.png";
- return 0;
- case ARG_LINES_TEXTURE:
- texture = "lines.png";
- return 0;
- case ARG_RANDOM_TEXTURE:
- key = Common::randomInt(3) + ARG_PLASMA_TEXTURE;
- goto retry;
- default:
- return ARGP_ERR_UNKNOWN;
- }
- }
- const struct argp* Hack::getParser() {
- static struct argp_option options[] = {
- { NULL, 0, NULL, 0, "Global options:" },
- { "wisps", ARG_WISPS, "NUM", 0, "Number of wisps (0-100, default = 5)" },
- { "background", ARG_BACKWISPS, "NUM", 0,
- "Number of background layers (0-100, default = 0)" },
- { NULL, 0, NULL, 0, "Wisp mesh options:" },
- { "density", ARG_DENSITY, "NUM", 0,
- "Mesh density (2-100, default = 25)" },
- { "speed", ARG_SPEED, "NUM", 0,
- "Motion speed (1-100, default = 15)" },
- { "visibility", ARG_VISIBILITY, "NUM", 0,
- "Mesh visibility (1-100, default = 35)" },
- { "wireframe", ARG_WIREFRAME, NULL, 0,
- "Enable wireframe mesh" },
- { "no-wireframe", ARG_NO_WIREFRAME, NULL, OPTION_ALIAS | OPTION_HIDDEN },
- { "texture", ARG_TEXTURE, "FILE", 0,
- "Wisp texture (default = no texture)" },
- { NULL, 0, NULL, 0, "Predefined textures:" },
- { "plain", ARG_NO_TEXTURE, NULL, 0 },
- { "plasma", ARG_PLASMA_TEXTURE, NULL, 0 },
- { "stringy", ARG_STRINGY_TEXTURE, NULL, 0 },
- { "lines", ARG_LINES_TEXTURE, NULL, 0 },
- { "random", ARG_RANDOM_TEXTURE, NULL, 0 },
- { NULL, 0, NULL, 0, "Feedback options:" },
- { "feedback", ARG_FEEDBACK, "NUM", 0,
- "Feedback intensity (0-100, default = 0)" },
- { "feedbackspeed", ARG_FEEDBACKSPEED, "NUM", 0,
- "Feedback speed (1-100, default = 1)" },
- { "feedbacksize", ARG_FEEDBACKSIZE, "NUM", 0,
- "Feedback size (1-10, default = 3)" },
- {}
- };
- static struct argp parser = {
- options, parse, NULL,
- "Draws patterned wisps, with optional psychadelic feedback."
- };
- return &parser;
- }
- std::string Hack::getShortName() { return "euphoria"; }
- std::string Hack::getName() { return "Euphoria"; }
- void Hack::start() {
- glViewport(0, 0, Common::width, Common::height);
- _tex = 0;
- if (texture.length()) {
- glEnable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- _tex = Common::resources->genTexture(
- GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT,
- PNG(texture)
- );
- }
- if (feedback > 0.0f) {
- _feedbackTexSize = 1 << feedbackSize;
- while (
- (_feedbackTexSize > Common::width) ||
- (_feedbackTexSize > Common::height)
- )
- _feedbackTexSize >>= 1;
- // feedback texture setup
- glEnable(GL_TEXTURE_2D);
- _feedbackMap.resize(_feedbackTexSize, _feedbackTexSize);
- _feedbackTex = Common::resources->genTexture(
- GL_LINEAR, GL_LINEAR, GL_CLAMP, GL_CLAMP,
- 3, _feedbackTexSize, _feedbackTexSize,
- GL_RGB, GL_UNSIGNED_BYTE, &_feedbackMap.front(), false
- );
- // feedback velocity variable setup
- _fv[0] = feedbackSpeed * (Common::randomFloat(0.025f) + 0.025f);
- _fv[1] = feedbackSpeed * (Common::randomFloat(0.05f) + 0.05f);
- _fv[2] = feedbackSpeed * (Common::randomFloat(0.05f) + 0.05f);
- _fv[3] = feedbackSpeed * (Common::randomFloat(0.1f) + 0.1f);
- _lv[0] = feedbackSpeed * (Common::randomFloat(0.0025f) + 0.0025f);
- _lv[1] = feedbackSpeed * (Common::randomFloat(0.0025f) + 0.0025f);
- _lv[2] = feedbackSpeed * (Common::randomFloat(0.0025f) + 0.0025f);
- }
- // Initialize wisps
- stdx::construct_n(_wisps, numWisps);
- stdx::construct_n(_backWisps, numBackWisps);
- }
- void Hack::tick() {
- Common::run();
- // setup regular drawing area just in case feedback isn't used
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- gluPerspective(20.0, Common::aspectRatio, 0.01, 20);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- glTranslatef(0.0, 0.0, -5.0);
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE);
- glLineWidth(2.0f);
- glEnable(GL_LINE_SMOOTH);
- glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
- // Update wisps
- stdx::call_all(_wisps, &Wisp::update);
- stdx::call_all(_backWisps, &Wisp::update);
- if (feedback > 0.0f) {
- static float feedbackIntensity = feedback / 101.0f;
- // update feedback variables
- for (unsigned int i = 0; i < 4; ++i) {
- _fr[i] += Common::elapsedSecs * _fv[i];
- if (_fr[i] > M_PI * 2.0f)
- _fr[i] -= M_PI * 2.0f;
- }
- _f[0] = 30.0f * std::cos(_fr[0]);
- _f[1] = 0.2f * std::cos(_fr[1]);
- _f[2] = 0.2f * std::cos(_fr[2]);
- _f[3] = 0.8f * std::cos(_fr[3]);
- for (unsigned int i = 0; i < 3; ++i) {
- _lr[i] += Common::elapsedSecs * _lv[i];
- if (_lr[i] > M_PI * 2.0f)
- _lr[i] -= M_PI * 2.0f;
- _l[i] = std::cos(_lr[i]);
- _l[i] = _l[i] * _l[i];
- }
- // Create drawing area for feedback texture
- glViewport(0, 0, _feedbackTexSize, _feedbackTexSize);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(30.0, Common::aspectRatio, 0.01f, 20.0f);
- glMatrixMode(GL_MODELVIEW);
- // Draw
- glClear(GL_COLOR_BUFFER_BIT);
- glColor3f(feedbackIntensity, feedbackIntensity, feedbackIntensity);
- glBindTexture(GL_TEXTURE_2D, _feedbackTex);
- glPushMatrix();
- glTranslatef(_f[1] * _l[1], _f[2] * _l[1], _f[3] * _l[2]);
- glRotatef(_f[0] * _l[0], 0, 0, 1);
- glBegin(GL_TRIANGLE_STRIP);
- glTexCoord2f(-0.5f, -0.5f);
- glVertex3f(-Common::aspectRatio * 2.0f, -2.0f, 1.25f);
- glTexCoord2f(1.5f, -0.5f);
- glVertex3f(Common::aspectRatio * 2.0f, -2.0f, 1.25f);
- glTexCoord2f(-0.5f, 1.5f);
- glVertex3f(-Common::aspectRatio * 2.0f, 2.0f, 1.25f);
- glTexCoord2f(1.5f, 1.5f);
- glVertex3f(Common::aspectRatio * 2.0f, 2.0f, 1.25f);
- glEnd();
- glPopMatrix();
- glBindTexture(GL_TEXTURE_2D, _tex);
- stdx::call_all(_backWisps, &Wisp::drawAsBackground);
- stdx::call_all(_wisps, &Wisp::draw);
- // readback feedback texture
- glReadBuffer(GL_BACK);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, _feedbackTexSize);
- glBindTexture(GL_TEXTURE_2D, _feedbackTex);
- glReadPixels(0, 0, _feedbackTexSize, _feedbackTexSize, GL_RGB,
- GL_UNSIGNED_BYTE, &_feedbackMap.front());
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _feedbackTexSize, _feedbackTexSize,
- GL_RGB, GL_UNSIGNED_BYTE, &_feedbackMap.front());
- // create regular drawing area
- glViewport(0, 0, Common::width, Common::height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(20.0, Common::aspectRatio, 0.01f, 20.0f);
- glMatrixMode(GL_MODELVIEW);
- // Draw again
- glClear(GL_COLOR_BUFFER_BIT);
- glColor3f(feedbackIntensity, feedbackIntensity, feedbackIntensity);
- glPushMatrix();
- glTranslatef(_f[1] * _l[1], _f[2] * _l[1], _f[3] * _l[2]);
- glRotatef(_f[0] * _l[0], 0, 0, 1);
- glBegin(GL_TRIANGLE_STRIP);
- glTexCoord2f(-0.5f, -0.5f);
- glVertex3f(-Common::aspectRatio * 2.0f, -2.0f, 1.25f);
- glTexCoord2f(1.5f, -0.5f);
- glVertex3f(Common::aspectRatio * 2.0f, -2.0f, 1.25f);
- glTexCoord2f(-0.5f, 1.5f);
- glVertex3f(-Common::aspectRatio * 2.0f, 2.0f, 1.25f);
- glTexCoord2f(1.5f, 1.5f);
- glVertex3f(Common::aspectRatio * 2.0f, 2.0f, 1.25f);
- glEnd();
- glPopMatrix();
- glBindTexture(GL_TEXTURE_2D, _tex);
- } else
- glClear(GL_COLOR_BUFFER_BIT);
- stdx::call_all(_backWisps, &Wisp::drawAsBackground);
- stdx::call_all(_wisps, &Wisp::draw);
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- //Common::flush();
- // Clear the error flag
- glGetError();
- }
- void Hack::reshape() {
- glViewport(0, 0, Common::width, Common::height);
- // setup regular drawing area just in case feedback isn't used
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(20.0, Common::aspectRatio, 0.01, 20);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.0, 0.0, -5.0);
- }
- void Hack::stop() {
- _wisps.clear();
- _backWisps.clear();
- _feedbackMap.clear();
- }
- void Hack::keyPress(char c, const KeySym&) {
- switch (c) {
- case 3: case 27:
- case 'q': case 'Q':
- Common::running = false;
- break;
- }
- }
- void Hack::keyRelease(char, const KeySym&) {}
- void Hack::pointerMotion(int, int) {}
- void Hack::buttonPress(unsigned int) {}
- void Hack::buttonRelease(unsigned int) {}
- void Hack::pointerEnter() {}
- void Hack::pointerLeave() {}
- #define _LINUX
- #include "../../../addons/include/xbmc_scr_dll.h"
- extern "C" {
- ADDON_STATUS ADDON_Create(void* hdl, void* props)
- {
- if (!props)
- return ADDON_STATUS_UNKNOWN;
- SCR_PROPS* scrprops = (SCR_PROPS*)props;
- Common::width = scrprops->width;
- Common::height = scrprops->height;
- Common::aspectRatio = float(Common::width) / float(Common::height);
- Common::init(0, NULL);
- return ADDON_STATUS_OK;
- }
- void Start()
- {
- Hack::start();
- }
- void Render()
- {
- Hack::tick();
- }
- void ADDON_Stop()
- {
- Hack::stop();
- }
- void ADDON_Destroy()
- {
- }
- ADDON_STATUS ADDON_GetStatus()
- {
- return ADDON_STATUS_OK;
- }
- bool ADDON_HasSettings()
- {
- return false;
- }
- unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet)
- {
- return 0;
- }
- ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue)
- {
- return ADDON_STATUS_OK;
- }
- void ADDON_FreeSettings()
- {
- }
- void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data)
- {
- }
- void GetInfo(SCR_INFO *info)
- {
- }
- void Remove()
- {
- }
- }