I have spent a big part of my free time on this and there are some updates (mostly bad ones):
I decompiled parts of the code that deal with animation files (*.ani). Looks like there is just a variable number of animations packed into that *.ani file. For example, for people moving on the streets (say kids_m_sma.ani) there would be 8 animations that correspond to movement in each direction. For people's movement inside the restaurant (fe. kids_m_big.ani), there would be 8 animations for movement, 4 animations for sitting at the table, and 4 animations for eating. "Animation" itself is just a sequence of 24 sprites. Each of them of course in that stupid compressed SPR format seen in the previous post. So it's impossible to do anything with these animations without understanding the compression algorithm apart from changing movement speed. Which I did, but there is not much sense in that anyway).
And regarding the SPR files: I actually found some pieces of code that process the compressed part I showed in the previous post. But I have no clue what is going on there.
I found out it generates a new array of 512 bytes in size from the last 768 bytes in the SPR file (which I assumed to be a color palette) and uses it somewhere.
Then it iterates through the compressed part. "FF" values from the previous post are some kind of "separators". It would read that array from one "FF" byte to another, doing something with the byte which comes just after "FF" - either of 05/03/02/01 in this case. And then processing the rest of the values till the next "FF" value.
Here is another good example of 3 sprites with small size, same shape but different colors:
m_kids.spr,
m_teens.spr,
m_studies.spr.
Corresponding in-game images for kids, teens and studies (sprites are probably without background):

Both parts of SPR files are different when I compare them. But the first part is somewhat similar. It's only that "separator" that is different.
The game is using ddraw.dll and DirectX 7. Maybe it's some kind of format that this DDRAW thing renders automatically and I'm digging too deep missing something obvious?
To finish the post on a positive note, I managed to relatively easily decompile the code that sets and displays building attendance numbers. They are all hard-coded into an exe file, so binary patch is required. I did that and managed to make a train station "alive". This empty train station has always been super irritating and illogical to me. Now it's full of people!

I am not sure how to share the details on what bytes need to be patched as the offsets probably depend on the game version. But if anyone is interested, just drop me your exe file and I can do it.
I also accidentally found the code which calculates income when pizza is served to the customer (from some hard-coded strings the developers have left for debugging purposes

). It revealed each served customer is counted as 100 pizzas sold. But what is more interesting, there are hidden tips percentage coefficients for each customer group. Which are added to each of these 100 sold pizzas. I find this both fascinating and illogical. Fascinating because it's not mentioned anywhere I had no clue something like this was happening while I was playing the game for the last 20 years. And illogical because tips is something that waiters get - and not the restaurant owner.
Oh, and I found a way to enable fps indication which was used by developers/testers to check performance back in a day. Cool, but kind of useless thing
