ScummVM logo ScummVM website - Forums - BuildBot - Doxygen
Contact us - Buy Supported Games: GOG.com
curved edge

PlanetPlanet

Welcome to the ScummVM planet - This aggregates the personal blogs of developers, teams members and active participants from all around the ScummVM community.
If you wish to subscribe to updates to the planet or individual blogs please use the links on the right hand side.
To add your blog to the planet contact DJWillis.

June 24, 2018

Andrii Prykhodko (whiterandrek) - GSoC

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:

gifWalkBroken.gif

After:

gifWalk1.gif

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

Next week I will implement the game menu.

by whiterandrek at June 24, 2018 05:22 PM

Liu Zhaosong (Douglas) - GSoC

ResidualVM: Week 6

Not much update this week. The conversation log menu is still under review at this point, but it should be merged very soon.

The recent plan is to finish some small things left that are related to all the newly implemented menus. I have included all of them in the project on ResidualVM's GitHub page. Right now I have finished implementing two of them:

Task 1: Improve the debug console. Basically, this is a task about fixing issues. There is a debug console, which I have shown in week 1, provided in ResidualVM's The Longest Journey, where a number of commands are provided for users to look at the game's data and probably mess up with it. In the previous implementation, the console will crash if the user types improper commands in improper locations. Fixing this is not that hard, just add a bunch of checking beforehand and you are done with it.

Task 2: Add the version info text in the main menu. The lacking of the version info text was aware of weeks ago. I just want to tackle it later, and it's right to do so since now, with the previous experience, I am crystal clear about how to deal with this: the "VERSION INFO HERE" widget is used for the text, so I just need to access its RenderEntry, get the VisualText it contains, and reset the text, plus twisting the position. It took me some time to think of a way to display the copyright symbol ©, but the rest is a piece of cake.

The Version Info Text

Before I wrote this blog I opened the pull request for the debug console and I intended to do the same for the version info one, but in order to avoid potential conflict, I created those two branches based on the branch of the conversation log menu, which hasn't been merged yet, so the commit history of both of them is not clean and they will be rebased soon after the merging. I don't like putting things that I deem unclean here. Anyway, if you are interested in the development, feel free to take a look at my GitHub.


All code images are generated through Carbon.

by Douglas Liu (noreply@blogger.com) at June 24, 2018 12:13 PM

June 23, 2018

Joseph-Eugene Winzer (Joefish) - GSoC

Week 5 -- It's Alive!

Week 5 -- It's Alive!

Overview

  • Map rendering working
  • Remaining Dialog texts ported

Details

Your image looks corrupted and you definitely ruled out pointer errors? Well, it’s a pointer error anyway.
Or endianess. Or both together…
It took a while to realize that subtile indices are stored as uint16BE but now I AM BACK IN BUSINESS!

Next

This weekend I want to add viewport clipping and map masking so you don’t see the whole map ingame like in the above image. There’s also some tile specific code left to implement (like the water in the sewers) but that’s for another time. Finally we can get going on implementing the actual gameplay \o/

by Joe Winzer (noreply@blogger.com) at June 23, 2018 09:09 AM

June 21, 2018

Matthew Stewart (Drenn) - GSoC

GSoC Week 5: Star Trek Teaches Chemistry: How to Make Laughing Gas

Mission 3: Love’s Labor Jeopardized. It’s about 90% finished.

The mission starts with a rather ear-grating computer voice. Thank god they got Majel Barrett for the sequel.

That said, this is a neat mission. You’re given information about various chemical compounds that may be useful in the mission, then you need to figure out which ones are important and mix up some ingredients to cure a virus that’s running loose through the station.

Or you can just, you know, inhale some laughing gas instead.

Mission bugs

Last week, I promised there would be bugs in this mission. There’s nothing mission-breaking that I’ve found, though, mostly text stuff.

The most eggregious is a weird textbox I encountered in my casual playthrough. As far as I know, you’ll always encounter this if you take long enough during the mission.

I also encountered this following bug while writing this blog post. This is part of the 10% of the mission I haven’t rewritten yet, though, so I can’t explain what it’s about.

Aside from that, there are a couple of cases where voice acting doesn’t play when it should. And, if you look at Dr. Marcus when she’s tied up, it plays the wrong file entirely; only narrating the first half of the textbox. There was an unused audio file that narrated the entire textbox, so I replaced it with that.

