diff --git a/src/add-ons/screen_savers/Jamfile b/src/add-ons/screen_savers/Jamfile index 1116db75f6..1bf5874376 100644 --- a/src/add-ons/screen_savers/Jamfile +++ b/src/add-ons/screen_savers/Jamfile @@ -4,6 +4,7 @@ SubInclude HAIKU_TOP src add-ons screen_savers butterfly ; 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 gravity ; SubInclude HAIKU_TOP src add-ons screen_savers haiku ; SubInclude HAIKU_TOP src add-ons screen_savers icons ; SubInclude HAIKU_TOP src add-ons screen_savers ifs ; diff --git a/src/add-ons/screen_savers/gravity/Gravity.cpp b/src/add-ons/screen_savers/gravity/Gravity.cpp new file mode 100644 index 0000000000..5010f5c089 --- /dev/null +++ b/src/add-ons/screen_savers/gravity/Gravity.cpp @@ -0,0 +1,17 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Tri-Edge AI + */ + + +#include "GravityScreenSaver.hpp" + + +extern "C" _EXPORT BScreenSaver* +instantiate_screen_saver(BMessage* pbmPrefs, image_id iidImage) +{ + return new GravityScreenSaver(pbmPrefs, iidImage); +} diff --git a/src/add-ons/screen_savers/gravity/Gravity.rdef b/src/add-ons/screen_savers/gravity/Gravity.rdef new file mode 100644 index 0000000000..e941f3c2b3 --- /dev/null +++ b/src/add-ons/screen_savers/gravity/Gravity.rdef @@ -0,0 +1,14 @@ +resource app_signature "application/x-vnd.Haiku-GravityScreenSaver"; + +resource app_name_catalog_entry "x-vnd.Haiku-GravityScreenSaver:System name:Gravity"; + +resource app_version +{ + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "1.0", + long_info = "The screensaver simulates a gravity hole effect with particles, utilizing the OpenGL interface for Haiku." +}; diff --git a/src/add-ons/screen_savers/gravity/GravityConfigView.cpp b/src/add-ons/screen_savers/gravity/GravityConfigView.cpp new file mode 100644 index 0000000000..1a12fa9d94 --- /dev/null +++ b/src/add-ons/screen_savers/gravity/GravityConfigView.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Tri-Edge AI + */ + + +#include "GravityConfigView.hpp" + + +class GravityScreenSaver; + +GravityConfigView::GravityConfigView(GravityScreenSaver* parent, BRect frame) + : + BView(frame, "", B_FOLLOW_ALL_SIDES, B_WILL_DRAW) +{ + this->parent = parent; + + SetLayout(new BGroupLayout(B_HORIZONTAL)); + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + BStringView* pbsvTitle = new BStringView(frame, B_EMPTY_STRING, + "OpenGL Gravity Effect", B_FOLLOW_LEFT); + + BStringView* pbsvAuthor = new BStringView(frame, B_EMPTY_STRING, + "by Tri-Edge AI", B_FOLLOW_LEFT); + + pbsParticleCount = new BSlider(frame, B_EMPTY_STRING, "Particle Count: ", + new BMessage('pcnt'), 0, 4, B_BLOCK_THUMB); + + pbsvShadeText = new BStringView(frame, B_EMPTY_STRING, "Shade: ", + B_FOLLOW_LEFT); + + pblvShade = new BListView(frame, B_EMPTY_STRING, B_SINGLE_SELECTION_LIST, + B_FOLLOW_ALL); + + pblvShade->SetSelectionMessage(new BMessage('shds')); + + pblvShade->AddItem(new BStringItem("Red")); + pblvShade->AddItem(new BStringItem("Green")); + pblvShade->AddItem(new BStringItem("Blue")); + pblvShade->AddItem(new BStringItem("Orange")); + pblvShade->AddItem(new BStringItem("Purple")); + pblvShade->AddItem(new BStringItem("White")); + pblvShade->AddItem(new BStringItem("Rainbow")); + + pblvShade->Select(parent->Config.ShadeID); + + BScrollView* scroll = new BScrollView(B_EMPTY_STRING, pblvShade, + B_WILL_DRAW | B_FRAME_EVENTS, false, true); + + pbsParticleCount->SetHashMarks(B_HASH_MARKS_BOTTOM); + pbsParticleCount->SetHashMarkCount(5); + pbsParticleCount->SetLimitLabels("128", "2048"); + + pbsParticleCount->SetValue(parent->Config.ParticleCount); + + AddChild(BGroupLayoutBuilder(B_VERTICAL, B_USE_DEFAULT_SPACING) + .Add(BGroupLayoutBuilder(B_VERTICAL, 0) + .Add(pbsvTitle) + .Add(pbsvAuthor) + ) + .Add(pbsvShadeText) + .Add(scroll) + .Add(pbsParticleCount) + .SetInsets(B_USE_DEFAULT_SPACING, + B_USE_DEFAULT_SPACING, + B_USE_DEFAULT_SPACING, + B_USE_DEFAULT_SPACING) + ); +} + + +void +GravityConfigView::AttachedToWindow() +{ + pblvShade->SetTarget(this); + pbsParticleCount->SetTarget(this); +} + + +void +GravityConfigView::MessageReceived(BMessage* pbmMessage) +{ + if (pbmMessage->what == 'pcnt') { + parent->Config.ParticleCount = pbsParticleCount->Value(); + } else if (pbmMessage->what == 'shds') { + parent->Config.ShadeID = pblvShade->CurrentSelection(); + } else { + BView::MessageReceived(pbmMessage); + } +} diff --git a/src/add-ons/screen_savers/gravity/GravityConfigView.hpp b/src/add-ons/screen_savers/gravity/GravityConfigView.hpp new file mode 100644 index 0000000000..b8f63faead --- /dev/null +++ b/src/add-ons/screen_savers/gravity/GravityConfigView.hpp @@ -0,0 +1,42 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Tri-Edge AI + */ +#ifndef _GRAVITY_CONFIG_VIEW_HPP_ +#define _GRAVITY_CONFIG_VIEW_HPP_ + + +#include "GravityScreenSaver.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + + +class GravityScreenSaver; + +class GravityConfigView : public BView +{ +public: + GravityConfigView(GravityScreenSaver* parent, BRect frame); + + void AttachedToWindow(); + void MessageReceived(BMessage* pbmMessage); + +private: + GravityScreenSaver* parent; + BListView* pblvShade; + BStringView* pbsvShadeText; + BSlider* pbsParticleCount; +}; + + +#endif /* _GRAVITY_CONFIG_VIEW_HPP_ */ diff --git a/src/add-ons/screen_savers/gravity/GravityHole.cpp b/src/add-ons/screen_savers/gravity/GravityHole.cpp new file mode 100644 index 0000000000..e71a0b7d85 --- /dev/null +++ b/src/add-ons/screen_savers/gravity/GravityHole.cpp @@ -0,0 +1,79 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Tri-Edge AI + */ + +#include "Particle.hpp" +#include "GravityHole.hpp" + +#include +#include + +#define frand() ((float)rand() / (float)RAND_MAX) + +GravityHole::GravityHole() +{ + x = 0.0f; + y = 0.0f; + z = 0.0f; + + vx = 0.0f; + vy = 0.0f; + vz = 0.0f; + + ax = frand() * 30.0f - 15.0f; + ay = frand() * 30.0f - 15.0f; + az = frand() * 10.0f - 5.0f; +} + + +void +GravityHole::Run() +{ + float dx = ax - x; + float dy = ay - y; + float dz = az - z; + + float d = dx * dx + dy * dy + dz * dz; + + vx += dx * 0.005f; + vy += dy * 0.005f; + vz += dz * 0.005f; + + x += vx; + y += vy; + z += vz; + + vx *= 0.95f; + vy *= 0.95f; + vz *= 0.95f; + + if (dx * dx + dy * dy + dz * dz < 10.0f) { + ax = frand() * 30.0f - 15.0f; + ay = frand() * 30.0f - 15.0f; + az = frand() * 10.0f - 5.0f; + } + + for (uint32 i = 0; i < Particle::list.size(); i++) { + dx = x - Particle::list[i]->x; + dy = y - Particle::list[i]->y; + dz = z - Particle::list[i]->z; + + d = dx * dx + dy * dy + dz * dz; + + Particle::list[i]->vx += dx / d * 0.5f; + Particle::list[i]->vy += dy / d * 0.5f; + Particle::list[i]->vz += dz / d * 0.5f; + Particle::list[i]->vr += 1.0f / d; + } +} + + +void +GravityHole::Draw() +{ + //... +} diff --git a/src/add-ons/screen_savers/gravity/GravityHole.hpp b/src/add-ons/screen_savers/gravity/GravityHole.hpp new file mode 100644 index 0000000000..9ede10fc57 --- /dev/null +++ b/src/add-ons/screen_savers/gravity/GravityHole.hpp @@ -0,0 +1,35 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Tri-Edge AI + */ + +#ifndef _GRAVITY_HOLE_HPP_ +#define _GRAVITY_HOLE_HPP_ + +#include + +class GravityHole +{ +public: + float x; + float y; + float z; + + float vx; + float vy; + float vz; + + float ax; + float ay; + float az; + + GravityHole(); + + void Run(); + void Draw(); +}; + +#endif /* _GRAVITY_HOLE_HPP */ diff --git a/src/add-ons/screen_savers/gravity/GravityScreenSaver.cpp b/src/add-ons/screen_savers/gravity/GravityScreenSaver.cpp new file mode 100644 index 0000000000..1524b0addb --- /dev/null +++ b/src/add-ons/screen_savers/gravity/GravityScreenSaver.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Tri-Edge AI + */ + + +#include +#include + +#include "GravityScreenSaver.hpp" + + +GravityScreenSaver::GravityScreenSaver(BMessage* pbmPrefs, image_id iidImage) + : + BScreenSaver(pbmPrefs, iidImage) +{ + srand(time(NULL)); + + if (pbmPrefs->IsEmpty()) { + Config.ParticleCount = 1; + Config.ShadeID = 2; + } else { + if (pbmPrefs->FindInt32("ParticleCount", &Config.ParticleCount) != B_OK) + Config.ParticleCount = 1; + + if (pbmPrefs->FindInt32("ShadeID", &Config.ShadeID) != B_OK) + Config.ShadeID = 2; + } +} + + +status_t +GravityScreenSaver::SaveState(BMessage* pbmPrefs) const +{ + pbmPrefs->AddInt32("ParticleCount", Config.ParticleCount); + pbmPrefs->AddInt32("ShadeID", Config.ShadeID); + return B_OK; +} + + +void +GravityScreenSaver::StartConfig(BView* pbvView) +{ + pbvView->AddChild(new GravityConfigView(this, pbvView->Bounds())); +} + + +status_t +GravityScreenSaver::StartSaver(BView* pbvView, bool bPreview) +{ + if (bPreview) { + view = NULL; + return B_ERROR; + } else { + SetTickSize((1000 / 30) * 1000); // ~30 FPS + + view = new GravityView(this, pbvView->Bounds()); + pbvView->AddChild(view); + + return B_OK; + } +} + + +void +GravityScreenSaver::StopSaver() +{ + if (view != NULL) { + view->EnableDirectMode(false); + } +} + + +void +GravityScreenSaver::DirectConnected(direct_buffer_info* pdbiInfo) +{ + if (view != NULL) { + // TODO: Find out why I had to uncomment this. + // view->DirectConnected(pdbiInfo); + // view->EnableDirectMode(true); + } +} + + +void +GravityScreenSaver::DirectDraw(int32 iFrame) +{ + view->Run(); + // Dummy rect + BRect rect; + view->Draw(rect); +} diff --git a/src/add-ons/screen_savers/gravity/GravityScreenSaver.hpp b/src/add-ons/screen_savers/gravity/GravityScreenSaver.hpp new file mode 100644 index 0000000000..40900e2c53 --- /dev/null +++ b/src/add-ons/screen_savers/gravity/GravityScreenSaver.hpp @@ -0,0 +1,53 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Tri-Edge AI + */ +#ifndef _GRAVITY_SCREEN_SAVER_HPP_ +#define _GRAVITY_SCREEN_SAVER_HPP_ + + +#include "GravityConfigView.hpp" +#include "GravityView.hpp" + +#include +#include +#include +#include + +#include +#include +#include + + +class GravityView; + +class GravityScreenSaver : public BScreenSaver +{ +public: + struct + { + int32 ShadeID; + int32 ParticleCount; + } Config; + + GravityScreenSaver(BMessage* pbmPrefs, image_id iidImage); + + status_t SaveState(BMessage* pbmPrefs) const; + + void StartConfig(BView* pbvView); + + status_t StartSaver(BView* pbvView, bool bPreview); + void StopSaver(); + + void DirectConnected(direct_buffer_info* pdbiInfo); + void DirectDraw(int32 iFrame); + +private: + GravityView* view; +}; + + +#endif /* _GRAVITY_SCREEN_SAVER_HPP_ */ diff --git a/src/add-ons/screen_savers/gravity/GravityView.cpp b/src/add-ons/screen_savers/gravity/GravityView.cpp new file mode 100644 index 0000000000..880ecf1133 --- /dev/null +++ b/src/add-ons/screen_savers/gravity/GravityView.cpp @@ -0,0 +1,101 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Tri-Edge AI + */ + + +#include "GravityView.hpp" + +#include + + +GravityView::GravityView(GravityScreenSaver* parent, BRect rect) + : + BGLView(rect, B_EMPTY_STRING, B_FOLLOW_NONE, 0, + BGL_RGB | BGL_DEPTH | BGL_DOUBLE), + fRect(rect) +{ + this->parent = parent; + + int realCount; + + if (parent->Config.ParticleCount == 0) + realCount = 128; + else if (parent->Config.ParticleCount == 1) + realCount = 256; + else if (parent->Config.ParticleCount == 2) + realCount = 512; + else if (parent->Config.ParticleCount == 3) + realCount = 1024; + else if (parent->Config.ParticleCount == 4) + realCount = 2048; + else + realCount = 128; // This shouldn't be happening either. + + Particle::Initialize(realCount, parent->Config.ShadeID); + + LockGL(); + + glClearDepth(1.0f); + + glEnable(GL_TEXTURE_2D); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0f, rect.Width() / rect.Height(), 2.0f, 20000.0f); + glTranslatef(0.0f, 0.0f, -30.0f); + + glDepthMask(GL_FALSE); + + glMatrixMode(GL_MODELVIEW); + + UnlockGL(); + + ghole = new GravityHole(); +} + + +GravityView::~GravityView() +{ + delete ghole; + Particle::Terminate(); +} + + +void +GravityView::AttachedToWindow() +{ + LockGL(); + BGLView::AttachedToWindow(); + UnlockGL(); +} + + +void +GravityView::Draw(BRect rect) +{ + LockGL(); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + Particle::DrawAll(); + ghole->Draw(); + + SwapBuffers(); + UnlockGL(); +} + + +void +GravityView::Run() +{ + Particle::RunAll(); + ghole->Run(); +} diff --git a/src/add-ons/screen_savers/gravity/GravityView.hpp b/src/add-ons/screen_savers/gravity/GravityView.hpp new file mode 100644 index 0000000000..49384374d1 --- /dev/null +++ b/src/add-ons/screen_savers/gravity/GravityView.hpp @@ -0,0 +1,40 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Tri-Edge AI + */ +#ifndef _GRAVITY_VIEW_HPP_ +#define _GRAVITY_VIEW_HPP_ + + +#include + +#include "Particle.hpp" +#include "GravityHole.hpp" +#include "GravityScreenSaver.hpp" + + +class GravityScreenSaver; + +class GravityView : public BGLView +{ +public: + GravityView(GravityScreenSaver* parent, BRect rect); + ~GravityView(); + + void AttachedToWindow(); + + void Draw(BRect rect); + void Run(); + +private: + BRect fRect; + + GravityScreenSaver* parent; + GravityHole* ghole; +}; + + +#endif /* _GRAVITY_VIEW_HPP_ */ diff --git a/src/add-ons/screen_savers/gravity/Jamfile b/src/add-ons/screen_savers/gravity/Jamfile new file mode 100644 index 0000000000..e0c7ed2d4e --- /dev/null +++ b/src/add-ons/screen_savers/gravity/Jamfile @@ -0,0 +1,29 @@ +SubDir HAIKU_TOP src add-ons screen_savers gravityhole ; +SubDirSysHdrs $(HAIKU_GLU_HEADERS) ; +SubDirSysHdrs $(HAIKU_MESA_HEADERS) ; + +AddResources Leaves : Gravity.rdef ; + +local sources = + Gravity.cpp + GravityConfigView.cpp + GravityHole.cpp + GravityScreenSaver.cpp + GravityView.cpp + Particle.cpp +; + +Includes [ FGristFiles $(sources) ] : $(HAIKU_MESA_HEADERS_DEPENDENCY) ; + # Dependency needed to trigger downloading/unzipping the package before + # compiling the files. + +ScreenSaver Gravity : + $(sources) + : be screensaver GL $(HAIKU_LOCALE_LIBS) $(TARGET_LIBSTDC++) +; + +DoCatalogs Gravity : + x-vnd.Haiku-GravityScreensaver + : + $(sources) +; diff --git a/src/add-ons/screen_savers/gravity/Particle.cpp b/src/add-ons/screen_savers/gravity/Particle.cpp new file mode 100644 index 0000000000..f5d3e62690 --- /dev/null +++ b/src/add-ons/screen_savers/gravity/Particle.cpp @@ -0,0 +1,132 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Tri-Edge AI + */ + + +#include "Particle.hpp" + + +#define frand() ((float)rand() / (float)RAND_MAX) + +vector Particle::list; + + +void +Particle::Initialize(int32 size, int32 shade) +{ + for (int32 i = 0; i < size; i++) { + Particle* p = new Particle(frand() * 30.0f - 15.0f, + frand() * 30.0f - 15.0f, frand() * 5.0f, frand() * 360.0f); + + p->vx = frand() - 0.5f; + p->vy = frand() - 0.5f; + p->vz = frand() - 0.5f; + p->vr = (frand() - 0.5f) * 180.0f; + + if (shade == 0) { // Red + p->red = 0.1f + frand() * 0.2f; + p->green = 0.0f; + p->blue = frand() * 0.05f; + } else if (shade == 1) { // Green + p->red = 0; + p->green = 0.1f + frand() * 0.2f; + p->blue = frand() * 0.05f; + } else if (shade == 2) { // Blue + p->red = 0; + p->green = frand() * 0.05f; + p->blue = 0.1f + frand() * 0.2f; + } else if (shade == 3) { // Orange + p->red = 0.1f + frand() * 0.1f; + p->green = 0.05f + frand() * 0.1f; + p->blue = 0.0f; + } else if (shade == 4) { // Purple + p->red = 0.1f + frand() * 0.2f; + p->green = 0.0f; + p->blue = 0.1f + frand() * 0.2f; + } else if (shade == 5) { // White + p->red = p->green = p->blue = 0.1f + frand() * 0.2f; + } else if (shade == 6) { // Rainbow + p->red = 0.1f + frand() * 0.2f; + p->green = 0.1f + frand() * 0.2f; + p->blue = 0.1f + frand() * 0.2f; + } else { + // Man, this shouldn't even happen.. Blue. + p->red = 0; + p->green = frand() * 0.05f; + p->blue = 0.1f + frand() * 0.2f; + } + + list.push_back(p); + } +} + + +void +Particle::Terminate() +{ + for (uint32 i = 0; i < list.size(); i++) + delete list[i]; + + list.clear(); +} + + +void +Particle::RunAll() +{ + for (uint32 i = 0; i < list.size(); i++) + list[i]->Run(); +} + + +void +Particle::DrawAll() +{ + for (uint32 i = 0; i < list.size(); i++) + list[i]->Draw(); +} + + +Particle::Particle(float x, float y, float z, float r) +{ + this->x = x; + this->y = y; + this->z = z; + this->r = r; +} + + +void +Particle::Run() +{ + x += vx; + y += vy; + z += vz; + r += vr; + + vx *= 0.98f; + vy *= 0.98f; + vz *= 0.98f; + vr *= 0.98f; +} + + +void +Particle::Draw() const +{ + glPushMatrix(); + glTranslatef(x, y, z); + glRotatef(r, 0.0f, 0.0f, 1.0f); + glBegin(GL_QUADS); + glColor3f(red, green, blue); + glVertex3f(-0.5f, 0.5f, 0.0f); + glVertex3f(-0.5f, -0.5f, 0.0f); + glVertex3f( 0.5f, -0.5f, 0.0f); + glVertex3f( 0.5f, 0.5f, 0.0f); + glEnd(); + glPopMatrix(); +} diff --git a/src/add-ons/screen_savers/gravity/Particle.hpp b/src/add-ons/screen_savers/gravity/Particle.hpp new file mode 100644 index 0000000000..bc8f2047cf --- /dev/null +++ b/src/add-ons/screen_savers/gravity/Particle.hpp @@ -0,0 +1,54 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Tri-Edge AI + */ +#ifndef _PARTICLE_HPP_ +#define _PARTICLE_HPP_ + + +#include + +#include +#include +#include + + +using namespace std; + + +class Particle +{ +public: + static vector list; + + static void Initialize(int32 size, int32 shade); + static void Terminate(); + static void RunAll(); + static void DrawAll(); + + float x; + float y; + float z; + float r; + + float vx; + float vy; + float vz; + float vr; + + float red; + float green; + float blue; + + Particle(float x, float y, float z, float r); + +private: + void Run(); + void Draw() const; +}; + + +#endif /* _PARTICLE_HPP_ */