{"id":685,"date":"2015-12-25T16:27:53","date_gmt":"2015-12-25T15:27:53","guid":{"rendered":"http:\/\/blog.blockos.org\/?p=685"},"modified":"2015-12-25T16:27:53","modified_gmt":"2015-12-25T15:27:53","slug":"8bit-archeology-returns","status":"publish","type":"post","link":"https:\/\/blog.blockos.org\/?p=685","title":{"rendered":"8bit archeology returns"},"content":{"rendered":"<p>While working on <a href=\"http:\/\/www.romhacking.net\/translations\/1637\/\">M\u00e4rchen Maze<\/a> translation I checked if other Namcot games use the same image encoding format. It appears that not only some Namcot games use it but there are Pack-In-Video games as well. Maybe the same subcontractor studio was involved.<br \/>\nAnyway, here is the list of the games I checked so far. <\/p>\n<ul>\n<li><a href=\"http:\/\/www.videogameden.com\/hucard.htm?mma\">M\u00e4rchen Maze<\/a><\/li>\n<li><a href=\"http:\/\/www.videogameden.com\/hucard.htm?obo\">Obocchama Kun<\/a><\/li>\n<li><a href=\"http:\/\/www.pcengine.co.uk\/HTML_Games\/World_Jockey.htm\">World Jockey<\/a><\/li>\n<li><a href=\"http:\/\/www.videogameden.com\/hucard.htm?zip\">Zipang<\/a><\/li>\n<\/ul>\n<p>The encoding is pretty simple. The image is split in 32 bytes blocs. Each bloc can be encoded using one of he following 4 techniques :<\/p>\n<ol start=\"0\">\n<li>0 filled : the bloc is filled with 0. A plain old memset is enough.\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">memset(out, 0, 32)<\/pre>\n<\/li>\n<li>Sparse : the bloc contains 0 bytes. The first 4 bytes indicates if the corresponding bloc byte is 0 or read from the data buffer.\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">uint8_t *input; \/\/ pointer to encoded input data.\r\nuint8_t *out;   \/\/ pointer to output data.\r\n\/\/ ...\r\n\/\/ sparse_decode\r\nint i, j;\r\nuint8_t *header = input;\r\nuint8_t *data   = input+4;\r\nuint8_t  bit;\r\nfor(i=0; i&lt;4; i++)\r\n{\r\n    bit = header[i];\r\n    for(j=0; j&lt;8; j++)\r\n    {\r\n        *out++ = (bit &amp; 1) ? *data++ : 0x00;\r\n        bit &gt;&gt;= 1;\r\n    }\r\n}\r\n<\/pre>\n<\/li>\n<li>XOR Sparse : Just like the &#8220;sparse&#8221; encoding but the bloc was previously processed using a sequence of xor on each consecutive 16 bytes in order to increase the number of 0 in the bloc.\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">sparse_decode(out, input);\r\n\/\/ xor\r\nfor(i=0; i&lt;16; i+=2)\r\n{\r\n    out[i+0x02] ^= out[i+0x00];\r\n    out[i+0x03] ^= out[i+0x01];\r\n    out[i+0x12] ^= out[i+0x10];\r\n    out[i+0x13] ^= out[i+0x11];\r\n} \r\n<\/pre>\n<\/li>\n<li>Raw : the bloc data is stored unencoded, just call\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">memcpy(out, data, 32)<\/pre>\n<\/li>\n<\/ol>\n<p>The encoding type is packed in 4 bits stored separately from the image data. This means that a byte stores the encoding type for 4 blocs.<\/p>\n<p>The pseudo code for the whole decoding routine looks like this.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nuint8_t *encoding; \/\/ pointer to the bloc encoding type array.\r\nuint8_t *data;     \/\/ pointer to the encoded image data.\r\nuint8_t *out;      \/\/ pointer to the output image data.\r\nsize_t bloc_count;\r\nuint8_t current_bloc_encoding;\r\nint i;\r\n\r\nfor(i=0; i&lt;bloc_count; i++)\r\n{\r\n    current_bloc_encoding = (encoding[i\/4] &gt;&gt; (i%4)) &amp; 0x03;\r\n    switch(current_bloc_encoding)\r\n    {\r\n        case 0: \/\/ zero filled.\r\n            memset(out, 0, 32);\r\n            break;\r\n        case 1: \/\/ sparse.\r\n            sparse_decode(out, data);\r\n            break;\r\n        case 2: \/\/ XOR sparse.\r\n            sparse_decode(out, data);\r\n            xor(out);\r\n            break;\r\n        case 3: \/\/ raw data.\r\n            memcpy(out, data, 32);\r\n            data += 32;\r\n            break;\r\n    }\r\n    out += 32;\r\n}\r\n<\/pre>\n<ul>\n<li><a href=\"http:\/\/blockos.org\/releases\/pcengine\/translation\/Obochama%20Kun\/extractGfx.c\" target=\"_blank\">Source code<\/a> for M\u00e4rchen Maze, Obocchama Kun and Zipang.<\/li>\n<li><a href=\"http:\/\/blockos.org\/releases\/pcengine\/translation\/World%20Jockey\/extractGfx.c\">Source code<\/a> for World Jockey.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>While working on M\u00e4rchen Maze translation I checked if other Namcot games use the same image encoding format. It appears that not only some Namcot games use it but there are Pack-In-Video games as well. Maybe the same subcontractor studio was involved. Anyway, here is the list of the games\u2026 <a class=\"continue-reading-link\" href=\"https:\/\/blog.blockos.org\/?p=685\">Continue reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,6],"tags":[27,30],"_links":{"self":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/685"}],"collection":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=685"}],"version-history":[{"count":24,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/685\/revisions"}],"predecessor-version":[{"id":1041,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/685\/revisions\/1041"}],"wp:attachment":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=685"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=685"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=685"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}