[comp.sys.mac.programmer] Game input -- Bypassing GetNextEvent

davet@cmi.com (David Temkin) (05/01/91)

I've run into a problem with a game I'm developing. The game is one of 
those "take-over-the-screen" arcade-type games, and I don't use the mouse 
pointer as such, although I do read the mouse for input.  Currently, the 
technique I use to read the keyboard and mouse is very simple, and it 
nearly works: I call GetNextEvent frequently. These are the problems: 

   1. Under Multifinder, if the user clicks in the upper right of the menu 
bar (although neither the menu bar nor the pointer is visible), the game 
application can be "switched out," which causes all kinds of problems, 
owing mainly to the fact that I'm writing directly to the screen and I 
want the cursor to be invisible. Is there a legitimate way of removing the 
menu bar? How do other games take over the screen in a foolproof manner?
    2. Screen savers: These will kick in of their own accord as a result 
of calling GetNextEvent a certain number of times without an event 
occurring. BUT, since I write directly to the screen and refresh most of 
the screen every time, this can be unsightly -- particularly since I use 
double-buffering when the hardware allows it.
   3. I need a way of changing the mouse's location. I'm aware of the low 
memory mouse globals and all that; it seems to work fine. Question: Is 
there a way of reading the movements of the mouse at a lower level, i.e. 
before they've been converted into coordinates? This would be most helpful.
   4. Calling GetNextEvent is slow. According to the THINK C profile, the 
game spends an inordinate amount of time doing this. What are the 
alternatives? Other than suspending certain types of background 
processing, what would this break? Would it be safe to repeatedly
read the low-memory globals for the mouse and, say, call GetKeys to read 
the keyboard? (the low memory keyboard map doesn't seem to get updated 
unless GetNextEvent gets called).

Anyway, I'm interested in hearing people's experiences with these issues. 
How do other games out there handle these problems? What are the 
consequences/techniques for bypassing the event manager altogether? 
Although I don't intend this game to be a very "cooperative" (windowing) 
application, I would like to ensure that it at least does not crash or 
cause any other serious problems under Multifinder and System 7. 
Suggestions?













David Temkin
Center for Machine Intelligence, EDS Corp.
davet@cmi.com

2fmlcalls@kuhub.cc.ukans.edu (05/01/91)

In article <10219@etsu.CMI.COM>, davet@cmi.com (David Temkin) writes:
> Anyway, I'm interested in hearing people's experiences with these issues. 
> How do other games out there handle these problems? What are the 
> consequences/techniques for bypassing the event manager altogether? 
> Although I don't intend this game to be a very "cooperative" (windowing) 
> application, I would like to ensure that it at least does not crash or 
> cause any other serious problems under Multifinder and System 7. 
> Suggestions?
> 
> David Temkin
> Center for Machine Intelligence, EDS Corp.
> davet@cmi.com

I encountered the same problems.  I took the don't-call-WNE-just-GetKeys-
and-GetMouse approach for the same resons you mentioned.  I too am bothered by
this approach.  I didn't do it out of arrogance, but because I know of no other
way.  And besides - games are exceptions :).

I can tell you that the method seems to work sans hitch under System 7 and
MultiFinder as well.  Unless someone with more experience can straighten us out
(?) I've found you can safely use this method.

john calhoun
'when we find what we want then who will turn out the light?'
r.e.m. 

hairston@henry.ece.cmu.edu (David Hairston) (05/02/91)

[davet@cmi.com (David Temkin) writes:]
[] Anyway, I'm interested in hearing people's experiences with these issues. 
[] How do other games out there handle these problems? What are the 
[] consequences/techniques for bypassing the event manager altogether? 
[] Although I don't intend this game to be a very "cooperative" (windowing) 
[] application, I would like to ensure that it at least does not crash or 
[] cause any other serious problems under Multifinder and System 7. 
[] Suggestions?

[2fmlcalls@kuhub.cc.ukans.edu writes:]
[] I encountered the same problems.  I took the don't-call-WNE-just-
[] GetKeys-and-GetMouse approach for the same resons you mentioned.  I too
[] am bothered by this approach.  I didn't do it out of arrogance, but
[] because I know of no other way.  And besides - games are exceptions :).
[]
[] I can tell you that the method seems to work sans hitch under System 7 and
[] MultiFinder as well.  Unless someone with more experience can straighten
[] us out (?) I've found you can safely use this method.

just curious ...
why not make your app use a window that uses DBoxProc?  this way you
can use WNE to your hearts content since MultiFinder will not swap you
out while the DBoxProc window is in front.  I'm not sure how this
affects speed, tho.  i'm also assuming that your window will cover the
entire desktop which allows you pull another stunt to get rid of the
menubar since you know you're on top and nothing else is visible
(essentially MBarHeight = 0 and yourWindow->visRgn = yourWindow->portRect
where portRect covers the entire screen).  when you're done (that is
when you're ready since nothing will swap you out) simply closing the
window will update whatever was behind it.  oh yeah, don't forget
MBarHeight = saveMBH.  the benefit here is that you allow background
tasking by calling WNE regularly.  so why not do it this way?

  -dave-  
hairston@henry.ece.cmu.edu

d88-jwa@byse.nada.kth.se (Jon W{tte) (05/02/91)

In article hairston@henry.ece.cmu.edu (David Hairston) writes:

(Hi, Dave ! :-)

   just curious ...

   why not make your app use a window that uses DBoxProc?  this way you
   can use WNE to your hearts content since MultiFinder will not swap you
   out while the DBoxProc window is in front.  I'm not sure how this
   affects speed, tho.  i'm also assuming that your window will cover the

WaitNextEvent will a) take time and b) let other program calculate in
the background, even if no major context switch is made. The minor
switch still takes time, since all lo-mem globals have to be shuffled.

   MBarHeight = saveMBH.  the benefit here is that you allow background
   tasking by calling WNE regularly.  so why not do it this way?

