Week 9

At the ninth week I have done:

  • partial implementation of ActionText. The code will be pushed when the main problems will be fixed.

A big thanks to Eugene Sandulenko for implementing the menu.

Problems with menu:

  1. Sounds and sprite timers don’t pause.
  2. No support for a multi-level menu.
  3. Menu content is hardcoded. To solve this a menu parser from exe will be written.

Problems with ActionText:

  1. no text because MacText doesn’t support unicode strings;
  2. no support for non-scrollable action text.

ActionText

Week 8

Nothing to show this week, besides some bugfixes.

 

Implementing menu and ActionText requires changes to ScummVm’s macgui class, as it is not suitable for Pink Panther games.

Beside this, I have started reverse engineering Pilot Brothers games. github

The engine of those games is bytecode interpreter with its own memory allocator and buffer for the file.  Compared to Panther engine, this hasn’t any additional info in exe. The only advantage is that it is much smaller.

Week 7

At the seventh week I have done:

 

  1. implemented Peril’s PDA commands
  2. implemented Peril’s PDA hardcode(thumb moving)
  3. code cleanup
  4. bugfixes

Finally the engine brach was merged with ScummVm’s main repository. Testers are welcome to download ScummVm from buildbot and test Pink Panther games.

Advantages over original engine:

1) Very low CPU usage even with scaling. The original engine doesn’t have a delay after each frame, so it consumes whole core.

2) Passport To Peril supports sound balance.

3) All advantages which ScummVm offers(scaling, cross-platform, etc)

So what’s left:

  1. Game menu.
  2. ActionText

These features don’t affect gameplay because ActionText is used only in PDA and menu is just needed to quickly navigate through PDA.

Week 6

At the sixth week I have done:

 

  1. fixes of game bugs. Thanks, Henke37 for bug reports.
  2. code cleanup
  3. implemented recalculation of walking sprites.
  4. added debug commands to list/goto modules, pages, to look/set variables, to add items.

This is how walking looked like before implementing frames recalculation:

After:

I have opened the pull request to merge engine with ScummVm’s repository.

Next week I will implement the game menu.

Week 5

The fifth week was very productive.

I have done:

 

  1. rewritten ActionCEL(sprite) and its inheritors. This was needed to properly implement reversed playing of sprites in ActionLoop.
  2. fixed rewinding of FLIC decoder in the main tree.
  3. implemented Hokus Pokus scripting system.
  4. implemented AudioInfo. This is the specific feature of Peril, activated by the right button.
  5. implemented skipping of the walk. This speeds up testing of games.

This is how sprites were drawing before rewriting ActionCEL.

That’s after

The Hokus Pocus’s scripting system is almost the same as Peril’s. It only adds support for playing scripts by the timer. The peril’s engine can only play 1 action by a timer.

Before:

After:

 

Week 4:

At the fourth week I have done:

 

  1. reworked sound system( now volume from objects attributes is used)
  2. implemented sound balance depending on sprite position.
  3. implemented dirty rectangles
  4. various fixes

Earlier engine was redrawing full screen each frame when smth updated. This was very ineffective.

An interesting thing that the original engine consumes full core of CPU. Probably it hasn’t any delay or just redraws screen each frame.

I have implemented various ways of effective drawing and compared their performance.

  1. Redraw only parts of the temporary screen, but make a full copy to the system. When sprite updates it is redrawn and intersecting parts of other sprites.
  2. Same as previous, but only dirty rectangles are copied to the system.
  3. When sprite updates, get dirty rectangles from decoder, merge them and redraw to the temporary surface. Then to the system. This method can be worse than simpler methods if there are too many dirty rectangles, which can’t be unioned. To solve this, a sprite must be redrawn fully if there are more than 100 – 200 rectangles.

I have compiled ScummVM in release mode with optimizations and set delay 5 ms. This means that maximum FPS will be 200.

Logo1 Logo2 Intro
3 No scaling 187.07 185.8 181.98
HQ 3X 177.28 162 164.03
2 No scaling 182.78 183.6 180.15
HQ 3X 169.42 160.8 160.44
1 No scaling 185.35 181.2 180.28
HQ 3X 167.92 126.6 152.91

Not big gain using dirty rectangles from decoder, but a huge improvement from dirty rectangles which are copied to the system because scalers redraw only parts which are changed.

Week 3

At the third week I have done:

  1. Added metadata to the saving system
  2. Added World Book implementation(PDA)

 

Not much for this week. PDA in games is slightly different, so I need to reverse 2 executables, which aren’t same. The newer executable has very aggressive inlining.

PDA consists of content(text, sprites) and buttons. Buttons have commands:

For now, I have implemented HokusCommandType.

Joke from executable)

  Code for this asm

Here we access non-existent string if the array size is zero. This is SIGSEGV.

Week 2

At the second week I have done:

  • Fixed formatting
  • Removed C++11 features(lambdas, auto, extended initializer lists)
  • Fixed unsigned vs signed comparison
  • Found and fixed bug in ScummVm’s hashmap
  • Added improved pause support
  • Added saving system (currently without metadata)

The most interesting was fixing the bug in Hashmap. At first,  I thought that this was problem with my code. Experimented with code and noticed that calling clear with true parameter causes this bug. So I looked at clear method implementation(Line 4):

 

And this part of HashMap constructor(Line 1):

Simple mistake, which was easily fixed

Pink Scripts Format

In Pink engine scripts are stored as serialized objects.

Let’s look at Wanderlust logo’s script

 

The execution starts from HandlerStartPage. The last Handler is unnecessary.

Firstly, Handler executes SideEffectExit, which sets next executors.

Then, Handler starts sequence.

The sequence consists of SequenceItems.

SequenceItem – sets action to actor.

SequenceItemLeader  – same as SequenceItem but action which it sets will be used as a mark of script ending. In this example, the script ends when the music ends.

SequenceItemDefaultAction – sets the action to the actor, but only if SequenceItem haven’t executed for that actor.

Also, sequence can consist of two or more subsequences.

The execution is the same, but we stop before next leader while the previous subsequence is playing.

Thanks Douglas for great tool Carbon

Week 1

At the first week I fixed bugs in Pink Panther engine.

 

Not much work was done because I have exams in university.

The games were crashing when decoding some sprites, but at first I thought that it was a problem with my code. I ran the game with Valgrind and found a method which wrote beyond the array. And it was ScummVm’s decoder method. It decoded BYTE_RUN chunk as standard FLC format.

https://github.com/scummvm/scummvm/pull/1190

Next, I fixed sprites which started to play with delay. The problem was in that I decode frames until startFrame, but didn’t take into account the next frame start time. So I added a method which decodes the frame, but didn’t add a frame delay.

https://github.com/whiterandrek/scummvm/commit/7fe6bb2963fe72f8aaaf0697aeb6c9da92aff722

Next week I plan to add the menu to call PDA from it and finish loop sprites which currently are played only forward.

Some gameplay from current version