home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * The main loop of Newton (event handling and stuff)
- * Yossi Friedman, 1988
- */
-
- #include <stdio.h>
- #include <gl.h>
- #include <device.h>
-
- #include "config.h"
- #include "newton.h"
- #include "windows.h"
- #include "slider.h"
-
-
-
- static int playing;
-
- /* values for mouse_buttons */
- #define LEFT_DOWN 0x010000
- #define MIDDLE_DOWN 0x000100
- #define RIGHT_ROWN 0x000001
- #define LEFT_UP 0x000101
- #define MIDDLE_UP 0x010001
- #define RIGHT_UP 0x010100
-
-
- static int spin_mode = SPIN_MODE_DEFAULT;
- #define SPIN_FRAME_ACTION 1
-
- extern int auto_mode;
-
- void do_inputchange(short val);
- void do_redraw(short val);
- void do_winquit(short val);
- void do_winfreeze(short val);
- void do_menu();
-
-
- play()
- {
- short dev, val;
- int mouse_buttons = 0;
- int spin_frame_count = 0;
- short omx, omy, nmx, nmy;
-
- #ifdef STATISTICS
- # define TIMES 100
- long genesis;
- int frame_count = 0;
- #endif /* STATISTICS */
-
-
- /* window manager events */
- qdevice(INPUTCHANGE);
- qdevice(REDRAW);
- qdevice(WINQUIT);
- qdevice(WINFREEZE);
- qdevice(WINTHAW);
-
- /* user events */
- qdevice(ESCKEY);
- qdevice(LEFTMOUSE);
- qdevice(MIDDLEMOUSE);
- qdevice(RIGHTMOUSE);
-
-
- #ifdef STATISTICS
- time(&genesis);
- #endif /* STATISTICS */
-
- /*
- * initialization. order matters.
- */
- initialize_models();
- initialize_menus();
-
- for (playing = 1; playing;) {
-
- if (auto_mode) {
- spin_mode = 1;
- start_gravity();
- }
-
- /* check events */
- while(qtest()) {
- dev=qread(&val);
-
- /*
- * handle window manager events separately
- */
- switch (dev) {
-
- case INPUTCHANGE:
- do_inputchange(val);
- continue;
-
- case REDRAW:
- do_redraw(val);
- continue;
-
- case WINQUIT:
- do_winquit(val);
- continue;
-
- case WINFREEZE:
- do_winfreeze(val);
- continue;
-
- case WINTHAW:
- /* is supposed to be handled by do_winfreeze */
- fprintf(stderr, "newton: Unexpected WINTHAW (val = %d)\n", val);
- continue;
- }
-
-
-
- /*
- * handle user events
- */
-
-
- /* see if it is a slider event */
- if (current_window && current_window->sid >= 0) {
- if (slider_event(current_window->sid, dev, val) == 0)
- close_current_window();
- continue;
- }
-
- /*
- * main window events
- */
- switch(dev) {
-
- case ESCKEY:
- if (!val)
- playing = 0;
- break;
-
- case LEFTMOUSE:
- if (val) {
- build_model(0);
- stop_gravity();
-
- omx = getvaluator(MOUSEX);
- omy = getvaluator(MOUSEY);
-
- mouse_buttons |= LEFT_DOWN;
- }
- else {
- start_gravity();
- mouse_buttons &= LEFT_UP;
- }
-
- break;
-
- case MIDDLEMOUSE:
- if (val) {
- omx = getvaluator(MOUSEX);
- omy = getvaluator(MOUSEY);
-
- mouse_buttons |= MIDDLE_DOWN;
- }
- else
- mouse_buttons &= MIDDLE_UP;
-
- break;
-
- case RIGHTMOUSE:
- if (val)
- do_menu();
- break;
-
- default:
- fprintf(stderr, "newton: Unknown device event (dev = %d, val = %d)\n", dev, val);
- break;
- }
- }
-
-
- if (current_window && current_window->sid >= 0)
- do_slider(current_window->sid);
-
- if (mouse_buttons) {
- nmx = getvaluator(MOUSEX);
- nmy = getvaluator(MOUSEY);
- reorient(mouse_buttons, 2*(nmx - omx), 2*(nmy - omy));
- omx = nmx;
- omy = nmy;
- }
-
- if (spin_mode && ++spin_frame_count == SPIN_FRAME_ACTION) {
- spin_frame_count = 0;
- reorient(
- MIDDLE_DOWN,
- (getvaluator(MOUSEX) - 640)/6,
- (getvaluator(MOUSEY) - 512)/5
- );
- }
-
- draw_everything();
- iterate();
-
- #ifdef STATISTICS
- if ((++frame_count % TIMES) == 0)
- printf("Average: %f frames per second\n",
- (float) frame_count / (float)(time(0) - genesis));
- #endif /* STATISTICS */
-
- }
- }
-
-
- /*
- * window manager event handlers
- */
-
- void
- do_inputchange(short val)
- {
- if (val == 0) {
- current_window = NULL;
- return;
- }
-
- /* search which window was entered */
- for (
- current_window = windows;
- current_window != NULL;
- current_window = current_window->next
- )
- if (current_window->wid == val)
- break;
-
- /*
- if (current_window == NULL)
- fprintf(stderr, "newton: Unidentified INPUTCHANGE (val = %d)\n", val);
- */
-
- }
-
- void
- do_redraw(short val)
- {
- struct window *wp;
- long tmp_wid;
- long size[2];
-
- /* find out which window has to be redrawn */
- for (wp = windows; wp != NULL; wp = wp->next)
- if (wp->wid == val)
- break;
-
- if (wp == NULL) {
- fprintf(stderr, "newton: Unidentified REDRAW (val = %d)\n", val);
- return;
- }
-
- /* is it a slider? */
- if (wp->sid >= 0)
- (void) slider_event(wp->sid, REDRAW, val);
- else {
- tmp_wid = winget();
- winset(wp->wid);
- reshapeviewport();
- if (tmp_wid != -1)
- winset(tmp_wid);
- }
-
- /* get new corners */
- tmp_wid = winget();
- winset(wp->wid);
- getorigin(&(wp->bot_left[X]), &(wp->bot_left[Y]));
- getsize(&size[X], &size[Y]);
- wp->top_right[X] = wp->bot_left[X] + size[X];
- wp->top_right[Y] = wp->bot_left[Y] + size[Y];
- if (tmp_wid != -1)
- winset(tmp_wid);
- }
-
- void
- do_winquit(short val)
- {
- struct window *wp;
- long tmp_wid;
-
- /* find out which window was quit */
- for (
- current_window = windows;
- current_window != NULL;
- current_window = current_window->next
- )
- if (current_window->wid == val)
- break;
-
- if (current_window == NULL) {
- fprintf(stderr, "newton: Unidentified WINQUIT (val = %d)\n", val);
- return;
- }
-
- /* is it a slider? */
- if (current_window->sid >= 0) {
- (void)slider_event(current_window->sid, WINQUIT, val);
- close_current_window();
- }
- else
- playing = 0;
- }
-
- void
- do_winfreeze(short val)
- {
- struct window *stowed, *wp;
- short dev;
- int i;
- extern void close_model_window(long);
-
- /*
- * -------------------- F R E E Z I N G --------------------
- */
-
- /* find out which window was stowed */
- for (stowed = windows; stowed != NULL; stowed = stowed->next)
- if (stowed->wid == val)
- break;
-
- if (stowed == NULL) {
- fprintf(stderr, "newton: Unindentified WINFREEZE (val = %d)\n", val);
- return;
- }
-
- /* close all windows except for the stowed one */
- for (wp = windows; wp != NULL; wp = wp->next)
- if (wp != stowed)
- if (wp->sid >= 0)
- close_slider(wp->sid);
- else
- close_model_window(wp->wid);
-
- #ifdef MP
-
- /* block all the slave processes */
- for (i = 1; i < nproc; i++)
- blockproc(slave_pid[i]);
-
- #endif /* MP */
-
-
- /* wait for a WINTHAW */
- while ((dev = qread(&val)) != WINTHAW)
- /* printf("do_winfreeze: got dev = %d, val = %d\n", dev, val) */
- ;
-
-
-
- /*
- * -------------------- T H A W I N G --------------------
- */
-
-
-
- /* open all windows that need to be opened */
- for (wp = windows; wp != NULL; wp = wp->next)
- if (wp != stowed) {
- prefposition(wp->bot_left[X], wp->top_right[X],
- wp->bot_left[Y], wp->top_right[Y]);
- if (wp->sid >= 0)
- wp->wid = open_slider(wp->sid);
- else
- wp->wid = open_model_window("newton");
- }
- else
- if (wp->sid >= 0)
- slider_event(wp->sid, REDRAW, wp->wid);
-
- #ifdef MP
-
- /* unblock all slave processes */
- for (i = 1; i < nproc; i++)
- unblockproc(slave_pid[i]);
-
- #endif /* MP */
-
-
- find_current_window();
- }
-
-
- initialize_sliders()
- {
- struct slider *sp;
-
- for (sp = sliders; sp < end_sliders; sp++)
- sp->sid = define_slider("Newton", sp->title, sp->lo, sp->hi, sp->dflt, sp->fun);
- }
-
-
-
- static int
- models_menu,
- physics_menu,
- model_draw_menu,
- wall_draw_menu,
- main_menu;
-
- initialize_menus()
- {
- char menu_buf[MAX_MENU_ITEMS*MAX_MENU_ITEM_LEN];
- char buf[MAX_MENU_ITEM_LEN], *p, *q;
- int i;
-
- /* make the models menu */
- for (p = menu_buf, i = 0; model_names + i != end_model_names; i++) {
- sprintf(buf,
- (i == 0)? "Models %%t|%s %%x%d": "|%s %%x%d",
- model_names[i], 101 + i);
- for (q = buf; *q; *p++ = *q++)
- ;
- }
- *p = 0;
- models_menu = defpup(menu_buf);
-
- /* make the physics menu */
- for (p = menu_buf, i = 0; i < end_sliders - sliders; i++) {
- sprintf(buf,
- (i == 0)? "Physics %%t|%s %%x%d": "|%s %%x%d",
- sliders[i].title, 201 + i);
- for (q = buf; *q; *p++ = *q++)
- ;
- }
- *p = 0;
- physics_menu = defpup(menu_buf);
-
- /* make the model draw menu */
- model_draw_menu = defpup(
- #ifdef HAS_BLENDING
- "Model Display %t|flat surfaces %x301|smooth surfaces %x302|springs %x303|toggle translucency %x304|toggle surfaces+springs %x305|Bermuda %x306"
- #else /* HAS_BLENDING */
- "Model Display %t|flat surfaces %x301|smooth surfaces %x302|springs %x303|toggle surfaces+springs %x305|Bermuda %x306"
- #endif /* HAS_BLENDING */
- );
-
- /* make the wall draw menu */
- wall_draw_menu = defpup("Room Display %t|lighted walls w/ shadows %x401|lighted walls w/o shadows %x402|pinball walls %x403");
-
- /* force main menu to be generated */
- main_menu = 0;
- }
-
-
- void
- do_menu()
- {
- int val;
- struct window *wp;
- int sid;
-
- if (main_menu == 0) {
- main_menu = defpup("Newton %t| models %m|physics %m|model display %m|room display %m",
- models_menu, physics_menu, model_draw_menu, wall_draw_menu);
- addtopup(main_menu, spin_mode? "spin mode off": "spin mode on");
- addtopup(main_menu, "exit");
- }
-
- val = dopup(main_menu);
-
- if (val > 400)
- /* wall draw menu */
- switch (val) {
- case 401:
- draw_wall = draw_lighted_wall;
- shadows_too = 1;
- break;
-
- case 402:
- draw_wall = draw_lighted_wall;
- shadows_too = 0;
- break;
-
- case 403:
- draw_wall = draw_pinball_wall;
- break;
- }
-
- if (val > 300)
- /* model draw menu */
- switch (val) {
- case 301:
- draw_model = draw_flat_surfs;
- if (mode != RGB) {
- mode = RGB;
- RGBmode();
- gconfig();
- }
- break;
-
- case 302:
- draw_model = draw_smooth_surfs;
- if (mode != RGB) {
- mode = RGB;
- RGBmode();
- gconfig();
- }
- break;
-
- case 303:
- draw_model = draw_springs;
- if (mode != RGB) {
- mode = RGB;
- RGBmode();
- gconfig();
- }
- break;
-
- #ifdef HAS_BLENDING
- case 304:
- alpha_blended = 1 - alpha_blended;
- break;
- #endif /* HAS_BLENDING */
-
- case 305:
- springs_too = 1 - springs_too;
- break;
-
- case 306:
- draw_model = draw_flat_surfs;
- if (mode != COLOR_MAP) {
- mode = COLOR_MAP;
- cmode();
- gconfig();
- }
- break;
- }
- else
- if (val > 200) {
- /* physics menu */
- if (&sliders[val - 201] >= end_sliders) {
- fprintf(stderr, "newton: Unknown physics menu selection\n");
- return;
- }
-
- sid = sliders[val - 201].sid;
- for (wp = windows; wp != NULL; wp = wp->next)
- if (wp->sid == sid) {
- /* window already open */
- (void) open_slider(sid);
- break;
- }
-
- if (wp == NULL)
- new_window(open_slider(sid), sid);
-
- find_current_window();
- }
- else
- if (val > 100) {
- /* models menu */
- model_index = val - 101;
- build_model(1);
- stop_gravity();
- }
- else
- /* main menu */
- switch (val) {
- case -1:
- break;
-
- case 5:
- spin_mode = (spin_mode == 0);
-
- /* force regeneration of main menu */
- freepup(main_menu);
- main_menu = 0;
- break;
-
- case 6:
- playing = 0;
- break;
-
- default:
- fprintf(stderr, "newton: Unknown menu selection (%d)\n", val);
- break;
- }
- }
-
-
- reorient(mouse_buttons, dx, dy)
- int mouse_buttons;
- int dx, dy;
- {
- if (mouse_buttons & LEFT_DOWN) {
- rotate_model((Angle) dx, 'Y');
- rotate_model((Angle)-dy, 'X');
- }
-
- if (mouse_buttons & MIDDLE_DOWN) {
- rotate_graphics((Angle) dx, 'Y');
- rotate_physics ((Angle)-dx, 'Y');
-
- rotate_graphics((Angle)-dy, 'X');
- rotate_physics ((Angle) dy, 'X');
- }
- }
-