home *** CD-ROM | disk | FTP | other *** search
- #pragma once
- //
- // Note: instances of class 'vretrace should _never_ be allocated on a relocatable block!
- // It also is unadvisory to forget to call 'stop' for an instance of vretrace for which
- // 'start' has been called. If that is done the VBL routine will be called after the
- // program which installed it has quit. This will sooner or later crash your machine.
- //
- // 950330:
- //
- // In article <jens_alfke-2803951102300001@jensothermac.apple.com>, jens_alfke@powertalk.apple.com (Jens Alfke) wrote:
- //
- // > In article <kastork-2803950428450001@slb140.cc.nps.navy.mil>,
- // > kastork@nps.navy.mil (Kirk A. Stork) wrote:
- // >
- // > > Don't constructors have to be public?
- // >
- // > No. A protected or private constructor is useful, as it prevents just
- // > anyone from creating an object of that class. If it's private, only a
- // > method of the class can create new objects (presumably you need a public
- // > static method to create the first one!). If it's protected, you can create
- // > subclasses that have public constructors.
- // > Similarly, you can make a class' operator new private, which prevents it
- // > from being allocated on the heap.
- // >
- // >
- // > Jens Alfke_________OpenDoc Geometer_________jens_alfke@powertalk.apple.com
- // > OpenDoc info: FTP to CILabs.org
- // >
- // > Visit Scenic Flood Control Dam No. 3.
- //
- // This is something to be implemented in the future.
- //
- // 940204: Although the destructor does call 'stop' when needed programs using
- // multiple vretrace instances do 'enter MacsBug' (some people call that 'crash')
- // regularly with a message 'spurious interrupt'. I am not sure whether this is due
- // to class vretrace, but calling 'stop()' for every start instance seems to prevent
- // these visits to MacsBug. A hunch tells me that SC++ occasionaly optimizes out
- // or forgets to call the (inline) destructor calls.
- //
- // BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT
- //
- // 950814: KNOWN BUG: the constructor vretrace::vretrace( const short how_often)
- // assumes that the current graphics device belongs to a physical screen and has
- // a vertical retrace queue associated with it. It uses the current graphics port
- // to determine for which device the vertical retrace task should be installed.
- //
- // BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT
- //
- #ifndef __CONDITIONALMACROS__
- #define VBLUPP VBLProcPtr
- #define NewRoutineDescriptor(theProc, theProcInfo, theISA) (theProc)
- #endif
-
- double framerate_of_main_monitor( void);
- double monitor_framerate( GDHandle the_gDevice);
-
- #pragma options align=mac68k
-
- class vretrace
- {
- public:
- //
- // defaults: main monitor (often the only one)
- //
- vretrace( const short how_often = 1);
- vretrace( GDHandle thegDevice, const short how_often = 1);
-
- ~vretrace();
- int start(); // returns error code from SlotVInstall
- int stop(); // returns error code from SlotVRemove
-
- void set_interval( const short new_interval);
- //
- // reset() resets the counter and returns its old value;
- //
- unsigned long reset( const unsigned long new_value);
-
- unsigned long operator()();
- //
- // The 'sync' members synchronise on a VBL using a busy loop.
- // The integer returned is the new current value of the counter
- //
- unsigned long sync( const unsigned long count = 1);
- void sync_till( const unsigned long count);
-
- static short getslot( const GDHandle gDev);
-
- private:
- static VBLUPP theVBLProcPtr;
-
- static VBLUPP allocateVBL( void);
-
- int is_running;
- //
- // Note: the following three fields _must_ be kept together in
- // this order (the VBL proc depends on this)
- //
- // 940211: Finally think I found the bug which was dormant for
- // weeks (and very awake for the last week or so): numtimes_run
- // should be allocated volatile since the VBL proc will change it.
- // (well, it was a bug, but it apparently still was dormant)
- // offset from 'myVBLTask'
- short the_interval; // -0x06
- volatile unsigned long numtimes_run; // -0x04
- VBLTask myVBLTask; // -0x00
-
- short mySlot;
-
- void init( const short theSlot, const short how_often);
- };
-
- #pragma options align=reset
-
- inline vretrace::vretrace( const short how_often)
- {
- init( getslot( GetGDevice()), how_often);
- }
-
- inline vretrace::vretrace( GDHandle thegDevice, const short how_often)
- {
- init( getslot( thegDevice), how_often);
- }
-
- inline vretrace::~vretrace()
- {
- if( is_running)
- {
- (void)stop();
- }
- }
-
- inline void vretrace::set_interval( const short new_interval)
- {
- the_interval = new_interval;
- }
-
- inline unsigned long vretrace::operator()()
- {
- return numtimes_run;
- }
-
- inline double framerate_of_main_monitor( void)
- {
- return monitor_framerate( GetMainDevice());
- }
-