inc = -Ilibs -Ilibs/imago -Ilibs/treestor/include -Ilibs/goat3d/include
libs = libs/unix/imago.a libs/unix/goat3d.a libs/unix/treestor.a
-CFLAGS = $(warn) $(dbg) $(opt) $(inc) $(def)
+CFLAGS = $(warn) $(dbg) $(opt) $(inc) $(def) -MMD
LDFLAGS = $(libs) -lGL -lGLU -lX11 -lm
$(bin): $(obj) libs
$(CC) -o $@ $(obj) $(LDFLAGS)
+-include $(dep)
+
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(obj) $(bin)
+.PHONY: cleandep
+cleandep:
+ rm -f $(dep)
+
.PHONY: libs
libs:
$(MAKE) -C libs
#include "input.h"
int mouse_x, mouse_y, mouse_state[3];
+int mouse_grabbed;
+unsigned int modkeys;
int win_width, win_height;
float win_aspect;
+int fullscr;
struct game_screen *cur_scr;
switch(key) {
case 27:
game_quit();
- break;
+ return;
+
+ case '\n':
+ case '\r':
+ if(modkeys & GKEY_MOD_ALT) {
+ case GKEY_F11:
+ game_fullscreen(-1);
+ }
+ return;
}
}
GKEY_INS
};
+enum {
+ GKEY_MOD_SHIFT = 1,
+ GKEY_MOD_CTRL = 4,
+ GKEY_MOD_ALT = 8
+};
+
struct game_screen {
const char *name;
};
extern int mouse_x, mouse_y, mouse_state[3];
+extern int mouse_grabbed;
+extern unsigned int modkeys;
extern int win_width, win_height;
extern float win_aspect;
+extern int fullscr;
extern struct game_screen *cur_scr;
/* defined in main.c */
void game_swap_buffers(void);
void game_quit(void);
+void game_fullscreen(int fs);
+void game_grabmouse(int grab);
#endif /* GAME_H_ */
#include "game.h"
static void idle(void);
+static void reshape(int x, int y);
static void keydown(unsigned char key, int x, int y);
static void keyup(unsigned char key, int x, int y);
static void skeydown(int key, int x, int y);
static void skeyup(int key, int x, int y);
static void mouse(int bn, int st, int x, int y);
+static void motion(int x, int y);
static int translate_skey(int key);
+static int warping;
int main(int argc, char **argv)
{
glutDisplayFunc(game_display);
glutIdleFunc(idle);
- glutReshapeFunc(game_reshape);
+ glutReshapeFunc(reshape);
glutKeyboardFunc(keydown);
glutKeyboardUpFunc(keyup);
glutSpecialFunc(skeydown);
glutSpecialUpFunc(skeyup);
glutMouseFunc(mouse);
- glutMotionFunc(game_motion);
+ glutMotionFunc(motion);
+ glutPassiveMotionFunc(motion);
if(game_init() == -1) {
return 1;
exit(0);
}
+void game_fullscreen(int fs)
+{
+ static int prev_w, prev_h;
+ static int prev_grab;
+
+ if(fs == -1) {
+ fs = !fullscr;
+ }
+
+ if(fs == fullscr) return;
+
+ if(fs) {
+ prev_w = glutGet(GLUT_WINDOW_WIDTH);
+ prev_h = glutGet(GLUT_WINDOW_HEIGHT);
+ prev_grab = mouse_grabbed;
+ game_grabmouse(1);
+ glutFullScreen();
+ } else {
+ glutReshapeWindow(prev_w, prev_h);
+ if(!prev_grab) {
+ game_grabmouse(0);
+ }
+ }
+ fullscr = fs;
+}
+
+void game_grabmouse(int grab)
+{
+ static int prev_x, prev_y;
+
+ if(grab == -1) {
+ grab = !mouse_grabbed;
+ }
+
+ if(grab == mouse_grabbed) return;
+
+ if(grab) {
+ warping = 1;
+ prev_x = mouse_x;
+ prev_y = mouse_y;
+ glutWarpPointer(win_width / 2, win_height / 2);
+ glutSetCursor(GLUT_CURSOR_NONE);
+ } else {
+ warping = 1;
+ glutWarpPointer(prev_x, prev_y);
+ glutSetCursor(GLUT_CURSOR_INHERIT);
+ }
+ mouse_grabbed = grab;
+}
+
static void idle(void)
{
glutPostRedisplay();
}
+static void reshape(int x, int y)
+{
+ if(fullscr) {
+ warping = 1;
+ glutWarpPointer(x / 2, y / 2);
+ }
+ game_reshape(x, y);
+}
+
static void keydown(unsigned char key, int x, int y)
{
+ modkeys = glutGetModifiers();
game_keyboard(key, 1);
}
static void skeydown(int key, int x, int y)
{
- int k = translate_skey(key);
- if(k >= 0) {
+ int k;
+ modkeys = glutGetModifiers();
+ if((k = translate_skey(key)) >= 0) {
game_keyboard(k, 1);
}
}
static void mouse(int bn, int st, int x, int y)
{
+ modkeys = glutGetModifiers();
game_mouse(bn - GLUT_LEFT_BUTTON, st == GLUT_DOWN, x, y);
}
+static void motion(int x, int y)
+{
+ if(mouse_grabbed) {
+ if(!warping) {
+ game_motion(x, y);
+ warping = 1;
+ glutWarpPointer(win_width / 2, win_height / 2);
+ } else {
+ warping = 0;
+ }
+ } else {
+ game_motion(x, y);
+ }
+}
+
static int translate_skey(int key)
{
switch(key) {
return GKEY_INS;
default:
if(key >= GLUT_KEY_F1 && key <= GLUT_KEY_F12) {
- return key - (GLUT_KEY_F1 + GKEY_F1);
+ return key - GLUT_KEY_F1 + GKEY_F1;
}
}
cur_cursor = cidx;
}
+void glutWarpPointer(int x, int y)
+{
+ XWarpPointer(dpy, None, win, 0, 0, 0, 0, x, y);
+}
+
void glutSetColor(int idx, float r, float g, float b)
{
XColor color;
}
}
+void glutWarpPointer(int x, int y)
+{
+ SetCursorPos(x, y);
+}
+
void glutSetColor(int idx, float r, float g, float b)
{
PALETTEENTRY col;
void glutSetIconTitle(const char *title);
void glutSetCursor(int cursor);
void glutSetColor(int idx, float r, float g, float b);
+void glutWarpPointer(int x, int y);
float glutGetColor(int idx, int comp);
void glutIgnoreKeyRepeat(int ignore);
gkeyb, gmouse, gmotion
};
-static float cam_theta, cam_phi = 20, cam_dist;
+static float view_mat[16], proj_mat[16];
+
+static float cam_theta, cam_phi, cam_dist;
static cgm_vec3 cam_pan;
static struct goat3d *gscn;
{
if(inpstate & INP_MOVE_BITS) {
cgm_vec3 fwd, right;
- float theta = cam_theta * M_PI / 180.0f;
- float phi = cam_phi * M_PI / 180.0f;
float dx = 0, dy = 0;
- fwd.x = -sin(theta) * cos(phi);
- fwd.y = sin(phi);
- fwd.z = cos(theta) * cos(phi);
- right.x = cos(theta);
+ fwd.x = -sin(cam_theta) * cos(cam_phi);
+ fwd.y = sin(cam_phi);
+ fwd.z = cos(cam_theta) * cos(cam_phi);
+ right.x = cos(cam_theta);
right.y = 0;
- right.z = sin(theta);
+ right.z = sin(cam_theta);
if(inpstate & INP_FWD_BIT) {
dy += 0.1;
tm_acc -= TSTEP;
}
+ cgm_mtranslation(view_mat, 0, 0, -cam_dist);
+ cgm_mprerotate(view_mat, cam_phi, 1, 0, 0);
+ cgm_mprerotate(view_mat, cam_theta, 0, 1, 0);
+ cgm_mpretranslate(view_mat, cam_pan.x, cam_pan.y, cam_pan.z);
glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0, 0, -cam_dist);
- glRotatef(cam_phi, 1, 0, 0);
- glRotatef(cam_theta, 0, 1, 0);
- glTranslatef(cam_pan.x, cam_pan.y, cam_pan.z);
+ glLoadMatrixf(view_mat);
set_light_dir(0, -1, 1, 5);
set_light_dir(1, 5, 0, 3);
static void greshape(int x, int y)
{
+ cgm_mperspective(proj_mat, cgm_deg_to_rad(60), win_aspect, 0.1, 100);
+ glMatrixMode(GL_PROJECTION);
+ glLoadMatrixf(proj_mat);
}
static void gkeyb(int key, int press)
break;
}
}
+
+ if(press) {
+ switch(key) {
+ case '`':
+ if(!fullscr) {
+ game_grabmouse(-1); /* toggle */
+ }
+ break;
+ }
+ }
}
static void gmouse(int bn, int press, int x, int y)
{
}
+#define PIHALF (M_PI / 2.0)
+
static void gmotion(int x, int y)
{
- int dx = x - mouse_x;
- int dy = y - mouse_y;
+ int dx, dy;
+
+ if(mouse_grabbed) {
+ dx = x - win_width / 2;
+ dy = y - win_height / 2;
+ } else {
+ dx = x - mouse_x;
+ dy = y - mouse_y;
+ }
if(!(dx | dy)) return;
- if(mouse_state[0]) {
- cam_theta += dx * 0.5;
- cam_phi += dy * 0.5;
- if(cam_phi < -90) cam_phi = -90;
- if(cam_phi > 90) cam_phi = 90;
+ if(mouse_state[0] || mouse_grabbed) {
+ cam_theta += dx * 0.01;
+ cam_phi += dy * 0.01;
+ if(cam_phi < -PIHALF) cam_phi = -PIHALF;
+ if(cam_phi > PIHALF) cam_phi = PIHALF;
}
/*
if(mouse_state[1]) {