*/
#ifdef STANDALONE /* xscreensaver mode */
-#define PROGCLASS "Sballs"
-#define HACK_INIT init_sballs
-#define HACK_DRAW draw_sballs
-#define HACK_RESHAPE reshape_sballs
-#define sballs_opts xlockmore_opts
#define DEFAULTS "*delay: 30000 \n" \
"*size: 0 \n" \
"*cycles: 4 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+# define refresh_sballs 0
#define MODE_sballs
#include "xlockmore.h" /* from the xscreensaver distribution */
+#include "gltrackball.h"
#else /* !STANDALONE */
#include "xlock.h" /* from the xlockmore distribution */
#include "visgl.h"
#define FRAME 50 /* frame count interval */
#define MAX_OBJ 8 /* number of 3D objects */
-#include <GL/gl.h>
-#include <GL/glx.h>
-#include <GL/glu.h>
-
-#if defined( USE_XPM ) || defined( USE_XPMINC ) || defined( HAVE_XPM )
+#if defined( USE_XPM ) || defined( USE_XPMINC ) || defined( STANDALONE )
/* USE_XPM & USE_XPMINC in xlock mode ; HAVE_XPM in xscreensaver mode */
# include "xpm-ximage.h"
# define I_HAVE_XPM
/* Manage option vars */
#define DEF_TEXTURE "True"
-#define DEF_TRACKMOUSE "False"
#define DEF_OBJECT "0"
static Bool do_texture;
-static Bool do_trackmouse;
static int object;
static int spheres;
static XrmOptionDescRec opts[] = {
{"-texture", ".sballs.texture", XrmoptionNoArg, "on"},
{"+texture", ".sballs.texture", XrmoptionNoArg, "off"},
- {"-trackmouse", ".sballs.trackmouse", XrmoptionNoArg, "on"},
- {"+trackmouse", ".sballs.trackmouse", XrmoptionNoArg, "off"},
{"-object", ".sballs.object", XrmoptionSepArg, 0},
};
static argtype vars[] = {
{&do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool},
- {&do_trackmouse, "trackmouse", "TrackMouse", DEF_TRACKMOUSE, t_Bool},
{&object, "object", "Object", DEF_OBJECT, t_Int},
};
/*{"-count spheres", "set number of spheres"},*/
/*{"-cycles speed", "set ball speed value"},*/
{"-/+texture", "turn on/off texturing"},
- {"-/+trackmouse", "turn on/off the tracking of the mouse"},
{"-object num", "number of the 3D object (0 means random)"},
};
-ModeSpecOpt sballs_opts =
+ENTRYPOINT ModeSpecOpt sballs_opts =
{ sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc };
#ifdef USE_MODULES
GLuint faceid; /* face texture id: GL world */
vec3_t eye;
- vec3_t rot;
vec3_t rotm;
int speed;
float radius[MAX_BALLS];
+ trackball_state *trackball;
+ Bool button_down_p;
+
} sballsstruct;
/* array of sballsstruct indexed by screen number */
static sballsstruct *sballs = (sballsstruct *) NULL;
/* lights */
-static float LightAmbient[]= { 1.0f, 1.0f, 1.0f, 1.0f };
-static float LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };
-static float LightPosition[]= { 0.0f, 0.0f, 4.0f, 1.0f };
+static const float LightAmbient[]= { 1.0f, 1.0f, 1.0f, 1.0f };
+static const float LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };
+static const float LightPosition[]= { 0.0f, 0.0f, 4.0f, 1.0f };
/* structure of the polyhedras */
typedef struct {
vec3_t v[MAX_BALLS];/* the vertices */
} Polyinfo;
-static Polyinfo polygons[] =
+static const Polyinfo polygons[] =
{
/* 0: objtetra - structure values for tetrahedron */
*-----------------------------------------------------------------------------
*/
-static void clamp(vec3_t v)
-{
- int i;
-
- for (i = 0; i < 3; i ++)
- if (v[i] > 360 || v[i] < -360)
- v[i] = 0;
-}
-
-/* track the mouse in a joystick manner : not perfect but it works */
-static void trackmouse(ModeInfo * mi)
-{
- sballsstruct *sb = &sballs[MI_SCREEN(mi)];
- /* we keep static values (not per screen) for the mouse stuff: in general you have only one mouse :-> */
- static int max[2] = { 0, 0 };
- static int min[2] = { 0x7fffffff, 0x7fffffff }, center[2];
- Window r, c;
- int rx, ry, cx, cy;
- unsigned int m;
-
- (void) XQueryPointer(MI_DISPLAY(mi), MI_WINDOW(mi),
- &r, &c, &rx, &ry, &cx, &cy, &m);
-
- if (max[0] < cx)
- max[0] = cx;
- if (min[0] > cx)
- min[0] = cx;
- center[0] = (max[0] + min[0]) / 2;
-
- if (max[1] < cy)
- max[1] = cy;
- if (min[1] > cy)
- min[1] = cy;
- center[1] = (max[1] + min[1]) / 2;
-
- if (fabs(center[0] - (float) cx) > 0.1 * (max[0] - min[0]))
- sb->rot[0] -= ((center[0] - (float) cx) / (max[0] - min[0]) * 180.0f) / 200.0f;
- if (fabs(center[1] - (float) cy) > 0.1 * (max[1] - min[1]))
- sb->rot[1] -= ((center[1] - (float) cy) / (max[1] - min[1]) * 180.0f) / 200.0f;;
- clamp(sb->rot);
-
- /* oops: can't get those buttons */
- if (m & Button4Mask)
- sb->speed++;
- if (m & Button5Mask)
- sb->speed--;
-
-}
/* initialise textures */
static void inittextures(ModeInfo * mi)
#ifndef STANDALONE
static void Reshape(ModeInfo * mi)
#else
-void reshape_sballs(ModeInfo * mi, int width, int height)
+ENTRYPOINT void reshape_sballs(ModeInfo * mi, int width, int height)
#endif
{
mi->polygon_count = 0;
- if (do_trackmouse && !MI_IS_ICONIC(mi))
- trackmouse(mi);
-
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glColor3f(0, 0, 0);
}
glBegin(GL_QUAD_STRIP);
+#ifndef USE_IPHONE
+ /* Letterbox the background image */
glNormal3f(0, 0, 1); glTexCoord2f(0,0); glVertex3f(8, 4.1, -4);
glNormal3f(0, 0, 1); glTexCoord2f(0,1); glVertex3f(8, -4.1, -4);
glNormal3f(0, 0, 1); glTexCoord2f(1,0); glVertex3f(-8, 4.1, -4);
glNormal3f(0, 0, 1); glTexCoord2f(1,1); glVertex3f(-8, -4.1, -4);
+#else
+ /* Fill the iPhone screen. Letterboxing looks dumb there. */
+ glNormal3f(0, 0, 1); glTexCoord2f(0,0); glVertex3f(4, 5.2, -4);
+ glNormal3f(0, 0, 1); glTexCoord2f(0,1); glVertex3f(4, -5.2, -4);
+ glNormal3f(0, 0, 1); glTexCoord2f(1,0); glVertex3f(-4, 5.2, -4);
+ glNormal3f(0, 0, 1); glTexCoord2f(1,1); glVertex3f(-4, -5.2, -4);
+#endif
glEnd();
mi->polygon_count++;
- /* rotate the mouse */
- glRotatef(sb->rot[0], 1.0f, 0.0f, 0.0f);
- glRotatef(sb->rot[1], 0.0f, 1.0f, 0.0f);
- glRotatef(sb->rot[2], 0.0f, 0.0f, 1.0f);
+ /* Do it twice because we don't track the device's orientation. */
+ glRotatef( current_device_rotation(), 0, 0, 1);
+ gltrackball_rotate (sb->trackball);
+ glRotatef(-current_device_rotation(), 0, 0, 1);
/* rotate the balls */
glRotatef(sb->rotm[0], 1.0f, 0.0f, 0.0f);
glRotatef(sb->rotm[1], 0.0f, 1.0f, 0.0f);
glRotatef(sb->rotm[2], 0.0f, 0.0f, 1.0f);
- sb->rotm[0] += sb->speed;
- sb->rotm[1] += -(sb->speed);
- sb->rotm[2] += 0;
+ if (! sb->button_down_p) {
+ sb->rotm[0] += sb->speed;
+ sb->rotm[1] += -(sb->speed);
+ sb->rotm[2] += 0;
+ }
/* draw the balls */
if (do_texture)
}
vinit(sb->eye ,0.0f, 0.0f, 6.0f);
- vinit(sb->rot ,0.0f, 0.0f, 0.0f);
vinit(sb->rotm ,0.0f, 0.0f, 0.0f);
sb->speed = MI_CYCLES(mi);
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);
glEnable(GL_LIGHT1);
-
- glClearColor(0, 0, 0, 0);
}
/*
*-----------------------------------------------------------------------------
*/
-void init_sballs(ModeInfo * mi)
+ENTRYPOINT void init_sballs(ModeInfo * mi)
{
sballsstruct *sb;
}
sb = &sballs[MI_SCREEN(mi)];
+ sb->trackball = gltrackball_init ();
+
if ((sb->glx_context = init_GL(mi)) != NULL) {
#ifndef STANDALONE
* Called by the mainline code periodically to update the display.
*-----------------------------------------------------------------------------
*/
-void draw_sballs(ModeInfo * mi)
+ENTRYPOINT void draw_sballs(ModeInfo * mi)
{
Display *display = MI_DISPLAY(mi);
Window window = MI_WINDOW(mi);
*-----------------------------------------------------------------------------
*/
-void release_sballs(ModeInfo * mi)
+ENTRYPOINT void release_sballs(ModeInfo * mi)
{
int screen;
FreeAllGL(mi);
}
-void change_sballs(ModeInfo * mi)
+ENTRYPOINT Bool
+sballs_handle_event (ModeInfo *mi, XEvent *event)
+{
+ sballsstruct *sb = &sballs[MI_SCREEN(mi)];
+
+ if (event->xany.type == ButtonPress &&
+ event->xbutton.button == Button1)
+ {
+ sb->button_down_p = True;
+ gltrackball_start (sb->trackball,
+ event->xbutton.x, event->xbutton.y,
+ MI_WIDTH (mi), MI_HEIGHT (mi));
+ return True;
+ }
+ else if (event->xany.type == ButtonRelease &&
+ event->xbutton.button == Button1)
+ {
+ sb->button_down_p = False;
+ return True;
+ }
+ else if (event->xany.type == ButtonPress &&
+ (event->xbutton.button == Button4 ||
+ event->xbutton.button == Button5 ||
+ event->xbutton.button == Button6 ||
+ event->xbutton.button == Button7))
+ {
+ gltrackball_mousewheel (sb->trackball, event->xbutton.button, 5,
+ !!event->xbutton.state);
+ return True;
+ }
+ else if (event->xany.type == MotionNotify &&
+ sb->button_down_p)
+ {
+ gltrackball_track (sb->trackball,
+ event->xmotion.x, event->xmotion.y,
+ MI_WIDTH (mi), MI_HEIGHT (mi));
+ return True;
+ }
+
+ return False;
+}
+
+
+#ifndef STANDALONE
+ENTRYPOINT void change_sballs(ModeInfo * mi)
{
sballsstruct *sb;
glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(sb->glx_context));
}
+#endif /* !STANDALONE */
+
+XSCREENSAVER_MODULE ("SBalls", sballs)
+
#endif /* MODE_sballs */