On Solaris, usleep is not thread-safe and will introduce a race
condition when used in a multithreaded environment. This manifests as
SIGALRM signals escaping from its internal call to sigsuspend. If a
signal is missing a handler, the process dies upon receiving it,
crashing.
The Solaris libc code does something rougly equivalent to this:
PreserveSignalHandlers(...);
/* Effectively NOPs out SIGALRM */
DisableSIGALRM(...);
SetTimer(...);
/* Suspends the thread until it receives a SIGALRM signal. When it
receives this signal, it both wakes up *and* receives the
signal. In this case we don't want to do anything but wake up,
so the SIGALRM handler is a NOP.
*/
sigsuspend(...);
RestoreSignalHandlers(...);
return;
The consequences of this code in a multithreaded context is that if
two sleeps are in progress at the same time, one will necessarily
finish before the other, *restore the non-existant handlers*, and go
on doing its thing. When the other sleep finishes, it won't have a NOP
handler to call when waking up, a handler is searched for, none is
found, and thus we crash.
The game appears to render level tiles as 16x16 pixel tiles, and many
of these do not require any transparency. So we now compute which
tiles are completely opaque and store those in a set, so that when we
draw them we can skip color keying.
Declaring a "register variable" isn't allowed in modern C++ so I ditch
that in the path that my dev machine compiles.
I *should* remove them from both and update GCC on the Sun to as new
as possible, but I'm not going to do that because that sound painful,
so this is what it is.
The main justification for this is that normal behaviour from a
backend is to have the main thread be interrupted by the audio system
and to then stay within the audio system while getting audio
frames. Parking the main thread simulates this by ensuring nothing
else happens in the game's logical flow at the same time.
Fixes screen-tearing in CSE2EX
...I should really figure out whether to enable vsync on other
platforms or not. I'm not even sure if the original DirectDraw
renderer used vsync - I swear I've never seen tearing in it before.