The one thing that might be considered a bug in the mission mechanics, is the way you can give water to the Romulans. Apparently you can get a point in your mission score for doing that. But, sometimes, if they’re unconscious, nothing happens. You lose the water, you don’t get any points, and not even a textbox is shown. It’s honestly kind of odd. I’m still debating what to do about that; for now I’ve made it so you can’t give water to them while they’re unconscious.

Other oddities

There are a number of cases where a single line is read multiple times by the actors, simply because the same textbox is shown in multiple different rooms. For example, if you scan the air with the medical tricorder, McCoy says the exact same line, but with a different voice clip depending on the room. I can just imagine the cast complaining about why they have to record the same voice clip three times.

Anyway, this mission should be completable in ScummVM within the next day or two. Next week will feature the return of Harry Mudd in one of this game’s weirder missions.

June 21, 2018 12:00 AM

June 18, 2018

Joseph-Eugene Winzer (Joefish) - GSoC

Week 4 -- Show me the World

Week 4 -- Show me the World
(Here is supposed to be a video of the map)

Overview

  • Map rendering
  • Improving dialog handling

Unfortunately the map rendering kept breaking so there’s no video of it right now. While there are improvements in other areas like the dialog handling, the map renderer blocked me for most of the week.
Below I describe the structure of the MAZE.CMP file that stores static background tiles and how it is used.

Details

struct Map { // MAZE.CMP
byte tileIndex[128][20]
byte subTileIndex[146][64]
byte bitmap[1832][32]
}

Compared to sprites from animation files (discussed in Week 2) the static background is composed of tiles from MAZE.CMP. Those tiles in turn are made of subtiles of 8x8 to save space by assembling the bigger tiles of the smaller ones. So the tileIndex are offsets into subTileIndex that again are offsets to the 8x8 pixel data in bitmap.

On every frame an indexMap is generated of the currently visible subtiles. The reason is not only for caching but for clipping tiles (that’s what kAnimationShadow* are for) and general tile manipulation depending on game state.
34x18 tiles are shown at a time on screen. There will be overdraw as the viewport is only 256x128 but it doesn’t matter as the video buffer is 320x200 and it is clipped off by the frame border in the end. Currently my implementation draws the frame border first for “clearing” the screen as it was convenient to just blit the fullscreen image without the need for transparency.

Next Week

The most urgent feature right now is renderering the map. Not only does it help to visually convey the progress better but other features like player movement, rendering of NPCs, Objects, animation of static objects like torches, collision, … depend on it. Besides that, the definitions for the all objects, … will need to be ported over as well.

by Joe Winzer (noreply@blogger.com) at June 18, 2018 01:34 PM

June 17, 2018

Andrii Prykhodko (whiterandrek) - GSoC

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.

gif2.gif

That’s after

gif

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:

scriptsBef.gif

After:

scriptsAfter.gif

 

by whiterandrek at June 17, 2018 05:20 PM

Liu Zhaosong (Douglas) - GSoC

ResidualVM: Week 5

This week's work nearly blew my mind...

So, it is finally the time to bring the conversation log back to The Longest Journey, which is another pretty complex menu in the game. In the conversation log, players may view all the past conversations they encountered. What makes this menu extremely complex is that it is completely dynamically data-driven generated. Based on your previous action, the conversations could be different. This means that retrieving all widgets of the current page at once is not working since you don't know for sure how many widgets there will be.

Worse still, this menu actually contains two submenus: the Index and the Content, which means I am actually implementing two menus on one trail. And just when I am typing this blog I suddenly realize that it won't be difficult to actually separate them as two distinct menus, damn...

The Index of Conversation Log

The Content of a Dialog

The mechanism of recording conversations has been implemented in the existing engine, so my job is just to retrieve them and properly render them on the screen. Wrapping the texts as classes and widgets has become handy for me, but the hard part is that I need to find a way to dynamically generate the layout of those texts.

In the game's data, there are two entities called IndexFrame and LogFrame, which contains damn only the bounding box of the layout. My way of using them is simple: A Point is used as the rendering position of the current manipulated text. The height of the built text will be used to check whether rendering this text in the current position will exceed the box. If not, put it in an array for rendering, update the next position and go to the next round, otherwise, this page is finished. It sounds simple, but it needs more efforts than before to make the logic clear and maintain a good structure.

