/* * Copyright (C) 2000 Jeremie Allard (Hufo / N.A.A.) * Ported to Linux by Tugrul Galatali * * hufo_smoke is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * hufo_smoke is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // hufo_smoke screen saver #include #include #include #include #include "driver.h" #include "rsRand.h" char *hack_name = (char *)"Hufo/N.A.A. particle system"; #include "FirePart.h" #define XSTD (4.0/3.0) float TFire; // fire time float TVit; float CylShad[9] = { 0.2f, 0.6f, 1.0f, 0.6f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f }; struct RGBColor { float r, g, b; }; #define SetRGBColor(c) glColor3f((c).r,(c).g,(c).b) RGBColor CylBColor = { 0.43f, 0.25f, 0.10f }; RGBColor CylColor[9]; bool AffGrid = false; float fr = 1.0f, fg = 1.0f, fb = 1.0f; float br = 1.0f, bg = 1.0f, bb = 1.0f; void hack_reshape (xstuff_t * XStuff) { float x = (float)XStuff->windowWidth / (float)XStuff->windowHeight; // Correct the viewing ratio of the window in the X axis. // Window initialization glViewport (0, 0, XStuff->windowWidth, XStuff->windowHeight); glMatrixMode (GL_PROJECTION); glLoadIdentity (); if (x > XSTD) gluOrtho2D (-x, x, -1, 1); // Reset to a 2D screen space. else gluOrtho2D (-XSTD, XSTD, -XSTD / x, XSTD / x); // Reset to a 2D screen space. glMatrixMode (GL_MODELVIEW); glLoadIdentity (); } // Startup Stuff. void hack_init (xstuff_t * XStuff) // Called right after the window is created, and OpenGL is initialized. { hack_reshape (XStuff); glCullFace (GL_FRONT); // reject fliped faces glDepthFunc (GL_LESS); glBlendFunc (GL_SRC_ALPHA, GL_ONE); glEnable (GL_BLEND); for (int i = 0; i < 9; ++i) { CylColor[i].r = CylBColor.r * CylShad[i]; CylColor[i].g = CylBColor.g * CylShad[i]; CylColor[i].b = CylBColor.b * CylShad[i]; } TFire = 0.0; TVit = 1.0; FireInit (); // initialise fire } void hack_cleanup (xstuff_t * XStuff) { } #define fSQRT_3_2 0.8660254038f void AffParticle (float ex, float ey, float dx, float dy, float a) { float hdx = 0.5f * dx; float s32_dy = fSQRT_3_2 * dy; glBegin (GL_TRIANGLE_FAN); glColor4f (fr, fg, fb, a); glVertex2f (ex, ey); glColor4f (br, bg, bb, 0.0f); glVertex2f (ex - dx, ey); glVertex2f (ex - hdx, ey + s32_dy); glVertex2f (ex + hdx, ey + s32_dy); glVertex2f (ex + dx, ey); glVertex2f (ex + hdx, ey - s32_dy); glVertex2f (ex - hdx, ey - s32_dy); glVertex2f (ex - dx, ey); glEnd (); } // Draw all the scene related stuff. void hack_draw (xstuff_t * XStuff, double currentTime, float frameTime) { TFire += frameTime; CalcFire (TFire, frameTime); // animate the fire glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); int n; glEnable (GL_BLEND); Particle *p = TblP; n = np; while (n) { if (p->dx) AffParticle (p->ex, p->ey, p->dx, p->dy, p->a); ++p; --n; } glDisable (GL_BLEND); if (AffGrid) { glColor3f (1.0f, 1.0f, 1.0f); AffFMotion (); } } void hack_handle_opts (int argc, char **argv) { int change_flag = 0; while (1) { int c; #ifdef HAVE_GETOPT_H static struct option long_options[] = { {"help", 0, 0, 'h'}, DRIVER_OPTIONS_LONG {"foreground", 1, 0, 'f'}, {"background", 1, 0, 'b'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, DRIVER_OPTIONS_SHORT "hf:b:", long_options, NULL); #else c = getopt (argc, argv, DRIVER_OPTIONS_SHORT "hf:b:"); #endif if (c == -1) break; switch (c) { DRIVER_OPTIONS_CASES case 'h': printf ("%s:" #ifndef HAVE_GETOPT_H " Not built with GNU getopt.h, long options *NOT* enabled." #endif "\n" DRIVER_OPTIONS_HELP "\t--foreground/-f\n" "\t--background/-b\n", argv[0]); exit (1); case 'f':{ int color = strtol_minmaxdef (optarg, 16, 0, 16777216, 0, 0xffffff, "--foreground: "); change_flag = 1; fr = ((color & 0xFF0000) >> 16) / 256.0f; fg = ((color & 0xFF00) >> 8) / 256.0f; fb = (color & 0xFF) / 256.0f; } break; case 'b':{ int color = strtol_minmaxdef (optarg, 16, 0, 16777216, 0, 0xffffff, "--background: "); change_flag = 1; br = ((color & 0xFF0000) >> 16) / 256.0f; bg = ((color & 0xFF00) >> 8) / 256.0f; bb = (color & 0xFF) / 256.0f; } break; } } if (!change_flag) { do { fr = rsRandf (256) / 256; fg = rsRandf (256) / 256; fb = rsRandf (256) / 256; br = rsRandi (256) / 256; bg = rsRandi (256) / 256; bb = rsRandi (256) / 256; } while ((fr + fg + fb < 1) && (br + bg + bb < 1)); } }