diff --git a/src/add-ons/screen_savers/Jamfile b/src/add-ons/screen_savers/Jamfile index d656a246d3..55b775a4ff 100644 --- a/src/add-ons/screen_savers/Jamfile +++ b/src/add-ons/screen_savers/Jamfile @@ -1,6 +1,8 @@ SubDir HAIKU_TOP src add-ons screen_savers ; SubInclude HAIKU_TOP src add-ons screen_savers debugnow ; +SubInclude HAIKU_TOP src add-ons screen_savers flurry ; +SubInclude HAIKU_TOP src add-ons screen_savers GLife ; SubInclude HAIKU_TOP src add-ons screen_savers haiku ; SubInclude HAIKU_TOP src add-ons screen_savers ifs ; SubInclude HAIKU_TOP src add-ons screen_savers message ; diff --git a/src/add-ons/screen_savers/flurry/Flurry.cpp b/src/add-ons/screen_savers/flurry/Flurry.cpp new file mode 100644 index 0000000000..73315c9b9d --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Flurry.cpp @@ -0,0 +1,388 @@ +/* + +Copyright (c) 2002, Calum Robinson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +/* + * Copyright Karsten Heimrich, host.haiku@gmx.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#include "Flurry.h" + +#include "Shared.h" +#include "Smoke.h" +#include "Spark.h" +#include "Star.h" +#include "Texture.h" + + +#include +#include +#include +#include + + +using namespace BPrivate; + + +FlurryView::FlurryView(BRect bounds) + : BGLView(bounds, NULL, B_FOLLOW_ALL, B_FRAME_EVENTS | B_WILL_DRAW, + BGL_RGB | BGL_ALPHA | BGL_DEPTH | BGL_DOUBLE), + fOldFrameTime(-1.0), + fFlurryInfo_t(NULL) +{ + fWidth = bounds.Width(); + fHeight = bounds.Height(); + fStartTime = _CurrentTime(); + + LockGL(); + _SetupFlurryBaseInfo(); + UnlockGL(); + + +} + + +FlurryView::~FlurryView() +{ + if (fFlurryInfo_t) { + LockGL(); + + free(fFlurryInfo_t->s); + free(fFlurryInfo_t->star); + for (int32 i = 0; i < MAX_SPARKS; ++i) + free(fFlurryInfo_t->spark[i]); + free(fFlurryInfo_t); + + UnlockGL(); + } +} + + +status_t +FlurryView::InitCheck() const +{ + return (fFlurryInfo_t != NULL) ? B_OK : B_ERROR; +} + + +void +FlurryView::AttachedToWindow() +{ + LockGL(); + + BGLView::AttachedToWindow(); + + MakeTexture(); + + glDisable(GL_DEPTH_TEST); + glAlphaFunc(GL_GREATER, 0.0); + glEnable(GL_ALPHA_TEST); + glShadeModel(GL_FLAT); + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + + glViewport(0, 0, int(fWidth), int(fHeight)); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0.0, fWidth, 0.0, fHeight); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + UnlockGL(); +} + + +void +FlurryView::DrawFlurryScreenSaver() +{ + double deltaFrameTime = 0.0; + const double newFrameTime = _CurrentTime(); + + GLfloat alpha = 1.0; + if (fOldFrameTime >= 0.0) { + deltaFrameTime = newFrameTime - fOldFrameTime; + alpha = 5.0 * deltaFrameTime; + + if (alpha > 0.2) + alpha = 0.2; + } + + fOldFrameTime = newFrameTime; + + LockGL(); + + // TODO: enable once double buffering is supported + //glDrawBuffer(GL_BACK); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glColor4f(0.0, 0.0, 0.0, alpha); + glRectd(0.0, 0.0, fWidth, fHeight); + + fFlurryInfo_t->dframe++; + fFlurryInfo_t->fOldTime = fFlurryInfo_t->fTime; + fFlurryInfo_t->fTime = _SecondsSinceStart() + fFlurryInfo_t->randomSeed; + fFlurryInfo_t->fDeltaTime = fFlurryInfo_t->fTime - fFlurryInfo_t->fOldTime; + fFlurryInfo_t->drag = (float)pow(0.9965, fFlurryInfo_t->fDeltaTime * 85.0); + + UpdateStar(fFlurryInfo_t, fFlurryInfo_t->star); + + glEnable(GL_BLEND); + glShadeModel(GL_SMOOTH); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + for (int32 i = 0; i < fFlurryInfo_t->numStreams; ++i) { + fFlurryInfo_t->spark[i]->color[0] = 1.0; + fFlurryInfo_t->spark[i]->color[1] = 1.0; + fFlurryInfo_t->spark[i]->color[2] = 1.0; + fFlurryInfo_t->spark[i]->color[3] = 1.0; + + UpdateSpark(fFlurryInfo_t, fFlurryInfo_t->spark[i]); + } + + UpdateSmoke_ScalarBase(fFlurryInfo_t, fFlurryInfo_t->s); + + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + const double brite = pow(deltaFrameTime, 0.75) * 10.0; + DrawSmoke_Scalar(fFlurryInfo_t, fFlurryInfo_t->s, + brite * fFlurryInfo_t->briteFactor); + + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + + glFinish(); + + SwapBuffers(); + UnlockGL(); +} + + +void +FlurryView::FrameResized(float newWidth, float newHeight) +{ + LockGL(); + + BGLView::FrameResized(newWidth, newHeight); + + if (fFlurryInfo_t) { + fWidth = newWidth; + fHeight = newHeight; + + fFlurryInfo_t->sys_glWidth = fWidth; + fFlurryInfo_t->sys_glHeight = fHeight; + + glViewport(0, 0, int(fWidth), int(fHeight)); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0.0, fWidth, 0.0, fHeight); + glMatrixMode(GL_MODELVIEW); + + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + glFlush(); + } + + UnlockGL(); +} + + +void +FlurryView::_SetupFlurryBaseInfo() +{ + fFlurryInfo_t = (flurry_info_t *)malloc(sizeof(flurry_info_t)); + + if (!fFlurryInfo_t) + return; + + fFlurryInfo_t->next = NULL; + fFlurryInfo_t->randomSeed = RandFlt(0.0, 300.0); + + fFlurryInfo_t->dframe = 0; + fFlurryInfo_t->fOldTime = 0.0; + fFlurryInfo_t->sys_glWidth = fWidth; + fFlurryInfo_t->sys_glHeight = fHeight; + fFlurryInfo_t->fTime = _SecondsSinceStart() + fFlurryInfo_t->randomSeed; + fFlurryInfo_t->fDeltaTime = fFlurryInfo_t->fTime - fFlurryInfo_t->fOldTime; + + fFlurryInfo_t->numStreams = 5; + fFlurryInfo_t->briteFactor = 1.0; + fFlurryInfo_t->streamExpansion = 10000.0; + fFlurryInfo_t->currentColorMode = tiedyeColorMode; + + fFlurryInfo_t->s = (SmokeV*)malloc(sizeof(SmokeV)); + InitSmoke(fFlurryInfo_t->s); + + fFlurryInfo_t->star = (Star*)malloc(sizeof(Star)); + InitStar(fFlurryInfo_t->star); + + fFlurryInfo_t->star->rotSpeed = 1.0; + + for (int32 i = 0; i < MAX_SPARKS; ++i) { + fFlurryInfo_t->spark[i] = (Spark*)malloc(sizeof(Spark)); + InitSpark(fFlurryInfo_t->spark[i]); + fFlurryInfo_t->spark[i]->mystery = 1800 * (i + 1) / 13; + UpdateSpark(fFlurryInfo_t, fFlurryInfo_t->spark[i]); + } + + for (int32 i = 0; i < NUMSMOKEPARTICLES / 4; ++i) { + for (int32 k = 0; k < 4; ++k) + fFlurryInfo_t->s->p[i].dead.i[k] = 1; + } +} + + +double +FlurryView::_CurrentTime() const +{ + return double(fDateTime.CurrentDateTime(B_LOCAL_TIME).Time_t() + + double(fTime.CurrentTime(B_LOCAL_TIME).Millisecond() / 1000.0)); +} + + +double +FlurryView::_SecondsSinceStart() const +{ + return _CurrentTime() - fStartTime; +} + + +// #pragma mark - Flurry + + +extern "C" BScreenSaver* +instantiate_screen_saver(BMessage* archive, image_id imageId) +{ + return new Flurry(archive, imageId); +} + + +Flurry::Flurry(BMessage* archive, image_id imageId) + : BScreenSaver(archive, imageId), + fFlurryView(NULL) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + srand((999 * tv.tv_sec) + (1001 * tv.tv_usec) + (1003 * getpid())); +} + + +Flurry::~Flurry() +{ +} + + +status_t +Flurry::InitCheck() +{ + return B_OK; +} + + +status_t +Flurry::StartSaver(BView* view, bool preview) +{ + status_t status = B_ERROR; + + if (preview) + return status; + + SetTickSize(50000); + + fFlurryView = new (std::nothrow) FlurryView(view->Bounds()); + if (fFlurryView) { + if (fFlurryView->InitCheck() != B_OK) { + delete fFlurryView; + fFlurryView = NULL; + } else { + status = B_OK; + view->AddChild(fFlurryView); + } + } + + return status; +} + + +void +Flurry::StopSaver() +{ + if (fFlurryView) + fFlurryView->EnableDirectMode(false); +} + + +void +Flurry::DirectDraw(int32 frame) +{ + fFlurryView->DrawFlurryScreenSaver(); +} + + +void +Flurry::DirectConnected(direct_buffer_info* info) +{ + if (fFlurryView) { + fFlurryView->DirectConnected(info); + fFlurryView->EnableDirectMode(true); + } +} + + +void +Flurry::StartConfig(BView* configView) +{ +} + + +void +Flurry::StopConfig() +{ +} + + +status_t +Flurry::SaveState(BMessage* into) const +{ + return B_ERROR; +} diff --git a/src/add-ons/screen_savers/flurry/Flurry.h b/src/add-ons/screen_savers/flurry/Flurry.h new file mode 100644 index 0000000000..5e678cc28b --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Flurry.h @@ -0,0 +1,70 @@ +/* + * Copyright Karsten Heimrich, host.haiku@gmx.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _FLURRY_H_ +#define _FLURRY_H_ + + +#include +#include +#include + + +struct flurry_info_t; + + +class FlurryView : public BGLView { +public: + FlurryView(BRect bounds); + virtual ~FlurryView(); + + status_t InitCheck() const; + + virtual void AttachedToWindow(); + virtual void DrawFlurryScreenSaver(); + virtual void FrameResized(float width, float height); + +private: + void _SetupFlurryBaseInfo(); + + double _CurrentTime() const; + double _SecondsSinceStart() const; + +private: + float fWidth; + float fHeight; + + double fStartTime; + double fOldFrameTime; + flurry_info_t* fFlurryInfo_t; + + BPrivate::BTime fTime; + BPrivate::BDateTime fDateTime; +}; + + +class Flurry : public BScreenSaver { +public: + Flurry(BMessage* archive, image_id imageId); + virtual ~Flurry(); + + virtual status_t InitCheck(); + + virtual status_t StartSaver(BView* view, bool preview); + virtual void StopSaver(); + + virtual void DirectDraw(int32 frame); + virtual void DirectConnected(direct_buffer_info* info); + + virtual void StartConfig(BView* configView); + virtual void StopConfig(); + + virtual status_t SaveState(BMessage* into) const; + +private: + FlurryView* fFlurryView; +}; + + +#endif // _FLURRY_H_ diff --git a/src/add-ons/screen_savers/flurry/Jamfile b/src/add-ons/screen_savers/flurry/Jamfile new file mode 100644 index 0000000000..978c32f537 --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Jamfile @@ -0,0 +1,13 @@ +SubDir HAIKU_TOP src add-ons screen_savers flurry ; + +UsePrivateHeaders shared ; + +ScreenSaver Flurry : + Flurry.cpp + Smoke.cpp + Spark.cpp + Star.cpp + Texture.cpp + : be screensaver GL libshared.a +; + diff --git a/src/add-ons/screen_savers/flurry/Shared.h b/src/add-ons/screen_savers/flurry/Shared.h new file mode 100644 index 0000000000..fd6f8c43cf --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Shared.h @@ -0,0 +1,93 @@ +/* + +Copyright (c) 2002, Calum Robinson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#ifndef _SHARED_H_ +#define _SHARED_H_ + +#include +#include + +#include +#include + +struct SmokeV; +struct Spark; +struct Star; + +#define MAX_SPARKS 64 +#define seraphDistance 2000.0f + +/* used to compute the min and max of two expresions */ +#define MIN_(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX_(a, b) (((a) > (b)) ? (a) : (b)) + +#define random() rand() +#define RandFlt(min, max) (min + (max - min) * rand() / (float) RAND_MAX) +#define RandBell(scale) (scale * (1.0f - (rand() + rand() + rand()) / ((float) RAND_MAX * 1.5f))) + +typedef enum _ColorModes +{ + redColorMode = 0, + magentaColorMode, + blueColorMode, + cyanColorMode, + greenColorMode, + yellowColorMode, + slowCyclicColorMode, + cyclicColorMode, + tiedyeColorMode, + rainbowColorMode, + whiteColorMode, + multiColorMode, + darkColorMode +} ColorModes; + +typedef struct flurry_info_t { + flurry_info_t *next; + ColorModes currentColorMode; + SmokeV *s; + Star *star; + Spark *spark[MAX_SPARKS]; + float streamExpansion; + int numStreams; + double randomSeed; + double fTime; + double fOldTime; + double fDeltaTime; + double briteFactor; + float drag; + int dframe; + float sys_glWidth; + float sys_glHeight; +} flurry_info_t; + + +#endif // _SHARED_H_ diff --git a/src/add-ons/screen_savers/flurry/Smoke.cpp b/src/add-ons/screen_savers/flurry/Smoke.cpp new file mode 100644 index 0000000000..6f934f40d0 --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Smoke.cpp @@ -0,0 +1,375 @@ +/* + +Copyright (c) 2002, Calum Robinson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#include "Smoke.h" + +#include "Shared.h" +#include "Star.h" +#include "Spark.h" + +#define MAXANGLES 16384 +#define NOT_QUITE_DEAD 3 + +#define streamBias 7.0f +#define incohesion 0.07f +#define streamSpeed 450.0 +#define gravity 1500000.0f +#define intensity 75000.0f; +#define streamSize 25000.0f +#define colorIncoherence 0.15f + +static float FastDistance2D(float x, float y) +{ + /* this function computes the distance from 0,0 to x,y with ~3.5% error */ + float mn; + + /* first compute the absolute value of x,y */ + x = (x < 0.0f) ? -x : x; + y = (y < 0.0f) ? -y : y; + + /* compute the minimum of x,y */ + mn = xnextParticle = 0; + s->nextSubParticle = 0; + s->lastParticleTime = 0.25f; + s->firstTime = 1; + s->frame = 0; + for (i=0;i<3;i++) { + s->old[i] = RandFlt(-100.0, 100.0); + } +} + +void UpdateSmoke_ScalarBase(flurry_info_t *info, SmokeV *s) +{ + int i,j,k; + float sx = info->star->position[0]; + float sy = info->star->position[1]; + float sz = info->star->position[2]; + double frameRate; + double frameRateModifier; + + + s->frame++; + + if(!s->firstTime) { + /* release 12 puffs every frame */ + if(info->fTime - s->lastParticleTime >= 1.0f / 121.0f) { + float dx,dy,dz,deltax,deltay,deltaz; + float f; + float rsquared; + float mag; + + dx = s->old[0] - sx; + dy = s->old[1] - sy; + dz = s->old[2] - sz; + mag = 5.0f; + deltax = (dx * mag); + deltay = (dy * mag); + deltaz = (dz * mag); + for(i=0;inumStreams;i++) { + float streamSpeedCoherenceFactor; + + s->p[s->nextParticle].delta[0].f[s->nextSubParticle] = deltax; + s->p[s->nextParticle].delta[1].f[s->nextSubParticle] = deltay; + s->p[s->nextParticle].delta[2].f[s->nextSubParticle] = deltaz; + s->p[s->nextParticle].position[0].f[s->nextSubParticle] = sx; + s->p[s->nextParticle].position[1].f[s->nextSubParticle] = sy; + s->p[s->nextParticle].position[2].f[s->nextSubParticle] = sz; + s->p[s->nextParticle].oldposition[0].f[s->nextSubParticle] = sx; + s->p[s->nextParticle].oldposition[1].f[s->nextSubParticle] = sy; + s->p[s->nextParticle].oldposition[2].f[s->nextSubParticle] = sz; + streamSpeedCoherenceFactor = MAX_(0.0f,1.0f + RandBell(0.25f*incohesion)); + dx = s->p[s->nextParticle].position[0].f[s->nextSubParticle] - info->spark[i]->position[0]; + dy = s->p[s->nextParticle].position[1].f[s->nextSubParticle] - info->spark[i]->position[1]; + dz = s->p[s->nextParticle].position[2].f[s->nextSubParticle] - info->spark[i]->position[2]; + rsquared = (dx*dx+dy*dy+dz*dz); + f = streamSpeed * streamSpeedCoherenceFactor; + + mag = f / (float) sqrt(rsquared); + + s->p[s->nextParticle].delta[0].f[s->nextSubParticle] -= (dx * mag); + s->p[s->nextParticle].delta[1].f[s->nextSubParticle] -= (dy * mag); + s->p[s->nextParticle].delta[2].f[s->nextSubParticle] -= (dz * mag); + s->p[s->nextParticle].color[0].f[s->nextSubParticle] = info->spark[i]->color[0] * (1.0f + RandBell(colorIncoherence)); + s->p[s->nextParticle].color[1].f[s->nextSubParticle] = info->spark[i]->color[1] * (1.0f + RandBell(colorIncoherence)); + s->p[s->nextParticle].color[2].f[s->nextSubParticle] = info->spark[i]->color[2] * (1.0f + RandBell(colorIncoherence)); + s->p[s->nextParticle].color[3].f[s->nextSubParticle] = 0.85f * (1.0f + RandBell(0.5f*colorIncoherence)); + s->p[s->nextParticle].time.f[s->nextSubParticle] = info->fTime; + s->p[s->nextParticle].dead.i[s->nextSubParticle] = 0; + s->p[s->nextParticle].animFrame.i[s->nextSubParticle] = random()&63; + s->nextSubParticle++; + if (s->nextSubParticle==4) { + s->nextParticle++; + s->nextSubParticle=0; + } + if (s->nextParticle >= NUMSMOKEPARTICLES/4) { + s->nextParticle = 0; + s->nextSubParticle = 0; + } + } + + s->lastParticleTime = info->fTime; + } + } else { + s->lastParticleTime = info->fTime; + s->firstTime = 0; + } + + for(i=0;i<3;i++) { + s->old[i] = info->star->position[i]; + } + + frameRate = ((double) info->dframe)/(info->fTime); + frameRateModifier = 42.5f / frameRate; + + for(i=0;ip[i].dead.i[k]) { + continue; + } + + deltax = s->p[i].delta[0].f[k]; + deltay = s->p[i].delta[1].f[k]; + deltaz = s->p[i].delta[2].f[k]; + + for(j=0;jnumStreams;j++) { + dx = s->p[i].position[0].f[k] - info->spark[j]->position[0]; + dy = s->p[i].position[1].f[k] - info->spark[j]->position[1]; + dz = s->p[i].position[2].f[k] - info->spark[j]->position[2]; + rsquared = (dx*dx+dy*dy+dz*dz); + + f = (gravity/rsquared) * frameRateModifier; + + if ((((i*4)+k) % info->numStreams) == j) { + f *= 1.0f + streamBias; + } + + mag = f / (float) sqrt(rsquared); + + deltax -= (dx * mag); + deltay -= (dy * mag); + deltaz -= (dz * mag); + } + + /* slow this particle down by info->drag */ + deltax *= info->drag; + deltay *= info->drag; + deltaz *= info->drag; + + if((deltax*deltax+deltay*deltay+deltaz*deltaz) >= 25000000.0f) { + s->p[i].dead.i[k] = 1; + continue; + } + + /* update the position */ + s->p[i].delta[0].f[k] = deltax; + s->p[i].delta[1].f[k] = deltay; + s->p[i].delta[2].f[k] = deltaz; + for(j=0;j<3;j++) { + s->p[i].oldposition[j].f[k] = s->p[i].position[j].f[k]; + s->p[i].position[j].f[k] += (s->p[i].delta[j].f[k])*info->fDeltaTime; + } + } + } +} + +void DrawSmoke_Scalar(flurry_info_t *info, SmokeV *s, float brightness) +{ + int svi = 0; + int sci = 0; + int sti = 0; + int si = 0; + float width; + float sx,sy; + float u0,v0,u1,v1; + float w,z; + float screenRatio = info->sys_glWidth / 1024.0f; + float hslash2 = info->sys_glHeight * 0.5f; + float wslash2 = info->sys_glWidth * 0.5f; + int i,k; + + width = (streamSize+2.5f*info->streamExpansion) * screenRatio; + + for (i=0;ip[i].dead.i[k]) { + continue; + } + thisWidth = (streamSize + (info->fTime - s->p[i].time.f[k])*info->streamExpansion) * screenRatio; + if (thisWidth >= width) + { + s->p[i].dead.i[k] = 1; + continue; + } + z = s->p[i].position[2].f[k]; + sx = s->p[i].position[0].f[k] * info->sys_glWidth / z + wslash2; + sy = s->p[i].position[1].f[k] * info->sys_glWidth / z + hslash2; + oldz = s->p[i].oldposition[2].f[k]; + if (sx > info->sys_glWidth+50.0f || sx < -50.0f || sy > info->sys_glHeight+50.0f || sy < -50.0f || z < 25.0f || oldz < 25.0f) + { + continue; + } + + w = MAX_(1.0f,thisWidth/z); + { + float oldx = s->p[i].oldposition[0].f[k]; + float oldy = s->p[i].oldposition[1].f[k]; + float oldscreenx = (oldx * info->sys_glWidth / oldz) + wslash2; + float oldscreeny = (oldy * info->sys_glWidth / oldz) + hslash2; + float dx = (sx-oldscreenx); + float dy = (sy-oldscreeny); + + float d = FastDistance2D(dx, dy); + + float sm, os, ow; + if (d) + { + sm = w/d; + } + else + { + sm = 0.0f; + } + ow = MAX_(1.0f,thisWidth/oldz); + if (d) + { + os = ow/d; + } + else + { + os = 0.0f; + } + + { + floatToVector cmv; + float cm; + float m = 1.0f + sm; + + float dxs = dx*sm; + float dys = dy*sm; + float dxos = dx*os; + float dyos = dy*os; + float dxm = dx*m; + float dym = dy*m; + + s->p[i].animFrame.i[k]++; + if (s->p[i].animFrame.i[k] >= 64) + { + s->p[i].animFrame.i[k] = 0; + } + + u0 = (s->p[i].animFrame.i[k]&&7) * 0.125f; + v0 = (s->p[i].animFrame.i[k]>>3) * 0.125f; + u1 = u0 + 0.125f; + v1 = v0 + 0.125f; + u1 = u0 + 0.125f; + v1 = v0 + 0.125f; + cm = (1.375f - thisWidth/width); + if (s->p[i].dead.i[k] == 3) + { + cm *= 0.125f; + s->p[i].dead.i[k] = 1; + } + si++; + cm *= brightness; + cmv.f[0] = s->p[i].color[0].f[k]*cm; + cmv.f[1] = s->p[i].color[1].f[k]*cm; + cmv.f[2] = s->p[i].color[2].f[k]*cm; + cmv.f[3] = s->p[i].color[3].f[k]*cm; + +#if 0 + /* MDT we can't use vectors in the Scalar routine */ + s->seraphimColors[sci++].v = cmv.v; + s->seraphimColors[sci++].v = cmv.v; + s->seraphimColors[sci++].v = cmv.v; + s->seraphimColors[sci++].v = cmv.v; +#else + { + int ii, jj; + for (jj = 0; jj < 4; jj++) { + for (ii = 0; ii < 4; ii++) { + s->seraphimColors[sci].f[ii] = cmv.f[ii]; + } + sci += 1; + } + } +#endif + + s->seraphimTextures[sti++] = u0; + s->seraphimTextures[sti++] = v0; + s->seraphimTextures[sti++] = u0; + s->seraphimTextures[sti++] = v1; + + s->seraphimTextures[sti++] = u1; + s->seraphimTextures[sti++] = v1; + s->seraphimTextures[sti++] = u1; + s->seraphimTextures[sti++] = v0; + + s->seraphimVertices[svi].f[0] = sx+dxm-dys; + s->seraphimVertices[svi].f[1] = sy+dym+dxs; + s->seraphimVertices[svi].f[2] = sx+dxm+dys; + s->seraphimVertices[svi].f[3] = sy+dym-dxs; + svi++; + + s->seraphimVertices[svi].f[0] = oldscreenx-dxm+dyos; + s->seraphimVertices[svi].f[1] = oldscreeny-dym-dxos; + s->seraphimVertices[svi].f[2] = oldscreenx-dxm-dyos; + s->seraphimVertices[svi].f[3] = oldscreeny-dym+dxos; + svi++; + } + } + } + } + glColorPointer(4,GL_FLOAT,0,s->seraphimColors); + glVertexPointer(2,GL_FLOAT,0,s->seraphimVertices); + glTexCoordPointer(2,GL_FLOAT,0,s->seraphimTextures); + glDrawArrays(GL_QUADS,0,si*4); +} diff --git a/src/add-ons/screen_savers/flurry/Smoke.h b/src/add-ons/screen_savers/flurry/Smoke.h new file mode 100644 index 0000000000..ad3db21932 --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Smoke.h @@ -0,0 +1,76 @@ +/* + +Copyright (c) 2002, Calum Robinson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#ifndef _SMOKE_H_ +#define _SMOKE_H_ + +struct flurry_info_t; + +#define NUMSMOKEPARTICLES 3600 + +typedef union { + float f[4]; +} floatToVector; + +typedef union { + unsigned int i[4]; +} intToVector; + +typedef struct SmokeParticleV +{ + floatToVector color[4]; + floatToVector position[3]; + floatToVector oldposition[3]; + floatToVector delta[3]; + intToVector dead; + floatToVector time; + intToVector animFrame; +} SmokeParticleV; + +typedef struct SmokeV +{ + SmokeParticleV p[NUMSMOKEPARTICLES/4]; + int nextParticle; + int nextSubParticle; + float lastParticleTime; + int firstTime; + long frame; + float old[3]; + floatToVector seraphimVertices[NUMSMOKEPARTICLES*2+1]; + floatToVector seraphimColors[NUMSMOKEPARTICLES*4+1]; + float seraphimTextures[NUMSMOKEPARTICLES*2*4]; +} SmokeV; + +void InitSmoke(SmokeV *s); +void UpdateSmoke_ScalarBase(flurry_info_t *flurry, SmokeV *s); +void DrawSmoke_Scalar(flurry_info_t *flurry, SmokeV *s, float); + +#endif // _SMOKE_H_ diff --git a/src/add-ons/screen_savers/flurry/Spark.cpp b/src/add-ons/screen_savers/flurry/Spark.cpp new file mode 100644 index 0000000000..5618dddea4 --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Spark.cpp @@ -0,0 +1,298 @@ +/* + +Copyright (c) 2002, Calum Robinson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#include "Spark.h" +#include "Shared.h" + +#define BIGMYSTERY 1800.0 +#define MAXANGLES 16384 + +#define fieldCoherence 0 +#define fieldSpeed 12.0f +#define fieldRange 1000.0f + +void InitSpark(Spark *s) +{ + int i; + for (i=0;i<3;i++) + { + s->position[i] = RandFlt(-100.0, 100.0); + } +} + +void DrawSpark(flurry_info_t *info, Spark *s) +{ + const float black[4] = {0.0f,0.0f,0.0f,1.0f}; + float width,sx,sy; + float a; + float c = 0.0625f; + float screenx; + float screeny; + float w,z, scale; + int k; + width = 60000.0f * info->sys_glWidth / 1024.0f; + + z = s->position[2]; + sx = s->position[0] * info->sys_glWidth / z + info->sys_glWidth * 0.5f; + sy = s->position[1] * info->sys_glWidth / z + info->sys_glHeight * 0.5f; + w = width*4.0f / z; + + screenx = sx; + screeny = sy; + + glPushMatrix(); + glTranslatef(screenx,screeny,0.0f); + scale = w/50.0f; + glScalef(scale,scale,0.0f); + for (k=0;k<12;k++) + { + a = ((float) (random() % 3600)) / 10.0f; + glRotatef(a,0.0f,0.0f,1.0f); + glBegin(GL_QUAD_STRIP); + glColor4fv(black); + glVertex2f(-3.0f,0.0f); + a = 2.0f + (float) (random() & 255) * c; + glVertex2f(-3.0f,a); + glColor4fv(s->color); + glVertex2f(0.0f,0.0f); + glColor4fv(black); + glVertex2f(0.0f,a); + glVertex2f(3.0f,0.0f); + glVertex2f(3.0f,a); + glEnd(); + } + glPopMatrix(); +} + +void UpdateSparkColour(flurry_info_t *info, Spark *s) +{ + const float rotationsPerSecond = (float) (2.0*M_PI*fieldSpeed/MAXANGLES); + double thisPointInRadians; + double thisAngle = info->fTime*rotationsPerSecond; + float cf; + float cycleTime = 20.0f; + float colorRot; + float redPhaseShift; + float greenPhaseShift; + float bluePhaseShift; + float baseRed; + float baseGreen; + float baseBlue; + float colorTime; + + if (info->currentColorMode == rainbowColorMode) + { + cycleTime = 1.5f; + } + else if (info->currentColorMode == tiedyeColorMode) + { + cycleTime = 4.5f; + } + else if (info->currentColorMode == cyclicColorMode) + { + cycleTime = 20.0f; + } + else if (info->currentColorMode == slowCyclicColorMode) + { + cycleTime = 120.0f; + } + colorRot = (float) (2.0*M_PI/cycleTime); + redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */ + greenPhaseShift = cycleTime / 3.0f; + bluePhaseShift = cycleTime * 2.0f / 3.0f ; + colorTime = info->fTime; + if (info->currentColorMode == whiteColorMode) + { + baseRed = 0.1875f; + baseGreen = 0.1875f; + baseBlue = 0.1875f; + } + else if (info->currentColorMode == multiColorMode) + { + baseRed = 0.0625f; + baseGreen = 0.0625f; + baseBlue = 0.0625f; + } + else if (info->currentColorMode == darkColorMode) + { + baseRed = 0.0f; + baseGreen = 0.0f; + baseBlue = 0.0f; + } + else + { + if (info->currentColorMode < slowCyclicColorMode) + { + colorTime = (info->currentColorMode / 6.0f) * cycleTime; + } + else + { + colorTime = info->fTime + info->randomSeed; + } + baseRed = 0.109375f * ((float) cos((colorTime+redPhaseShift)*colorRot)+1.0f); + baseGreen = 0.109375f * ((float) cos((colorTime+greenPhaseShift)*colorRot)+1.0f); + baseBlue = 0.109375f * ((float) cos((colorTime+bluePhaseShift)*colorRot)+1.0f); + } + + cf = ((float) (cos(7.0*((info->fTime)*rotationsPerSecond)) + + cos(3.0*((info->fTime)*rotationsPerSecond)) + + cos(13.0*((info->fTime)*rotationsPerSecond)))); + cf /= 6.0f; + cf += 2.0f; + thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY; + + s->color[0] = baseRed + 0.0625f * + (0.5f + (float) cos((15.0 * (thisPointInRadians + 3.0*thisAngle))) + + (float) sin((7.0 * (thisPointInRadians + thisAngle)))); + s->color[1] = baseGreen + 0.0625f * + (0.5f + (float) sin(((thisPointInRadians) + thisAngle))); + s->color[2] = baseBlue + 0.0625f * + (0.5f + (float) cos((37.0 * (thisPointInRadians + thisAngle)))); +} + +void UpdateSpark(flurry_info_t *info, Spark *s) +{ + const float rotationsPerSecond = (float) (2.0*M_PI*fieldSpeed/MAXANGLES); + double thisPointInRadians; + double thisAngle = info->fTime*rotationsPerSecond; + float cf; + int i; + double tmpX1,tmpY1,tmpZ1; + double tmpX2,tmpY2,tmpZ2; + double tmpX3,tmpY3,tmpZ3; + double tmpX4,tmpY4,tmpZ4; + double rotation; + double cr; + double sr; + float cycleTime = 20.0f; + float colorRot; + float redPhaseShift; + float greenPhaseShift; + float bluePhaseShift; + float baseRed; + float baseGreen; + float baseBlue; + float colorTime; + + float old[3]; + + if (info->currentColorMode == rainbowColorMode) { + cycleTime = 1.5f; + } else if (info->currentColorMode == tiedyeColorMode) { + cycleTime = 4.5f; + } else if (info->currentColorMode == cyclicColorMode) { + cycleTime = 20.0f; + } else if (info->currentColorMode == slowCyclicColorMode) { + cycleTime = 120.0f; + } + colorRot = (float) (2.0*M_PI/cycleTime); + redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */ + greenPhaseShift = cycleTime / 3.0f; + bluePhaseShift = cycleTime * 2.0f / 3.0f ; + colorTime = info->fTime; + if (info->currentColorMode == whiteColorMode) { + baseRed = 0.1875f; + baseGreen = 0.1875f; + baseBlue = 0.1875f; + } else if (info->currentColorMode == multiColorMode) { + baseRed = 0.0625f; + baseGreen = 0.0625f; + baseBlue = 0.0625f; + } else if (info->currentColorMode == darkColorMode) { + baseRed = 0.0f; + baseGreen = 0.0f; + baseBlue = 0.0f; + } else { + if(info->currentColorMode < slowCyclicColorMode) { + colorTime = (info->currentColorMode / 6.0f) * cycleTime; + } else { + colorTime = info->fTime + info->randomSeed; + } + baseRed = 0.109375f * ((float) cos((colorTime+redPhaseShift)*colorRot)+1.0f); + baseGreen = 0.109375f * ((float) cos((colorTime+greenPhaseShift)*colorRot)+1.0f); + baseBlue = 0.109375f * ((float) cos((colorTime+bluePhaseShift)*colorRot)+1.0f); + } + + for (i=0;i<3;i++) { + old[i] = s->position[i]; + } + + cf = ((float) (cos(7.0*((info->fTime)*rotationsPerSecond)) + + cos(3.0*((info->fTime)*rotationsPerSecond)) + + cos(13.0*((info->fTime)*rotationsPerSecond)))); + cf /= 6.0f; + cf += 2.0f; + thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY; + + s->color[0] = baseRed + 0.0625f * + (0.5f + (float) cos((15.0 * (thisPointInRadians + 3.0*thisAngle))) + + (float) sin((7.0 * (thisPointInRadians + thisAngle)))); + s->color[1] = baseGreen + 0.0625f * + (0.5f + (float) sin(((thisPointInRadians) + thisAngle))); + s->color[2] = baseBlue + 0.0625f * + (0.5f + (float) cos((37.0 * (thisPointInRadians + thisAngle)))); + s->position[0] = fieldRange * cf * + (float) cos(11.0 * (thisPointInRadians + (3.0*thisAngle))); + s->position[1] = fieldRange * cf * + (float) sin(12.0 * (thisPointInRadians + (4.0*thisAngle))); + s->position[2] = fieldRange * + (float) cos((23.0 * (thisPointInRadians + (12.0*thisAngle)))); + + rotation = thisAngle*0.501 + 5.01 * (double) s->mystery / (double) BIGMYSTERY; + cr = cos(rotation); + sr = sin(rotation); + tmpX1 = s->position[0] * cr - s->position[1] * sr; + tmpY1 = s->position[1] * cr + s->position[0] * sr; + tmpZ1 = s->position[2]; + + tmpX2 = tmpX1 * cr - tmpZ1 * sr; + tmpY2 = tmpY1; + tmpZ2 = tmpZ1 * cr + tmpX1 * sr; + + tmpX3 = tmpX2; + tmpY3 = tmpY2 * cr - tmpZ2 * sr; + tmpZ3 = tmpZ2 * cr + tmpY2 * sr + seraphDistance; + + rotation = thisAngle*2.501 + 85.01 * (double) s->mystery / (double) BIGMYSTERY; + cr = cos(rotation); + sr = sin(rotation); + tmpX4 = tmpX3 * cr - tmpY3 * sr; + tmpY4 = tmpY3 * cr + tmpX3 * sr; + tmpZ4 = tmpZ3; + + s->position[0] = (float) tmpX4 + RandBell(5.0f*fieldCoherence); + s->position[1] = (float) tmpY4 + RandBell(5.0f*fieldCoherence); + s->position[2] = (float) tmpZ4 + RandBell(5.0f*fieldCoherence); + + for (i=0;i<3;i++) { + s->delta[i] = (s->position[i] - old[i])/info->fDeltaTime; + } +} diff --git a/src/add-ons/screen_savers/flurry/Spark.h b/src/add-ons/screen_savers/flurry/Spark.h new file mode 100644 index 0000000000..a9aa095580 --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Spark.h @@ -0,0 +1,50 @@ +/* + +Copyright (c) 2002, Calum Robinson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#ifndef _SPARK_H_ +#define _SPARK_H_ + +struct flurry_info_t; + +typedef struct Spark +{ + float position[3]; + int mystery; + float delta[3]; + float color[4]; +} Spark; + +void InitSpark(Spark *s); +void DrawSpark(flurry_info_t *info, Spark *s); +void UpdateSparkColour(flurry_info_t *info, Spark *s); +void UpdateSpark(flurry_info_t *info, Spark *s); + +#endif // _SPARK_H_ diff --git a/src/add-ons/screen_savers/flurry/Star.cpp b/src/add-ons/screen_savers/flurry/Star.cpp new file mode 100644 index 0000000000..5caf0062ce --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Star.cpp @@ -0,0 +1,102 @@ +/* + +Copyright (c) 2002, Calum Robinson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#include "Star.h" +#include "Shared.h" + +#define BIGMYSTERY 1800.0 +#define MAXANGLES 16384 + +/* Construction/Destruction */ +void InitStar(Star *s) +{ + int i; + for (i=0;i<3;i++) { + s->position[i] = RandFlt(-10000.0, 10000.0); + } + s->rotSpeed = RandFlt(0.4, 0.9); + s->mystery = RandFlt(0.0, 10.0); +} + +void UpdateStar(flurry_info_t *info, Star *s) +{ + /* speed control */ + float rotationsPerSecond = (float) (2.0*M_PI*12.0/MAXANGLES) * s->rotSpeed; + double thisPointInRadians; + double thisAngle = info->fTime*rotationsPerSecond; + float cf; + double tmpX1,tmpY1,tmpZ1; + double tmpX2,tmpY2,tmpZ2; + double tmpX3,tmpY3,tmpZ3; + double tmpX4,tmpY4,tmpZ4; + double rotation; + double cr; + double sr; + + s->ate = 0; + + cf = ((float) (cos(7.0*((info->fTime)*rotationsPerSecond)) + + cos(3.0*((info->fTime)*rotationsPerSecond)) + + cos(13.0*((info->fTime)*rotationsPerSecond)))); + cf /= 6.0f; + cf += 0.75f; + thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY; + + s->position[0] = 250.0f * cf * (float) cos(11.0 * (thisPointInRadians + (3.0*thisAngle))); + s->position[1] = 250.0f * cf * (float) sin(12.0 * (thisPointInRadians + (4.0*thisAngle))); + s->position[2] = 250.0f * (float) cos((23.0 * (thisPointInRadians + (12.0*thisAngle)))); + + rotation = thisAngle*0.501 + 5.01 * (double) s->mystery / (double) BIGMYSTERY; + cr = cos(rotation); + sr = sin(rotation); + tmpX1 = s->position[0] * cr - s->position[1] * sr; + tmpY1 = s->position[1] * cr + s->position[0] * sr; + tmpZ1 = s->position[2]; + + tmpX2 = tmpX1 * cr - tmpZ1 * sr; + tmpY2 = tmpY1; + tmpZ2 = tmpZ1 * cr + tmpX1 * sr; + + tmpX3 = tmpX2; + tmpY3 = tmpY2 * cr - tmpZ2 * sr; + tmpZ3 = tmpZ2 * cr + tmpY2 * sr + seraphDistance; + + rotation = thisAngle*2.501 + 85.01 * (double) s->mystery / (double) BIGMYSTERY; + cr = cos(rotation); + sr = sin(rotation); + tmpX4 = tmpX3 * cr - tmpY3 * sr; + tmpY4 = tmpY3 * cr + tmpX3 * sr; + tmpZ4 = tmpZ3; + + s->position[0] = (float) tmpX4; + s->position[1] = (float) tmpY4; + s->position[2] = (float) tmpZ4; +} diff --git a/src/add-ons/screen_savers/flurry/Star.h b/src/add-ons/screen_savers/flurry/Star.h new file mode 100644 index 0000000000..ea9e2b58a5 --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Star.h @@ -0,0 +1,48 @@ +/* + +Copyright (c) 2002, Calum Robinson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#ifndef _STAR_H_ +#define _STAR_H_ + +struct flurry_info_t; + +typedef struct Star +{ + float position[3]; + float mystery; + float rotSpeed; + int ate; +} Star; + +void InitStar(Star *s); +void UpdateStar(flurry_info_t *flurry, Star *s); + +#endif // _STAR_H diff --git a/src/add-ons/screen_savers/flurry/Texture.cpp b/src/add-ons/screen_savers/flurry/Texture.cpp new file mode 100644 index 0000000000..39fcb428e0 --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Texture.cpp @@ -0,0 +1,205 @@ +/* + +Copyright (c) 2002, Calum Robinson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#include "Texture.h" +#include "Shared.h" + +static GLubyte smallTextureArray[32][32]; +static GLubyte bigTextureArray[256][256][2]; +GLuint theTexture = 0; + +/* simple smoothing routine */ +static void SmoothTexture(void) +{ + GLubyte filter[32][32]; + int i,j; + float t; + for (i=1;i<31;i++) + { + for (j=1;j<31;j++) + { + t = (float) smallTextureArray[i][j]*4; + t += (float) smallTextureArray[i-1][j]; + t += (float) smallTextureArray[i+1][j]; + t += (float) smallTextureArray[i][j-1]; + t += (float) smallTextureArray[i][j+1]; + t /= 8.0f; + filter[i][j] = (GLubyte) t; + } + } + for (i=1;i<31;i++) + { + for (j=1;j<31;j++) + { + smallTextureArray[i][j] = filter[i][j]; + } + } +} + +/* add some randomness to texture data */ +static void SpeckleTexture(void) +{ + int i,j; + int speck; + float t; + for (i=2;i<30;i++) + { + for (j=2;j<30;j++) + { + speck = 1; + while (speck <= 32 && random() % 2) + { + t = (float) MIN_(255,smallTextureArray[i][j]+speck); + smallTextureArray[i][j] = (GLubyte) t; + speck+=speck; + } + speck = 1; + while (speck <= 32 && random() % 2) + { + t = (float) MAX_(0,smallTextureArray[i][j]-speck); + smallTextureArray[i][j] = (GLubyte) t; + speck+=speck; + } + } + } +} + +static void MakeSmallTexture(void) +{ + static int firstTime = 1; + int i,j; + float r,t; + if (firstTime) + { + firstTime = 0; + for (i=0;i<32;i++) + { + for (j=0;j<32;j++) + { + r = (float) sqrt((i-15.5)*(i-15.5)+(j-15.5)*(j-15.5)); + if (r > 15.0f) + { + smallTextureArray[i][j] = 0; + } + else + { + t = 255.0f * (float) cos(r*M_PI/31.0); + smallTextureArray[i][j] = (GLubyte) t; + } + } + } + } + else + { + for (i=0;i<32;i++) + { + for (j=0;j<32;j++) + { + r = (float) sqrt((i-15.5)*(i-15.5)+(j-15.5)*(j-15.5)); + if (r > 15.0f) + { + t = 0.0f; + } + else + { + t = 255.0f * (float) cos(r*M_PI/31.0); + } + smallTextureArray[i][j] = (GLubyte) MIN_(255,(t+smallTextureArray[i][j]+smallTextureArray[i][j])/3); + } + } + } + SpeckleTexture(); + SmoothTexture(); + SmoothTexture(); +} + +static void CopySmallTextureToBigTexture(int k, int l) +{ + int i,j; + for (i=0;i<32;i++) + { + for (j=0;j<32;j++) + { + bigTextureArray[i+k][j+l][0] = smallTextureArray[i][j]; + bigTextureArray[i+k][j+l][1] = smallTextureArray[i][j]; + } + } +} + +static void AverageLastAndFirstTextures(void) +{ + int i,j; + int t; + for (i=0;i<32;i++) + { + for (j=0;j<32;j++) + { + t = (smallTextureArray[i][j] + bigTextureArray[i][j][0]) / 2; + smallTextureArray[i][j] = (GLubyte) MIN_(255,t); + } + } +} + +void MakeTexture() +{ + int i,j; + for (i=0;i<8;i++) + { + for (j=0;j<8;j++) + { + if (i==7 && j==7) + { + AverageLastAndFirstTextures(); + } + else + { + MakeSmallTexture(); + } + CopySmallTextureToBigTexture(i*32,j*32); + } + } + + glPixelStorei(GL_UNPACK_ALIGNMENT,1); + + glGenTextures(1, &theTexture); + glBindTexture(GL_TEXTURE_2D, theTexture); + + /* Set the tiling mode (this is generally always GL_REPEAT). */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + /* Set the filtering. */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + + gluBuild2DMipmaps(GL_TEXTURE_2D, 2, 256, 256, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, bigTextureArray); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +} diff --git a/src/add-ons/screen_savers/flurry/Texture.h b/src/add-ons/screen_savers/flurry/Texture.h new file mode 100644 index 0000000000..ae64a9567e --- /dev/null +++ b/src/add-ons/screen_savers/flurry/Texture.h @@ -0,0 +1,37 @@ +/* + +Copyright (c) 2002, Calum Robinson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#ifndef _TEXTURE_H_ +#define _TEXTURE_H_ + +void MakeTexture(); + +#endif // _TEXTURE_H_