Hey, they're talking action games...

--
						Jon W{tte
						h+@nada.kth.se
						- Power !

hairston@henry.ece.cmu.edu (David Hairston) (05/03/91)

[hairston@henry.ece.cmu.edu (David Hairston) writes:]
[] why not make your app use a window that uses DBoxProc?  this way you
[] can use WNE to your hearts content since MultiFinder will not swap you
[] out while the DBoxProc window is in front.
[] ...
[] MBarHeight = saveMBH.  the benefit here is that you allow background
[] tasking by calling WNE regularly.  so why not do it this way?

[d88-jwa@byse.nada.kth.se (Jon W{tte) writes:]
[] (Hi, Dave ! :-)

ummm, we have to stop meeting like this ... ;)

[d88-jwa@byse.nada.kth.se (Jon W{tte) writes:]
[] Hey, they're talking action games...

well, my gut response is that action games should still be cooperative.
if you find that you cannot run action game x because you're doing too
much background processing then the user should voluntarily stop the bg
applications.  i think this is preferred to the alternative of having
action game x unilaterally stop the bg apps.  cooperative multitasking
requires cooperation!

btw, an action game can determine if it is not running at a desirable
rate and in the extreme could simply complain that the machine is too
busy at the moment and "would you like to quit?" ...

  -dave-  
hairston@henry.ece.cmu.edu

d88-jwa@byse.nada.kth.se (Jon W{tte) (05/03/91)

In article <> hairston@henry.ece.cmu.edu (David Hairston) writes:

         MBarHeight = saveMBH.  the benefit here is that you allow background
         [] tasking by calling WNE regularly.  so why not do it this way?

      Hey, they're talking action games...

   well, my gut response is that action games should still be cooperative.
   if you find that you cannot run action game x because you're doing too
   much background processing then the user should voluntarily stop the bg
   applications.  i think this is preferred to the alternative of having
   action game x unilaterally stop the bg apps.  cooperative multitasking
   requires cooperation!

The problem with this is that WNE is pretty slow even if there are no
other background apps that want time. There's a lot of overhead
involved, and to get decent speed on a classic or LC...

Maybe an option ?

--
						Jon W{tte
						h+@nada.kth.se
						- Power !

deadman@garnet.berkeley.edu (Ben Haller) (05/05/91)

In article <D88-JWA.91May3101138@byse.nada.kth.se> d88-jwa@byse.nada.kth.se (Jon W{tte) writes:
>In article <> hairston@henry.ece.cmu.edu (David Hairston) writes:
>   well, my gut response is that action games should still be cooperative.
>   if you find that you cannot run action game x because you're doing too
>   much background processing then the user should voluntarily stop the bg
>   applications.  i think this is preferred to the alternative of having
>   action game x unilaterally stop the bg apps.  cooperative multitasking
>   requires cooperation!
>
>The problem with this is that WNE is pretty slow even if there are no
>other background apps that want time. There's a lot of overhead
>involved, and to get decent speed on a classic or LC...

  Also, MultiFinder is a little unpredictable.  It seems to just go out to
lunch occasionally, and it changes its mind about how much time to give to
the foreground app, *even* when that's the only app running (i.e. the
Finder).  Also, people do strange and time consuming things in the
background, so you don't want to give them time.  For instance the System
7.0 Finder appears to do several SetTrapAddress calls (believe it or not!)
every time through its event loop, as well as a SetCursor, etc.  Even if
these things are patched out by MultiFinder, they do take time.
  My personal policy is to call GetOSEvent to get keyboard events and such,
and munge with the low-memory globals to get the mouse position (ever
disassembled GetMouse() - under System 7.0, my god what a mess, it has a
come-from test and everything...!)
  Never call SystemTask unless you want little menu bar clocks, screen
savers, etc. punching through your pretty full-screen display.
  As far as getting cursor information *directly*, yes, you could patch the
cursor vectors, but these are not guaranteed to change, to say the least.
Still I know I guy who has done it so many times he doesn't even blink
anymore (actually he *does* blink, just not at that...)
  Finally, why call GetKeys?  It is more compatable and all, but if we're
interested in raw speed, why not?  And besides that rather stupid excuse, a
(possibly) more intelligent excuse is that so many people do it already
that Apple would never break it.  And if they did break it, to support
bigger keyboards, 2-byte characters, etc., I can't see how they would avoid
breaking GetKeys anyway.  Actually, I'm being a bit of a Devil's Advocate
here, since I firmly believe that access routines should always be called
because then one can patch the access routines... :->  But since patching
for such purposes is generally considered *worse* than using low-memory
globals, why call GetKeys?

-Ben Haller (deadman@garnet.berkeley.edu)
"Whatever" - Anon.

d88-jwa@alv.nada.kth.se (Jon W{tte) (05/05/91)

In article <> deadman@garnet.berkeley.edu (Ben Haller) writes:

   because then one can patch the access routines... :->  But since patching
   for such purposes is generally considered *worse* than using low-memory
   globals, why call GetKeys?

Because GetKeys is supported under A/UX, and KeyMap is not. Simple.

I know of at least one major action game (as yet unpiblished) that
runs well under A/UX (only losing a few frames of animation now & then)
so I guess that's the kind of compatibility you can demand these days.

--
						Jon W{tte
						h+@nada.kth.se
						- Power !