diff options
Diffstat (limited to 'debian/fireflies/fireflies-2.08/src')
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;
+}
|