No code pic this time, for the reason that it is really not something that can be shown with a few lines of codes. Anyway, implementing this conversation log menu is really a hard bone, way more complex than last week's work. But challenges make things interesting, aren't they? Although my brain nearly exploded and I literally dropped one commit to rewrite it in the process, I actually enjoyed myself and found the feeling of accomplishment. That's what makes GSoC valuable, I believe.

Well, it looks like the task of implementing the menu of The Longest Journey is in its last phrase. I am still not sure what to do next. We'll see.

By the way, tomorrow (June 18th) is the Dragon Boat Festival in China. If you see this, go have some Zongzi, will you?


For the detailed development of the codes, please refers to the Pull Request on GitHub.

by Douglas Liu (noreply@blogger.com) at June 17, 2018 03:25 PM

June 15, 2018

ResidualVM News Headlines

ResidualVM 0.3.1

Our previous release is already a few months old, it's time for a bug-fix release! ResidualVM 0.3.1 is available on our downloads page. It fixes a couple of Myst III bugs:

  • Fixed a rare crash when walking near the magnetic rings in Amateria.
  • Fixed unresponsive controls for the holographic projectors in J'nanin.

That's not much, but Cyan and GOG.com are planning to use ResidualVM for the Myst III digital release and we want it to be as stable as possible.

In other news, progress on adding support for The Longest Journey to ResidualVM continues thanks to our GSoC student Liu "Douglas" Zhaosong. You can follow his work on his blog.

by bgK (nospam@residualvm.org) at June 15, 2018 12:00 AM

Matthew Stewart (Drenn) - GSoC

GSoC Week 4: Dammit Jim, I'm a doctor, not a QA tester!

Star Trek’s second mission, “Hijacked”, is finished. It’s very short, only consisting of 4 rooms. Despite this, the devs didn’t fail to insert a number of bugs into the mission, most of them in the final room.

Let’s start simple: if you talk to McCoy at a specific time, he has no text.

However, there is an audio file which fits perfectly for this situation. So, I whipped up some corresponding text to go along with it, and inserted it appropriately. Honestly, how could I let DeForest Kelley’s wonderfully snarky voice acting go to waste?

It’s not the only voice clip that’s unused, either. There are a surprising number of cases where they clearly intended for some dialogue to be said, but there’s problems in the implementation causing it to not occur; for example, when you try to shoot the Masada crewman, he’s supposed to say something, but due to a bug(?), he didn’t in the original.

There’s also an oversight with the mission scoring system. You’re supposed to combine some inventory items together to progress through the mission, but you only get points for this if you do it in a specific room! This is the consequence of each room having entirely separate codebases; the code needed to be copied for each room, and clearly, they must have forgotten that the code was duplicated when they made some changes to it.

Lastly, the final room is pretty buggy. Don’t read any further if you want to avoid spoilers.

So, there are three ways to end the mission; either you shoot the Elasi, they surrender, or they attempt to deorbit the ship. But… these aren’t mutually exclusive. In fact, all three can happen, and the devs clearly didn’t think this through properly.

Consider scenario #1: You shoot the Elasi. This aggros them, and they immediately kill your redshirt, followed by Kirk. However, you can still talk to the Elasi if you’re fast enough. If you convince them to surrender… they don’t actually surrender, despite saying so, they just keep killing you. If they deorbit the ship, you can call Sulu, stabilize the orbit, and beam out, WHILE THEY’RE STILL SHOOTING YOU.

Scenario #2: You talk to the Elasi, and you choose the worst option, causing them to both deorbit the ship and start shooting you. This one’s funny, because there’s no way to finish the mission in a way that makes sense. You can do one of two things:

Scenario #2a: Shoot the Elasi. This is sensible since you only have a few seconds before they kill you. After this, the mission is “successful”, even though you never save the Masada from deorbiting. I guess the security team that beams over dies when the ship goes down…

Scenario #2b: Call Sulu to prevent the ship from deorbiting. This results in the same issue as scenario #1.

It’s a mess. I’ve tried to fix things as best I can, by requiring that if the ship is being deorbited, shooting the elasi doesn’t end the mission, and vice-versa; saving the ship from deorbiting doesn’t end the mission if the Elasi are still a threat. Also, if the Elasi say they surrender, they actually do surrender now.

