summaryrefslogtreecommitdiffstats
path: root/debian/fireflies/fireflies-2.08/src
diff options
context:
space:
mode:
Diffstat (limited to 'debian/fireflies/fireflies-2.08/src')
-rw-r--r--debian/fireflies/fireflies-2.08/src/Makefile29
-rw-r--r--debian/fireflies/fireflies-2.08/src/arrow.cc53
-rw-r--r--debian/fireflies/fireflies-2.08/src/arrow.h31
-rw-r--r--debian/fireflies/fireflies-2.08/src/bait.cc98
-rw-r--r--debian/fireflies/fireflies-2.08/src/bait.h40
-rw-r--r--debian/fireflies/fireflies-2.08/src/canvas_base.cc106
-rw-r--r--debian/fireflies/fireflies-2.08/src/canvas_base.h46
-rw-r--r--debian/fireflies/fireflies-2.08/src/canvas_glx.cc92
-rw-r--r--debian/fireflies/fireflies-2.08/src/canvas_glx.h37
-rw-r--r--debian/fireflies/fireflies-2.08/src/canvas_sdl.cc218
-rw-r--r--debian/fireflies/fireflies-2.08/src/canvas_sdl.h38
-rw-r--r--debian/fireflies/fireflies-2.08/src/control.h31
-rw-r--r--debian/fireflies/fireflies-2.08/src/firefly.cc84
-rw-r--r--debian/fireflies/fireflies-2.08/src/firefly.h32
-rw-r--r--debian/fireflies/fireflies-2.08/src/main.cc396
-rw-r--r--debian/fireflies/fireflies-2.08/src/main.h11
-rw-r--r--debian/fireflies/fireflies-2.08/src/modes.cc211
-rw-r--r--debian/fireflies/fireflies-2.08/src/modes.h34
-rw-r--r--debian/fireflies/fireflies-2.08/src/resource.h25
-rw-r--r--debian/fireflies/fireflies-2.08/src/resource.rc88
-rw-r--r--debian/fireflies/fireflies-2.08/src/resource.rc.french88
-rw-r--r--debian/fireflies/fireflies-2.08/src/scene.cc252
-rw-r--r--debian/fireflies/fireflies-2.08/src/scene.h80
-rw-r--r--debian/fireflies/fireflies-2.08/src/tail.cc89
-rw-r--r--debian/fireflies/fireflies-2.08/src/tail.h37
-rw-r--r--debian/fireflies/fireflies-2.08/src/utils.cc161
-rw-r--r--debian/fireflies/fireflies-2.08/src/utils.h83
-rw-r--r--debian/fireflies/fireflies-2.08/src/vroot.h156
-rw-r--r--debian/fireflies/fireflies-2.08/src/winsaver.cc415
29 files changed, 3061 insertions, 0 deletions
diff --git a/debian/fireflies/fireflies-2.08/src/Makefile b/debian/fireflies/fireflies-2.08/src/Makefile
new file mode 100644
index 00000000..bbcf658d
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/Makefile
@@ -0,0 +1,29 @@
+include ../Make.include
+
+#CFLAGS += -DDEBUG
+
+HEADERS=$(wildcard *.h)
+HEADERS_GCH=$(HEADERS:.h=.h.gch)
+
+all: $(PROGRAM)
+
+$(PROGRAM): $(OBJECTS)
+ $(CXX) -o $(PROGRAM) $(OBJECTS) $(LIBS)
+ strip $(PROGRAM)
+
+$(OBJECTS): $(HEADERS)
+
+.SUFFIXES:
+.SUFFIXES: .cc .rc .o
+
+.cc.o:
+ $(CXX) -c $(CFLAGS) -o $@ $<
+
+#$(HEADERS_GCH): %.h.gch: %.h
+# $(CXX) -c -x c++-header $(CFLAGS) -o $@ $<
+
+.rc.o:
+ windres -o $@ $<
+
+clean:
+ rm -f *.o $(PROGRAM)
diff --git a/debian/fireflies/fireflies-2.08/src/arrow.cc b/debian/fireflies/fireflies-2.08/src/arrow.cc
new file mode 100644
index 00000000..12d03d5a
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/arrow.cc
@@ -0,0 +1,53 @@
+#include "arrow.h"
+#include "scene.h"
+
+// Draw a wireframe axis-aligned box whose opposite corners are given by the
+// points 'min' and 'max'.
+void draw_box(const Vec3f& min, const Vec3f& max)
+{
+ glBegin(GL_LINE_LOOP);
+ glVertex3d(min[0],min[1],min[2]); glVertex3d(min[0],max[1],min[2]);
+ glVertex3d(max[0],max[1],min[2]); glVertex3d(max[0],min[1],min[2]);
+ glEnd();
+
+ glBegin(GL_LINE_LOOP);
+ glVertex3d(min[0],min[1],max[2]); glVertex3d(min[0],max[1],max[2]);
+ glVertex3d(max[0],max[1],max[2]); glVertex3d(max[0],min[1],max[2]);
+ glEnd();
+
+ glBegin(GL_LINES);
+ glVertex3d(min[0],min[1],min[2]); glVertex3d(min[0],min[1],max[2]);
+ glVertex3d(min[0],max[1],min[2]); glVertex3d(min[0],max[1],max[2]);
+ glVertex3d(max[0],max[1],min[2]); glVertex3d(max[0],max[1],max[2]);
+ glVertex3d(max[0],min[1],min[2]); glVertex3d(max[0],min[1],max[2]);
+ glEnd();
+}
+
+void Arrow::draw()
+{
+ glColor4fv(color);
+ apply_transform();
+
+ glBegin(GL_TRIANGLE_FAN); // the front pyramid
+ glVertex3d(0., 0., scene.fsize*3); // height
+ glVertex3d(scene.fsize, 0., 0.);
+ glVertex3d(0., -scene.fsize, 0.);
+ glVertex3d(-scene.fsize, 0., 0.);
+ glVertex3d(0., scene.fsize, 0.);
+ glEnd();
+
+ glBegin(GL_TRIANGLE_FAN); // the butt pyramid
+ glVertex3d(0., 0., -scene.fsize*2); // height
+ glVertex3d(scene.fsize, 0., 0.);
+ glVertex3d(0., -scene.fsize, 0.);
+ glVertex3d(-scene.fsize, 0., 0.);
+ glVertex3d(0., scene.fsize, 0.);
+ glEnd();
+}
+
+void Arrow::point(Vec3f dir)
+{
+ double angle = acos(Vec3f(0, 0, 1)*unit_vec(dir));
+ rot_axis = unit_vec(cross(Vec3f(0, 0, 1), dir));
+ rot_angle = RAD_TO_DEG(angle);
+}
diff --git a/debian/fireflies/fireflies-2.08/src/arrow.h b/debian/fireflies/fireflies-2.08/src/arrow.h
new file mode 100644
index 00000000..d6aeeeca
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/arrow.h
@@ -0,0 +1,31 @@
+#ifndef _Arrow_H
+#define _Arrow_H
+
+#define DEG_TO_RAD(angle) (angle*M_PI/180.0)
+#define RAD_TO_DEG(angle) (angle*180.0/M_PI)
+
+#include "control.h"
+#include "utils.h"
+
+class Arrow : public Control
+{
+public:
+ hsvColor hsv;
+ rgbColor color;
+ Vec3f velocity; // current velocity
+ Vec3f accel; // current acceleration
+
+ Arrow() : hsv(0.0f, 0.8f, 0.8f, 1.0f) {}
+ virtual ~Arrow() {}
+
+ // draw the Arrow
+ virtual void draw();
+ // let t seconds elapse
+ virtual void elapse(double t) = 0;
+ // point me in direction of 'dir'.
+ void point(Vec3f dir);
+};
+
+void draw_box(const Vec3f& min, const Vec3f& max);
+
+#endif // Arrow.h
diff --git a/debian/fireflies/fireflies-2.08/src/bait.cc b/debian/fireflies/fireflies-2.08/src/bait.cc
new file mode 100644
index 00000000..417b9b72
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/bait.cc
@@ -0,0 +1,98 @@
+#include "bait.h"
+#include "modes.h"
+#include "scene.h"
+
+Bait::Bait()
+ : Arrow()
+{
+ age = rand_real(0., 10.);
+ fuzz = rand_real(0.7, 1.4);
+ glow = false;
+ attractor = 0;
+ bait_start_mode(this, BMODE_NORMAL);
+
+ hsv[0] = 30.0*rand_int(0, 12); // initial hue
+ turn_delay = rand_real(1., 4.);
+ turn_when = age + rand_real(0.5, turn_delay);
+ pos = Vec3f(
+ rand_real(-world[0], world[0]),
+ rand_real(-world[1], world[1]),
+ rand_real(-world[2], world[2]));
+ velocity = bspeed*unit_vec(-pos);
+
+ for (int i = 0; i < 3; i++) {
+ if (rand_int(0, 1)==0) accel[i] = -baccel;
+ else accel[i] = baccel;
+ }
+
+ set_color();
+
+#ifdef DEBUG
+ cerr << "bait: " << bspeed << " and " << baccel
+ << "\tflies: " << fspeed << " and " << faccel << endl;
+#endif
+}
+
+void Bait::draw()
+{
+ if (!scene.draw_bait)
+ return;
+
+ glPushMatrix();
+ Arrow::draw();
+ glPopMatrix();
+}
+
+void Bait::elapse(double t)
+{
+ hsv[0] += hue_rate*t;
+ age += t;
+
+ if (age >= mode_when)
+ bait_start_mode(this, mode_next);
+ while (stop_timer.is_ready(age))
+ bait_stop_mode(this, stop_timer.pop());
+
+ calc_accel();
+ velocity += accel*t;
+ clamp_vec(velocity, bspeed);
+ pos += velocity*t;
+
+ point(velocity);
+ set_color();
+}
+
+void Bait::calc_accel()
+{
+ if (attractor) {
+ accel = baccel*unit_vec((*attractor) - pos);
+ return;
+ }
+
+ // time to turn
+ if (age >= turn_when) {
+ for (int i = 0; i < 3; i++) {
+ if (rand_int(0, 1) == 0)
+ accel[i] = -SIGN(accel[i])*baccel;
+ }
+ turn_when = age + rand_real(0.5, turn_delay);
+ }
+
+ for (int i = 0; i < 3; i++) {
+ if (pos[i] < -world[i]) accel[i] = baccel;
+ else if (pos[i] > world[i]) accel[i] = -baccel;
+ }
+}
+
+void Bait::set_color()
+{
+ // keep everything as before
+
+ // clamp to my range
+ while (hsv[0] > 360.f)
+ hsv[0] -= 360.f;
+ while (hsv[0] < 0.f)
+ hsv[0] += 360.f;
+
+ color = hsv_to_rgb(hsv);
+}
diff --git a/debian/fireflies/fireflies-2.08/src/bait.h b/debian/fireflies/fireflies-2.08/src/bait.h
new file mode 100644
index 00000000..8ffdd6c5
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/bait.h
@@ -0,0 +1,40 @@
+#ifndef _Bait_H
+#define _Bait_H
+
+#include "utils.h"
+#include "arrow.h"
+
+class Bait : public Arrow
+{
+public:
+ double age; // timer with random initial value
+ double fuzz; // my little bit of randomness
+ double turn_delay; // max delay before turning (higher = slower changing)
+ double turn_when; // when to change acceleration (referenced from timer)
+ int mode_next; // the next mode to activate
+ double mode_when; // next time to activate a mode (ref timer)
+ Timer stop_timer; // timer for stopping events
+
+ // options
+ double bspeed; // my speed
+ double baccel; // my accel
+ double fspeed; // speed of the fireflies chasing me
+ double faccel; // acceleration of the fireflies chasing me
+ double hue_rate; // my color-cycling rate
+ bool glow; // should tails glow
+
+ Vec3f *attractor;
+
+ Bait();
+
+ // draw me
+ virtual void draw();
+ // let t seconds elapse
+ virtual void elapse(double t);
+ // calculate acceleration
+ virtual void calc_accel();
+ // change colors based on parameters
+ void set_color();
+};
+
+#endif // Bait.h
diff --git a/debian/fireflies/fireflies-2.08/src/canvas_base.cc b/debian/fireflies/fireflies-2.08/src/canvas_base.cc
new file mode 100644
index 00000000..008aada9
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/canvas_base.cc
@@ -0,0 +1,106 @@
+#include "canvas_base.h"
+
+#ifdef WIN32
+#include <time.h>
+#else
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+CanvasBase::CanvasBase(Scene *s, bool fs, int m)
+ : scene(s), full_screen(fs), mspf(m)
+{
+ animate = true;
+ need_refresh = true;
+ width = height = 0;
+}
+
+int CanvasBase::create_window()
+{
+ // it would be nice if this were pure virtual, but that makes my
+ // version of g++ fucks up for some reason.
+ return -1;
+}
+
+int CanvasBase::init()
+{
+#ifdef WIN32
+ srand(time(0));
+#else
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ srand(1000*tv.tv_sec + tv.tv_usec/1000);
+#endif
+
+ int ret;
+ if ((ret = create_window()) < 0)
+ return ret;
+
+ resize();
+
+ return 0;
+}
+
+void CanvasBase::resize()
+{
+ glViewport(0, 0, width, height);
+ scene->resize(width, height);
+}
+
+void CanvasBase::draw()
+{
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+ scene->apply_camera();
+ scene->draw();
+}
+
+int CanvasBase::loop()
+{
+ int remain, ret;
+ last_tick = get_ms();
+
+ while (true) {
+ if ((remain = tick()) > 0) // time left till tick: sleep
+ delay(remain);
+ if ((ret = handle_events()) > 0) // wants us to quit
+ return ret;
+ }
+}
+
+int CanvasBase::tick()
+{
+ if (need_refresh) {
+ draw();
+ need_refresh = false;
+ }
+
+ int now = get_ms();
+ int ms = now - last_tick;
+
+ // Animate the scene
+ if (ms >= mspf) {
+ last_tick = now;
+ if (animate) {
+ scene->elapse(ms/1000.0);
+ need_refresh = true;
+ }
+ return 0;
+ }
+ return (mspf - ms);
+}
+
+// these are dumb. See create_window()
+int CanvasBase::handle_events()
+{
+ return 1;
+}
+
+int CanvasBase::get_ms()
+{
+ return 0;
+}
+
+void CanvasBase::delay(int ms)
+{
+}
diff --git a/debian/fireflies/fireflies-2.08/src/canvas_base.h b/debian/fireflies/fireflies-2.08/src/canvas_base.h
new file mode 100644
index 00000000..b1adb333
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/canvas_base.h
@@ -0,0 +1,46 @@
+#ifndef _CANVASBASE_H
+#define _CANVASBASE_H
+
+#include "scene.h"
+
+// base class for a GL/DirectX Canvas
+class CanvasBase {
+//protected:
+public:
+ Scene *scene; // the thing that handles drawing and such
+ bool need_refresh; // do we need to redraw the canvas?
+ int last_tick;
+
+ // create the window
+ virtual int create_window();
+public:
+ bool full_screen; // use full screen?
+ int mspf; // ms per frame (ie, 1000/30 mspf instead of 30 fps)
+ bool animate;
+ int width;
+ int height;
+
+ CanvasBase(Scene *s, bool full_screen, int mspf);
+ virtual ~CanvasBase() {}
+
+ // initialize the window and GL stuff
+ virtual int init();
+ // resize the viewport and apply frustum transformation
+ virtual void resize();
+ // repaint what's on the canvas
+ virtual void draw();
+ // the event loop. handles events and animates the game
+ virtual int loop();
+ // tick if it spf seconds have elapsed since last tick
+ // returns 0 if ticked, else time remaining till tick.
+ virtual int tick();
+ // handle all events, and call proper handlers.
+ // returns 0 normally, else >0 on QUIT
+ virtual int handle_events();
+ // get current millisecond (arbitrary reference: used for change in millis)
+ virtual int get_ms();
+ // delay for specified number of milliseconds
+ virtual void delay(int ms);
+};
+
+#endif // canvas_base.h
diff --git a/debian/fireflies/fireflies-2.08/src/canvas_glx.cc b/debian/fireflies/fireflies-2.08/src/canvas_glx.cc
new file mode 100644
index 00000000..6b6809ab
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/canvas_glx.cc
@@ -0,0 +1,92 @@
+#include "canvas_glx.h"
+
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "vroot.h"
+
+CanvasGLX::CanvasGLX(Scene *s, bool fs, int m, Window wid)
+ : CanvasBase(s, fs, m), window_id(wid)
+{
+ window = 0;
+ display = 0;
+}
+
+int CanvasGLX::create_window()
+{
+ if ((display = XOpenDisplay(0)) == 0)
+ return -1;
+ screen = DefaultScreen(display);
+
+ window = window_id ? window_id : RootWindow(display, screen);
+ XWindowAttributes wa;
+ XGetWindowAttributes(display, window, &wa);
+ Visual *visual = wa.visual;
+
+ XVisualInfo templ;
+ templ.screen = screen;
+ templ.visualid = XVisualIDFromVisual(visual);
+ int out_count;
+ XVisualInfo *vinfo = XGetVisualInfo(display,
+ VisualScreenMask | VisualIDMask, &templ, &out_count);
+ if (!vinfo)
+ return -1;
+
+ GLXContext context = glXCreateContext(display, vinfo, 0, GL_TRUE);
+ XFree(vinfo);
+ if (!context)
+ return -1;
+
+ if (!glXMakeCurrent(display, window, context))
+ return -1;
+
+ XMapRaised(display, window);
+
+ return 0;
+}
+
+void CanvasGLX::resize()
+{
+ XWindowAttributes attrib;
+ XGetWindowAttributes(display, window, &attrib);
+ width = attrib.width;
+ height = attrib.height;
+
+ CanvasBase::resize();
+}
+
+void CanvasGLX::draw()
+{
+ CanvasBase::draw();
+
+ glXSwapBuffers(display, window);
+}
+
+int CanvasGLX::handle_events()
+{
+ XEvent event;
+ while (XPending(display)) {
+ XNextEvent(display, &event);
+ switch (event.type) {
+ case ConfigureNotify:
+ resize();
+ break;
+ }
+ }
+ return 0;
+}
+
+int CanvasGLX::get_ms()
+{
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ return (1000*tv.tv_sec + tv.tv_usec/1000);
+}
+
+void CanvasGLX::delay(int ms)
+{
+ struct timeval tv;
+ tv.tv_sec = ms/1000;
+ tv.tv_usec = (ms%1000)*1000;
+ select(0, 0, 0, 0, &tv);
+}
diff --git a/debian/fireflies/fireflies-2.08/src/canvas_glx.h b/debian/fireflies/fireflies-2.08/src/canvas_glx.h
new file mode 100644
index 00000000..330f5deb
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/canvas_glx.h
@@ -0,0 +1,37 @@
+#ifndef _CANVASGLX_H
+#define _CANVASGLX_H
+
+#include "canvas_base.h"
+
+#include <GL/glx.h>
+
+// A Canvas for drawing to a GL window via GLX
+// (currently only works on root window)
+class CanvasGLX : public CanvasBase {
+protected:
+ Window window;
+ Display *display;
+ int screen;
+
+ // create the window (either SDL or GLX)
+ virtual int create_window();
+public:
+ Window window_id;
+
+ CanvasGLX(Scene *s, bool full_screen, int mspf, Window wid);
+ virtual ~CanvasGLX() {}
+
+ // resize the viewport and apply frustum transformation
+ virtual void resize();
+ // repaint what's on the canvas
+ virtual void draw();
+ // handle all events, and call proper handlers.
+ // returns 0 normally, else >0 on QUIT
+ virtual int handle_events();
+ // get current millisecond (arbitrary reference: used for change in millis)
+ virtual int get_ms();
+ // delay for specified number of milliseconds
+ virtual void delay(int ms);
+};
+
+#endif // canvas_glx.h
diff --git a/debian/fireflies/fireflies-2.08/src/canvas_sdl.cc b/debian/fireflies/fireflies-2.08/src/canvas_sdl.cc
new file mode 100644
index 00000000..97b7bf81
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/canvas_sdl.cc
@@ -0,0 +1,218 @@
+#include "main.h"
+#include "canvas_sdl.h"
+#include "modes.h"
+
+#include <iostream>
+
+#include <gfx/quat.h>
+#include <gfx/mat4.h>
+
+using namespace std;
+
+CanvasSDL::CanvasSDL(Scene *s, bool fs, int m, char *t, char *c)
+ : CanvasBase(s, fs, m), wm_title(t), wm_class(c)
+{
+ surface = 0;
+}
+
+int CanvasSDL::create_window()
+{
+ int ret, flags = SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER
+ | SDL_HWPALETTE | SDL_HWACCEL | SDL_RESIZABLE | SDL_OPENGL;
+
+ if ((ret=SDL_Init(SDL_INIT_VIDEO)) < 0)
+ return ret;
+
+ if (full_screen)
+ flags |= SDL_FULLSCREEN;
+
+ SDL_Rect **modes;
+ modes = SDL_ListModes(0, flags);
+ if (modes == (SDL_Rect**)0) {
+ cerr << "CanvasSDL ERROR: no modes available" << endl;
+ return -1;
+ }
+ if (modes == (SDL_Rect**)-1) {
+ width = 1024;
+ height = 768;
+ }
+ else {
+ width = modes[0]->w;
+ height = modes[0]->h;
+ }
+
+ surface = SDL_SetVideoMode(width, height, 16, flags|SDL_RESIZABLE);
+ if (!surface)
+ return -1;
+
+ SDL_WM_SetCaption(wm_title, wm_class);
+
+ return 0;
+}
+
+void CanvasSDL::resize()
+{
+ width = surface->w;
+ height = surface->h;
+
+ CanvasBase::resize();
+}
+
+void CanvasSDL::draw()
+{
+ CanvasBase::draw();
+
+#if 0
+#define BORDER_COLOR 150
+ SDL_Rect rect;
+ rect.x = 500;
+ rect.y = 500;
+ rect.w = rect.h = 100;
+ SDL_FillRect(surface, &rect,
+ SDL_MapRGB(surface->format, BORDER_COLOR,
+ BORDER_COLOR, BORDER_COLOR));
+#endif
+
+ SDL_GL_SwapBuffers();
+}
+
+int CanvasSDL::handle_events()
+{
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_VIDEOEXPOSE:
+ need_refresh = true;
+ break;
+ case SDL_VIDEORESIZE:
+ need_refresh = true;
+ surface = SDL_SetVideoMode(event.resize.w, event.resize.h, 16, SDL_OPENGL|SDL_RESIZABLE);
+ if (!surface) {
+ cerr << "CanvasSDL ERROR: cannot set video mode after resize" << endl;
+ SDL_Quit();
+ return 2;
+ }
+ resize();
+ break;
+ case SDL_MOUSEMOTION:
+ if (on_mouse_drag(event.motion) < 0)
+ return 1;
+ break;
+ case SDL_KEYDOWN:
+ if (on_keydown(event.key) < 0)
+ return 1;
+ break;
+ case SDL_QUIT:
+ SDL_Quit();
+ return 1;
+ break;
+ }
+ }
+ return 0;
+}
+
+int CanvasSDL::get_ms()
+{
+ return SDL_GetTicks();
+}
+
+void CanvasSDL::delay(int ms)
+{
+ SDL_Delay(ms);
+}
+
+int CanvasSDL::on_mouse_drag(SDL_MouseMotionEvent& event)
+{
+ Mat4 inv_camera = rotation_matrix_deg(-scene->camera.rot_angle, Vec3(scene->camera.rot_axis));
+ Vec3 horiz = inv_camera*Vec3(1, 0, 0);
+ Vec3 vert = inv_camera*Vec3(0, 1, 0);
+
+ if (SDL_GetModState() & KMOD_CTRL) {
+ Quat q = axis_to_quat(scene->camera.rot_axis, DEG_TO_RAD(scene->camera.rot_angle));
+ if (event.state & SDL_BUTTON(1)) { // rotate
+ Quat qx = axis_to_quat(vert, event.xrel*0.05);
+ Quat qy = axis_to_quat(horiz, event.yrel*0.05);
+
+ q = q * qy;
+ q = q * qx;
+ unitize(q);
+
+ scene->camera.rot_axis = q.vector();
+ scene->camera.rot_angle = RAD_TO_DEG(2.0*acos(q.scalar()));
+ need_refresh = true;
+ }
+ }
+ else {
+ if (event.state & SDL_BUTTON(1)) { // move camera
+ scene->camera.pos += 0.5*Vec3f(event.xrel, -event.yrel, 0.);
+ need_refresh = true;
+ }
+ else if (event.state & SDL_BUTTON(3)) { // zoom in/out
+ scene->camera.pos += 0.5*Vec3f(0., 0., event.yrel);
+ need_refresh = true;
+ }
+ }
+
+ return 0;
+}
+
+int CanvasSDL::on_keydown(SDL_KeyboardEvent& event)
+{
+ switch (event.keysym.sym) {
+ case SDLK_q:
+ SDL_Quit();
+ return -1;
+ break;
+ case SDLK_p: // pause or unpause
+ animate = !animate;
+ break;
+ case SDLK_t: // show the time
+ cout << "Elapsed time: " << scene->curtime << "s" << endl;
+ break;
+ case SDLK_UP:
+ scene->fast_forward *= 2;
+ cout << "fast forward: " << scene->fast_forward << "x" << endl;
+ break;
+ case SDLK_DOWN:
+ if (scene->fast_forward > 1)
+ scene->fast_forward /= 2;
+ cout << "fast forward: " << scene->fast_forward << "x" << endl;
+ break;
+ case SDLK_RIGHT:
+ scene->fast_forward += 1;
+ cout << "fast forward: " << scene->fast_forward << "x" << endl;
+ break;
+ case SDLK_LEFT:
+ if (scene->fast_forward > 1)
+ scene->fast_forward -= 1;
+ cout << "fast forward: " << scene->fast_forward << "x" << endl;
+ break;
+ default: {
+ int c = event.keysym.sym - '0';
+ if (event.keysym.mod & KMOD_SHIFT) {
+ if (c >= 0 && c < NUM_BMODES) {
+ vector<Bait*>::iterator it = scene->baits.begin();
+ for (; it != scene->baits.end(); it++)
+ bait_start_mode(*it, c);
+ cout << "started bait mode " << c << endl;
+ }
+ }
+ else if (event.keysym.mod & KMOD_CTRL) {
+ if (c >= 0 && c < NUM_BMODES) {
+ vector<Bait*>::iterator it = scene->baits.begin();
+ for (; it != scene->baits.end(); it++)
+ bait_stop_mode(*it, c);
+ cout << "stopped bait mode " << c << endl;
+ }
+ }
+ else {
+ if (c >= 0 && c < NUM_SMODES) {
+ scene_start_mode(c);
+ cout << "started scene mode " << c << endl;
+ }
+ }
+ break;
+ }
+ }
+ return 0;
+}
diff --git a/debian/fireflies/fireflies-2.08/src/canvas_sdl.h b/debian/fireflies/fireflies-2.08/src/canvas_sdl.h
new file mode 100644
index 00000000..4b51fe45
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/canvas_sdl.h
@@ -0,0 +1,38 @@
+#ifndef _CANVASSDL_H
+#define _CANVASSDL_H
+
+#include "canvas_base.h"
+
+#include "SDL.h"
+
+// A Canvas for drawing to a GL window via SDL
+class CanvasSDL : public CanvasBase {
+protected:
+ SDL_Surface *surface;
+ char *wm_title;
+ char *wm_class;
+
+ // create the window (either SDL or GLX)
+ virtual int create_window();
+public:
+ CanvasSDL(Scene *s, bool full_screen, int mspf, char *wm_title, char *wm_class);
+ virtual ~CanvasSDL() {}
+
+ // resize the viewport and apply frustum transformation
+ virtual void resize();
+ // repaint what's on the canvas
+ virtual void draw();
+ // handle all events, and call proper handlers.
+ // returns 0 normally, else >0 on QUIT
+ virtual int handle_events();
+ // get current millisecond (arbitrary reference: used for change in millis)
+ virtual int get_ms();
+ // delay for specified number of milliseconds
+ virtual void delay(int ms);
+
+ // handle a mouse drag event
+ int on_mouse_drag(SDL_MouseMotionEvent& event);
+ int on_keydown(SDL_KeyboardEvent& event);
+};
+
+#endif // canvas_sdl.h
diff --git a/debian/fireflies/fireflies-2.08/src/control.h b/debian/fireflies/fireflies-2.08/src/control.h
new file mode 100644
index 00000000..653b91ec
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/control.h
@@ -0,0 +1,31 @@
+#ifndef _CONTROL_H
+#define _CONTROL_H
+
+#include "main.h"
+#include <gfx/vec3.h>
+
+#define DEG_TO_RAD(angle) (angle*M_PI/180.0)
+#define RAD_TO_DEG(angle) (angle*180.0/M_PI)
+
+// a set of controls for objects and the camera. directly corresponds to
+// OpenGL calls.
+class Control {
+public:
+ Vec3f pos;
+ double rot_angle; // in degrees
+ Vec3f rot_axis;
+
+ Control() : rot_angle(0)
+ {}
+ void apply_transform()
+ {
+ glTranslated(pos[0], pos[1], pos[2]);
+ glRotated(rot_angle, rot_axis[0], rot_axis[1], rot_axis[2]);
+#if 0
+ // we don't use this
+ glScaled(scale[0], scale[1], scale[2]);
+#endif
+ }
+};
+
+#endif // _CONTROL_H
diff --git a/debian/fireflies/fireflies-2.08/src/firefly.cc b/debian/fireflies/fireflies-2.08/src/firefly.cc
new file mode 100644
index 00000000..b4f50d68
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/firefly.cc
@@ -0,0 +1,84 @@
+#include "firefly.h"
+#include "scene.h"
+#include "modes.h"
+
+Firefly::Firefly(Bait *_bait, Vec3f ctr, double spread)
+ : Arrow(), bait(_bait), age(0.)
+{
+ pos = ctr;
+ pos += rand_vec3(-spread, spread);
+
+ velocity = bait->fspeed*unit_vec(bait->pos - pos);
+ tail = new Tail(this);
+}
+
+Firefly::~Firefly()
+{
+ tail->owner = 0;
+ scene.dead_tails.push_back(tail);
+}
+
+void Firefly::draw()
+{
+ glPushMatrix();
+ Arrow::draw();
+ glPopMatrix();
+
+ tail->draw();
+}
+
+void Firefly::elapse(double t)
+{
+ age += t;
+
+ calc_accel();
+ velocity += accel*t;
+ clamp_vec(velocity, bait->fspeed);
+ pos += velocity*t;
+
+ point(velocity);
+ set_color();
+
+ // elapse, my children
+ tail->elapse(t);
+}
+
+void Firefly::calc_accel()
+{
+ if (age > 2.0 && rand_int(0, 60)==0) {
+ GLuint i, closest_i = 0;
+ double dist, closest_dist = 1e10;
+ for (i = 0; i < scene.baits.size(); i++) {
+ if ((dist=norm(scene.baits[i]->pos - pos)) < closest_dist) {
+ closest_dist = dist;
+ closest_i = i;
+ }
+ }
+ dist = norm(bait->pos - pos);
+ if (closest_dist < dist-1.0) {
+ bait = scene.baits[closest_i];
+ age = 0.;
+ }
+ }
+ else if (age > 5.0) {
+ if (norm(bait->pos - pos) >= 200 && !(bait->bspeed == 0 || bait->attractor)) {
+ bait->mode_next = BMODE_STOP;
+ }
+ }
+
+ accel = bait->faccel*unit_vec(bait->pos - pos);
+}
+
+void Firefly::set_color()
+{
+ hsv = bait->hsv;
+ hsv[0] += 40*norm2(velocity)/(bait->fspeed*bait->fspeed) - 20;
+
+ // clamp to my range
+ while (hsv[0] > 360.f)
+ hsv[0] -= 360.f;
+ while (hsv[0] < 0.f)
+ hsv[0] += 360.f;
+
+ color = hsv_to_rgb(hsv);
+}
diff --git a/debian/fireflies/fireflies-2.08/src/firefly.h b/debian/fireflies/fireflies-2.08/src/firefly.h
new file mode 100644
index 00000000..784b4ccb
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/firefly.h
@@ -0,0 +1,32 @@
+#ifndef _PARTICLE_H
+#define _PARTICLE_H
+
+#include "arrow.h"
+#include "tail.h"
+#include "bait.h"
+
+class Firefly : public Arrow
+{
+public:
+ Bait *bait; // the bait I'm after
+ Tail *tail; // my pretty tail
+ double age; // how long I've been alive
+
+ // Firefly(
+ // the bait I'm after,
+ // where to put me,
+ // plus/minus this amount)
+ Firefly(Bait *_bait, Vec3f ctr, double spread);
+ virtual ~Firefly();
+
+ // draw me and my tail
+ virtual void draw();
+ // let t seconds elapse
+ virtual void elapse(double t);
+ // calculate acceleration
+ void calc_accel();
+ // change colors based on parameters
+ void set_color();
+};
+
+#endif // Firefly.h
diff --git a/debian/fireflies/fireflies-2.08/src/main.cc b/debian/fireflies/fireflies-2.08/src/main.cc
new file mode 100644
index 00000000..be440235
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/main.cc
@@ -0,0 +1,396 @@
+#include "main.h"
+#include "scene.h"
+
+#include "canvas_base.h"
+#ifdef HAVE_SDL
+#include "canvas_sdl.h"
+#endif
+#ifdef HAVE_GLX
+#include "canvas_glx.h"
+#endif
+
+#include <iostream>
+#include <stdlib.h>
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <argp.h>
+#endif
+
+CanvasBase *canvas;
+Scene scene;
+
+enum {CANVAS_SDL, CANVAS_GLX} canvas_type = CANVAS_SDL;
+int window_id = 0;
+int mspf = 1000/30;
+bool full_screen = false;
+
+#ifdef WIN32
+// mingw doesn't have argp. implement half-assed version
+
+#define OPTION_HIDDEN 1
+#define OPTION_DOC 2
+
+#define ARGP_KEY_ARG 0
+#define ARGP_ERR_UNKNOWN 0
+
+#define ARGP_LONG_ONLY 1
+
+typedef int (*argp_parser_t)(int, char*, struct argp_state*);
+
+struct argp_option {
+ const char *name;
+ int key;
+ const char *arg;
+ int flags;
+ const char *doc;
+ int group;
+};
+
+struct argp {
+ const struct argp_option *options;
+ argp_parser_t parser;
+ const char *args_doc;
+ const char *doc;
+ // there are more members, but this is all I need
+};
+
+struct argp_state {
+ int argc;
+ char **argv;
+ int next;
+ char *name;
+ // there are more members, but this is all I need
+};
+
+void argp_help(struct argp *argp_s)
+{
+ cerr << argp_s->doc << endl;
+
+ for (int i = 0; argp_s->options[i].name; i++) {
+ if (argp_s->options[i].flags & OPTION_HIDDEN)
+ continue;
+ if (argp_s->options[i].flags & OPTION_DOC)
+ cerr << argp_s->options[i].name << endl;
+ else {
+ if (isprint(argp_s->options[i].key))
+ cerr << " -" << (char)argp_s->options[i].key << ",";
+ else
+ cerr << " ";
+ cerr << " --" << argp_s->options[i].name << "\t";
+ cerr << argp_s->options[i].doc << endl;
+ }
+ }
+}
+
+// doesn't work exactly as real argp, but suits this program
+int argp_parse(struct argp *argp_s, int argc, char *argv[], int, int *, void *)
+{
+ char *opt, *arg=0;
+ int optind = 0;
+
+ struct argp_state state;
+ state.argc = argc;
+ state.argv = argv;
+ state.name = argv[0];
+
+ for (int i = 1; i < state.argc; i = state.next) {
+ opt = state.argv[i];
+ arg = 0;
+ optind = -1;
+ state.next = i+1;
+
+ if (opt[0] != '-') {
+ if ((*argp_s->parser)(ARGP_KEY_ARG, 0, &state) < 0)
+ return -1;
+ continue;
+ }
+ opt++;
+ if (*opt == '-')
+ opt++;
+
+ if ((arg = strchr(opt, '=')))
+ *arg++ = 0;
+
+ if (opt[1] == 0) { // short option
+ for (int j = 0; argp_s->options[j].name; j++) {
+ if (opt[0] == argp_s->options[j].key) {
+ optind = j;
+ break;
+ }
+ }
+ if (optind >= 0)
+ ;
+ else if (opt[0] == 'h') {
+ argp_help(argp_s);
+ return -1;
+ }
+ else if (opt[0] == 'u') {
+ argp_help(argp_s);
+ return -1;
+ }
+ else if (opt[0] == 'V') {
+ extern char *argp_program_version;
+ cerr << argp_program_version << endl;
+ return -1;
+ }
+ }
+ else { // long option
+ for (int j = 0; argp_s->options[j].name; j++) {
+ if (strcmp(opt, argp_s->options[j].name)==0) {
+ optind = j;
+ break;
+ }
+ }
+ if (optind >= 0)
+ ;
+ else if (strcmp(opt, "help") == 0) {
+ argp_help(argp_s);
+ return -1;
+ }
+ else if (strcmp(opt, "usage") == 0) {
+ argp_help(argp_s);
+ return -1;
+ }
+ else if (strcmp(opt, "version") == 0) {
+ extern char *argp_program_version;
+ cerr << argp_program_version << endl;
+ return -1;
+ }
+ }
+ if (optind < 0) { // doesn't exist
+ cerr << state.name << ": unrecognized option `"
+ << state.argv[i] << "'" << endl;
+ cerr << "Try `" << state.name << " --help' or `"
+ << state.name << " --usage' for more information" << endl;
+ return -1;
+ }
+ if (argp_s->options[optind].arg != 0 && arg == 0) {
+ state.next = i+2;
+ if (i+1 >= state.argc) {
+ cerr << state.name << ": option requires an argument -- "
+ << opt << endl;
+ return -1;
+ }
+ arg = state.argv[i+1];
+ }
+ if ((*argp_s->parser)(argp_s->options[optind].key, arg, &state) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+#endif
+
+#define OPT_FULLSCREEN 1
+#define OPT_FPS 2
+#define OPT_FASTFORWARD 3
+
+char *mode_help =
+"\n"
+"Per-swarm modes and their default probabilities:\n"
+" 1: normal p=20\n"
+" 2: stop (bait stays still for a brief period) p=10\n"
+" 3: circle (bait loops in a circle briefly) p=10\n"
+" 4: rainbow (color cycle speeds up) p=10\n"
+" 5: glow (tails glow as their width increases) p=15\n"
+" 6: hyperspeed (swarm speeds up) p=10\n"
+" 7: faded (colors fade) p=10\n"
+"Major modes and their default probabilities:\n"
+" 1: all swarms pick a random per-swarm mode p=5\n"
+" 2: kill some flies p=10\n"
+" 3: make some new flies p=10\n"
+" 4: wind speed picks up p=10\n"
+" 5: matrix-style pause and rotate of the scene p=10\n"
+" 6: split a random swarm into two swarms p=10\n"
+" 7: merge two random swarms into one p=10\n"
+"Note: mode probabilities are relative. For example, if A has p=5, and B has\n"
+"p=1, that simply means A is 5 times more likely to occur than B.";
+
+const char *argp_program_version =
+"Fireflies " PACKAGE_VERSION " by Mattperry <[email protected]>";
+
+static char doc[] =
+"Moving swarms of delicious eye candy.";
+
+static struct argp_option options[] = {
+{"window-id", 'W', "WinID", OPTION_HIDDEN},
+{"root", 'r', 0, 0, "Draw on the root window"},
+
+{"fullscreen", OPT_FULLSCREEN, 0, 0, "Full screen mode"},
+{"fps", OPT_FPS, "NUM", 0, "Frames per second (default = 30 fps)"},
+{"fastforward", OPT_FASTFORWARD, "NUM", 0, "Fast forward factor (default = 1)"},
+{"minbaits", 'b', "NUM", 0, "Minimum baits (default = 2)"},
+{"maxbaits", 'B', "NUM", 0, "Maximum baits (default = 5)"},
+{"minflies", 'f', "NUM", 0, "Minimum total fireflies (default = 100)"},
+{"maxflies", 'F', "NUM", 0, "Maximum total fireflies (default = 175)"},
+{"size", 's', "NUM", 0, "Firefly size (default = 15)"},
+{"bspeed", 'V', "NUM", 0, "Bait speed (default = 50)"},
+{"baccel", 'A', "NUM", 0, "Bait acceleration (default = 600)"},
+{"fspeed", 'v', "NUM", 0, "Firefly speed (default = 100)"},
+{"faccel", 'a', "NUM", 0, "Firefly acceleration (default = 300)"},
+{"colorspeed", 'c', "NUM", 0, "Swarm's color cycling speed (default = 15)"},
+{"taillength", 't', "NUM", 0, "Firefly's tail length (default = 23)"},
+{"tailwidth", 'T', "NUM", 0, "Firefly's tail width (default = 25)"},
+{"tailopacity", 'o', "NUM", 0,
+ "Firefly's tail opacity/brightness ([0-100] default = 60)"},
+{"glowfactor", 'g', "NUM", 0,
+ "Factor by which tailwidth increases during glow (default = 20)"},
+{"wind", 'w', "NUM", 0, "Wind speed (default = 30)"},
+{"drawbait", 'd', 0, 0, "Draw the baits that the fireflies chase"},
+{"modeswarm", 'm', "MODENUM VAL", 0,
+ "Change the frequency of per-swarm mode MODENUM to VAL"},
+{"modemajor", 'M', "MODENUM VAL", 0,
+ "Change the frequency of major mode MODENUM to VAL"},
+{mode_help, 0, 0, OPTION_DOC, 0, -1},
+{0, 0, 0, 0}
+};
+
+int parse_opt(int key, char *arg, struct argp_state *state)
+{
+ switch (key) {
+ case 'W':
+ canvas_type = CANVAS_GLX;
+ window_id = strtol(arg, 0, 0);
+ break;
+ case 'r':
+ canvas_type = CANVAS_GLX;
+ break;
+ case OPT_FULLSCREEN:
+ full_screen = true;
+ break;
+ case OPT_FPS:
+ mspf = 1000/atoi(arg);
+ break;
+ case OPT_FASTFORWARD:
+ scene.fast_forward = atoi(arg);
+ if (scene.fast_forward == 0) {
+ cerr << state->name
+ << ": -fastforward must be > 0" << endl;
+ return -1;
+ }
+ break;
+ case 'b':
+ scene.minbaits = (unsigned)atoi(arg);
+ break;
+ case 'B':
+ scene.maxbaits = (unsigned)atoi(arg);
+ break;
+ case 'f':
+ scene.minflies = (unsigned)atoi(arg);
+ break;
+ case 'F':
+ scene.maxflies = (unsigned)atoi(arg);
+ break;
+ case 's':
+ scene.fsize = atoi(arg)/10.0;
+ break;
+ case 'V':
+ scene.bspeed = atoi(arg);
+ break;
+ case 'A':
+ scene.baccel = atoi(arg);
+ break;
+ case 'v':
+ scene.fspeed = atoi(arg);
+ break;
+ case 'a':
+ scene.faccel = atoi(arg);
+ break;
+ case 'c':
+ scene.hue_rate = atoi(arg);
+ break;
+ case 't':
+ scene.tail_length = atoi(arg)/10.0;
+ break;
+ case 'T':
+ scene.tail_width = atoi(arg)/10.0;
+ break;
+ case 'o':
+ scene.tail_opaq = atoi(arg)/100.0;
+ if (scene.tail_opaq < 0 || scene.tail_opaq > 1) {
+ cerr << state->name
+ << ": -tailopacity must be in the range [0,100]" << endl;
+ return -1;
+ }
+ break;
+ case 'g':
+ scene.glow_factor = atoi(arg)/10.0;
+ break;
+ case 'w':
+ scene.wind_speed = atoi(arg)/10.0;
+ break;
+ case 'd':
+ scene.draw_bait = true;
+ break;
+ case 'm': {
+ int which = atoi(arg);
+ unsigned val;
+ if (state->next < state->argc) {
+ val = (unsigned)atoi(state->argv[state->next]);
+ state->next++;
+ }
+ else {
+ cerr << state->name << ": option -modebait requires 2 arguments" << endl;
+ return -1;
+ }
+ scene.bmodes.change(which, (double)val);
+ break;
+ }
+ case 'M': {
+ int which = atoi(arg);
+ unsigned val;
+ if (state->next < state->argc) {
+ val = (unsigned)atoi(state->argv[state->next]);
+ state->next++;
+ }
+ else {
+ cerr << state->name << ": option -modebait requires 2 arguments" << endl;
+ return -1;
+ }
+ scene.smodes.change(which, (double)val);
+ break;
+ }
+ default:
+ return ARGP_ERR_UNKNOWN;
+ break;
+ }
+ return 0;
+}
+
+static struct argp argp_s = { options, parse_opt, 0, doc };
+
+int main(int argc, char **argv)
+{
+ if (argp_parse (&argp_s, argc, argv, ARGP_LONG_ONLY, 0, 0) != 0)
+ return 0;
+
+ switch (canvas_type) {
+ case CANVAS_GLX:
+#ifdef HAVE_GLX
+ canvas = new CanvasGLX(&scene, full_screen, mspf, window_id);
+#else
+ cerr << argv[0] << ": cannot make GLX window (you must have GLX support enabled)" << endl;
+ return 1;
+#endif
+ break;
+ case CANVAS_SDL:
+#ifdef HAVE_SDL
+ canvas = new CanvasSDL(&scene, full_screen, mspf, "Fireflies", "fireflies");
+#else
+ cerr << argv[0] << ": cannot make SDL window (you must have SDL support enabled)" << endl;
+ return 1;
+#endif
+ break;
+ }
+
+ if (canvas->init() < 0) {
+ cerr << "Can't init display." << endl;
+ return 0;
+ }
+
+ scene.create();
+
+ return canvas->loop();
+}
diff --git a/debian/fireflies/fireflies-2.08/src/main.h b/debian/fireflies/fireflies-2.08/src/main.h
new file mode 100644
index 00000000..3663ebc6
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/main.h
@@ -0,0 +1,11 @@
+#ifndef _MAIN_H
+#define _MAIN_H
+
+#include "../config.h"
+
+#include <gfx/config.h> // libgfx is retarded
+#include <GL/gl.h>
+
+using namespace std;
+
+#endif // _MAIN_H
diff --git a/debian/fireflies/fireflies-2.08/src/modes.cc b/debian/fireflies/fireflies-2.08/src/modes.cc
new file mode 100644
index 00000000..780c7488
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/modes.cc
@@ -0,0 +1,211 @@
+#include "modes.h"
+#include "bait.h"
+#include "scene.h"
+
+#define BMODE_WAIT rand_real(10., 15.)
+#define SMODE_WAIT rand_real(10., 20.)
+
+void bait_start_mode(Bait *b, int mode)
+{
+ b->mode_next = scene.bmodes.rand();
+ b->mode_when = b->age + BMODE_WAIT;
+
+ switch (mode) {
+ case BMODE_NORMAL: // normal mode
+ if (b->attractor) {
+ delete b->attractor;
+ b->attractor = 0;
+ }
+ b->bspeed = b->fuzz*scene.bspeed;
+ b->baccel = b->fuzz*scene.baccel;
+ b->fspeed = b->fuzz*scene.fspeed;
+ b->faccel = b->fuzz*scene.faccel;
+
+ b->hue_rate = b->fuzz*scene.hue_rate;
+ break;
+ case BMODE_STOP: // stop mode
+ if (b->attractor || b->bspeed==0) // don't do it if we're already doing it
+ break;
+ b->bspeed = 0;
+ b->stop_timer.add(mode, b->age + rand_real(2., 3.));
+ break;
+ case BMODE_ATTRACTOR: // attractor
+ if (b->attractor || b->bspeed==0) // don't do it if we're already doing it
+ break;
+ b->attractor = new Vec3f(b->pos + rand_vec3(-10, 10));
+ b->baccel = (b->bspeed*b->bspeed/20.0);
+ b->stop_timer.add(mode, b->age + rand_real(5., 10.));
+ break;
+ case BMODE_RAINBOW: // rainbow mode
+ b->hue_rate = rand_int(10, 15)*scene.hue_rate;
+ b->stop_timer.add(mode, b->age + rand_real(10., 15.));
+ break;
+ case BMODE_GLOW: // glow mode
+ b->glow = true;
+ b->stop_timer.add(mode, b->age + rand_real(10., 20.));
+ break;
+ case BMODE_HYPERSPEED: // hyperspeed mode
+ b->bspeed = 1.5*scene.bspeed;
+ b->baccel = 1.5*scene.baccel;
+ b->fspeed = 2*scene.fspeed;
+ b->faccel = 3*scene.faccel;
+ b->stop_timer.add(mode, b->age + rand_real(10., 20.));
+ break;
+ case BMODE_FADED: // faded color mode
+ b->hsv[1] = rand_real(0.4, 0.6);
+ b->stop_timer.add(mode, b->age + rand_real(10., 20.));
+ break;
+ }
+
+#ifdef DEBUG
+ cerr << "baitmode=" << mode << " for "
+ << (b->stop_timer.events.empty() ? 0 : b->stop_timer.events[0].second-b->age)
+ << "s\tnext=" << b->mode_next << " in " << b->mode_when-b->age << "s" << endl;
+#endif
+}
+
+void bait_stop_mode(Bait* b, int mode)
+{
+ switch (mode) {
+ case BMODE_NOTHING:
+ case BMODE_NORMAL:
+ return;
+ break;
+ case BMODE_STOP: // anti stop mode
+ b->bspeed = b->fuzz*scene.bspeed;
+ break;
+ case BMODE_ATTRACTOR: // anti attractor
+ delete b->attractor;
+ b->attractor = 0;
+ b->baccel = b->fuzz*scene.baccel;
+ break;
+ case BMODE_RAINBOW: // anti rainbow mode
+ b->hue_rate = b->fuzz*scene.hue_rate;
+ break;
+ case BMODE_GLOW: // anti glow mode
+ b->glow = false;
+ break;
+ case BMODE_HYPERSPEED: // anti hyperspeed mode
+ b->bspeed = b->fuzz*scene.bspeed;
+ b->baccel = b->fuzz*scene.baccel;
+ b->fspeed = b->fuzz*scene.fspeed;
+ b->faccel = b->fuzz*scene.faccel;
+ break;
+ case BMODE_FADED:
+ b->hsv[1] = 0.8;
+ break;
+ }
+
+#ifdef DEBUG
+ cerr << "\tstopped=" << mode << endl;
+#endif
+}
+
+void scene_start_mode(int mode)
+{
+ scene.mode_next = scene.smodes.rand();
+ scene.mode_when = scene.curtime + SMODE_WAIT;
+
+ // negatives keep them off the modelist
+ switch (mode) {
+ case SMODE_SWARMS: { // all-swarm mode
+ int bmode = scene.bmodes.rand();
+ if (bmode < 0)
+ break;
+ for (GLuint i = 0; i < scene.baits.size(); i++) {
+ scene.baits[i]->stop_timer.clear(); // clear out any stops
+ bait_start_mode(scene.baits[i], BMODE_NORMAL); // set default.
+ bait_start_mode(scene.baits[i], bmode);
+ }
+ break;
+ }
+ case SMODE_FLYKILL: { // firefly go byebye
+ if (scene.flies.size() <= scene.minflies) // not too few
+ break;
+ int max = (scene.flies.size() - scene.minflies);
+ int n = rand_int(max/3, max);
+ scene.rem_flies(n);
+#ifdef DEBUG
+ cerr << "deleted " << n << " flies" << endl;
+#endif
+ break;
+ }
+ case SMODE_FLYBIRTH: { // hello firefly
+ if (scene.flies.size() >= scene.maxflies) // not too many
+ break;
+ int max = (scene.maxflies - scene.flies.size());
+ int n = rand_int(max/3, max);
+ scene.add_flies(n);
+#ifdef DEBUG
+ cerr << "created " << n << " flies" << endl;
+#endif
+ break;
+ }
+ case SMODE_WINDY: // it's getting windy in here!
+ scene.wind_speed *= 3;
+ scene.mode_next = -SMODE_WINDY;
+ break;
+ case -SMODE_WINDY: // calm the wind down
+ scene.wind_speed /= 3;
+ break;
+ case SMODE_MATRIX: {// matrix mode
+ scene.matrix = scene.curtime;
+ scene.matrix_axis = Vec3f(rand_int(-1, 1), rand_int(-1, 1), rand_int(-1, 1));
+ if (norm2(scene.matrix_axis) == 0)
+ scene.matrix_axis = Vec3f(0, 1, 0);
+ unitize(scene.matrix_axis);
+ scene.mode_next = -SMODE_MATRIX;
+ scene.mode_when = scene.curtime + rand_real(4.0, 5.0);
+ break;
+ }
+ case -SMODE_MATRIX: // anti matrix
+ scene.matrix = -1.0;
+ break;
+ case SMODE_SWARMSPLIT: { // split mode
+ if (scene.baits.size() >= scene.maxbaits) // not too many
+ break;
+ Bait *b1 = scene.baits[rand_int(0, scene.baits.size()-1)];
+ Bait *b2 = new Bait();
+ b2->pos = b1->pos;
+ scene.baits.push_back(b2);
+ double fpb = (double)scene.flies.size()/scene.baits.size();
+ int n = rand_int((int)(fpb/4), (int)(fpb/2));
+ for (GLuint i = 0; i < scene.flies.size() && n > 0; i++) {
+ if (scene.flies[i]->bait == b1) {
+ scene.flies[i]->bait = b2;
+ scene.flies[i]->age = 0.0;
+ n--;
+ }
+ }
+ break;
+ }
+ case SMODE_SWARMMERGE: { // merge mode
+ if (scene.baits.size() <= scene.minbaits)
+ break;
+ int i1 = rand_int(0, scene.baits.size()-1);
+ int i2 = rand_other(0, scene.baits.size()-1, i1);
+ Bait *b1 = scene.baits[i1];
+ Bait *b2 = scene.baits[i2];
+
+ for (GLuint i = 0; i < scene.flies.size(); i++) {
+ if (scene.flies[i]->bait == b2) {
+ scene.flies[i]->bait = b1;
+ scene.flies[i]->age = 0.0;
+ }
+ }
+ vector<Bait*>::iterator it = scene.baits.begin();
+ for (; it != scene.baits.end(); it++) {
+ if ((*it) == b2) {
+ scene.baits.erase(it);
+ break;
+ }
+ }
+ delete b2;
+ break;
+ }
+ }
+#ifdef DEBUG
+ cerr << "scenemode=" << mode << ", next=" << scene.mode_next << " in "
+ << scene.mode_when-scene.curtime << endl;
+#endif
+}
diff --git a/debian/fireflies/fireflies-2.08/src/modes.h b/debian/fireflies/fireflies-2.08/src/modes.h
new file mode 100644
index 00000000..8884c37d
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/modes.h
@@ -0,0 +1,34 @@
+#ifndef _MODES_H
+#define _MODES_H
+
+#define SMODE_NOTHING 0
+#define SMODE_SWARMS 1
+#define SMODE_FLYKILL 2
+#define SMODE_FLYBIRTH 3
+#define SMODE_WINDY 4
+#define SMODE_MATRIX 5
+#define SMODE_SWARMSPLIT 6
+#define SMODE_SWARMMERGE 7
+#define NUM_SMODES 8
+
+#define BMODE_NOTHING 0
+#define BMODE_NORMAL 1
+#define BMODE_STOP 2
+#define BMODE_ATTRACTOR 3
+#define BMODE_RAINBOW 4
+#define BMODE_GLOW 5
+#define BMODE_HYPERSPEED 6
+#define BMODE_FADED 7
+#define NUM_BMODES 8
+
+class Bait;
+
+// force b to start behaving in manner described by "mode"
+void bait_start_mode(Bait *b, int mode);
+// cancel effects of mode "mode" - may cancel other modes too
+void bait_stop_mode(Bait *b, int mode);
+
+// activate the scene mode "mode"
+void scene_start_mode(int mode);
+
+#endif // _MODES_H
diff --git a/debian/fireflies/fireflies-2.08/src/resource.h b/debian/fireflies/fireflies-2.08/src/resource.h
new file mode 100644
index 00000000..54d69491
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/resource.h
@@ -0,0 +1,25 @@
+//{{NO_DEPENDENCIES}}
+#define IDC_CONF_MINBAITS 1000
+#define IDC_CONF_MAXBAITS 1001
+#define IDC_CONF_MINFLIES 1002
+#define IDC_CONF_MAXFLIES 1003
+#define IDC_CONF_FSIZE 1004
+#define IDC_CONF_BSPEED 1005
+#define IDC_CONF_BACCEL 1006
+#define IDC_CONF_FSPEED 1007
+#define IDC_CONF_FACCEL 1008
+#define IDC_CONF_HUERATE 1009
+#define IDC_CONF_TAILLENGTH 1010
+#define IDC_CONF_TAILWIDTH 1011
+#define IDC_CONF_TAILOPAQ 1012
+#define IDC_CONF_GLOWFACTOR 1013
+#define IDC_CONF_WIND 1014
+#define IDC_CONF_DRAWBAIT 1015
+#define IDC_CONF_FASTFORWARD 1016
+#define IDC_CONF_FPS 1017
+#define IDC_CONF_BMODE(n) 1020+n
+#define IDC_CONF_SMODE(n) 1040+n
+
+#define IDC_DEFAULTS 1100
+
+#define IDC_STATIC -1
diff --git a/debian/fireflies/fireflies-2.08/src/resource.rc b/debian/fireflies/fireflies-2.08/src/resource.rc
new file mode 100644
index 00000000..f68ef468
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/resource.rc
@@ -0,0 +1,88 @@
+#include <windows.h>
+#include <winbase.h>
+#include <scrnsave.h>
+#include <string.h>
+#include <time.h>
+#include "resource.h"
+#include "../config.h"
+
+#define X1 10
+#define W1 70
+#define X2 90
+#define W2 25
+#define X3 125
+#define W3 70
+#define X4 190
+#define W4 25
+
+#define Y1(n) 2+15*n
+#define Y2(n) 15*n
+
+#define H1 12
+
+#define WIDTH 235
+
+#define BOX_COL1(row, text, id)\
+ LTEXT text,IDC_STATIC,X1,Y1(row),W1,H1\
+ EDITTEXT id, X2,Y2(row),W2,H1,ES_AUTOHSCROLL|ES_NUMBER
+#define BOX_COL2(row, text, id)\
+ LTEXT text,IDC_STATIC,X3,Y1(row),W3,H1\
+ EDITTEXT id, X4,Y2(row),W4,H1,ES_AUTOHSCROLL|ES_NUMBER
+
+// Dialog
+DLG_SCRNSAVECONFIGURE DIALOG DISCARDABLE 34, 32, WIDTH, Y1(22)
+STYLE DS_MODALFRAME|WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU
+CAPTION "Fireflies Screen Saver"
+FONT 8, "Helv"
+BEGIN
+ CTEXT "Fireflies " PACKAGE_VERSION,IDC_STATIC,0,5,WIDTH,8
+ CTEXT "by Matt Perry",IDC_STATIC,0,15,WIDTH,8
+ CTEXT "http://somewhere.fscked.org",IDC_STATIC,0,25,WIDTH,8
+ BOX_COL1(3, "Frames per sec:", IDC_CONF_FPS)
+ BOX_COL2(3, "Fast forward speed:", IDC_CONF_FASTFORWARD)
+ BOX_COL1(4, "Minimum baits:", IDC_CONF_MINBAITS)
+ BOX_COL2(4, "Minimum fireflies:", IDC_CONF_MINFLIES)
+ BOX_COL1(5, "Maximum baits:", IDC_CONF_MAXBAITS)
+ BOX_COL2(5, "Maximum fireflies:", IDC_CONF_MAXFLIES)
+ CONTROL "Draw baits",IDC_CONF_DRAWBAIT,"Button",
+ BS_AUTOCHECKBOX|WS_TABSTOP, X1,Y1(6),W1,10
+ BOX_COL2(6, "Firefly size:", IDC_CONF_FSIZE)
+ BOX_COL1(7, "Firefly speed:", IDC_CONF_FSPEED)
+ BOX_COL2(7, "Firefly acceleration:", IDC_CONF_FACCEL)
+ BOX_COL1(8, "Bait speed:", IDC_CONF_BSPEED)
+ BOX_COL2(8, "Bait acceleration:", IDC_CONF_BACCEL)
+ BOX_COL1(9, "Color cycle speed:", IDC_CONF_HUERATE)
+ BOX_COL2(9, "Glow factor:", IDC_CONF_GLOWFACTOR)
+ BOX_COL1(10, "Tail length:", IDC_CONF_TAILLENGTH)
+ BOX_COL2(10, "Tail width:", IDC_CONF_TAILWIDTH)
+ BOX_COL1(11, "Tail opacity (0-100):", IDC_CONF_TAILOPAQ)
+ BOX_COL2(11, "Wind speed:", IDC_CONF_WIND)
+
+ CTEXT "Per-swarm mode frequency:",IDC_STATIC, X1,Y1(12),X3-10 - X1,H1
+ CTEXT "Major mode frequency:",IDC_STATIC, X3,Y1(12),WIDTH-10 - X3,H1
+
+ BOX_COL1(13, "Normal mode:", IDC_CONF_BMODE(1))
+ BOX_COL1(14, "Bait takes a breather:", IDC_CONF_BMODE(2))
+ BOX_COL1(15, "Bait goes in a loop:", IDC_CONF_BMODE(3))
+ BOX_COL1(16, "Psychadelic tails:", IDC_CONF_BMODE(4))
+ BOX_COL1(17, "Glowing tails:", IDC_CONF_BMODE(5))
+ BOX_COL1(18, "Swarms get hyper:", IDC_CONF_BMODE(6))
+ BOX_COL1(19, "Faded colors:", IDC_CONF_BMODE(7))
+
+ BOX_COL2(13, "All-Swarm mode:", IDC_CONF_SMODE(1))
+ BOX_COL2(14, "Kill some flies:", IDC_CONF_SMODE(2))
+ BOX_COL2(15, "Create some flies:", IDC_CONF_SMODE(3))
+ BOX_COL2(16, "Wind picks up:", IDC_CONF_SMODE(4))
+ BOX_COL2(17, "Matrix mode:", IDC_CONF_SMODE(5))
+ BOX_COL2(18, "A swarm splits in 2:", IDC_CONF_SMODE(6))
+ BOX_COL2(19, "Two swarms merge:", IDC_CONF_SMODE(7))
+
+ DEFPUSHBUTTON "OK",IDOK, X1+10,Y1(21),50,14,WS_GROUP
+ PUSHBUTTON "Restore Defaults",IDC_DEFAULTS,X1+75,Y1(21),70,14
+ PUSHBUTTON "Cancel",IDCANCEL, X3+40,Y1(21),50,14
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_DESCRIPTION "Fireflies"
+END
diff --git a/debian/fireflies/fireflies-2.08/src/resource.rc.french b/debian/fireflies/fireflies-2.08/src/resource.rc.french
new file mode 100644
index 00000000..b0729f65
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/resource.rc.french
@@ -0,0 +1,88 @@
+#include <windows.h>
+#include <winbase.h>
+#include <scrnsave.h>
+#include <string.h>
+#include <time.h>
+#include "resource.h"
+#include "../config.h"
+
+#define X1 10
+#define W1 70
+#define X2 90
+#define W2 25
+#define X3 125
+#define W3 70
+#define X4 190
+#define W4 25
+
+#define Y1(n) 2+15*n
+#define Y2(n) 15*n
+
+#define H1 12
+
+#define WIDTH 235
+
+#define BOX_COL1(row, text, id)\
+ LTEXT text,IDC_STATIC,X1,Y1(row),W1,H1\
+ EDITTEXT id, X2,Y2(row),W2,H1,ES_AUTOHSCROLL|ES_NUMBER
+#define BOX_COL2(row, text, id)\
+ LTEXT text,IDC_STATIC,X3,Y1(row),W3,H1\
+ EDITTEXT id, X4,Y2(row),W4,H1,ES_AUTOHSCROLL|ES_NUMBER
+
+// Dialog
+DLG_SCRNSAVECONFIGURE DIALOG DISCARDABLE 34, 32, WIDTH, Y1(22)
+STYLE DS_MODALFRAME|WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU
+CAPTION "Fireflies Screen Saver"
+FONT 8, "Helv"
+BEGIN
+ CTEXT "Fireflies " PACKAGE_VERSION,IDC_STATIC,0,5,WIDTH,8
+ CTEXT "par Matt Perry",IDC_STATIC,0,15,WIDTH,8
+ CTEXT "http://somewhere.fscked.org",IDC_STATIC,0,25,WIDTH,8
+ BOX_COL1(3, "Images par sec:", IDC_CONF_FPS)
+ BOX_COL2(3, "Vitesse d'avance rapide:", IDC_CONF_FASTFORWARD)
+ BOX_COL1(4, "Nombre min. d'app�ts :", IDC_CONF_MINBAITS)
+ BOX_COL2(4, "Nombre min. de lucioles :", IDC_CONF_MINFLIES)
+ BOX_COL1(5, "Nombre max. d'app�ts :", IDC_CONF_MAXBAITS)
+ BOX_COL2(5, "Nombres maxi. de lucioles :", IDC_CONF_MAXFLIES)
+ CONTROL "Dessiner les app�ts",IDC_CONF_DRAWBAIT,"Button",
+ BS_AUTOCHECKBOX|WS_TABSTOP, X1,Y1(6),W1,10
+ BOX_COL2(6, "Taille des lucioles :", IDC_CONF_FSIZE)
+ BOX_COL1(7, "Vitesse des lucioles :", IDC_CONF_FSPEED)
+ BOX_COL2(7, "Acc�l�ration des lucioles :", IDC_CONF_FACCEL)
+ BOX_COL1(8, "Vitesse des app�ts :", IDC_CONF_BSPEED)
+ BOX_COL2(8, "Acc�l�ration des app�ts :", IDC_CONF_BACCEL)
+ BOX_COL1(9, "Vitesse du cycle de couleurs :", IDC_CONF_HUERATE)
+ BOX_COL2(9, "Luminescence :", IDC_CONF_GLOWFACTOR)
+ BOX_COL1(10, "Longueur de la queue :", IDC_CONF_TAILLENGTH)
+ BOX_COL2(10, "Largeur de la queue :", IDC_CONF_TAILWIDTH)
+ BOX_COL1(11, "Opacit� de la queue : (0-100):", IDC_CONF_TAILOPAQ)
+ BOX_COL2(11, "Vitesse du vent :", IDC_CONF_WIND)
+
+ CTEXT "Fr�quence du mode par essaim :",IDC_STATIC, X1,Y1(12),X3-10 - X1,H1
+ CTEXT "Fr�quence du mode majeur :",IDC_STATIC, X3,Y1(12),WIDTH-10 - X3,H1
+
+ BOX_COL1(13, "Mode normal :", IDC_CONF_BMODE(1))
+ BOX_COL1(14, "Pause syndicale de l'app�t :", IDC_CONF_BMODE(2))
+ BOX_COL1(15, "App�t parti en boucle :", IDC_CONF_BMODE(3))
+ BOX_COL1(16, "Queues psych�d�liques :", IDC_CONF_BMODE(4))
+ BOX_COL1(17, "Queues luminescentes :", IDC_CONF_BMODE(5))
+ BOX_COL1(18, "Essaim excit� :", IDC_CONF_BMODE(6))
+ BOX_COL1(19, "Fl�trissement des couleurs :", IDC_CONF_BMODE(7))
+
+ BOX_COL2(13, "Mode Tout-Essaim :", IDC_CONF_SMODE(1))
+ BOX_COL2(14, "Extinction de lucioles :", IDC_CONF_SMODE(2))
+ BOX_COL2(15, "Naissance de lucioles :", IDC_CONF_SMODE(3))
+ BOX_COL2(16, "Le vent se l�ve :", IDC_CONF_SMODE(4))
+ BOX_COL2(17, "Mode Matrix :", IDC_CONF_SMODE(5))
+ BOX_COL2(18, "Scission d'un essaim :", IDC_CONF_SMODE(6))
+ BOX_COL2(19, "Fusion de 2 essaims :", IDC_CONF_SMODE(7))
+
+ DEFPUSHBUTTON "OK",IDOK, X1+10,Y1(21),50,14,WS_GROUP
+ PUSHBUTTON "R�tablir les valeurs par d�faut",IDC_DEFAULTS,X1+75,Y1(21),70,14
+ PUSHBUTTON "Annuler",IDCANCEL, X3+40,Y1(21),50,14
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_DESCRIPTION "Fireflies"
+END
diff --git a/debian/fireflies/fireflies-2.08/src/scene.cc b/debian/fireflies/fireflies-2.08/src/scene.cc
new file mode 100644
index 00000000..1f8872dd
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/scene.cc
@@ -0,0 +1,252 @@
+#include "scene.h"
+#include "modes.h"
+
+#include <GL/glu.h>
+
+Vec3f world;
+
+#define WIND_WAIT rand_real(4*tail_length, 8*tail_length)
+#define OFFSCREEN_VEC3() rand_vec3(-2*world[0], 2*world[0])
+
+// max elapse time is 1/10th of a second so we don't get jaggies even if
+// the CPU load is high and everything slows down
+#define MAX_ELAPSE 0.1
+
+Scene::Scene() : matrix(-1.0)
+{
+ set_defaults();
+}
+
+Scene::~Scene()
+{
+ GLuint i;
+ for (i = 0; i < baits.size(); i++)
+ delete baits[i];
+ for (i = 0; i < flies.size(); i++)
+ delete flies[i];
+}
+
+void Scene::set_defaults()
+{
+ bmodes.clear();
+ smodes.clear();
+
+ // all bmodes equally likely
+ for (int i = 0; i < NUM_BMODES; i++)
+ bmodes.add(i, 10);
+
+ // except these
+ bmodes.change(BMODE_NORMAL, 20);
+ bmodes.change(BMODE_GLOW, 15);
+
+ // all smodes equally likely
+ for (int i = 0; i < NUM_SMODES; i++)
+ smodes.add(i, 10);
+
+ // except...
+ smodes.change(SMODE_SWARMS, 5);
+
+ fast_forward = 1;
+ minbaits = 2;
+ maxbaits = 5;
+ minflies = 100;
+ maxflies = 175;
+ fsize = 1.5;
+ bspeed = 50.;
+ baccel = 600.;
+ fspeed = 100.;
+ faccel = 300.;
+ hue_rate = 15.;
+ tail_length = 2.25;
+ tail_width = 2.5;
+ tail_opaq = 0.6;
+ glow_factor = 2.;
+ wind_speed = 3.;
+ draw_bait = false;
+}
+
+void Scene::create()
+{
+ GLuint i, nbaits, nflies;
+
+ curtime = 0.0;
+ wind_when = curtime + WIND_WAIT;
+ scene_start_mode(-1); // non-existent, just to initialize
+
+ nbaits = (minbaits + maxbaits)/2;
+ nflies = (minflies + maxflies)/2;
+
+ baits.reserve(nbaits);
+ for (i = 0; i < nbaits; i++) {
+ baits.push_back(new Bait());
+ }
+
+ add_flies(nflies);
+
+ for (i = 0; i < 3; i++) {
+ switch (rand_int(0, 1)) {
+ case 0: accel[i] = -1; wind[i] = -wind_speed; break;
+ default: accel[i] = 1; wind[i] = wind_speed; break;
+ }
+ }
+}
+
+void Scene::add_flies(unsigned n)
+{
+ if (flies.size() >= maxflies)
+ return;
+ if (flies.size()+n >= maxflies)
+ n = maxflies - flies.size();
+
+ // about 3 groups per bait
+ int groupsize = (flies.size()+n)/(3*baits.size());
+ if (groupsize < 10) // but at least size 10
+ groupsize = 10;
+ Vec3f where;
+ Bait *b = baits[0];
+ flies.reserve(flies.size()+n);
+ for (unsigned i = 0; i < n; i++) {
+ if ((i % groupsize) == 0) {
+ where = OFFSCREEN_VEC3();
+ b = baits[rand_int(0, baits.size()-1)];
+ }
+ flies.push_back(new Firefly(b, where, world[2]/3));
+ }
+}
+
+void Scene::rem_flies(unsigned n)
+{
+ if (flies.size() <= minflies)
+ return;
+ if (flies.size()-n <= minflies)
+ n = flies.size() - minflies;
+
+ Bait *b = baits[rand_int(0, baits.size()-1)];
+ vector<Firefly*>::iterator it = flies.begin();
+ while (it != flies.end() && n > 0) {
+ if ((*it)->bait == b) {
+ delete (*it);
+ it = flies.erase(it);
+ n--;
+ }
+ else
+ it++;
+ }
+}
+
+void Scene::resize(int width, int height)
+{
+ GLfloat aspect = (GLfloat)width / (GLfloat)height;
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(80., aspect, 5, 2000);
+
+ world[2] = 50.;
+ if (width > height) {
+ world[1] = 80.;
+ world[0] = world[1] * (width) / height;
+ }
+ else {
+ world[0] = 80.;
+ world[1] = world[0] * (height) / width;
+ }
+ camera.pos = Vec3f(0., 0., 3*world[2]);
+
+ // For some reason this needs to be done everytime we resize, otherwise
+ // blending is disabled (and I assume other functions)
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+}
+
+void Scene::apply_camera()
+{
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslated(-camera.pos[0], -camera.pos[1], -camera.pos[2]);
+ glRotated(camera.rot_angle, camera.rot_axis[0], camera.rot_axis[1], camera.rot_axis[2]);
+}
+
+void Scene::draw()
+{
+#if 0
+ glColor4f(0.5f, 0.5f, 0.5f, 1.0f);
+ draw_box(-world, world);
+#endif
+
+ for (GLuint i = 0; i < baits.size(); i++)
+ baits[i]->draw();
+
+ for (GLuint i = 0; i < flies.size(); i++)
+ flies[i]->draw();
+
+ vector<Tail*>::iterator it = dead_tails.begin();
+ for (; it != dead_tails.end(); it++)
+ (*it)->draw();
+
+}
+
+void Scene::elapse(double t)
+{
+ for (unsigned i = 0; i < fast_forward; i++)
+ elapse_once(t);
+}
+
+void Scene::elapse_once(double t)
+{
+ if (t > MAX_ELAPSE)
+ t = MAX_ELAPSE;
+ // matrix mode?
+ if (matrix > 0) {
+ matrix += t;
+ if (matrix >= mode_when)
+ scene_start_mode(-SMODE_MATRIX);
+ else if (matrix-curtime >= 0.5) {
+ Quat q = axis_to_quat(camera.rot_axis, DEG_TO_RAD(camera.rot_angle));
+ Quat dq = axis_to_quat(matrix_axis, 0.7*t);
+
+ q = q * dq;
+ unitize(q);
+
+ camera.rot_axis = q.vector();
+ camera.rot_angle = RAD_TO_DEG(2.0*acos(q.scalar()));
+ }
+ return;
+ }
+
+ curtime += t;
+ if (curtime >= mode_when)
+ scene_start_mode(mode_next);
+
+ // the wind, she's a changin!
+ if (curtime >= wind_when) {
+ for (int i = 0; i < 3; i++) {
+ if (rand_int(0, 1) == 0)
+ accel[i] = -accel[i];
+ }
+ // next change based on tail length (so we can see a whole cycle of
+ // prettiness blow one way before it gets tossed another)
+ wind_when = curtime + WIND_WAIT;
+ }
+
+ wind += accel*t;
+ clamp_vec(wind, wind_speed);
+
+ // elapse, my children
+ for (GLuint i = 0; i < baits.size(); i++)
+ baits[i]->elapse(t);
+
+ for (GLuint i = 0; i < flies.size(); i++)
+ flies[i]->elapse(t);
+
+ vector<Tail*>::iterator it = dead_tails.begin();
+ while (it != dead_tails.end()) {
+ if ((*it)->elapse(t)) { // he's dead!
+ delete (*it);
+ it = dead_tails.erase(it);
+ }
+ else it++;
+ }
+}
diff --git a/debian/fireflies/fireflies-2.08/src/scene.h b/debian/fireflies/fireflies-2.08/src/scene.h
new file mode 100644
index 00000000..10df4710
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/scene.h
@@ -0,0 +1,80 @@
+#ifndef _SCENE_H
+#define _SCENE_H
+
+#include "main.h"
+
+#include "control.h"
+#include "bait.h"
+#include "firefly.h"
+#include "tail.h"
+
+#include <gfx/quat.h>
+#include <vector>
+
+class Scene {
+public:
+ vector<Bait*> baits;
+ vector<Firefly*> flies;
+ vector<Tail*> dead_tails;
+
+ Control camera; // camera orientation
+ double curtime; // total time the program's been running
+ Vec3f wind; // current wind direction
+ Vec3f accel; // wind is changing
+ double wind_when; // time before next wind change
+ int mode_next; // the next mode to activate
+ double mode_when; // next time to activate a mode
+ double matrix; // -1 if not active, else a timer for how long
+ // the "matrix" mode has been active
+ Vec3f matrix_axis; // the axis to rotate around matrix-style
+
+ // options
+ RandVar smodes; // enabled modes for scene
+ RandVar bmodes; // enabled modes for baits
+
+ unsigned fast_forward;
+ unsigned minbaits;
+ unsigned maxbaits;
+ unsigned minflies;
+ unsigned maxflies;
+ double fsize;
+ double bspeed;
+ double baccel;
+ double fspeed;
+ double faccel;
+ double hue_rate;
+ double tail_length;
+ double tail_width;
+ double tail_opaq;
+ double glow_factor;
+ double wind_speed;
+ bool draw_bait;
+
+ Scene();
+ ~Scene();
+
+ // set default options (called from constructor)
+ void set_defaults();
+ // create the scene with the following parameters
+ // NOTE: the scene does not exist until this is called!
+ void create();
+ // add 'n' flies to random baits
+ void add_flies(unsigned n);
+ // remove 'n' flies from random baits
+ void rem_flies(unsigned n);
+ // resize the scene.
+ void resize(int width, int height);
+ // apply the camera transformations (translate+rotate)
+ void apply_camera();
+ // draw the scene (CREATE it first!)
+ void draw();
+ // animation: let t seconds elapse (fast_forward times)
+ void elapse(double t);
+ // animation: let t seconds elapse once
+ void elapse_once(double t);
+};
+
+extern Vec3f world;
+extern Scene scene;
+
+#endif // scene.h
diff --git a/debian/fireflies/fireflies-2.08/src/tail.cc b/debian/fireflies/fireflies-2.08/src/tail.cc
new file mode 100644
index 00000000..18e013b6
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/tail.cc
@@ -0,0 +1,89 @@
+#include "tail.h"
+#include "firefly.h"
+#include "scene.h"
+
+Tail::Tail(Firefly *_owner)
+ : owner(_owner)
+{
+}
+
+#define SET_COLOR(c, a) glColor4f(c[0], c[1], c[2], a)
+#define SET_VERTEX(v, dx) glVertex3d(v[0]+dx, v[1], v[2])
+#define DO_POINT(t, dx, a)\
+ SET_COLOR((t).color, a); SET_VERTEX((t).pos, dx)
+
+void Tail::draw()
+{
+ if (links.size() < 2) // need at least 2 links
+ return;
+
+ deque<Link>::iterator it = links.begin();
+ double glow_width = scene.glow_factor*scene.tail_width;
+ double stretch_factor = 2*scene.fsize*scene.wind[0];
+ double dx1, dx2;
+
+ dx2 = ((*it).glow ? glow_width : scene.tail_width);
+ for (; (it+1) != links.end(); it++) {
+ // half-width of the tail
+ dx1 = dx2;
+ dx2 = ((*(it+1)).glow ? glow_width : scene.tail_width);
+
+ // have the wind stretch the tail (greater effect on ends)
+ double age = (*it).age/scene.tail_length;
+ double stretch = stretch_factor*age*age;
+ double alpha = 0.9 - age;
+ if (alpha > scene.tail_opaq)
+ alpha = scene.tail_opaq;
+
+ // two rectangles: outer vertices have alpha=0, inner two have
+ // alpha based on age. note: alpha goes negative, but opengl
+ // should clamp it to 0.
+ if (stretch > 0) { // stretch to the right
+ glBegin(GL_QUAD_STRIP);
+ DO_POINT(*it, -dx1, 0);
+ DO_POINT(*(it+1), -dx2, 0);
+
+ DO_POINT(*it, 0, alpha);
+ DO_POINT(*(it+1), 0, alpha);
+
+ DO_POINT(*it, dx1 + stretch, 0);
+ DO_POINT(*(it+1), dx2 + stretch, 0);
+ }
+ else { // stretch to the left
+ glBegin(GL_QUAD_STRIP);
+ DO_POINT(*it, -dx1 + stretch, 0);
+ DO_POINT(*(it+1), -dx2 + stretch, 0);
+
+ DO_POINT(*it, 0, alpha);
+ DO_POINT(*(it+1), 0, alpha);
+
+ DO_POINT(*it, dx1, 0);
+ DO_POINT(*(it+1), dx2, 0);
+ }
+ glEnd();
+ }
+}
+
+bool Tail::elapse(double t)
+{
+ // pop off the dead ones.
+ // note we only have to check the end, since that's where they're gonna
+ // be dying from. deque is very nice for this, because it has constant
+ // time insertion/removal from both ends.
+ while (!links.empty() && links.back().age >= scene.tail_length)
+ links.pop_back();
+
+ deque<Link>::iterator it = links.begin();
+ for (; it != links.end(); it++) {
+ (*it).age += t;
+ double age = (*it).age/scene.tail_length;
+ (*it).pos += scene.wind*age*age;
+ }
+
+ if (owner == 0) // my owner died! grow no longer
+ return links.empty(); // if we're empty, tell caller we're dead
+
+ links.push_front(Link(owner->pos, owner->color, owner->bait->glow));
+
+ return false;
+}
diff --git a/debian/fireflies/fireflies-2.08/src/tail.h b/debian/fireflies/fireflies-2.08/src/tail.h
new file mode 100644
index 00000000..727a8479
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/tail.h
@@ -0,0 +1,37 @@
+#ifndef _TAIL_H
+#define _TAIL_H
+
+#include "main.h"
+#include "utils.h"
+#include <gfx/vec3.h>
+#include <deque>
+
+class Firefly;
+
+class Tail
+{
+ struct Link {
+ Vec3f pos; // position of this link
+ rgbColor color; // color
+ double age; // how long this link has existed (in seconds)
+ bool glow; // glow = wider size and higher alpha
+ Link(Vec3f _pos, rgbColor _color, bool _glow)
+ : pos(_pos), color(_color), age(0), glow(_glow) {}
+ };
+ deque<Link> links;
+public:
+ Firefly *owner; // the firefly I'm attached to
+
+ // Tail(
+ // the firefly we're attached to)
+ Tail(Firefly *_owner);
+ virtual ~Tail() {}
+
+ // draw the tail
+ // returns: true if we're a dead tail, false otherwise
+ virtual void draw();
+ // let t seconds elapse
+ virtual bool elapse(double t);
+};
+
+#endif // tail.h
diff --git a/debian/fireflies/fireflies-2.08/src/utils.cc b/debian/fireflies/fireflies-2.08/src/utils.cc
new file mode 100644
index 00000000..c63d75e9
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/utils.cc
@@ -0,0 +1,161 @@
+#include "utils.h"
+
+#ifndef DEBUG
+#define NDEBUG
+#endif
+#include <assert.h>
+
+void clamp_vec(Vec3f& vec, double max)
+{
+ for (int i = 0; i < 3; i++) {
+ if (vec[i] > max) vec[i] = max;
+ else if (vec[i] < -max) vec[i] = -max;
+ }
+}
+
+int rand_other(int lo, int hi, int other)
+{
+ int r;
+ assert(lo != hi);
+ while ((r = rand_int(lo, hi)) == other)
+ ;
+ return r;
+}
+
+// rgb range [0,1]
+// hsv range hue:[0,360], sat and val:[0,1]
+hsvColor rgb_to_hsv(const rgbColor& rgb)
+{
+ hsvColor hsv;
+ float max, min, diff;
+
+ hsv[3] = rgb[3]; // alpha value
+
+ max = MAX3(rgb[0], rgb[1], rgb[2]);
+ min = MIN3(rgb[0], rgb[1], rgb[2]);
+ diff = max - min;
+
+ hsv[2] = max; // value = max
+
+ if (FEQ(max, 0)) {
+ hsv[0] = 0; // hue should be undefined.. oh well
+ hsv[1] = 0; // saturation = 0
+ return hsv;
+ }
+ else
+ hsv[1] = diff/max; // saturation
+
+ if (rgb[0] == max) // red is max
+ hsv[0] = (rgb[1] - rgb[2]) / diff; // hue between yellow and mag
+ else if (rgb[1] == max) // green is max
+ hsv[0] = 2 + (rgb[2] - rgb[1]) / diff; // hue between cyan and yellow
+ else // blue is max
+ hsv[0] = 4 + (rgb[0] - rgb[1]) / diff; // hue between magenta and cyan
+
+ hsv[0] *= 60.; // degrees
+ if (hsv[0] < 0)
+ hsv[0] += 360.;
+
+ return hsv;
+}
+
+rgbColor hsv_to_rgb(const hsvColor& hsv)
+{
+ rgbColor rgb;
+ float h = hsv[0]/60, s = hsv[1], v = hsv[2];
+ float f, p, q, t;
+ int i;
+
+ rgb[3] = hsv[3]; // alpha value
+
+ if (FEQ(s, 0)) {
+ rgb[0] = rgb[1] = rgb[2] = v;
+ return rgb;
+ }
+
+ // don't ask me what this means.. I yoinked it from a website.
+ i = (int)floor(h); // sectors 0 - 5
+ f = h - i;
+ p = v*(1 - s);
+ q = v*(1 - s*f);
+ t = v*(1 - s*(1-f));
+
+ switch (i) { // what sector?
+ case 0: rgb[0] = v; rgb[1] = t; rgb[2] = p; break;
+ case 1: rgb[0] = q; rgb[1] = v; rgb[2] = p; break;
+ case 2: rgb[0] = p; rgb[1] = v; rgb[2] = t; break;
+ case 3: rgb[0] = p; rgb[1] = q; rgb[2] = v; break;
+ case 4: rgb[0] = t; rgb[1] = p; rgb[2] = v; break;
+ default: rgb[0] = v; rgb[1] = p; rgb[2] = q; break;
+ }
+ return rgb;
+}
+
+void Timer::add(int what, double when)
+{
+ deque<Event>::iterator it = events.begin();
+ while (it != events.end()) {
+ if (when < (*it).second)
+ break;
+ it++;
+ }
+ events.insert(it, Event(what, when));
+}
+
+bool Timer::is_ready(double now)
+{
+ return (!events.empty() && (now >= events[0].second));
+}
+
+void Timer::clear()
+{
+ events.clear();
+}
+
+int Timer::pop()
+{
+ int what = events[0].first;
+ events.pop_front();
+ return what;
+}
+
+void RandVar::add(int val, double prob)
+{
+ max_prob += prob;
+ events.push_back(Event(val, prob));
+}
+
+void RandVar::change(int val, double newprob)
+{
+ for (size_t i = 0; i < events.size(); i++) {
+ if (events[i].first == val) {
+ max_prob += (newprob - events[i].second);
+ events[i].second = newprob;
+#ifdef DEBUG
+ cerr << val << " changed to " << newprob << " out of " <<
+ max_prob << endl;
+#endif
+ return;
+ }
+ }
+ // didn't find a match, so add it
+ add(val, newprob);
+}
+
+void RandVar::clear()
+{
+ events.clear();
+ max_prob = 0.0;
+}
+
+int RandVar::rand()
+{
+ double r = rand_real(0., max_prob);
+ double prob = 0.;
+ for (size_t i = 0; i < events.size(); i++) {
+ prob += events[i].second;
+ if (r < prob)
+ return events[i].first;
+ }
+ return -1; // should never happen
+}
diff --git a/debian/fireflies/fireflies-2.08/src/utils.h b/debian/fireflies/fireflies-2.08/src/utils.h
new file mode 100644
index 00000000..819303e8
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/utils.h
@@ -0,0 +1,83 @@
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#include "main.h"
+#include <gfx/mat4.h>
+#include <deque>
+#include <vector>
+#include <utility>
+
+#define SIGN(x) ((x >= 0) ? 1 : -1)
+
+#define MAX3(x, y, z) ( (x>y) ? ((x>z) ? x : z) : y )
+#define MIN3(x, y, z) ( (x<y) ? ((x<z) ? x : z) : y )
+
+typedef Vec4f rgbColor;
+typedef Vec4f hsvColor;
+
+// clamp vector's components each to +/- magnitude
+void clamp_vec(Vec3f& vec, double max);
+
+// return a random number between lo and hi inclusive
+inline int rand_int(int lo, int hi)
+{ return lo + (int)((hi-lo+1)*((double)rand()/(double)(RAND_MAX+1.0))); }
+
+inline double rand_real(double lo, double hi)
+{ return lo + (hi-lo)*((double)rand()/(double)(RAND_MAX+1.0)); }
+
+inline Vec3f rand_vec3(double lo, double hi)
+{ return Vec3f(rand_real(lo, hi), rand_real(lo, hi), rand_real(lo, hi)); }
+
+// return a random int other than 'other'
+int rand_other(int lo, int hi, int other);
+
+// return the unit vector in the direction of v
+inline Vec3f unit_vec(const Vec3f& v)
+{ double n = norm(v); return (n == 0) ? v : v/n; }
+
+// color space conversion
+hsvColor rgb_to_hsv(const rgbColor& rgb);
+rgbColor hsv_to_rgb(const hsvColor& hsv);
+
+// a set of events and the time for them to occur
+class Timer {
+public:
+ typedef pair<int, double> Event;
+ deque<Event> events;
+
+ Timer() {}
+ // add an event that needs to be done at time 'when'
+ void add(int what, double when);
+ // checks if an event is ready, ie the current time (now) is past one
+ // of the times for an event.
+ bool is_ready(double now);
+ // clears all events
+ void clear();
+ // return the earliest-to-occur event. note: this (obviously) does not
+ // check that the current time is past the event's time.
+ int pop();
+};
+
+// a random variable which takes on a given value with a given probability
+class RandVar {
+public:
+ typedef pair<int, double> Event;
+ vector<Event> events;
+ double max_prob; // the sum of probabilities of all events
+
+ RandVar() : max_prob(0.0) {}
+
+ // add a value and it's probability weight to the set
+ void add(int val, double prob);
+ // change a value's probability weight. if val is not in the set,
+ // it is added.
+ void change(int val, double newprob);
+ // clear all events
+ void clear();
+ // return one of the values based on the weighted probability of each
+ // value. for example, if value '0' has probability 0.9, it will be
+ // returned 90% of the time.
+ int rand();
+};
+
+#endif // _UTILS_H
diff --git a/debian/fireflies/fireflies-2.08/src/vroot.h b/debian/fireflies/fireflies-2.08/src/vroot.h
new file mode 100644
index 00000000..65097b83
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/vroot.h
@@ -0,0 +1,156 @@
+/* -*- Mode: C; tab-width: 2 -*- */
+/*****************************************************************************/
+/** Copyright 1991 by Andreas Stolcke **/
+/** Copyright 1990 by Solbourne Computer Inc. **/
+/** Longmont, Colorado **/
+/** **/
+/** All Rights Reserved **/
+/** **/
+/** Permission to use, copy, modify, and distribute this software and **/
+/** its documentation for any purpose and without fee is hereby **/
+/** granted, provided that the above copyright notice appear in all **/
+/** copies and that both that copyright notice and this permis- **/
+/** sion notice appear in supporting documentation, and that the **/
+/** name of Solbourne not be used in advertising **/
+/** in publicity pertaining to distribution of the software without **/
+/** specific, written prior permission. **/
+/** **/
+/** ANDREAS STOLCKE AND SOLBOURNE COMPUTER INC. DISCLAIMS ALL WARRANTIES **/
+/** WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF **/
+/** MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ANDREAS STOLCKE **/
+/** OR SOLBOURNE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL **/
+/** DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/
+/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/
+/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/
+/** OR PERFORMANCE OF THIS SOFTWARE. **/
+/*****************************************************************************/
+/*
+ * vroot.h -- Virtual Root Window handling header file
+ *
+ * This header file redefines the X11 macros RootWindow and DefaultRootWindow,
+ * making them look for a virtual root window as provided by certain `virtual'
+ * window managers like swm and tvtwm. If none is found, the ordinary root
+ * window is returned, thus retaining backward compatibility with standard
+ * window managers.
+ * The function implementing the virtual root lookup remembers the result of
+ * its last invocation to avoid overhead in the case of repeated calls
+ * on the same display and screen arguments.
+ * The lookup code itself is taken from Tom LaStrange's ssetroot program.
+ *
+ * Most simple root window changing X programs can be converted to using
+ * virtual roots by just including
+ *
+ * #include <X11/vroot.h>
+ *
+ * after all the X11 header files. It has been tested on such popular
+ * X clients as xphoon, xfroot, xloadimage, and xaqua.
+ * It also works with the core clients xprop, xwininfo, xwd, and editres
+ * (and is necessary to get those clients working under tvtwm).
+ * It does NOT work with xsetroot; get the xsetroot replacement included in
+ * the tvtwm distribution instead.
+ *
+ * Andreas Stolcke <[email protected]>, 9/7/90
+ * - replaced all NULL's with properly cast 0's, 5/6/91
+ * - free children list (suggested by Mark Martin <[email protected]>), 5/16/91
+ * - include X11/Xlib.h and support RootWindowOfScreen, too 9/17/91
+ *
+ * Jamie Zawinski <[email protected]>, 28-Apr-1997
+ * - use ANSI C
+ *
+ * Jamie Zawinski <[email protected]>, 3-Sep-2003
+ * - if the environment variable "XSCREENSAVER_WINDOW" is set, use that
+ * as the root window instead of searching for __SWM_VROOT.
+ *
+ * Jamie Zawinski <[email protected]>, 14-Aug-2004
+ * - changes to get gcc to stop whining about "type punning".
+ *
+ * Jamie Zawinski <[email protected]>, 16-Dec-2004
+ * - fixed that last fix.
+ */
+
+#ifndef _VROOT_H_
+#define _VROOT_H_
+#define _XSCREENSAVER_VROOT_H_
+
+#if !defined(lint) && !defined(SABER)
+static const char vroot_rcsid[] =
+ "#Id: vroot.h,v 1.8 2004/12/16 05:33:54 jwz Exp #" "\n"
+ "#Id: vroot.h,v 1.4 1991/09/30 19:23:16 stolcke Exp stolcke #";
+#endif
+
+#include <X11/X.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+
+static Window
+#ifdef __STDC__ /* ANSIfication added by jwz, to avoid superfluous warnings. */
+VirtualRootWindowOfScreen(Screen *screen)
+#else /* !__STDC__ */
+VirtualRootWindowOfScreen(screen) Screen *screen;
+#endif /* !__STDC__ */
+{
+ static Screen *save_screen = (Screen *)0;
+ static Window root = (Window)0;
+
+ if (screen != save_screen) {
+ Display *dpy = DisplayOfScreen(screen);
+ Atom __SWM_VROOT = None;
+ int i;
+ Window rootReturn, parentReturn, *children;
+ unsigned int numChildren;
+
+ /* first check for a hex or decimal window ID in the environment */
+ const char *xss_id = getenv("XSCREENSAVER_WINDOW");
+ if (xss_id && *xss_id) {
+ unsigned long id = 0;
+ char c;
+ if (1 == sscanf (xss_id, " 0x%lx %c", &id, &c) ||
+ 1 == sscanf (xss_id, " %lu %c", &id, &c)) {
+ root = (Window) id;
+ save_screen = screen;
+ return root;
+ }
+ }
+
+ root = RootWindowOfScreen(screen);
+
+ /* go look for a virtual root */
+ __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False);
+ if (XQueryTree(dpy, root, &rootReturn, &parentReturn,
+ &children, &numChildren)) {
+ for (i = 0; i < numChildren; i++) {
+ Atom actual_type;
+ int actual_format;
+ unsigned long nitems, bytesafter;
+ unsigned char *newRoot = 0;
+
+ if (XGetWindowProperty(dpy, children[i],
+ __SWM_VROOT, 0, 1, False, XA_WINDOW,
+ &actual_type, &actual_format,
+ &nitems, &bytesafter,
+ &newRoot) == Success
+ && newRoot) {
+ root = *((Window *) newRoot);
+ break;
+ }
+ }
+ if (children)
+ XFree((char *)children);
+ }
+
+ save_screen = screen;
+ }
+
+ return root;
+}
+
+#undef RootWindowOfScreen
+#define RootWindowOfScreen(s) VirtualRootWindowOfScreen(s)
+
+#undef RootWindow
+#define RootWindow(dpy,screen) VirtualRootWindowOfScreen(ScreenOfDisplay(dpy,screen))
+
+#undef DefaultRootWindow
+#define DefaultRootWindow(dpy) VirtualRootWindowOfScreen(DefaultScreenOfDisplay(dpy))
+
+#endif /* _VROOT_H_ */
diff --git a/debian/fireflies/fireflies-2.08/src/winsaver.cc b/debian/fireflies/fireflies-2.08/src/winsaver.cc
new file mode 100644
index 00000000..8e98396d
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/winsaver.cc
@@ -0,0 +1,415 @@
+#include "main.h"
+#include "scene.h"
+#include "modes.h"
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <windows.h>
+#include <scrnsave.h>
+#include <iostream>
+#include <sys/timeb.h>
+
+#include "resource.h"
+
+#define MY_HKEY "Software\\Fireflies\\2.0"
+
+//Define a Windows timer
+#define TIMER 1
+
+// the default fps
+double fps = 20;
+
+Scene scene;
+
+static struct timeb then;
+
+void init_gl(HWND hWnd, HDC & hDC, HGLRC & hRC)
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ ZeroMemory( &pfd, sizeof pfd );
+ pfd.nSize = sizeof pfd;
+ pfd.nVersion = 1;
+ //pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; //blaine's
+ pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 24;
+
+ hDC = GetDC( hWnd );
+
+ int i = ChoosePixelFormat( hDC, &pfd );
+ SetPixelFormat( hDC, i, &pfd );
+
+ hRC = wglCreateContext( hDC );
+ wglMakeCurrent( hDC, hRC );
+}
+
+// Shut down OpenGL
+void close_gl(HWND hWnd, HDC hDC, HGLRC hRC)
+{
+ wglMakeCurrent( NULL, NULL );
+ wglDeleteContext( hRC );
+
+ ReleaseDC( hWnd, hDC );
+}
+
+void start_animate(int width, int height)
+{
+ glViewport(0, 0, width, height);
+
+ scene.resize(width, height);
+ scene.create();
+
+ ftime(&then);
+}
+
+void on_timer(HDC hDC) //increment and display
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ struct timeb now;
+ ftime(&now);
+ double t = double(now.time - then.time)
+ + double((now.millitm - then.millitm)/1000.0);
+ then = now;
+ scene.elapse(t);
+ scene.apply_camera();
+ scene.draw();
+
+ glFinish();
+ SwapBuffers(hDC);
+}
+
+// Registry bullshit
+void reg_get_val(HKEY key, char *str, bool *val)
+{
+ DWORD dsize = sizeof(int);
+ DWORD dwtype = 0;
+ int tmp;
+
+ if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0)
+ *val = (tmp==1);
+}
+
+void reg_get_val(HKEY key, char *str, int *val)
+{
+ DWORD dsize = sizeof(int);
+ DWORD dwtype = 0;
+ int tmp;
+
+ if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0)
+ *val = tmp;
+}
+
+void reg_get_val(HKEY key, char *str, unsigned *val)
+{
+ DWORD dsize = sizeof(int);
+ DWORD dwtype = 0;
+ int tmp;
+
+ if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0)
+ *val = (unsigned)tmp;
+}
+
+void reg_get_val(HKEY key, char *str, double *val)
+{
+ DWORD dsize = sizeof(int);
+ DWORD dwtype = 0;
+ int tmp;
+
+ if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0)
+ *val = (double)tmp;
+}
+
+void reg_get_val_div10(HKEY key, char *str, double *val)
+{
+ DWORD dsize = sizeof(int);
+ DWORD dwtype = 0;
+ int tmp;
+
+ if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0)
+ *val = (double)tmp/10.0;
+}
+
+void reg_get_val_div100(HKEY key, char *str, double *val)
+{
+ DWORD dsize = sizeof(int);
+ DWORD dwtype = 0;
+ int tmp;
+
+ if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0)
+ *val = (double)tmp/100.0;
+}
+
+void reg_set_val(HKEY key, char *str, bool val)
+{
+ int tmp = val ? 1 : 0;
+ RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&tmp, sizeof(tmp));
+}
+
+void reg_set_val(HKEY key, char *str, int val)
+{
+ RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&val, sizeof(val));
+}
+
+void reg_set_val(HKEY key, char *str, unsigned val)
+{
+ RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&val, sizeof(val));
+}
+
+void reg_set_val(HKEY key, char *str, double val)
+{
+ int tmp = (int)val;
+ RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&tmp, sizeof(tmp));
+}
+
+void reg_set_val_tim10(HKEY key, char *str, double val)
+{
+ int tmp = (int)(val*10);
+ RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&tmp, sizeof(tmp));
+}
+
+void reg_set_val_tim100(HKEY key, char *str, double val)
+{
+ int tmp = (int)(val*100);
+ RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&tmp, sizeof(tmp));
+}
+
+void read_config()
+{
+ HKEY key;
+ char buf[256];
+ double tmp;
+
+ scene.set_defaults();
+ if (RegOpenKeyEx( HKEY_CURRENT_USER,
+ MY_HKEY,
+ 0, //reserved
+ KEY_QUERY_VALUE,
+ &key) == ERROR_SUCCESS)
+ {
+ reg_get_val(key, "minbaits", &scene.minbaits);
+ reg_get_val(key, "maxbaits", &scene.maxbaits);
+ reg_get_val(key, "minflies", &scene.minflies);
+ reg_get_val(key, "maxflies", &scene.maxflies);
+ reg_get_val_div10(key, "fsize", &scene.fsize);
+ reg_get_val(key, "bspeed", &scene.bspeed);
+ reg_get_val(key, "baccel", &scene.baccel);
+ reg_get_val(key, "fspeed", &scene.fspeed);
+ reg_get_val(key, "faccel", &scene.faccel);
+ reg_get_val(key, "hue_rate", &scene.hue_rate);
+ reg_get_val_div10(key, "tail_length", &scene.tail_length);
+ reg_get_val_div10(key, "tail_width", &scene.tail_width);
+ reg_get_val_div100(key, "tail_opaq", &scene.tail_opaq);
+ reg_get_val_div10(key, "glow_factor", &scene.glow_factor);
+ reg_get_val_div10(key, "wind_speed", &scene.wind_speed);
+ reg_get_val(key, "draw_bait", &scene.draw_bait);
+ reg_get_val(key, "fast_forward", &scene.fast_forward);
+ reg_get_val(key, "fps", &fps);
+
+ for (GLuint i = 0; i < NUM_BMODES; i++) {
+ snprintf(buf, sizeof(buf), "bmode%d", i);
+ reg_get_val(key, buf, &tmp);
+ scene.bmodes.change(i, tmp);
+ }
+ for (GLuint i = 0; i < NUM_SMODES; i++) {
+ snprintf(buf, sizeof(buf), "smode%d", i);
+ reg_get_val(key, buf, &tmp);
+ scene.smodes.change(i, tmp);
+ }
+
+ RegCloseKey(key);
+ }
+}
+
+void write_config(HWND hDlg)
+{
+ HKEY key;
+ DWORD lpdw;
+
+ scene.minbaits = (int)GetDlgItemInt(hDlg, IDC_CONF_MINBAITS, 0, TRUE);
+ scene.maxbaits = (int)GetDlgItemInt(hDlg, IDC_CONF_MAXBAITS, 0, TRUE);
+ scene.minflies = (int)GetDlgItemInt(hDlg, IDC_CONF_MINFLIES, 0, TRUE);
+ scene.maxflies = (int)GetDlgItemInt(hDlg, IDC_CONF_MAXFLIES, 0, TRUE);
+ scene.fsize = ((int)GetDlgItemInt(hDlg, IDC_CONF_FSIZE, 0, TRUE))/10.0;
+ scene.bspeed = (int)GetDlgItemInt(hDlg, IDC_CONF_BSPEED, 0, TRUE);
+ scene.baccel = (int)GetDlgItemInt(hDlg, IDC_CONF_BACCEL, 0, TRUE);
+ scene.fspeed = (int)GetDlgItemInt(hDlg, IDC_CONF_FSPEED, 0, TRUE);
+ scene.faccel = (int)GetDlgItemInt(hDlg, IDC_CONF_FACCEL, 0, TRUE);
+ scene.hue_rate = (int)GetDlgItemInt(hDlg, IDC_CONF_HUERATE, 0, TRUE);
+ scene.tail_length =
+ ((int)GetDlgItemInt(hDlg, IDC_CONF_TAILLENGTH, 0, TRUE))/10.0;
+ scene.tail_width =
+ ((int)GetDlgItemInt(hDlg, IDC_CONF_TAILWIDTH, 0, TRUE))/10.0;
+ scene.tail_opaq =
+ ((int)GetDlgItemInt(hDlg, IDC_CONF_TAILOPAQ, 0, TRUE))/100.0;
+ scene.glow_factor =
+ ((int)GetDlgItemInt(hDlg, IDC_CONF_GLOWFACTOR, 0, TRUE))/10.0;
+ scene.wind_speed =
+ ((int)GetDlgItemInt(hDlg, IDC_CONF_WIND, 0, TRUE))/10.0;
+ scene.draw_bait = (IsDlgButtonChecked(hDlg, IDC_CONF_DRAWBAIT)==BST_CHECKED);
+ scene.fast_forward = (int)GetDlgItemInt(hDlg, IDC_CONF_FASTFORWARD, 0, TRUE);
+ fps = (int)GetDlgItemInt(hDlg, IDC_CONF_FPS, 0, TRUE);
+ for (GLuint i = 0; i < NUM_BMODES; i++) {
+ scene.bmodes.change(i, (double)
+ (UINT)GetDlgItemInt(hDlg, IDC_CONF_BMODE(i), 0, FALSE));
+ }
+ for (GLuint i = 0; i < NUM_SMODES; i++) {
+ scene.smodes.change(i, (double)
+ (UINT)GetDlgItemInt(hDlg, IDC_CONF_SMODE(i), 0, FALSE));
+ }
+
+ if (RegCreateKeyEx( HKEY_CURRENT_USER,
+ MY_HKEY,
+ 0, //reserved
+ "", //ptr to null-term string specifying the object type of this key
+ REG_OPTION_NON_VOLATILE,
+ KEY_WRITE,
+ NULL,
+ &key,
+ &lpdw) == ERROR_SUCCESS)
+ {
+ reg_set_val(key, "minbaits", scene.minbaits);
+ reg_set_val(key, "maxbaits", scene.maxbaits);
+ reg_set_val(key, "minflies", scene.minflies);
+ reg_set_val(key, "maxflies", scene.maxflies);
+ reg_set_val_tim10(key, "fsize", scene.fsize);
+ reg_set_val(key, "bspeed", scene.bspeed);
+ reg_set_val(key, "baccel", scene.baccel);
+ reg_set_val(key, "fspeed", scene.fspeed);
+ reg_set_val(key, "faccel", scene.faccel);
+ reg_set_val(key, "hue_rate", scene.hue_rate);
+ reg_set_val_tim10(key, "tail_length", scene.tail_length);
+ reg_set_val_tim10(key, "tail_width", scene.tail_width);
+ reg_set_val_tim100(key, "tail_opaq", scene.tail_opaq);
+ reg_set_val_tim10(key, "glow_factor", scene.glow_factor);
+ reg_set_val_tim10(key, "wind_speed", scene.wind_speed);
+ reg_set_val(key, "draw_bait", scene.draw_bait);
+ reg_set_val(key, "fast_forward", scene.fast_forward);
+ reg_set_val(key, "fps", fps);
+
+ char buf[256];
+ for (GLuint i = 0; i < NUM_BMODES; i++) {
+ snprintf(buf, sizeof(buf), "bmode%d", i);
+ reg_set_val(key, buf, scene.bmodes.events[i].second);
+ }
+ for (GLuint i = 0; i < NUM_SMODES; i++) {
+ snprintf(buf, sizeof(buf), "smode%d", i);
+ reg_set_val(key, buf, scene.smodes.events[i].second);
+ }
+
+ RegCloseKey(key);
+ }
+}
+
+// main() function
+LRESULT WINAPI
+ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static HDC hDC;
+ static HGLRC hRC;
+ static RECT rect;
+ int width, height;
+
+ srand(time(0));
+ switch ( message ) {
+ case WM_CREATE:
+ GetClientRect(hWnd, &rect);
+ width = rect.right;
+ height = rect.bottom;
+
+ read_config();
+
+ init_gl( hWnd, hDC, hRC );
+ start_animate(width, height);
+
+ // tick every 1000/fps ms
+ SetTimer( hWnd, TIMER, (unsigned)(1000/fps), NULL );
+ return 0;
+
+ case WM_DESTROY:
+ KillTimer( hWnd, TIMER );
+ close_gl(hWnd, hDC, hRC);
+ return 0;
+
+ case WM_TIMER:
+ on_timer(hDC);
+ return 0;
+ }
+
+ return DefScreenSaverProc(hWnd, message, wParam, lParam);
+}
+
+void set_dialog(HWND hDlg)
+{
+ SetDlgItemInt(hDlg, IDC_CONF_MINBAITS, (UINT)scene.minbaits, TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_MAXBAITS, (UINT)scene.maxbaits, TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_MINFLIES, (UINT)scene.minflies, TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_MAXFLIES, (UINT)scene.maxflies, TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_FSIZE, (UINT)(scene.fsize*10), TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_BSPEED, (UINT)scene.bspeed, TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_BACCEL, (UINT)scene.baccel, TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_FSPEED, (UINT)scene.fspeed, TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_FACCEL, (UINT)scene.faccel, TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_HUERATE, (UINT)scene.hue_rate, TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_TAILLENGTH, (UINT)(scene.tail_length*10), TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_TAILWIDTH, (UINT)(scene.tail_width*10), TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_TAILOPAQ, (UINT)(scene.tail_opaq*100), TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_GLOWFACTOR, (UINT)(scene.glow_factor*10), TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_WIND, (UINT)(scene.wind_speed*10), TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_FASTFORWARD, (UINT)(scene.fast_forward), TRUE);
+ SetDlgItemInt(hDlg, IDC_CONF_FPS, (UINT)(fps), TRUE);
+
+ CheckDlgButton(hDlg, IDC_CONF_DRAWBAIT,
+ scene.draw_bait ? BST_CHECKED : BST_UNCHECKED);
+ for (GLuint i = 0; i < NUM_BMODES; i++) {
+ SetDlgItemInt(hDlg, IDC_CONF_BMODE(scene.bmodes.events[i].first),
+ (UINT)scene.bmodes.events[i].second, FALSE);
+ }
+ for (GLuint i = 0; i < NUM_SMODES; i++) {
+ SetDlgItemInt(hDlg, IDC_CONF_SMODE(scene.smodes.events[i].first),
+ (UINT)scene.smodes.events[i].second, FALSE);
+ }
+}
+
+// configure dialog
+BOOL WINAPI
+ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static HWND hIDOK;
+
+ switch (message) {
+ case WM_INITDIALOG:
+ LoadString(hMainInstance, IDS_DESCRIPTION, szAppName, 40);
+ read_config();
+ set_dialog(hDlg);
+
+ hIDOK = GetDlgItem(hDlg, IDOK);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (wParam) {
+ case IDOK:
+ write_config(hDlg);
+ EndDialog(hDlg, TRUE);
+ return TRUE;
+
+ case IDCANCEL:
+ EndDialog(hDlg, FALSE);
+ return TRUE;
+
+ case IDC_DEFAULTS:
+ scene.set_defaults();
+ fps = 20;
+ set_dialog(hDlg);
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+// needed for SCRNSAVE.LIB
+BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
+{
+ return TRUE;
+}