Loading pictures

Yes, loads of them! Let me show you the events of the past few days in the form of a screenshot first, and then I’ll wrote about them in detail. Here you go:

The first thing you may have noticed looking the picture is that I changed back the resolution to 640×200. I decided to do so because I got the information that DOSBox only emulates the bigger screen height, and as Thomas said in a comment under my previous post, Avalanche really uses 200 pixel height, so I don’t see the point in mimicking DOSBox’s output instead of recreating the original experience. Also, if we decide that a bigger resolution would be nicer, it wouldn’t take much more than adding a few lines of code to Graph::refreshScreen().

The second one is that there are much more things in the picture. Yes, I can say that the toolbar on the bottom is almost fully done and only the clock is missing from it. (Which – I assume – will miss for a couple of days/weeks because it’s not so important regrading the actual gameplay, but tricky enough to recreate. And now I have much more urgent tasks to deal with before midterm – the characters, the dropdown menu on the top and the keyboard/mouse input -, and the days are just getting shorter and shorter.)
To be honest, after understanding how EGA graphics work and implementing the loading of the background image, the toolbar itself wasn’t such a big problem, since it uses an almost identical method to load the parts of it as pictures. I can divide the bottom of the screen to 5 bigger parts: the background of the toolbar (the big blue thing), the “Thinks:” field of it, the score display, the clock, and that little picture (in the above screenshot a brown STOP sign) at the top left of it which tells the player if Avalot is standing in one place or moving in a given direction.
I implemented these parts in the exact order as I enumerated them in my previous sentence. To do this, I had to find out (obviously, with the help of fuzzie) that these pictures’ encoding differ a bit from the background’s. They are using row-planar EGA data, instead of graphic-planar EGA data which I used in the algorithm published in my previous post. Luckily, the methods for these two styles don’t differ much, so the implementation of a function which will handle all of the pictures what are not the background was quite easy. To do so, I reworked Graph a little bit, and finally Graph::drawPicture() was born (to replace Graph::copySurface()):

void Graph::drawPicture(const byte *source, uint16 destX, uint16 destY) {
 // The height and the width are stored in 2-2 bytes. We have to add 1 to each because Pascal stores the value of them -1.
 uint16 pictureWidth = READ_LE_UINT16(source) + 1;
 uint16 pictureHeight = READ_LE_UINT16(source + 2) + 1;

 uint32 i = 4;

 Graphics::Surface picture; // We make a Surface object for the picture itself.

 picture.create(pictureWidth, pictureHeight, Graphics::PixelFormat::createFormatCLUT8());

 // Produce the picture.
 for (byte y = 0; y < pictureHeight; y++)
  for (int8 plane = 3; plane >= 0; plane--) // The planes are in the opposite way.
   for (uint16 x = 0; x < pictureWidth; x += 8) {
    byte pixel = source[i++];
    for (byte i = 0; i < 8; i++) {
     byte pixelBit = (pixel >> i) & 1;
     *(byte *)picture.getBasePtr(x + 7 - i, y) += (pixelBit << plane);
    } 
   }

 // Copy the picture to a given place on the screen.
 for (uint16 y = 0; y < picture.h; y++)
  for (uint16 x = 0; x < picture.w; x++)
   *(byte *)_surface.getBasePtr(x + destX, y + destY) = *(byte *)picture.getBasePtr(x, y);  
}

During the implementation of it, I found this little help during a simple search with Google. You can see that my code dips a lot from it: I read in the width and the height of the picture first, then create a Graphics::Surface object to store the picture in it, and then a very familiar algorithm comes with a little modification regarding the order of the planes. At last, I copy the image to a given point of the screen. So Tom Swigle, if you are reading this post somewhere, sometime: thank you, you are awesome!
After I finished with drawPicture, my only task was to replace the original PutImage() calls of the Pascal code with it, since I’ve done the loading of the pictures into byte arrays (what drawPicture gets as a parameter to work with) a few weeks earlier. And that’s all, you can see yourself the result of it in the image above.

The last thing you might have noticed in the screenshot is a little pink rectangle in the middle of the screen. Don’t worry, it’s not a glitch! It’s the very place where the hero of the game, Avalot d’ Argent himself will manifest – I hope – within a couple of days. (I just put it there to see if I get the coordinates of the character accurately.)
Maybe next time we can see him in the screen as well? 😉

First screenshot

Yes, you are not dreaming! It’s true, it’s fresh, it’s happening RIGHT NOW! Ladies and gentlemen, I proudly present you the very first screenshot of Avalot d’ Argent in the holy embrace of SvummVM!

Okay, the colors really need some adjustments, but apart from that you can see that the background image is successfully loaded and shown accurately. (Of course here will come the GUI in the top and the bottom, but that’s not my first priority at the moment.)

Lucerna

