home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 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.
- */
- /////////////////////////////////////////////////////////////////////
- //
- // Driver.c++ - implementation of the driver class
- //
- // Driver is the interface to the user. It receives user
- // input and displays output.
- //
- //////////////////////////////////////////////////////////////////////
-
- #include <Inventor/SbTime.h>
- #include <Inventor/SbPList.h>
- #include <gl/gl.h>
- #include <gl/device.h>
- #include <gl/qcontrol.h>
- #include "Simulation.h"
- #include "Car.h"
- #include "Cockpit.h"
- #include "Engine.h"
- #include "Road.h"
- #include "Stretch.h"
- #include "Dynamics.h"
- #include "Driver.h"
- #include "Render.h"
- #include "Noise.h"
- #include "Keys.h"
- #include "Scenery.h"
- #include "Timer.h"
- #include "Help.h"
-
- // Moving the mouse to the edge of the window is like turning
- // the steering wheel this many degrees
- const float EDGE_DEGREES = 180.0;
-
- // frames behind the car that the helicopter lags
- const int HELICOPTER_LAG = 10;
-
- // different views
- const int DRIVER = 0;
- const int HELICOPTER = 1;
-
- Driver::Driver(Car *c)
- {
- _car = c;
-
- open(); // open a window that the driver can see out of
-
- init_devices(); // initializes input devices
-
- init_render(); // initialize lighting, colors, etc.
-
- // must come after open() since does some GL
- _cockpit = new Cockpit(_car);
-
- // each driver does her own timing
- _timer = new Timer;
- _timer->reset();
- _first_timing = TRUE;
-
- // initialize view
- _display.view = DRIVER;
-
- // initialize helicopter
- _helio_offset.setValue(0.0,-10.0,-30.0); // from car
- _helio_lag = (int)(0.1*_fps); // lag in seconds
- _helio_orientation = new SbMatrix[_helio_lag]; // allocate the list
- _helio_position = new SbVec3f[_helio_lag];
- reset_helicopter();
-
- // keep going till we're outta here
- _done = FALSE;
-
- // only if they ask for it
- _helping = FALSE;
-
- _display.drawStyle = RENDER_FILLED;
- _display.flags = FALSE;
- _display.fog = FALSE;
-
- // nice grey on hollywood: r=224, g=224, b=208
- _display.fog_params[0] = .005;
- _display.fog_params[1] = 224./255.;
- _display.fog_params[2] = 224./255.;
- _display.fog_params[3] = 208./255.;
-
- _cranking = FALSE;
- _crashed = FALSE;
- _crash_handled = FALSE;
- _broken_winshield = FALSE;
-
- // i love the sound of breaking glass
- if (_car->get_simulation()->sound_capable())
- {
- SbString crashpath(_car->get_simulation()->get_path().getString());
- SbString crashfile("crash.aiff");
- crashpath += crashfile;
-
- _crash_noise = readsample(crashpath.getString());
- }
- else
- _crash_noise = NULL;
-
- // save old key warp params and set new ones
- // need this to prevent keyboard repeat
- qcontrol(QC_GETKEYWARP, 0, (short *)NULL, 2, _old_keywarp);
- short new_keywarp[2];
- new_keywarp[0] = 1000;
- new_keywarp[1] = 1000;
- qcontrol(QC_SETKEYWARP, 2, new_keywarp, 0, (short *)NULL);
- }
-
-
- Driver::~Driver()
- {
- // clear the overlay crap
- _cockpit->clear_indicators();
-
- delete _cockpit;
- // delete [_helio_lag] _helio_orientation;
- // delete [_helio_lag] _helio_position;
- delete [] _helio_orientation;
- delete [] _helio_position;
-
- if (_crash_noise)
- freesample(_crash_noise);
-
- // reset key repeat to original values
- qcontrol(QC_SETKEYWARP, 2, _old_keywarp, 0, (short *)NULL);
- }
-
-
- void Driver::open()
- {
- // open parent window
- _parent_win.xmax = getgdesc(GD_XPMAX);
- _parent_win.ymax = getgdesc(GD_YPMAX);
-
- long left = _parent_win.xmax/3 - 50;
- long right = _parent_win.xmax - 1 - 50;
- long bottom = _parent_win.ymax/3 - 50;
- long top = _parent_win.ymax - 1 - 50;
-
- _parent_win.aspect = 1.0/(1.0 - COCKPIT_TOP);
- _parent_win.sizex = right - left;
- _parent_win.sizey = top - bottom;
-
- #ifdef DEBUG
- foreground();
- #endif
-
- prefposition(left,right,bottom,top);
- _parent_win.wid = winopen("Backseat Driver");
- icontitle("Driver");
- color(0); clear(); // clear the muck
- keepaspect(_parent_win.xmax, _parent_win.ymax);
- winconstraints();
-
- // open out-the-window view subwindow, double buffered
- _view_win.wid = swinopen(_parent_win.wid);
- doublebuffer();
- RGBmode();
- gconfig();
- mmode(MVIEWING);
-
- // open cockpit subwindow, single buffered
- _cockpit_win.wid = swinopen(_parent_win.wid);
- RGBmode();
- gconfig();
- mmode(MVIEWING);
-
- // force initial redraw by inserting REDRAW into
- // event queue, not by explicity drawing. This allows
- // a chance to read window info (size, position, etc)
- _redraw_cockpit = _redraw_view = FALSE;
- qenter(REDRAW,(short)_parent_win.wid);
-
- char gstring[12]; // hah hah
- gversion(gstring);
- gstring[6] = (char)NULL;
-
- // set up hardware dependent things
- // take an initial guess at fps, it will get updated as soon
- // as the rendering loop starts
-
- _max_fps = _fps = 60.0;
- _last_frame_time = 125000; // usecs
- _display.zbuffer = FALSE;
-
- if (strcmp( &gstring[4], "PI") == 0)
- {
- // fprintf(stderr,"On a PI, using shademodel(FLAT)\n");
- // fprintf(stderr,"On a PI\n");
- subpixel(FALSE);
- }
- else if (strcmp( &gstring[4], "VG") == 0)
- {
- // fprintf(stderr,"On a VGX, using subpixel(TRUE)\n");
- subpixel(TRUE);
- }
- else if (strcmp( &gstring[4], "GT") == 0)
- {
- // fprintf(stderr,"On a GTX\n");
- }
- else if (strcmp( &gstring[4], "LG") == 0)
- {
- // fprintf(stderr,"On an LG, using subpixel(TRUE)\n");
- subpixel(TRUE);
- shademodel(FLAT);
- _display.zbuffer = FALSE; // XXX SW zbuffer just ain't fast enough
- }
- else
- // fprintf(stderr,"On unknown graphics\n");
- subpixel(TRUE);
-
- _parent_win.zmin = getgdesc(GD_ZMIN);
- _parent_win.zmax = getgdesc(GD_ZMAX);
-
- winset(_view_win.wid);
- zbuffer(_display.zbuffer && (_display.drawStyle == RENDER_FILLED));
- backface(_display.drawStyle == RENDER_FILLED);
- }
-
-
- void Driver::init_devices()
- {
- // express interest in user devices
- qdevice(GAS);
- qdevice(BRAKES);
- qdevice(CLUTCH);
- qdevice(STEERING);
-
- qdevice(VIEWKEY);
- qdevice(DISPLAYKEY);
- // qdevice(FLAGKEY);
- qdevice(SOUNDKEY);
- qdevice(IGNITIONKEY);
- qdevice(RESETKEY);
- qdevice(HELPKEY);
- qdevice(FOGKEY);
- // qdevice(NIGHTKEY);
-
- // qdevice(REVERSE);
- qdevice(NEUTRAL);
- qdevice(FIRST);
- qdevice(SECOND);
- qdevice(THIRD);
- qdevice(FOURTH);
- qdevice(FIFTH);
-
- qdevice(UPSHIFTKEY);
- qdevice(DOWNSHIFTKEY);
-
- qdevice(QUITKEY);
- qdevice(WINQUIT);
- qdevice(WINSHUT);
- qdevice(WINCLOSE);
- }
-
-
- void Driver::reshape_subwindow(long wid)
- {
- if (wid == _cockpit_win.wid)
- {
- _cockpit_win.left = 0;
- _cockpit_win.right = _parent_win.sizex-1;
- _cockpit_win.bottom = 0;
- _cockpit_win.top = (long)(COCKPIT_TOP*(float)_parent_win.sizey);
-
- _cockpit_win.sizex = _cockpit_win.right - _cockpit_win.left + 1;
- _cockpit_win.sizey = _cockpit_win.top - _cockpit_win.bottom + 1;
- _cockpit_win.orgx = _cockpit_win.left;
- _cockpit_win.orgy = _cockpit_win.bottom;
-
- winset(_cockpit_win.wid);
- winposition(
- _cockpit_win.left,_cockpit_win.right,
- _cockpit_win.bottom,_cockpit_win.top);
-
- reshapeviewport();
- }
- else if (wid == _view_win.wid)
- {
- // will be positioned by the REDRAW
- // limits relative to parent window
- _view_win.left = 0;
- _view_win.right = _parent_win.sizex-1;
- _view_win.bottom = (long)(COCKPIT_TOP*(float)_parent_win.sizey) + 1;
- _view_win.top = _parent_win.sizey - 1;
-
- _view_win.sizex = _view_win.right - _view_win.left + 1;
- _view_win.sizey = _view_win.top - _view_win.bottom + 1;
- _view_win.orgx = _view_win.left;
- _view_win.orgy = _view_win.bottom;
-
- winset(_view_win.wid);
- winposition(
- _view_win.left,_view_win.right,
- _view_win.bottom,_view_win.top);
- reshapeviewport();
- }
- }
-
-
-
- void Driver::event(long dev, short val)
- {
- switch (dev)
- {
- case REDRAW:
- // clear the overlay crap
- winset(_view_win.wid);
- _cockpit->clear_indicators();
-
- // get new size and position info
- winset(_parent_win.wid);
- getorigin(&_parent_win.orgx, &_parent_win.orgy);
- getsize(&_parent_win.sizex,&_parent_win.sizey);
- reshapeviewport();
-
- if (val == _parent_win.wid)
- {
- _redraw_cockpit = _redraw_view = TRUE;
- reshape_subwindow(_cockpit_win.wid);
- reshape_subwindow(_view_win.wid);
- }
- else if (val == _cockpit_win.wid)
- {
- _redraw_cockpit = TRUE;
- reshape_subwindow(val);
- }
- else if (val == _view_win.wid)
- {
- _redraw_view = TRUE;
- reshape_subwindow(val);
- }
-
- break;
-
- case INPUTCHANGE:
- if (val)
- init_colormaps();
- break;
-
- case CLUTCH:
- _cockpit->set_clutch((float)val);
- break;
-
- case BRAKES:
- _cockpit->set_brakes((float)val);
-
- break;
-
- case GAS:
- _cockpit->set_gas((float)val);
-
- break;
-
- case STEERING:
- // scale mouse val, -1.0 to 1.0
- _mouse_x =
- 2.0*((float)(val - _parent_win.orgx)/
- (float)_parent_win.sizex) - 1.0;
-
- // edges window corresponds to an EDGE_DEGREES degree turn
- // steering is positive clockwise
- // steering is saved as radians
- _cockpit->set_steering(EDGE_DEGREES * M_PI/180.0 * _mouse_x);
-
- break;
-
- case VIEWKEY:
- if (val)
- {
- if (_display.view == HELICOPTER)
- _display.view = DRIVER;
- else
- _display.view = HELICOPTER;
-
- _redraw_view = TRUE;
- }
- break;
-
- case DISPLAYKEY:
- if (val)
- {
- if (_display.drawStyle == RENDER_FILLED)
- _display.drawStyle = RENDER_WIREFRAME;
- else
- _display.drawStyle = RENDER_FILLED;
-
-
- const SbPList *car_list=_car->get_simulation()->get_car_list();
- for (int i = 0; i < car_list->length(); i++)
- {
- Car * car = (Car *)(* car_list)[i];
- car->setDrawStyle(_display.drawStyle);
- }
-
- _redraw_view = TRUE;
-
- zbuffer(_display.zbuffer && (_display.drawStyle == RENDER_FILLED));
- backface(_display.drawStyle == RENDER_FILLED);
- }
-
- break;
-
- /*
- case FLAGKEY:
- if (val)
- {
- _display.flags = ! _display.flags;
- _redraw_view = TRUE;
- }
- break;
- */
-
- case SOUNDKEY:
- if (val)
- _car->get_engine()->set_sound(
- _car->get_simulation()->toggle_sound());
- break;
-
- case FOGKEY:
- if (val)
- {
- _display.fog = ! _display.fog;
- if (_display.fog)
- {
- winset(_view_win.wid);
- fogvertex(FG_VTX_EXP,_display.fog_params);
- fogvertex(FG_ON,(float *)NULL);
- }
- else
- {
- winset(_view_win.wid);
- fogvertex(FG_OFF,(float *)NULL);
- }
-
- _redraw_view = TRUE;
- }
- break;
-
- case RESETKEY:
- if (val)
- reset_all();
-
- break;
-
- case HELPKEY:
- if (val)
- {
- qdevice(KEYBD);
- _timer->stop();
- _helping = TRUE;
- _redraw_view = TRUE;
- }
-
- break;
-
- case KEYBD:
- _helping = FALSE;
- unqdevice(KEYBD);
- _redraw_view = TRUE;
- if (! _first_timing)
- _timer->start();
- break;
-
- case IGNITIONKEY:
- // beware of keyboard repeat
- if ((_cranking && (!val)) || ((!_cranking) && val))
- {
- _cranking = val;
-
- // move to beginning
- // Go to neutral - drivers never remember
- if (val && _crashed)
- {
- // remove the car from the stretch it
- // was on
- _car->get_dynamics()->get_stretch(BACK)->remove_car(_car);
-
- // and put it back to the beginning.
- // (reset_to_start adds the car to
- // the stretch)
- _car->get_dynamics()->reset_to_start(
- _car->get_dynamics()->get_stretch(BACK),
- RIGHT);
-
- _car->get_engine()->set_gear(0);
-
- _broken_winshield = FALSE;
- _crashed = FALSE;
-
- _redraw_view = TRUE;
-
- // put helicopter back where car is
- reset_helicopter();
- }
-
- }
- break;
-
- /*
- case REVERSE:
- if (val)
- _car->get_engine()->set_gear(-1);
- break;
- */
-
- case NEUTRAL:
- if (val)
- _car->get_engine()->set_gear(0);
- break;
-
- case FIRST:
- if (val)
- _car->get_engine()->set_gear(1);
- break;
-
- case SECOND:
- if (val)
- _car->get_engine()->set_gear(2);
- break;
-
- case THIRD:
- if (val)
- _car->get_engine()->set_gear(3);
- break;
-
- case FOURTH:
- if (val)
- _car->get_engine()->set_gear(4);
- break;
-
- case FIFTH:
- if (val)
- _car->get_engine()->set_gear(5);
- break;
-
- case UPSHIFTKEY:
- if (val)
- _car->get_engine()->upshift();
- break;
-
- case DOWNSHIFTKEY:
- if (val)
- _car->get_engine()->downshift();
- break;
-
- case WINQUIT:
- case WINCLOSE:
- case WINSHUT:
- _done = TRUE;
- break;
-
- case QUITKEY:
- if (! val)
- _done = TRUE;
- break;
- }
- }
-
-
- void Driver::draw_flags()
- {
- const SbPList *car_list=_car->get_simulation()->get_car_list();
-
- for (int i = 0; i < car_list->length(); i++)
- {
- Car * car = (Car *)(* car_list)[i];
-
- SbVec3f flag[2];
-
- for (int end = BACK; end <= FRONT; end++)
- {
- if (end == FRONT)
- cpack(0xFFFFFF);
- else
- cpack(0xFF);
-
- flag[0] = flag[1] =
- car->get_dynamics()->get_position(end);
-
- flag[1][1] += 5.0;
- bgnline();
- v3f((float *)flag[0].getValue());
- v3f((float *)flag[1].getValue());
- endline();
-
- if (car->get_type() == LOCAL_CAR)
- for (int side = LEFT; side <= RIGHT; side++)
- {
- flag[0] = flag[1] =
- car->get_dynamics()->get_flag(side, end);
-
- flag[1][1] += 5.0;
-
- bgnline();
- v3f((float *)flag[0].getValue());
- v3f((float *)flag[1].getValue());
- endline();
- }
- }
-
- for (int side = LEFT; side <= RIGHT; side++)
- {
- flag[0] = flag[1] =
- car->get_dynamics()->get_side_position(side);
-
- flag[1][1] += 5.0;
-
- bgnline();
- v3f((float *)flag[0].getValue());
- v3f((float *)flag[1].getValue());
- endline();
- }
-
- // draw flag at car center
- flag[0] = flag[1] =
- car->get_dynamics()->get_car_position();
-
- flag[1][1] += 5.0;
-
- cpack(0xFFFFFF);
- bgnline();
- v3f((float *)flag[0].getValue());
- v3f((float *)flag[1].getValue());
- endline();
- }
- }
-
-
-
- void Driver::draw_view()
- {
- if (_display.drawStyle == RENDER_FILLED)
- {
- if (! _display.fog)
- {
- if (_display.zbuffer)
- czclear(SKY_COL,_parent_win.zmax);
- else
- {
- cpack(SKY_COL);
- clear();
- }
- }
- else
- {
- c3f(&_display.fog_params[1]);
- clear();
- if (_display.zbuffer)
- zclear();
- }
- }
- else
- {
- cpack(0);
- clear();
- }
-
- pushmatrix();
- // set the viewing xform
- set_view();
-
- /*
- // XXX kills the frame rate -- need a better terrain
- // model
- // use a very far far so the mountains don't get clipped
- perspective(450, _parent_win.aspect, 1.0, 4000.0);
-
- // XXX Ooooh. I just love cheap hacks.
- if (_display.drawStyle == RENDER_FILLED)
- draw_mountains(
- _car->get_dynamics()->get_yaw(),
- 2000.0, 45.0*_parent_win.aspect*M_PI/180.0);
- */
-
- // back to something reasonable
- perspective(450, _parent_win.aspect, 1.0, 500.0);
-
- // the sun is in world coords, so bind after viewing xform
- if (_display.drawStyle == RENDER_FILLED)
- {
- lmbind(LMODEL,1);
- lmbind(LIGHT0,SUN);
- }
-
- if (_display.view == HELICOPTER)
- {
- // draw the road starting with the stretch one before the one
- // the car is on
- _car->get_road()->draw(
- _car->get_dynamics()->get_stretch(BACK)->get_prev(),
- 0,
- _display.drawStyle,
- (Car *)NULL); // draw all cars including mine
-
- if (_display.drawStyle == RENDER_FILLED)
- {
- lmbind(LMODEL,1);
- lmbind(LIGHT0,SUN);
- }
- }
- else
- {
- // draw the road starting with the stretch the
- // the car is on
- _car->get_road()->draw(
- _car->get_dynamics()->get_stretch(BACK),
- _car->get_dynamics()->get_marker(BACK),
- _display.drawStyle,
- (Car *) _car); // draw all cars except mine
- }
-
- if (_display.flags)
- draw_flags();
-
- popmatrix();
-
- // hood is drawn relative to eye position
- if (_display.view == DRIVER)
- _cockpit->draw_hood(_display.drawStyle);
-
- if (_broken_winshield)
- draw_crash();
- }
-
-
- void Driver::draw()
- {
- if (_redraw_view)
- {
- winset(_view_win.wid);
-
- if (_helping)
- draw_help(_parent_win.sizex, _parent_win.sizey);
- else
- draw_view();
-
-
- swapbuffers();
- }
-
- winset(_cockpit_win.wid);
-
- if (_redraw_cockpit) // only draw static portions if necessary
- _cockpit->draw_cockpit((int)_cockpit_win.sizex);
-
- // indicators get drawn in the pup planes
- _cockpit->draw_indicators(FALSE);
- }
-
-
- // XXX Use Inventor camera positioning
- void Driver::set_view()
- {
- SbMatrix orientation;
-
- // turn the quaternion into a rotation matrix
- _car->get_dynamics()->get_view_orientation().getValue(orientation);
-
- const SbVec3f car_pos = _car->get_dynamics()->get_car_position();
- const SbVec3f eye_pos = _car->get_dynamics()->get_eye_position();
-
-
- // if first time, fill up the circular buffer
- if (_helio_fill_index == _helio_use_index)
- {
- for (int i = 0; i < _helio_lag; i++)
- {
- _helio_orientation[_helio_fill_index] = orientation;
- _helio_position[_helio_fill_index++] = - car_pos - eye_pos;
- }
-
- _helio_use_index = 0;
- _helio_fill_index = _helio_lag - 1;
- }
-
- _helio_orientation[_helio_fill_index] = orientation;
- _helio_position[_helio_fill_index++] = - car_pos - eye_pos;
- _helio_fill_index %= _helio_lag;
-
- if (_display.view == HELICOPTER)
- {
- rotate(184,'x');
- translate(_helio_offset[0], _helio_offset[1], _helio_offset[2]);
-
- multmatrix((Matrix) &_helio_orientation[_helio_use_index][0][0]);
- translate(_helio_position[_helio_use_index][0],
- _helio_position[_helio_use_index][1],
- _helio_position[_helio_use_index][2]);
- }
- else // _display.view == DRIVER
- {
- multmatrix((Matrix) &orientation[0][0]);
- translate(-car_pos[0], -car_pos[1], -car_pos[2]);
- translate(-eye_pos[0], -eye_pos[1], -eye_pos[2]);
- }
-
- // increment even if not used so helicopter doesn't sit still
- // when view first invoked
- _helio_use_index = (_helio_use_index + 1)%_helio_lag;
-
- }
-
-
- void Driver::reset_helicopter()
- {
- // set the circular list pointers to the same place
- // this makes the list empty, and puts the helicopter right
- // behind the car
- _helio_fill_index = _helio_use_index = 0;
- }
-
-
- void Driver::reset_all()
- {
- _helio_fill_index = _helio_use_index = 0; // in circular list
-
- _cranking = FALSE;
- _crashed = FALSE;
- _crash_handled = FALSE;
- _broken_winshield = FALSE;
-
- _car->get_engine()->reset_all();
-
- // remove the car from the stretch it is on
- _car->get_dynamics()->get_stretch(BACK)->remove_car(_car);
-
- // and put it back to the beginning
- _car->get_dynamics()->reset_to_start(_car->get_road()->get_start(), RIGHT);
-
- _redraw_view = TRUE;
-
- _timer->reset();
- _first_timing = TRUE;
- }
-
-
- void Driver::handle_crash()
- {
- _car->get_engine()->stall(FALSE); // don't play stalling noise
-
- if (_car->get_simulation()->play_sound())
- playsample(_crash_noise);
-
- _crash_handled = TRUE;
- }
-
-
- // draw the windshield breaking
- void Driver::draw_crash()
- {
- const int LEGS = 10;
- const float WANDER = 5.0;
- float a[2], b[2];
-
- ortho2(-.5,.5,-.5,.5);
-
- srand48(0); // make the windshield always look the same
-
- float theta = 0.0;
-
- for (int leg = 0; leg < LEGS; leg++)
- {
- a[0] = a[1] = 0.0;
- for (float r = .1; r <= 0.75; r += .1)
- {
- b[0] = r*fcos(theta) + (drand48()-.5)/WANDER;
- b[1] = r*fsin(theta) + (drand48()-.5)/WANDER;
-
- cpack(0xFFFFFF);
- bgnline(); v2f(a); v2f(b); endline();
-
- a[0] = b[0]; a[1] = b[1];
- }
-
- theta += 2.0*M_PI/(float)LEGS;
- }
- }
-
-
- void Driver::timed_draw(Boolean include_in_avg)
- {
- SbTime time;
- long sec;
- static SbTime start, end, s, e;
- static long frame_count = 0;
-
- // minimum average fps
- const float MIN_FPS = 4.0;
-
- // maximum individual frame time, in microseconds
- // need this to prevent audio from trying to play when
- // a long redraw occurs
- const float MAX_FRAME_TIME = 125000.0;
-
- // frames to count when computing FPS
- const int SAMPLE_FRAMES = 10;
-
- s = SbTime::getTimeOfDay();
- draw();
- e = SbTime::getTimeOfDay();
-
- if (include_in_avg && (frame_count % SAMPLE_FRAMES) == 0)
- start = s;
-
- // find last frame time in microseconds
- // bold assumption that we are getting at least 1 fps
- time = e - s;
- time.getValue(sec, _last_frame_time);
-
- // ignore outrageouse frame times
- if (_last_frame_time > MAX_FRAME_TIME)
- _last_frame_time = MAX_FRAME_TIME;
-
- if (include_in_avg && ((++frame_count % SAMPLE_FRAMES) == 0))
- {
- long u_sec;
- float seconds;
-
- end = e;
-
- time = end - start;
- time.getValue(sec, u_sec);
- seconds = (float)sec + (float)u_sec/1000000.0;
-
- float fps = SAMPLE_FRAMES/seconds;
-
- if (fps > MIN_FPS) // ignore outrageous times
- _fps = fps;
- }
-
- _redraw_cockpit = _redraw_view = FALSE;
- }
-
-
- // Being the only car (only_car == TRUE) implies that it
- // is OK for this routine to go to sleep if nothing is happening.
- // Otherwise, must go back and update all other cars.
- void Driver::update(Boolean only_car)
- {
- static Boolean moving = FALSE;
- static Boolean revving = FALSE;
-
- long any_events = qtest();
-
- while
- ((! _done) &&
- (any_events ||
- (only_car && (!_cranking)&&
- (! moving)&&(! revving)&&(! _redraw_view)&&(!_redraw_cockpit))))
- {
- long dev; short val;
-
- // need to redraw once before going to sleep
- // so speedo will get to zero
- if ((! any_events) && (! moving))
- timed_draw(FALSE);
-
- dev = qread(&val);
- event(dev,val);
-
- if (only_car &&
- (! moving) && (! revving) && (! _crashed) && (! _helping))
- {
- _car->get_engine()->update();
- revving = _car->get_engine()->revving();
-
- _car->get_dynamics()->update();
- moving = _car->get_dynamics()->moving();
- }
-
- any_events = qtest();
- }
-
- if ((! _crashed) && (! _helping))
- {
- _car->get_engine()->update();
- _car->get_dynamics()->update();
- }
-
-
- if (only_car)
- {
- revving = _car->get_engine()->revving();
- moving = _car->get_dynamics()->moving();
-
- if (! _redraw_view)
- _redraw_view = moving;
- }
- else
- // if other cars are on the road, always redraw
- _redraw_view = TRUE;
-
- if (_crashed && (! _crash_handled))
- {
- // stall the engine, play the crashing noise
- handle_crash();
-
- _broken_winshield = TRUE;
- _crash_handled = TRUE;
- _redraw_view = TRUE;
- }
- else if (_cranking)
- _car->get_engine()->crank(TRUE);
-
-
- if (_first_timing && _car->get_engine()->get_gear() >= 1)
- {
- _timer->start();
- _first_timing = FALSE;
- }
-
- _timer->update();
-
- if (_redraw_cockpit || _redraw_view || moving || revving)
- timed_draw(TRUE);
- }
-