There are many more minor bugs, such as the Elasi guards freezing up if you shoot one of them at a specific time; but I’d be here all day if I listed them all. I’ve put down “BUGFIX” tags in the source code whenever something like this comes up. I’ve no doubt I’ll encounter more while working on the next mission.

June 15, 2018 12:00 AM

June 12, 2018

ScummVM News Headlines

ScummVM and Cyan, Inc. are working together!

Today, we have some awesome news to share. As you might have heard, Cyan, Inc. — the makers of Myst and Riven — are re-releasing the entire Myst series to celebrate the 25th anniversary of the original Myst game. And ScummVM and ResidualVM take part in this celebration in a special way!

Myst — Masterpiece Edition and Riven — The Sequel to Myst are powered by ScummVM, while Myst III — Exile is driven by ResidualVM.

In order to achieve the best possible gaming experience and to make your journey through the Ages even more pleasant, Cyan and ScummVM are establishing a new partnership, with both teams working together as closely as possible in the future!

Perhaps the ending has not yet been written — more news will follow soon!

by rootfather (nospam@scummvm.org) at June 12, 2018 09:00 AM

June 11, 2018

Joseph-Eugene Winzer (Joefish) - GSoC

Week 3 -- Game intro running

Week 3 -- Game intro running

Overview

  • Text rendering
  • Basic Dialog implementation for intro
  • Logic abstraction

The porting process is tougher than I had anticipated. I described my problems with the animations in Week 2 and continued with correctly positioning sprites in the dialog. Fortunately I [found my mistake](link to Renderer::drawSprite pos calc) and dialogs not only for the intro, but in general will be solved soon.

Details

The logic differentiates between different states like showing a dialog, the game, a cutscene, and so on. This helps the logic to know when to update what so that for example you are not slain while still picking up items from a chest. link
The characters for text rendering are stored in general2.anm that use the ASCII value as an offset to access the sprite in the animation (link to Dialog::update default case). The dialog strings contain information directly for fadein/out, what type of dialog it should be (Yes/No, Ok, multipage, immediate) and so on.
In general the implementation is quite simple. The engine iterates over every char one after another and either executes the ‘meta char’ (e.g. ‘|’ for fade in text) or renders the sprite for the character. When the null terminator is reached and no further string is to be loaded, the dialog rendering terminates and depending on if the dialog expects user input (password, yes/no, ok) the logic either waits on a keypress before switching back to its ‘game state’ and continues where the player left off.

Next Week

Judging from my current speed, I hope to get our hero making its first steps in the first level and ironing out the remaining dialog bugs.

by Joe Winzer (noreply@blogger.com) at June 11, 2018 08:56 PM

June 10, 2018

Arnaud Boutonné (Strangerke)

Drenn Weekly Post #3

So, here is the next blog post written by Drenn in the scope of the GSoC.

A lot of nice progress as usual, ... so don't miss it!

It's There!

by Arnaud Boutonné (noreply@blogger.com) at June 10, 2018 08:11 PM

Andrii Prykhodko (whiterandrek) - GSoC

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.

by whiterandrek at June 10, 2018 05:19 PM

Liu Zhaosong (Douglas) - GSoC

ResidualVM: Week 4

Not many things to update this week. I just started doing the internship, so I am still getting used to the new schedule. There is one thing I found out though: GSoC is like a million million million time more interesting than my internship. So sad that I cannot use GSoC to cover the credit requirement of my university.

OK, back to business. There are two focuses in this week: one is the video replay menu, the place where you can replay the video you have seen in the game, and the other is the diary pages menu, where you can read April's diary. These two menus are both pretty easy, so I actually didn't work heavy on them. The overall logic for them is pretty straightforward and is basically the same as what we have done previously. Get the widgets, render them, put actions on them, done.

The video replay menu

A diary page

Although pretty simple, there are still some small things that need to be treated specifically in these two menus.

For the video replay menu, the widgets for videos behave slightly differently from other normal widgets: the cursor will not change when you move your mouse on it. Since the mouse changing mechanism is controlled by other entities, it just felt silly to change the existing mechanism to deal with this case, plus the behaviours of video widgets are all very simple. Therefore, I decided to build a new class called FMVWidget, specifically built for this menu. It's like a simplified version of the previous StaticLocationWidget, with fields and functions that just covers the need of the video replay menu.
See, it's so simple that I inline many functions

