{"id":31,"date":"2013-07-19T16:15:39","date_gmt":"2013-07-19T16:15:39","guid":{"rendered":"https:\/\/blogs.scummvm.org\/uruk\/?p=31"},"modified":"2022-05-22T13:52:40","modified_gmt":"2022-05-22T13:52:40","slug":"loading-pictures","status":"publish","type":"post","link":"https:\/\/blogs.scummvm.org\/uruk\/2013\/07\/19\/loading-pictures\/","title":{"rendered":"Loading pictures"},"content":{"rendered":"<p>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&#8217;ll wrote about them in detail. Here you go:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.scummvm.org\/uruk\/wp-content\/uploads\/sites\/48\/2022\/05\/almost_avvy.png\" \/><\/p>\n<div class=\"separator\"><\/div>\n<div>The first thing you may have noticed looking the picture is that I changed back the resolution to 640&#215;200. I decided to do so because I got the information that DOSBox only emulates the bigger screen height, and as Thomas said in\u00a0<a href=\"http:\/\/urukgsoc.blogspot.hu\/2013\/07\/first-screenshot.html?showComment=1373990874542#c6859997194981733312\" target=\"_blank\" rel=\"noopener\">a comment<\/a>\u00a0under my previous post, Avalanche really uses 200 pixel height, so I don&#8217;t see the point in mimicking DOSBox&#8217;s output instead of recreating the original experience. Also, if we decide that a bigger resolution would be nicer, it wouldn&#8217;t take much more than adding a few lines of code to\u00a0Graph::refreshScreen().<\/p>\n<p>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 &#8211; I assume &#8211; will miss for a couple of days\/weeks because it&#8217;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 &#8211; the characters, the dropdown menu on the top and the keyboard\/mouse input -, and the days are just getting shorter and shorter.)<br \/>\nTo be honest, after understanding how EGA graphics work and implementing the loading of the background image, the toolbar itself wasn&#8217;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\u00a0<i>background of the toolbar<\/i>\u00a0(the big blue thing), the\u00a0<i>&#8220;Thinks:&#8221; field<\/i>\u00a0of it, the<i>\u00a0score display<\/i>, the\u00a0<i>clock<\/i>, and\u00a0<i>that little picture<\/i>\u00a0(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.<br \/>\nI 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&#8217; encoding differ a bit from the background&#8217;s. They are using\u00a0<a href=\"http:\/\/www.shikadi.net\/moddingwiki\/Raw_EGA_data\" target=\"_blank\" rel=\"noopener\">row-planar EGA data<\/a>, instead of graphic-planar EGA data which I used in the algorithm published in\u00a0<a href=\"http:\/\/urukgsoc.blogspot.hu\/2013\/07\/first-screenshot.html\" target=\"_blank\" rel=\"noopener\">my previous post<\/a>. Luckily, the methods for these two styles don&#8217;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\u00a0<a href=\"https:\/\/github.com\/urukgit\/scummvm\/blob\/avalanche\/engines\/avalanche\/graph.cpp\" target=\"_blank\" rel=\"noopener\">Graph<\/a>\u00a0a little bit, and finally Graph::drawPicture() was born (to replace Graph::copySurface()):<\/p>\n<pre class=\"brush:cpp;\">void Graph::drawPicture(const byte *source, uint16 destX, uint16 destY) {\r\n \/\/ 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.\r\n uint16 pictureWidth = READ_LE_UINT16(source) + 1;\r\n uint16 pictureHeight = READ_LE_UINT16(source + 2) + 1;\r\n\r\n uint32 i = 4;\r\n\r\n Graphics::Surface picture; \/\/ We make a Surface object for the picture itself.\r\n\r\n picture.create(pictureWidth, pictureHeight, Graphics::PixelFormat::createFormatCLUT8());\r\n\r\n \/\/ Produce the picture.\r\n for (byte y = 0; y &lt; pictureHeight; y++)\r\n  for (int8 plane = 3; plane &gt;= 0; plane--) \/\/ The planes are in the opposite way.\r\n   for (uint16 x = 0; x &lt; pictureWidth; x += 8) {\r\n    byte pixel = source[i++];\r\n    for (byte i = 0; i &lt; 8; i++) {\r\n     byte pixelBit = (pixel &gt;&gt; i) &amp; 1;\r\n     *(byte *)picture.getBasePtr(x + 7 - i, y) += (pixelBit &lt;&lt; plane);\r\n    } \r\n   }\r\n\r\n \/\/ Copy the picture to a given place on the screen.\r\n for (uint16 y = 0; y &lt; picture.h; y++)\r\n  for (uint16 x = 0; x &lt; picture.w; x++)\r\n   *(byte *)_surface.getBasePtr(x + destX, y + destY) = *(byte *)picture.getBasePtr(x, y);  \r\n}\r\n<\/pre>\n<p>During the implementation of it, I found\u00a0<a href=\"https:\/\/groups.google.com\/forum\/#!topic\/alt.msdos.programmer\/-Zc78FBkBDQ\" target=\"_blank\" rel=\"noopener\">this little help<\/a>\u00a0during 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<b>\u00a0<\/b><b>Tom Swigle<\/b>,\u00a0if you are reading this post somewhere,\u00a0sometime: thank you, you are awesome!<br \/>\nAfter I finished with drawPicture, my only task was to replace the original\u00a0<a href=\"http:\/\/www.freepascal.org\/docs-html\/rtl\/graph\/putimage.html\" target=\"_blank\" rel=\"noopener\">PutImage()<\/a>\u00a0calls of the Pascal code with it, since I&#8217;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&#8217;s all, you can see yourself the result of it in the image above.<\/p>\n<p>The last thing you might have noticed in the screenshot is a little pink rectangle in the middle of the screen. Don&#8217;t worry, it&#8217;s not a glitch! It&#8217;s the very place where the hero of the game, Avalot d&#8217; Argent himself will manifest &#8211; I hope &#8211; within a couple of days. (I just put it there to see if I get the coordinates of the character accurately.)<br \/>\nMaybe next time we can see him in the screen as well? \ud83d\ude09<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;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&#215;200. I decided to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-31","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.scummvm.org\/uruk\/wp-json\/wp\/v2\/posts\/31","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.scummvm.org\/uruk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.scummvm.org\/uruk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/uruk\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/uruk\/wp-json\/wp\/v2\/comments?post=31"}],"version-history":[{"count":1,"href":"https:\/\/blogs.scummvm.org\/uruk\/wp-json\/wp\/v2\/posts\/31\/revisions"}],"predecessor-version":[{"id":32,"href":"https:\/\/blogs.scummvm.org\/uruk\/wp-json\/wp\/v2\/posts\/31\/revisions\/32"}],"wp:attachment":[{"href":"https:\/\/blogs.scummvm.org\/uruk\/wp-json\/wp\/v2\/media?parent=31"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/uruk\/wp-json\/wp\/v2\/categories?post=31"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/uruk\/wp-json\/wp\/v2\/tags?post=31"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}