Hi Alex,

> > >     // Start the message loop.
> > > 
> > >     while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
> > >     {
> > >         if (bRet == -1)
> > >         {
> > >             // handle the error and possibly exit
> > >         }
> > >         else
> > >         {
> > >             TranslateMessage(&msg);
> > >             DispatchMessage(&msg);
> > >         }
> > >     }
> > > 
> > > Looking at that above, I would say that DispatchMessage is what causes the
> > > message to be processed (see (a) above).
> > 
> > Excellent- now we're getting somewhere! What does TranslateMessag() do?
> > What do the other parameters go GetEvent() mean? Is it possible to specify
> > a timeout there?
> 
> TranslateMessage() is just something you need to do. But if you really want to 
> know: "The TranslateMessage function translates virtual-key messages
>    into character messages. The character messages are posted to
>    the calling thread's message queue, to be read the next time the
>    thread calls the GetMessage or PeekMessage function." (Platform SDK docs)

OK, so we can skip that here, since we're only using custom messages for
these.

> Other parameters to GetMessage():
> 
> BOOL GetMessage(
>       LPMSG lpMsg,         // message information (a)
>       HWND hWnd,           // handle to window (b)
>       UINT wMsgFilterMin,  // first message (c)
>       UINT wMsgFilterMax   // last message (d)
>     );
> 
> (a) Pointer to a MSG structure that receives message information from the 
> thread's message queue. This allows us to access WPARAM and LPARAM (the data) 
> right here. Makes me wonder why we'd need a callback function at all since we'd 
> be able to process all messages in this loop in the server. I'll check if we need 
> one when I get home later.

Good question indeed...

> There is no way you can specify a timeout using one these calls. It'd be a case 
> of endlessly looping PeekMessage() and then retrieving the message (by using 
> GetMessage()) and processing it. And perhaps sleeping every so often if this 
> takes up a lot of CPU time.

That's not particularly efficient and won't give us good timing. What we
could use would be a third thread for timing (is this what you suggested
in one of your previous mails?) like this:

main       timer       snd
 |           |           |
 |           \Playnote-> +
 |           |           |
 +SetVolume->+---------->*
 |           |           |
 v           v           v


i.e. 'snd' would start 'timer', which main would send its commands to (so
that they reach 'snd' instead); also 'timer' just sleeps and sends
"TIMER_TICK" 60 times per second (or whenever needed, if possible) 
messages to itself, also causing 'snd' to process them.

So 'main' would be pretty much unchanged, 'timer' would look like this:

while (1) {
        sleep(16.666ms);
        SendMessage(self, TIMER_TICK, 0, 0);
}


and 'sound' would look vaguely like this:


while( (GetMessage( &msg, NULL, 0, 0 )) != 0) {
        if (msg.type == TIMER_TICK)
                snd_do_sound();
        else
                snd_process_command(convert_message_to_freesci_format(msg));
}


It's still not particularly elegant, though.

BTW, how bad are the problems with the current sound implementation,
anyway?

llap,
 Christoph


Reply via email to