For the diary pages menu, although the texts of the diary can be retrieved with the class RenderEntry, like the classic StaticLocationWidget,  the game identifies them not through their own names, but the names of resource layers that they belong to. So we need to go to the Layer class to retrieve the text we want.
The DiaryWidget

Well, that basically is it. After these two menus are fully polished and on the trail, it shall be the time to move to a hard bone: the dialogue menu. Let's see what will happen there.


For the detailed development of the codes, please refers to this and this Pull Request on GitHub.
All code images are generated through Carbon.

by Douglas Liu (noreply@blogger.com) at June 10, 2018 02:10 PM

June 07, 2018

Matthew Stewart (Drenn) - GSoC

GSoC Week 3: R̶e̶b̶e̶l̶ Elasi Scum

The main task of this last week was to implement saving. This had a surprising amount of nuance to it, since I need to provide ScummVM with various metadata, including a thumbnail of the savefile, the savegame description, etc… fortunately it wasn’t too difficult to use other engines as templates on how to accomplish this. I’m quite glad I found out about ScummVM’s built-in serializer before starting on this, as it reduces the amount of redundant code by a lot (saving and loading is done with the same code).

The main issue I encountered, was a portability concern. I can’t simply memcpy a data structure to save it, since there are no guarantees about struct packing, or endianness, etc… so, I need to specify each individual variable that goes into the savefile. This is a huge pain to do, since each individual room has its own set of variables, and I’m still figuring out what they are. I’ve mostly held off on saving room-specific variables for now. Hopefully I’ll find a better solution, but obviously I must eventually solve this for saves to work properly.

In the meantime, the next mission is coming along, in which Kirk faces off against the Elasi - the biggest pest in the universe after the rebel alliance. #TheEmpireDidNothingWrong.

June 07, 2018 12:00 AM

June 06, 2018

Arnaud Boutonné (Strangerke)

Drenn Weekly post 2

You liked Drenn post #1? You'll love #2

Here is the link:
Drenn Weekly post 2

As I mentioned in the previous post, we still have issues with Planet for some reasons, so I'll keep putting links here until it's fixed, or until the end of GSoC, whatever comes first.

You could also prefer to directly check Drenn's blog. It's There!

by Arnaud Boutonné (noreply@blogger.com) at June 06, 2018 08:09 PM

June 05, 2018

Arnaud Boutonné (Strangerke)

Drenn weekly post 1

We had, and still have, some issues to synchronize Drenn's blog with planet (in the scope of GSoC 2018). I therefore decided to post links to his blog posts so it's visible on Planet.

Here is the first blog entry posted by Drenn more than a Week ago. He made impressive progress on his Star Trek engine. Enjoy!

by Arnaud Boutonné (noreply@blogger.com) at June 05, 2018 08:11 PM

Kingdom on hold

I've finally reversed the whole hardcoded logic again for the demo (because BinDiff wasn't able to handle small changes in giant functions). The positive part of that is that it made me point some small bugs I fixed in the full version.

At this point, the engine is only missing the MVE video player. I don't think I'm able to handle that myself despite TMM pushed the missing opcodes in ffmpeg. So, the engine is on hold undefinitely (at least until someone is willing to help me with that player).

I'm still tossing a coin to decide what I'll work on next.

by Arnaud Boutonné (noreply@blogger.com) at June 05, 2018 08:11 PM

June 03, 2018

Andrii Prykhodko (whiterandrek) - GSoC

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.

scumm

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

For now, I have implemented HokusCommandType.

Joke from executable)

idaj.png  Code for this asmcarbon (3).png

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

by whiterandrek at June 03, 2018 07:14 PM

Joseph-Eugene Winzer (Joefish) - GSoC

Week 2 -- Animation

Week 2 -- Animation

I picked the animations above randomly but I just realized how they depict the development process so far.
Coffee fueled nights, excruciating pain bursting my skull (most of the time because of dumb mistakes I miss for hours), but you must press on! ;)

Overview

  • .anm file support 1
  • Mapping animations 1 2
  • Render support for animations

Details

