Tuesday, February 20, 2018

Thread the Needle

So today was the day. I decided to get the 1Ch thread working once and for all, only to have is spectacularly blow up in my face. Turns out, threads are hard, and when you introduce them to code that was never designed for them, it becomes a gigantic mess.

 Here's a little synopsis to get people up to speed.

In the original game there was a function that was attached to interrupt 28. In hexadecimal this is 1C, which is why I call it the 1Ch thread. How the interrupt originally worked was every 55 milliseconds game control was taken away and the interrupt would update various variables and things on the screen. Then it would give control back to the main game again. ROE is funny because it doesn't really have a "main loop" like you would assume. The game is screen based and each screen has it's own input loop. When the input is captured the state of the screen is changed.  The "master" loop is actually the interrupt that runs independently of the screens.

Because interrupts are not available and I couldn't use a program loop to poll events, I decided to use a thread that just woke up every 55 milliseconds, did it's thing and went to sleep. The original interrupt was controlled  by globals that directed what parts would run. I used the same variables to control my thread.

Everything seemed to work fine. My first hurdle was to gracefully kill the running thread at shutdown. Normally just returning from the function killed the thread, but I set mine up to run forever in a while() loop. Because the thread also contained allegro drawing functions, when I shut down allegro on exit, the thread would crash. Using a no control global I was able to get the game to exit gracefully. Look OK so far.

The thread is corrupting my blits :(
But it's the thread's drawing functions that are wrecking havoc on my game. In the original game, when the interrupt took control, everything stopped. My thread, however, can run at the same time as the game, and actually execute the same function that is currently being run. This is causing my drawing buffers to be snatched away by the thread as things are being drawn and making garbage get drawn everywhere. (That or crashing the game entirely)

I'm going to need to implement a mutex, which is a thing I learned today, so that I can politely wait until the drawing surface is clear so I can write to it with my thread. How fun.

I knew that was going to be hard. I was warned about using a thread too. I didn't exactly think it would cause everything to blow up in my face though.

No comments:

Post a Comment