{"id":401,"date":"2021-12-02T22:15:39","date_gmt":"2021-12-02T22:15:39","guid":{"rendered":"https:\/\/writingagame.com\/?p=401"},"modified":"2021-12-02T22:19:08","modified_gmt":"2021-12-02T22:19:08","slug":"chapter-8-external-data-files-android-assets","status":"publish","type":"post","link":"https:\/\/writingagame.com\/index.php\/2021\/12\/02\/chapter-8-external-data-files-android-assets\/","title":{"rendered":"Chapter 8. External data files, Android assets"},"content":{"rendered":"\n<p>The idea is the same as in previous chapter &#8211; to place the data files within the reach of the executable. However, in Android&#8217;s case we are dealing NOT with the &#8220;executable&#8221;, but with APK. Besides, we have to deliver data files not just to different folder, but to different device. The only &#8220;transport&#8221; (known to me) is a special &#8220;<strong>assets<\/strong>&#8221; folder that can be embedded into APK, that will be eventually installed on destination device. So, let&#8217;s create it.<\/p>\n\n\n\n<p>1. Start Visual Studio, open <em>C:\\CPP\\a999hello\\p_android\\p_android.sln<\/em> solution.<br>Right-click on  <em>p_android.Packaging<\/em> project (NOT <em>p_android.NativeActivity<\/em> as usual, but  <em>p_android.<\/em><strong><em>Packaging<\/em> <\/strong>). <em>Add -&gt; New <strong>Folder<\/strong><\/em>, call it <strong>assets<\/strong>. It&#8217;s a special reserved name,  <em>p_android.Packaging<\/em> will know what to do with it.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>2. Now, open  <em>p_android.NativeActivity<\/em>  project Properties, All Configurations \/ ARM64, go to <em>Configuration Properties -&gt; Build Events -&gt; Post-Build Event -&gt; Command Line -&gt; Edit<\/em>, add command<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>xcopy \"..\\..\\..\\engine\\dt\\*.*\" \"..\\$(RootNamespace).Packaging\\assets\\dt\\\" \/E \/R \/D \/y<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Ok, Apply, Ok<\/p>\n\n\n\n<p>Clarification:<\/p>\n\n\n\n<p> &#8220;<strong>..\\..\\..\\engine\\dt\\*.*<\/strong>&#8221;  &#8211; copy from. Unlike in Windows, here we have to go 1 folder level higher.<\/p>\n\n\n\n<p>&#8220;..\\$(RootNamespace).Packaging\\assets\\dt\\&#8221; &#8211; copy to where. Since this command will be executed from  <em>p_android.NativeActivity<\/em>  folder, we need to step 1 folder level up and proceed to  <em>p_android.Packaging<\/em> folder and then to <em>assets<\/em>.<\/p>\n\n\n\n<p>The rest is the same as for Windows.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\"><li><em>VS top menu -&gt; Build -&gt; Rebuild Solution<\/em>. Result: \u201c2 succeeded, 0 failed, 0 skipped\u201d.<\/li><\/ol>\n\n\n\n<p>Now, if we open <em>C:\\CPP\\a999hello\\p_android\\p_android.Packaging\\assets<\/em> folder (in <strong>Windows File Explorer<\/strong>, not in VS), we&#8217;ll find there our &#8220;dt&#8221;. Now it&#8217;s also supposed to be included in the APK as well. But, to my big surprise, it is not. No trace of test0.txt file in the APK (which is located at <em>C:\\CPP\\a999hello\\p_android\\p_android.Packaging\\ARM64\\Debug<\/em>).<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>4. It turned out that we had to manually add each file and folder to assets, as we usually do with program files (right-click, add item, and so on). This is a BIG problem. Obviously, we will have a huge number of these files and folders: shaders, models, textures, etc. It is simply impossible to keep track of this. We need to somehow force the assets folder to automatically fetch its contents.<\/p>\n\n\n\n<p>The solution did not come easy, had to dive VERY deep, but NOW I know<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to add files to Android assets in Visual Studio<\/h2>\n\n\n\n<p>In Android Studio (as opposed to Visual Studio), anything placed in the <em>assets <\/em>folder will be automatically included into APK. To reproduce this behavior, we need to edit <em>p_android.Packaging<\/em> project file:<\/p>\n\n\n\n<p>Close Visual Studio.<\/p>\n\n\n\n<p>In a <strong>Text Editor<\/strong> open <em>C:\\CPP\\a999hello\\p_android\\p_android.Packaging\\p_android.Packaging.androidproj<\/em><\/p>\n\n\n\n<p>Scroll down. Closer to the end you will see the section:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  &lt;ItemGroup&gt;\n    &lt;Content Include=\"res\\values\\strings.xml\" \/&gt;\n    &lt;AntBuildXml Include=\"build.xml\" \/&gt;\n    &lt;AndroidManifest Include=\"AndroidManifest.xml\" \/&gt;\n    &lt;AntProjectPropertiesFile Include=\"project.properties\" \/&gt;\n  &lt;\/ItemGroup&gt;\n<\/code><\/pre>\n\n\n\n<p>In the top of this section add:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;Content Include=\"assets\\**\" \/&gt;<\/code><\/pre>\n\n\n\n<p>so the section will now be:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; highlight: [2]; title: ; notranslate\" title=\"\">\n  &lt;ItemGroup&gt;\n    &lt;Content Include=&quot;assets\\**&quot; \/&gt;\n    &lt;Content Include=&quot;res\\values\\strings.xml&quot; \/&gt;\n    &lt;AntBuildXml Include=&quot;build.xml&quot; \/&gt;\n    &lt;AndroidManifest Include=&quot;AndroidManifest.xml&quot; \/&gt;\n    &lt;AntProjectPropertiesFile Include=&quot;project.properties&quot; \/&gt;\n  &lt;\/ItemGroup&gt;\n\n<\/pre><\/div>\n\n\n<p><\/p>\n\n\n\n<p><strong>Save<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>5. Start Visual Studio, open  <em>C:\\CPP\\a999hello\\p_android\\p_android.sln<\/em> solution.<\/p>\n\n\n\n<p><em>Top menu -&gt; Build -&gt; Rebuild solution<\/em>. Result: &#8220;2 succeeded, 0 failed, 0 skipped&#8221;.<\/p>\n\n\n\n<p>Now, if you open <em>C:\\CPP\\a999hello\\p_android\\p_android.Packaging\\ARM64\\Debug\\p_android.apk<\/em> in a <strong>text editor<\/strong>, you can make sure that the test0.txt file is there.<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"https:\/\/writingagame.com\/img\/b01\/c08\/01.jpg\"><\/p>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>6. So now we can read the file on Android?? Most certainly. The code: <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n\t\/\/reading test file\n\tchar buff&#91;256];\n\tAAssetManager* am = androidApp-&gt;activity-&gt;assetManager;\n\tAAsset* asset = AAssetManager_open(am, &quot;dt\/shaders\/test0.txt&quot;, AASSET_MODE_UNKNOWN);\n\tif (asset != NULL) {\n\t\tlong size = AAsset_getLength(asset);\n\t\tAAsset_read(asset, buff, size);\n\t\tmylog(&quot;File size = %d, text:\\n%s\\n&quot;, size, buff);\n\t\tAAsset_close(asset);\n\t}\n\telse {\n\t\tmylog(&quot;Asset not found.\\n&quot;);\n\t}\n\n<\/pre><\/div>\n\n\n<p><\/p>\n\n\n\n<p>Open <em>main.cpp<\/em>. Scroll down. Insert this code right before <em>theGame.run()<\/em>.<\/p>\n\n\n\n<p>Switch on, <strong>unlock <\/strong>and plug in Android, allow debugging.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Open Logcat first (VS top menu -&gt; <em>Tools -&gt; Android Tools -&gt; Logcat<\/em>), in search field type &#8220;<strong>mylog<\/strong>&#8220;, Enter. If necessary &#8211; clean the screen (red cross icon in Logcat&#8217;s menu).<\/li><\/ul>\n\n\n\n<p>Now &#8211; build and run (green arrow). Re-open Logcat if closed. Result:<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"https:\/\/writingagame.com\/img\/b01\/c08\/02.jpg\"><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Now what? Shaders??<\/p>\n\n\n\n<p>No, not yet, not yet\u2026<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"https:\/\/writingagame.com\/img\/b01\/c08\/03.jpg\"><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>To be continued\u2026<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n","protected":false},"excerpt":{"rendered":"<p class=\"mb-2\">The idea is the same as in previous chapter &#8211; to place the data files within the reach of the executable. However, in Android&#8217;s case we are dealing NOT with the &#8220;executable&#8221;, but with APK. Besides, we have to deliver data files not just to different folder, but to different device. The only &#8220;transport&#8221; (known [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-401","post","type-post","status-publish","format-standard","hentry","category-cross-platform-3d"],"_links":{"self":[{"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/posts\/401","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/comments?post=401"}],"version-history":[{"count":13,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/posts\/401\/revisions"}],"predecessor-version":[{"id":417,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/posts\/401\/revisions\/417"}],"wp:attachment":[{"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/media?parent=401"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/categories?post=401"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/tags?post=401"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}