All sprites are stored in .anm files, divided intro multiple sprite chunks that either form an animation or just an accumulation of sprites like inventory icons or characters.
There is no meta information that would help identify what frames form an animation in cases where several animations are stored in one sprite chunk (blood splatter effects for example). So i manually mapped them what can be quite error prone, especially as some animations are not used in the game and seem to differ from version to version.
The DOS/Genesis/NES version have a battle scene compared to other versions where the fighting happens on the map. Some of the sprites are still available but the animations seem to be incomplete.

struct AnmFile {
struct AnimationHeader {
u16 offsetToSpriteOffsets
u16 numFrames
u16 centerX
u16 centerY
} [numOfAnimationsInFile]

u16 offsetToSprites[header.numFrames]

struct Sprite {
byte x
byte y
byte width
byte height
byte remap
byte widthPerLine[sprite.height]
byte pixelPosOffset[sprite.height]
byte pixelData[] // one nibble per pixel
} []
}

Next Week

Until the end of this week, I will implement the game intro what will encompass extending the game logic and dialog implementation.

by Joe Winzer (noreply@blogger.com) at June 03, 2018 03:40 PM

Liu Zhaosong (Douglas) - GSoC

ResidualVM: Week 3

Time flies, isn't it?

This week's focus is on the save & load menu. Similar to the settings menu, the most important part of implementing the save & load menu is to implementing the widget that shows the save data.

I created a new class called SaveDataWidget for this purpose. A SaveDataWidget consists of three parts: the screenshot thumbnail, the text, and a blue outline that shows up when you move the mouse on it.

The save menu of the original game

The thumbnail and (most of) the text are already saved in the original save data. All I need to do is to extract them out and properly store and render them. The thumbnail will be read as a Surface, which will then be bound to a Texture and then got rendered by a SurfaceRenderer.
Load the content

The text further consists of two parts: the title of the chapter and the saving time. The title will be saved and loaded through the description field of the original save data, while the time is already saved in other fields, well, almost. The original version of the save data lacks the "seconds" part, which needs to be added on. For this reason, some version checking needs to be done so as to preserve the compatibility of old save data.
Version checking in the metadata

Since the titles of the chapters will be stored in the save data as well, there needs a way to obtain them. It cannot be hard-coded since there are versions of The Longest Journey that are in different language (like French, the language of my best mentor bgK). In the game's data, names of the chapters are all stored in the file called "chapters.ini". For a better modularity (and because I foresee the need from the conversation dialogue), I created a new service called GameChapter, which loads all the chapters' name in the beginning and provides them to other entities when needed.
The GameChapter service

After all these were done, the rest of implementing the actions performed by widgets were trivial. The save menu and load menu use the same location for resources, so they are greatly benefited from the use of inheritance.

Very soon, the The Longest Journey on ResidualVM shall fully support saving and loading through its original menu!


For the detailed development of the codes, please refers to the pull request on GitHub.
All code images are generated through Carbon.

by Douglas Liu (noreply@blogger.com) at June 03, 2018 09:58 AM

May 30, 2018

Matthew Stewart (Drenn) - GSoC

GSoC Week 2: Everyone Gets Vaporized

My work this week has been the repetitive and somewhat tedious task of rewriting the code for Mission 1. It did take a while, but hardly the entire month my original schedule called for! My original schedule didn’t anticipate that I would finish the entire game within GSoC, but at this rate, it seems quite possible.

Anyway, this week’s work speaks for itself: the first mission is fully playable in ScummVM. There are just a handful of animation errors and default interactions missing (ie. using a tricorder on something when no “action” is defined for that).

Something I struggled with this week was text handling, keeping in mind that I’ll eventually want to port the French and German versions to scummvm as well. Before, that would have been extremely difficult due to the way I was hardcoding text into the code, so I switched to a system where each piece of text is referenced by a constant integer value; this will make it easy to support other languages later. And, as it turns out, almost every piece of text already has a unique “name” in the form of the corresponding audio filename, so this system was actually pretty easy to implement.

Instead of going straight to mission 2 next, I’ll be taking a break from mission-specific logic by looking into the saving system next. It’s sorely needed to make testing easier.

May 30, 2018 12:00 AM

May 23, 2018

Matthew Stewart (Drenn) - GSoC

GSoC Week 1: Kirk is incompetent