Let me tell you a little story about my fight with the bits! Everything started after my latest post: I began to mess around with graphics, and I had some mailing with dreammaster, who helped me a lot and gave me an awesome “Graphics in ScummVM for dummies” guide. By following that, I successfully set up the basics of the screen handling in my engine, what you can find here and here. Graph’s initial purpose was to replace the Graph unit from Pascal with a C++ class, so it can work in synergy with Lucerna (the class/unit which is responsible for the screen, keyboard and mouse handling) but as time passes I am slowly getting convinced that it will eventually become a replacement for Lucerna. I don’t see it clear yet, time will tell…

At the moment Graph is not much more than a wrapper around a Graphics::Surface object.
I got the resolution of the game (what you can find in the header file of Graph) from this function call in the original code:
 gd:=3; gm:=0; initgraph(gd,gm,”);
Where 3 stands for EGA graphic driver and 0 means EGALo mode, which is equal to 640×200 screen resolution, 16 colors and 4 screen pages. (I’ll bother with these “pages” later.)
I also had some difficulties setting up the color palette to mimic the EGA display, but dreammaster told me a lot about it, and by “borrowing” a little bit of code from Strangerke’s Mortvielle engine, I get over with it quite fast too. As you may see it in the screenshot at the beginning of the post, there is still a couple of things to do with it, since the colors in the original game are much more livid, but I’ll leave it’s fix for later.
The next big deal came right after that. I had a long conversation with fuzzie (who is “substituting” Strangerke, my mentor, while he is on holiday) about the topic and she told me a great deal about EGA displays and how did they handle data.
The function which is responsible for loading the data of each screen is Lucerna::load(). The tricky part was here to notice the loop in the original code (which is fuzzie’s merit), and recognize that we have to face the “four plane style”. After that, recreating it in C++ was quite easy, and fuzzie helped me a lot with that as well.
Here’s the result of it:

 

f.seek(177);

/*for (bit = 0; bit <= 3; bit++) {
 port[0x3c4] = 2;
 port[0x3ce] = 4;
 port[0x3c5] = 1 << bit;
 port[0x3cf] = bit;
 blockread(f, a0, 12080);
 move(a0, a1, 12080);
}*/

Graphics::Surface background;
background.create(_vm->_graph._screenWidth, _vm->_graph._screenHeight, Graphics::PixelFormat::createFormatCLUT8());

byte backgroundHeight = 8 * 12080 / _vm->_graph._screenWidth; // With 640 width it's 151
// The 8 = number of bits in a byte, and 12080 comes from the original code (see above)

for (byte plane = 0; plane < 4; plane++)
 for (uint16 y = 0; y < backgroundHeight; y++)
  for (uint16 x = 0; x < _vm->_graph._screenWidth; x += 8) {
   byte pixel = f.readByte();
   for (byte i = 0; i < 8; i++) {
    byte pixelBit = (pixel >> i) & 1;
    *(byte *)background.getBasePtr(x + 7 - i, y) += (pixelBit << plane);
   } 
  }

_vm->_graph.copySurface(background);

background.free();
As you can see I left the automatically converted loop in a comment. Under that, there’s my C++ interpretation of it. You can find the idea behind that loop’s core on this page. We guessed it’s using four planes because the original loop goes from 0 to 3. So my code does the very same. It first reads the blue component of every pixel: since every bit represent a pixel, we jump in the x loop 8 times every time, and read a byte only after every 8th processed pixel. After that, we loop through the given byte, get the blue component of every pixel, and put them in their place. We do that four times, so every plane (blue, green, red, intensity) is read by the end of the big, plane loop, and finally we got the background image!
The interesting part with this is the following: we read an image with the size of 640×151. That’s ok, but after playing the game a couple of times using DOSBox, I clearly saw that it shows the background image (and obviously the whole game too) in a much bigger resolution. I found that the window’s size the emulator uses is 640×400. It’s very strange since the original Pascal code (as I mentioned above) uses half of that height. To mimic DOSBox’s output, I put a little supplement into Graph::copySurface() which copies every line of the background 2 times. After that, my graphical output became almost the same with the one DOSBox produced, but I am still not sure if it’s the right way of operation and I am still searching for traces of this “stretching” in the original code.
(P.s.: Thomas: if you read this post and have any clue or suggestion about this resolution-problem, I’d be very glad if you could share it with me in a comment or by mail! 🙂 Is the original output of the game really in 640×400, and if it is, where the “trick” is located in the original code which makes it possible?)

End of file handling

Hey everybody!

Sorry for my long absence! The case is that we just renovated our house with my family during the weekend (starting with Thursday), so I didn’t have much time to spend with coding. But as we finished with all the work around our house yesterday, here I am again, more tenacious than ever!
I also finished today with the file handling (at least with those parts what don’t involve saving/loading current game stance, only loading screens, sprites, texts, etc.). Sometimes figuring out what the Pascal sources are intended to do and converting it to C++ code was a rather tricky thing. (For example the problem with Pascal-style arrays and strings. Especially strings.) But finally I came over it, and now it’s done and working. At least I think it does. I made several tests to them, almost trying with all the functions and all their source files (mostly *.AVDs), but the real test will be using them in the final code. (You can check this link, if you’d like to know more about Avalanche engine’s file types and other related topics. Written by the original author of the game himself!)
My plans for the following days are these: I’ll follow the program flow with the help of the warnings I placed previously in the code during stubbing, and going one by one, I’ll implement each and every function in the code. I think the real pain will come with the screen processing units, but I don’t think I have anything to fear as long as I have as awesome helpers as fuzzie or dreammaster.
(Sadly, my mentor, Strangerke is on holiday and we can connect only rarely, but luckily SvummVM has a great community, so I don’t think that I’ll be suffering from the absence of help even for a minute.)

