{"id":62,"date":"2021-08-03T16:54:14","date_gmt":"2021-08-03T16:54:14","guid":{"rendered":"https:\/\/blogs.scummvm.org\/ayyg\/?p=62"},"modified":"2021-08-10T04:34:32","modified_gmt":"2021-08-10T04:34:32","slug":"the-beginning-of-the-end-3-progress-report","status":"publish","type":"post","link":"https:\/\/blogs.scummvm.org\/ayyg\/2021\/08\/03\/the-beginning-of-the-end-3-progress-report\/","title":{"rendered":"The Beginning (?) of The End 3 (Progress Report)"},"content":{"rendered":"\n<p>Time for the weekly progress report! This week I have finals, so studies had to be prioritized, but here is what has progressed since the last report:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bugs<\/h2>\n\n\n\n<p>Here are the newly identified bugs:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">Bug<\/td><td class=\"has-text-align-center\" data-align=\"center\">Steps to reproduce<\/td><td class=\"has-text-align-center\" data-align=\"center\">Explanation<\/td><td>Solved<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">The first track played when the game start is random<\/td><td class=\"has-text-align-center\" data-align=\"center\"><\/td><td class=\"has-text-align-center\" data-align=\"center\">When running in DOSBox, it always starts in track 4<\/td><td>No<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Battle sound effects not synchronizing<\/td><td class=\"has-text-align-center\" data-align=\"center\"><\/td><td class=\"has-text-align-center\" data-align=\"center\">Sometimes the battle sound effects last after the battle is over<\/td><td>No<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Crash when starting new game after ending<\/td><td class=\"has-text-align-center\" data-align=\"center\"><\/td><td class=\"has-text-align-center\" data-align=\"center\">The New Game dialog pops up after an ending<\/td><td>Yes<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Non-printable keys being printed in savefiles<\/td><td class=\"has-text-align-center\" data-align=\"center\"><\/td><td class=\"has-text-align-center\" data-align=\"center\">For instance, SHIFT inserts a character when inserting the savefile name<\/td><td>Yes<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">The wrong game version shows when viewing credits<\/td><td class=\"has-text-align-center\" data-align=\"center\"><\/td><td class=\"has-text-align-center\" data-align=\"center\">Credits show vW95 on Scummvm (vDOS on DOSBox)<\/td><td>No<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Attack after death being possible<\/td><td class=\"has-text-align-center\" data-align=\"center\">Wait until your HP is 0 but the enemy attack animation\/sound isn&#8217;t over, then attack back<\/td><td class=\"has-text-align-center\" data-align=\"center\">Sometimes your attack animation can span until after you&#8217;re dead. This requires a few retries. Something similar can be achieved in the original (DOSBox), so maybe this is expected behavior<\/td><td>No<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Crash on reading documents<\/td><td class=\"has-text-align-center\" data-align=\"center\">Read every single document in the inn<\/td><td class=\"has-text-align-center\" data-align=\"center\">Heap-buffer overflow caused by pointer arithmetic<\/td><td>Yes<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Doors not opening<\/td><td class=\"has-text-align-center\" data-align=\"center\">Try to open the first door to the upper right in the starting screen<\/td><td class=\"has-text-align-center\" data-align=\"center\">That (and a few other) doors are supposed to be openable<\/td><td>No<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Crash after saving<\/td><td class=\"has-text-align-center\" data-align=\"center\">Save the game once and walk around the map<\/td><td class=\"has-text-align-center\" data-align=\"center\"><\/td><td>No<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Some of these have already been solved, while the third and fourth seemed low-priority, so I left them for later. The last two bugs were discovered recently and they&#8217;re quite high-priority, due to affecting the gameplay (doors not opening) and being a common source of crash (may crash after saving).<\/p>\n\n\n\n<p>Meanwhile, some of the bugs I mentioned in the last post have also been solved:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sound Issues<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Music volume not syncing to what is on the config at game startup<\/li><\/ul>\n\n\n\n<p>How it was fixed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Music::Music(hResContext *musicRes) : _musicContext(musicRes), _parser(0) {\n...\n\n\t_currentVolume = 255;\n\t_currentMusicBuffer = nullptr;\n\n\t_trackNumber = 0;\n\n+++\tsyncSoundSettings();\n}<\/code><\/pre>\n\n\n\n<p><code>sync<a href=\"https:\/\/doxygen.scummvm.org\/d8\/d9b\/class_engine.html#abbdb6c48eb1e941a997787c124e754db\">SoundSettings<\/a><\/code> is a method for syncing the internal volume with the config.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Notify the engine that the sound settings in the config manager might have changed and that it should adjust any internal volume (and other) values accordingly.<\/p><cite>ScummVM Doxygen<\/cite><\/blockquote>\n\n\n\n<p>Therefore we call it once in the <code>Music<\/code> constructor to initialize its values accordingly to the config manager.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Music does not cut out at zero<\/li><\/ul>\n\n\n\n<p>How it was fixed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>inline int16 quantizedVolume(uint16 trueVolume) {\n\tint16 quantized = trueVolume &amp; 0xFFF8;\n\tquantized += (quantized \/ 16);\n\n\n---\tquantized += 2; \/\/ In ScummVM the range is 0..255\n+++\tquantized = CLIP(quantized, (int16)0, (int16)255);\n\n\treturn quantized;\n}<\/code><\/pre>\n\n\n\n<p>Here <code>quantized<\/code> is the value used for the config manager, which is 0-255 for ScummVM. Thankfully quantized already goes from 0-255 (except when fully maxed, at which point it slightly caps over 255, which is why we clip it).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Document Issues<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Arrow sprites not changing<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>\n\/\/  Sets the mouse pointer imagery\nvoid gMousePointer::setImage(\n    gPixelMap       &amp;img,\n    int             x,\n    int             y) {\n\tPoint16         pos = currentPosition - offsetPosition;\n\n\tif (pointerImage != &amp;img\n\t        ||  x != offsetPosition.x\n\t        ||  y != offsetPosition.y\n\t        ||  img.size != saveMap.size) {\n\t\toffsetPosition.x = x;\n\t\toffsetPosition.y = y;\n        ...\n        }\n...\n}<\/code><\/pre>\n\n\n\n<p>When changing the pointer image (done with <code>gMousePointer::setImage<\/code>) we check whether the <code>img<\/code> pointer changed. However in <code>mouseimg.cpp<\/code> where we call <code>setImage<\/code>,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>createStackedImage(combinedImage, &amp;combinedImageCenter, imageArray, imageCenterArray, imageIndex);\n\nimageOffset.x = combinedImageCenter - mouseImage-&gt;size.x \/ 2;\nimageOffset.y = 0;\n\n\/\/  Set the combined image as the new mouse cursor\ng_vm-&gt;_pointer-&gt;hide();\ng_vm-&gt;_pointer-&gt;setImage(combinedImage, mouseImageOffset.x - imageOffset.x, mouseImageOffset.y - imageOffset.y);\ng_vm-&gt;_pointer-&gt;show();<\/code><\/pre>\n\n\n\n<p><code>combinedImage<\/code> never actually changes value. Therefore we change <code>createStackedImage<\/code> to modify combined <code>combinedImage<\/code> everytime it is called:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void createStackedImage(gPixelMap **newImage, int *newImageCenter, gPixelMap **imageArray, int *imageCenterArray, int images) {\n\tassert(images != 0);\n\n\tif (*newImage)\n\t\tdelete *newImage;\n\n\t*newImage = new gPixelMap;\n...\n}<\/code><\/pre>\n\n\n\n<p>Of course, we modify the usage in the rest of code for this.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Close parchment button not working<\/li><\/ul>\n\n\n\n<p>The cause for this was a typo. Oops.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CDocumentAppearance parchAppearance = {\n\t{202, 54, 208, 256},\n\t1,\n\tpageOrientVertical,\n\tbookTextColors,\n\t{ {27, 18, 149, 212}, {0, 0, 0, 0} },\n--\t{64, 229,  20,  20},\n++\t{164, 229,  20,  20},\n\tparchDecorations,\n\tARRAYSIZE(parchDecorations),\n\tMKTAG('P', 'A', 'R', 'C'),\n\tMKTAG('P', 'C', 'H', 0)\n};<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>Crash on reading Kaidar&#8217;s book<\/li><\/ul>\n\n\n\n<p>The cause for this was a unsigned to signed conversion. Therefore, we make a cast to <code>uint16<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>uint8 *Thread::strAddress(int strNum) {\n\tuint16 seg    = READ_LE_INT16(codeSeg + 2);\n\tuint16 offset = READ_LE_INT16(codeSeg + 4);\n\tuint8 *strSeg = segmentAddress(seg, offset);\n\n\tassert(strNum &gt;= 0);\n\tassert(codeSeg);\n\tassert(strSeg);\n\n---\treturn strSeg + READ_LE_INT16(strSeg + 2 * strNum);\n+++\treturn strSeg + (uint16)READ_LE_INT16(strSeg + 2 * strNum);\n}<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>Crash on Credits<\/li><\/ul>\n\n\n\n<p>The cause for this was a strcat overlap. <em>How did this work in the original, even?<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bool CDocument::checkForPageBreak(char *string, uint16 index, int32 &amp;offset) {\n\n\t\/\/ get the current index into the string\n\tchar    *strIndex       = string + index;\n+++\tchar *strAfter;\n\n\t\/\/ page break detected\n\tif (strIndex&#091;1] == dPageBreak&#091;0] &amp;&amp;\n\t        strIndex&#091;2] == dPageBreak&#091;1]) {\n\t\t\/\/ eat the page breaks chars\n\t\t\/\/ tie off the end\n\t\tstrIndex&#091;0] = 0;\n+++\t\tstrAfter = new char&#091;textSize];\n+++\t\tCommon::strlcpy(strAfter, &amp;strIndex&#091;3], textSize);\n\n\t\t\/\/ string them together\n---\t\tstrcat(&amp;strIndex&#091;0], &amp;strIndex&#091;2 + 1]);\n+++\t\tstrcat(&amp;strIndex&#091;0], strAfter);\n\n\t\t\/\/ take the offset to the end of this line\n\t\toffset = index;\n\n\t\t\/\/ and set the new page flag\n\n+++\t\tdelete&#091;] strAfter;\n\t\treturn true;\n\t}\n\n\treturn false;\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Keyboard<\/h2>\n\n\n\n<p>We change the original game&#8217;s scheme of key recognition to the one found in <code>common\/keyboard.h<\/code>. Therefore we change things like <code>SpecialKey(upArrowKey)<\/code> to <code>Common::KEYCODE_UP<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>switch (key) {\ncase Common::KEYCODE_UP:\n\tselectionUp(1);\n\treturn true;\n\ncase Common::KEYCODE_DOWN:\n\tselectionDown(1);\n\treturn true;\n\ncase Common::KEYCODE_PAGEUP:\n\tselectionUp(linesPerPage);\n\treturn true;\n\ncase Common::KEYCODE_PAGEDOWN:\n\tselectionDown(linesPerPage);\n\treturn true;\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<p>A few weeks left until GSoC ends, while summer break is about to start here. Let&#8217;s do our best.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Time for the weekly progress report! This week I have finals, so studies had to be prioritized, but here is what has progressed since the last report: Bugs Here are the newly identified bugs: Bug Steps to reproduce Explanation Solved The first track played when the game start is random When running in DOSBox, it [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-62","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.scummvm.org\/ayyg\/wp-json\/wp\/v2\/posts\/62","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.scummvm.org\/ayyg\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.scummvm.org\/ayyg\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/ayyg\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/ayyg\/wp-json\/wp\/v2\/comments?post=62"}],"version-history":[{"count":2,"href":"https:\/\/blogs.scummvm.org\/ayyg\/wp-json\/wp\/v2\/posts\/62\/revisions"}],"predecessor-version":[{"id":65,"href":"https:\/\/blogs.scummvm.org\/ayyg\/wp-json\/wp\/v2\/posts\/62\/revisions\/65"}],"wp:attachment":[{"href":"https:\/\/blogs.scummvm.org\/ayyg\/wp-json\/wp\/v2\/media?parent=62"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/ayyg\/wp-json\/wp\/v2\/categories?post=62"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/ayyg\/wp-json\/wp\/v2\/tags?post=62"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}