It’s been a week and change since GSoC started. When we left off, I’d just finished implementing pathfinding. In the week since then, I’ve been busy implementing the action system, which is central to any adventure game.

The action menu and inventory

First thing’s first: we need to be able to select our actions.

This game’s interface is… questionable. You click on a body part to select your action, ie. clicking on the mouth selects the “speak” action. It may look cool and all, but the selection areas are just a bit too small. I also really dislike how the game is constantly warping the mouse around - I never have any idea where it will be after closing a menu… but alas, my job is to recreate the game faithfully, not to change the things I deem clunky.

The inventory was the next logical target. By this point, I had also figured out hotspot detection; I started to get a good grasp on how the game handles interaction between objects.

Inventory items were also a good test subject for implementing the “look” action.

Room-specific code

With the interaction system just about figured out at this point, it was time to look at room-specific code. This is what makes the missions tick; each room has a series of “event hooks” that may run when the room is first entered, when a certain amount of time passes, or when you try to vandalize a sign with a phaser.

Rewriting this will easily be the most time-consuming part of the project, and I suspect that future progress updates won’t be much more than “I finished rewriting these rooms, check it out”.

That being said, I finished rewriting the first room, check it out.

If all goes well, maybe the first mission will be completable by next week’s blog post. Here’s hoping.

May 23, 2018 12:00 AM

May 21, 2018

Paul Gilbert (Dreammaster)

It's an UltimaTE unwinding

After all this time, support for the Might & Magic Xeen games is finally close to being finished. It's currently the official testing period for all the Xeen games, and I've already had a whole bunch of useful bug reports, which I've all taken care of. At this point, it's almost certain that the Xeen engine, and games, will be supported in the next official ScummVM release. It's a nice feeling. More than any other game engine I've worked on, the Xeen engine was the one that got put on hiatus the most number of times. It's very satisfying to finally complete it.

What's in store for me now? Well, I do want to spend some time properly unwinding and actually playing some games. They've only just come out with the sequel to Pillars of Eternity, which I'm now getting into, and plus I have a backlog of other RPG and adventure games that I want to have a chance to properly play. So that will probably keep me occupied for a few months at least. I've also got a move from the US East Coast to West Coast coming up next month. So various preparations are consuming my time, and it's all to the good that work on Xeen has already finished.

Not that I'm totally stopping work on ScummVM stuff. As with the early days of work on Starship Titanic, I started doing some casual reverse engineering during my lunch breaks. By happenstance, I experimented with the Ultima 1 executables, and become enamored by how simple they were to reverse. Both due to the simplicity of the game (considering how old it was), and the way the code was implemented. It was just the thing for doing casual reversing work in chunks of an hour at a time.

As a result of this, I've already implemented a great deal of foundation code in ScummVM for supporting the game, with a long term eye for having a clean engine structure that could support all the early Ultima games.  Here's some screenshots of the player within the overworld, a city, and within the dungeons:



At this point, I've got basic movement functionality working. The player can roam around the map, entering cities, castles, and dungeons. Dungeon movement also works, as does going up and down ladders, so the dungeon can be further ventured down into, or left entirely. That's it at the moment, though; it doesn't yet have any combat, magic, inventory, character interaction, etc. See this Youtube video for an example walk-about that covers venturing into a dungeon, and then heading over to the city of Britian.

Don't expect too much more work on this in the near term, though. As I said, this is more a side thing, and I definitely do want to spend some time unwinding and playing some games. When I get my fill, later in the year, then we'll see. At the moment, it's looking strongly like I'll keep working further on this. I've some crazy ideas about not only adding support for the game, but also reusing the Ultima VI tileset to create an "enhanced" Ultima 1 experience that's more visually pleasing, and rework the controls and user interface to be likewise more player friendly. I know that oh, pretty much everyone who ever played their way through the space simulation section would much appreciate mouse control for aiming at enemy vessels. :)

I kind of consider the RPG series of Ultima, Might & Magic, and Wizardry the triumvirate of major RPGs from the last century and, now that ScummVM is embracing RPGs in addition to adventures, I'd love to see them all under the ScummVM banner. Now that at least some of the earlier Might & Magic games are supported, it may well be time to start in on Ultima support :) Of course, I'm not entirely abandoning working on adventure games. I'd previously made some promising initial progress in reversing some of the Legend Entertainment games.. Companions of Xanth and Gateway. Irrespective of how much time I end up devoting to working on Ultima I, I may end up also devoting some of my time to those games as well.