End of stubbing

I just wanted to tell you guys that I am finished with the stubbing. And I am totally exhausted. And I am finished with the stubbing.
I can’t describe how relieved I feel now. 😀

Lets begin with file handling!

Yes, lets go!

As I am finished with the stubbing at last (*Phew!*), I can finally start reworking the code and implementing the functions of the classes made during the past two weeks. My plans for today is filling the gaps in the main class Avalot and then following the execution path of the program to get an even better sight of the behavior of it. (Because during the stubbing of the engine I think I understand the connections between the original units pretty well, but there are still blind spots here and there.) After that, I’ll jump right into file handling and keep working on it until everything is going fine and smooth.
See you later! I’ll report you guys as soon as I progress significantly!

Sign of life

Hey everybody!

Don’t worry, I am still alive! 😉 The cause of the absence of posts is that I still keep on stubbing the engine to make it work, to make it more object oriented and in general: more C++-like. (Which I am sure you can see if you check my GitHub repository regularly.)
I followed a dead track for some days: I made all of the Pascal units into C namespaces, but after my mentor highlighted a much better way (using C++ classes instead of namespaces), I changed my methods and I am proceeding quite well now. Sometimes I just really don’t know what I would do without him.
Thomas (one of the original creators of the game) was also very kind and provided me with a recreation of the missing ROOMNUMS.INC file (It can be found in my repo under the name of “roomnums.h” now.), which I am using since then. He saved me a bunch of time with his action and I am very thankful for that.
So please stay tuned! Only a few more days and I’ll be finished with the stubbing and I can finally start working on the implementation of the functions and the real fun will begin.
See you soon!

Stubbing

Just beautiful… But it’s a bit repetitive, isn’t it? 🙂
That’s the actual output of my project, as well as a blank main ScummVM window.
Although it doesn’t seem so (judging by the picture), I’ve made incredible progression (compared to myself) during the past three days. My engine is now up and hooked into the VM. (After many hours of struggling with the detection – Right, Arnaud? ;D)
Besides that, I also included the main loop of the game in avalanche.cpp and started working on the include files of the original sources what I’ll need in order to make the function run_avalot() (in the main loop) operate. (Which calls the method of the class Avalot you see in the picture, which will be responsible for the actual gameplay.) My first target was Gyro, what I stubbed heavily to make it behave, and during the following days I’ll keep on adding and working on these (now header, not include) files as fast as possible.
Listening to the advice of my mentor, I also reorganised the sources: I made a new folder for the already used and the not-yet used converted files and left the files I made myself in the root. I think now my work will be more followable for those who doesn’t have the MSVS2010 project file I use.

Beginning

As Google Summer of Code officially started on yesterday, I started the actual coding as well. The amount of code is still frightening a bit, but with the help of my mentor and enough tenacity, I am sure I will succeed.

Looking through the automatically converted sources (made with PtoC) and adding the standard header to the files (with the awesome help of License Header Manager for Visual Studio) and a namespace for my engine took up most of my Monday. Luckily, I am a bit more familiar with Git by now, so using it didn’t cause me any troubles.
My plan is now to make the converted sources more readable using Artistic Style, then add an empty engine to my work and hook it into ScummVM. You can read more about the procedure here. (And I hope soon here, in my blog as well when I am finished with it.)
There is still the problem of the missing ROOMNUMS.INC, but I think we’ll be able to get through it, thanks to this great wiki the original author made himself to help the porters. (Especially with the help of this page.)
By the way, if you are interested in my work and would like to follow it a little closer, you can find my repository on GitHub, where I “commit early, commit often.”

Acceptance

Yesterday I got my e-mail from Google: my project is among the accepted ones, I can participate in Google Summer of Code this year! I just can’t describe the happiness I felt then. It’s something like a dream came true for me.

So this is my very first post in my very first blog, where I will describe my progression during GSoC in 2013. I hope it will be as much fun to read as I think it will be to write.

My project (in a nutshell) is the following: https://google-melange.appspot.com/gsoc/project/google/gsoc2013/uruk/53001
I have a detailed plan for the next few months and I hope I will be able to accomplish everything I described earlier. On the other hand, I don’t take ScummVM as a one-time thing, so it won’t be a tragedy if I don’t finish my project by the end of September. (But of course I will try my best to do so.) I’d really love to stay in the community and become a developer myself with this engine, and later with other projects. I think the organization’s goals are great and I am proud that I can contribute to the success of it.

The actual coding will begin by the 17th of June, so I’ll start posting regularly by then. See you later, my dear reader! I hope we’ll have a great summer together! 😉

P.S.: Sorry for my English well in advance – I am not a native speaker and never been the best with the language itself.