Click here to return to "Plan C - Make Coalcar Optional".
The original "accident mode" in the C-version of "sl" has a couple of stick figures in the windows of the C51 and D51 trains, hollering "Help!". We should be able to emulate that behavior.
The C-version of "sl" has a drawing function for each type of train it can draw; a function for the D51, and one for the C51, and one for the Little train. This is how we started to write out version of "sl", but then we opted to write just one drawing function, and to feed to it the various images in the form of a vector of String vectors holding the drawing. In the C-version, each of these functions calls an "add_man" function when the "accident mode" is invoked. Here's what that call looks like for the C51 function in the C-version of "sl":
This code basically says that when the ACCIDENT mode is enabled, call the "add_man()" function twice, with the location to add a man being at 3 rows down from the top of the train, and 45/49 columns from the left-nose of the train.
Then the C-version of that "add_man()" function looks like this:
This function recieves an (Y,X) coordinate for drawing a man, and depending on some math, draws either the word "Help!" next to a tick-figure head with arms raised high, or no word with a stick-figure head with hands wrapped around the face in an "Oh No!" posture.
Now that we know the basic idea, we can do the same in our Rust version of "sl".
Each time we draw a frame of an image, we'll need to check to see if "accident mode" has been enabled and call an "accident()" function if so. We can call custom accident functions depending on the image that is being animated.
And then we'll need the actual accident function. Here's a dummy function for testing:
The above code should flash "RED ALERT!" in the top-left of the terminal window every 14th column as the train animates across the screen (when "col" divided by 14 has no remainder). I just picked "14" randomly; feel free to try other numbers; this is just a temporary test to make sure the basic logic/code works. Different math will get you different results. For example, try this:
if col %21 == 0 { mv(2, 2); addstr("RED ALERT!"); } elseif col % 7 == 0 { mv(2, 2); addstr(" "); }
Now let's change our message, and the location of the message. Because our message will be moving with the train, it might sometimes be off-screen. Therefore, we want to use our custom "my_mvaddstr" to prevent trying to display the parts of the message that might be off-screen. That means we'll have to provide the screen dimensions to the function:
and ...
But when we run this (with something like $ cargo run -- --oops
), not only is the "Help!" message flashing too fast, the program crashes as soon as the "Help!" message gets off-screen.
Looking at the "my_mvaddstr()" function, I see pretty quickly why the program is crashing. As the image moves off the left side of the screen, the line of the image being displayed is trimmed shorter and shorter; the "Help!" line, being shorter to begin with than the rest of the train, gets cut down to nothing, and then the cutting keeps going further into a string that has already been cut to nothing. This causes the crash. The easy fix is to put a check into the code, to make sure the string is not already down to nothing before trimming it further:
I've been rethinking this project, and I think I'm ready to move on to Plan D.