Anyway, that's probably enough for now. I still want to get in some Pillars of Eternity 2 before it's time for bed. :)





by Dreammaster (noreply@blogger.com) at May 21, 2018 01:42 AM

May 15, 2018

Matthew Stewart (Drenn) - GSoC

GSoC Week 0: Implementing the basics in Star Trek

Google Summer of Code officially started yesterday; but, since I got started a bit early, I already have a week’s worth of things to talk about. If I want to support both Star Trek: 25th Anniversary and Star Trek: Judgment Rites, I need to get moving!

Audio and the Options Menu

Since the engine could already display textboxes, the options menu seemed like a juicy next target. In fact, I barely needed to do anything to make it display; the buttons were loaded in exactly the same way as other textboxes.

This provided a nice segue into audio code; it showed me which variables corresponded to “music enabled” and “sfx enabled”. MIDI music already worked thanks to the efforts of clone2727 from years back. I added support for midi sound effects, which turned out to just be separate tracks on the same midi file as the music.

But there’s more than just MIDI - the game features voice acting from the original Star Trek cast. Their lines, plus some other audio, are stored in .voc files on the CD. To work with ScummVM, they need to be copied from the CD to the hard drive with the rest of the game’s data.

I figured it would be easy. ScummVM has a built-in VOC decoder. What could possibly go wrong?

Well, I was greeted by this. SWEET JESUS THAT IS LOUD. (I always use headphones, by the way.) However, it’s definitely the red alert sound.

OK, so after a quick look at the decoder function’s flags, I passed Audio::FLAG_UNSIGNED to the decoder. That’s much better.

Beam me down, Scotty

With audio working, animations were next on my list. As it turned out, the transporter room was perfect for testing this; the entire sequence is just 5 objects being animated.

Did you notice that every crewman is McCoy? That’s because the other 3 officers have their animations based on McCoy’s. They just apply an xor over the face and recolor the uniforms.

After fixing that (and discovering that the timer runs at 18.206 Hz, the rate of the DOS clock), the animations looked perfect, aside from layering.

Scaling

Sprite scaling would be needed before tackling away missions. Star Trek optimized this heavily; they wrote a function which constructed another function in RAM! This resulting function was just an unrolled loop which copies a row of unscaled pixels to a row of scaled pixels. This is DOS, so there’s no interpolation here.

I obviously don’t need to do anything as fancy as dynamically constructing a function in ScummVM. There’s no way I could do that portably, anyway. Fortunately, my computer is probably a hundred times faster than what Star Trek was developed on, so I’m not too worried.

Weirdest transporter accident I've ever seen...Weirdest transporter accident I've ever seen...

Away Missions

With animations done, it was time for me to do movement and pathfinding.

Pathfinding is a simple system where each room has a set of waypoints. Given a source and a destination, the game locates the waypoints closest to each. Kirk then moves to the source waypoint, moves along a set path to the destination waypoint, and then moves from there to the exact destination you clicked on. This sometimes causes Kirk to walk back-and-forth when he’s starting a walk, since he might need to move backwards to reach a waypoint. I’m not sure if other adventure games do this, but it does make movement in this game feel somewhat finicky.

Anyway, just today I figured out how warps work - some of them, anyway. Each room has a set of polygons where warps occur if Kirk walks into them. However, apparently the doors in the first room of the first mission are more complicated. It seems that, since a sound effect goes with them, they need to call some room-specific code to handle that.

The game is suddenly starting to feel alive. Not only can I control Kirk, but the crewmen follow behind him when moving between screens, or do their idle animation when waiting around. It’s a small thing, but it’s rather refreshing after looking at static screens for so long.

Other stuff

I found an interesting error message:

Jay didn't think about pmcheck.

Jay is probably Jayesh Patel, who is credited as one of the programmers. I don’t really know what that error message means, but at least I’ll know who to blame if I ever see it. :)

Anyway, next on my list of things is to work on the action menu and inventory menu. And, very soon, I’ll need to start looking into how room-specific logic works. Again, this is all done with x86 code and not a scripting language, so it will need to be tackled on a room-by-room basis.

May 15, 2018 12:00 AM

 

curved edge   curved edge