{"id":16035,"date":"2026-07-02T01:38:59","date_gmt":"2026-07-02T01:38:59","guid":{"rendered":"https:\/\/8657085.xyz\/?p=16035"},"modified":"2026-07-02T01:38:59","modified_gmt":"2026-07-02T01:38:59","slug":"60-fps-on-e-ink-this-game-boy-emulator-shows-it-can-be-done","status":"publish","type":"post","link":"https:\/\/8657085.xyz\/?p=16035","title":{"rendered":"60 FPS on E-Ink? This Game Boy Emulator Shows It Can Be Done"},"content":{"rendered":"<p> <div style=\"display: grid; grid-template-columns: 300px 160px; gap: 2px; width: 460px; background: #eee; padding: 2px;\">\r\n\r\n  <!-- \u6574\u884c\u5bbd\u5e7f\u544a -->\r\n  <div style=\"grid-column: 1\/-1; width: 460px; height: 250px; background: #ccc; display: grid; place-items: center;\">\r\n  <script async type=\"application\/javascript\" src=\"https:\/\/a.magsrv.com\/ad-provider.js\"><\/script> \r\n <ins class=\"eas6a97888e2\" data-zoneid=\"5876674\"><\/ins> \r\n <script>(AdProvider = window.AdProvider || []).push({\"serve\": {}});<\/script>\r\n  <\/div>\r\n  <div style=\"grid-column: 1\/-1; width: 460px; height: 90px; background: #ccc; display: grid; place-items: center;\">\r\n  <script async type=\"application\/javascript\" src=\"https:\/\/a.magsrv.com\/ad-provider.js\"><\/script> \r\n <ins class=\"eas6a97888e2\" data-zoneid=\"5876676\"><\/ins> \r\n <script>(AdProvider = window.AdProvider || []).push({\"serve\": {}});<\/script>\r\n  <\/div>\r\n\r\n  <!-- \u5de6\u4fa7\u7ad6\u6392 -->\r\n  <div style=\"height: 250px; background: #ccc; display: grid; place-items: center;\">\r\n  <script async type=\"application\/javascript\" src=\"https:\/\/a.magsrv.com\/ad-provider.js\"><\/script> \r\n <ins class=\"eas6a97888e2\" data-zoneid=\"5876672\"><\/ins> \r\n <script>(AdProvider = window.AdProvider || []).push({\"serve\": {}});<\/script>\r\n  <\/div>\r\n  <div style=\"height: 500px; background: #ccc; display: grid; place-items: center;\">\r\n  <script async type=\"application\/javascript\" src=\"https:\/\/a.magsrv.com\/ad-provider.js\"><\/script> \r\n <ins class=\"eas6a97888e2\" data-zoneid=\"5876680\"><\/ins> \r\n <script>(AdProvider = window.AdProvider || []).push({\"serve\": {}});<\/script>\r\n  <\/div>\r\n\r\n  <!-- \u53f3\u4fa7\u6469\u5929\u697c\uff08\u548c\u5de6\u4fa7\u5b8c\u5168\u5bf9\u9f50\uff09 -->\r\n  <div style=\"grid-row: 3\/5; height: 750px; background: #ccc; display: grid; place-items: center;\">\r\n  <script async type=\"application\/javascript\" src=\"https:\/\/a.magsrv.com\/ad-provider.js\"><\/script> \r\n <ins class=\"eas6a97888e2\" data-zoneid=\"5876678\"><\/ins> \r\n <script>(AdProvider = window.AdProvider || []).push({\"serve\": {}});<\/script>\r\n  <\/div>\r\n  \r\n  <script async type=\"application\/javascript\" src=\"https:\/\/a.magsrv.com\/ad-provider.js\"><\/script> \r\n <ins class=\"eas6a97888e6\" data-zoneid=\"5876682\"><\/ins> \r\n <script>(AdProvider = window.AdProvider || []).push({\"serve\": {}});<\/script>\r\n<\/div><br \/>\n<\/p>\n<div>\n<p><img decoding=\"async\" src=\"https:\/\/images.techeblog.com\/wp-content\/uploads\/2026\/07\/01175446\/paperboys3-epaper-e-ink-game-boy.jpg\" alt=\"Paper Boy S3 ePaper E-Ink Game Boy\" width=\"960\" height=\"960\"\/><br \/>Wenting Zhang looked at the M5PaperS3 and decided its e-ink screen could do more than display static pages. The compact development board from M5Stack carries an ESP32-S3 processor, a 4.7-inch 960-by-540 e-ink touchscreen, a simple buzzer, and a microSD slot. He turned the whole package into a handheld that runs original Game Boy software at a steady 60 frames per second.<\/p>\n<p><span id=\"more-248703\"\/><br \/><iframe title=\"GameBoy Emulator on ESP32 + Eink (M5Stack PaperS3)\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/oPbOK90aJEo?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><noscript><iframe title=\"GameBoy Emulator on ESP32 + Eink (M5Stack PaperS3)\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/oPbOK90aJEo?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/noscript><br \/>Most e-ink displays are noted for being a little slow. It has a lot to do with how charged particles in the panel take their time drifting into place, thus a full refresh can take hundreds of milliseconds and frequently produces a faint afterimage. Zhang stomped on those physical constraints. He did not simply accept the status quo and dismiss those restrictions as the maximum. Instead, he created a bespoke driver that only works with the display\u2019s low-level parallel interface. This driver holds a super-compact state record for each pixel, with only four bits per dot.<\/p>\n<p>\nThat state buffer receives a new set of image data every sixtieth of a second, while the driver nudges each pixel into place using a series of voltage changes. It\u2019s a clever approach that renders the standard global lock, which requires the entire panel to complete one full cycle before receiving fresh commands, completely obsolete. The Game Boy panels are small (160 by 144 pixels), therefore a crisp threefold upscale with slight dithering is well within the processor\u2019s capabilities. Fortunately, all of the active buffers fit inside the ESP32-S3\u2019s extremely fast internal SRAM.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/images.techeblog.com\/wp-content\/uploads\/2026\/07\/01180321\/paperboys3-epaper-e-ink-game-boy-1.jpg\" alt=\"Paper Boy S3 ePaper E-Ink Game Boy\" width=\"1280\" height=\"1280\"\/><br \/>The two cores on the board function together, with one running the emulator itself. The second core is responsible for processing display updates and sending new data via DMA transfers timed to the vertical sync signal. This preserves the 60 Hz rhythm perfectly on beat even when the emulation workload changes. Zhang tried several Game Boy emulator cores before settling on CrankBoy, an optimized fork of Peanut GB. It provided the best trade-off between speed and compatibility on this hardware. Most games run close to full speed. The system will skip the odd frame to keep the timing just perfect for sound and input in the event of a demanding situation. Unfortunately, Game Boy Color titles remain out of reach for the time being due to their roughly doubled processing demand.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/images.techeblog.com\/wp-content\/uploads\/2026\/07\/01180329\/paperboys3-epaper-e-ink-game-boy-2.jpg\" alt=\"Paper Boy S3 ePaper E-Ink Game Boy\" width=\"1280\" height=\"1280\"\/><br \/>The sound emanates from a single buzzer on the board. Zhang created a rapid-switching scheme that cycles between crude approximations of the four original Game Boy audio channels. The end output is recognized chiptune music rather than exact waveform playback, but it preserves the essence of the games without the need for additional gear. The touchscreen includes all of the controls. The panel\u2019s lower portion displays a Game Boy-style directional pad and various action buttons. Any taps register right away. There is experimental Bluetooth LE gamepad support, although it only works with a limited number of controllers right now.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/images.techeblog.com\/wp-content\/uploads\/2026\/07\/01180333\/paperboys3-epaper-e-ink-game-boy-3.jpg\" alt=\"Paper Boy S3 ePaper E-Ink Game Boy\" width=\"1280\" height=\"1280\"\/><br \/>Saved data is stored on the microSD card, and the hardware power button only cuts power, with no shutdown process (Zhang added a manual save button to the screen). Quick save states add an extra degree of security during lengthy gaming sessions. The entire project\u2019s source code (known as Paper Boy S3 in some places) is now available on GitLab. There\u2019s also a separate proof-of-concept JIT recompiler that another developer worked on, demonstrating one approach to go even faster if someone wants to take it a step further.<br \/><span>[Source]<\/span><\/p>\n<\/p><\/div>\n<p><!-- \u603b\u5bb9\u5668\uff1a\u6700\u5927\u5bbd908px Grid\u7d27\u51d1\u5e03\u5c40 -->\r\n<div style=\"display: grid; grid-template-columns: 728px 160px; gap:2px; width:908px; background:#eee; padding:2px;\">\r\n\r\n  <!-- \u901a\u680f\u9876\u90e8\uff1a\u6700\u5927\u6a2a\u5e45 908x258 \u8de8\u6574\u884c -->\r\n  <div style=\"grid-column:1\/-1; height:258px; background:#ff6b6b; display:grid; place-items:center;\">\r\n    <!-- JuicyAds v3.0 -->\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async src=\"https:\/\/poweredby.jads.co\/js\/jads.js\"><\/script>\r\n<ins id=\"1114307\" data-width=\"908\" data-height=\"258\"><\/ins>\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async>(adsbyjuicy = window.adsbyjuicy || []).push({'adzone':1114307});<\/script>\r\n<!--JuicyAds END-->\r\n  <\/div>\r\n\r\n  <!-- \u7b2c\u4e8c\u901a\u680f\uff1a728\u00d790 \u901a\u680f -->\r\n  <div style=\"grid-column:1\/-1; height:90px; background:#4ecdc4; display:grid; place-items:center;\">\r\n    <!-- JuicyAds v3.0 -->\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async src=\"https:\/\/poweredby.jads.co\/js\/jads.js\"><\/script>\r\n<ins id=\"1114300\" data-width=\"728\" data-height=\"90\"><\/ins>\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async>(adsbyjuicy = window.adsbyjuicy || []).push({'adzone':1114300});<\/script>\r\n<!--JuicyAds END-->\r\n  <\/div>\r\n\r\n  <!-- \u5de6\u4fa7\u4e3b\u680f\uff1a\u591a\u5e7f\u544a\u5806\u53e0 -->\r\n  <div style=\"display:grid; gap:2px;\">\r\n    <div style=\"height:60px; background:#45b7d1; display:grid; place-items:center;\">\r\n\t<!-- JuicyAds v3.0 -->\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async src=\"https:\/\/poweredby.jads.co\/js\/jads.js\"><\/script>\r\n<ins id=\"1114308\" data-width=\"468\" data-height=\"60\"><\/ins>\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async>(adsbyjuicy = window.adsbyjuicy || []).push({'adzone':1114308});<\/script>\r\n<!--JuicyAds END-->\r\n\t<\/div>\r\n    <div style=\"height:250px; background:#ffe066; display:grid; place-items:center;\">\r\n\t<!-- JuicyAds v3.0 -->\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async src=\"https:\/\/poweredby.jads.co\/js\/jads.js\"><\/script>\r\n<ins id=\"1114299\" data-width=\"300\" data-height=\"250\"><\/ins>\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async>(adsbyjuicy = window.adsbyjuicy || []).push({'adzone':1114299});<\/script>\r\n<!--JuicyAds END-->\r\n\t<\/div>\r\n    <div style=\"height:250px; background:#ff9ecd; display:grid; place-items:center;\">\r\n\t<!-- JuicyAds v3.0 -->\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async src=\"https:\/\/poweredby.jads.co\/js\/jads.js\"><\/script>\r\n<ins id=\"1114305\" data-width=\"250\" data-height=\"250\"><\/ins>\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async>(adsbyjuicy = window.adsbyjuicy || []).push({'adzone':1114305});<\/script>\r\n<!--JuicyAds END-->\r\n\t<\/div>\r\n    <div style=\"height:139px; background:#c792ea; display:grid; place-items:center;\">\r\n\t<!-- JuicyAds v3.0 -->\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async src=\"https:\/\/poweredby.jads.co\/js\/jads.js\"><\/script>\r\n<ins id=\"1114302\" data-width=\"133\" data-height=\"139\"><\/ins>\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async>(adsbyjuicy = window.adsbyjuicy || []).push({'adzone':1114302});<\/script>\r\n<!--JuicyAds END-->\r\n\t<\/div>\r\n    <div style=\"height:125px; background:#91e7ac; display:grid; place-items:center;\">\r\n\t\r\n<!-- JuicyAds v3.0 -->\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async src=\"https:\/\/poweredby.jads.co\/js\/jads.js\"><\/script>\r\n<ins id=\"1114303\" data-width=\"125\" data-height=\"125\"><\/ins>\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async>(adsbyjuicy = window.adsbyjuicy || []).push({'adzone':1114303});<\/script>\r\n<!--JuicyAds END-->\r\n\t<\/div>\r\n  <\/div>\r\n\r\n  <!-- \u53f3\u4fa7\u7ad6\u680f\uff1a160\u00d7600 \u6574\u5217\u9ad8\u5e7f\u544a -->\r\n  <div style=\"grid-row:3\/8; height:600px;  display:grid; place-items:center;\">\r\n    <!-- JuicyAds v3.0 -->\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async src=\"https:\/\/poweredby.jads.co\/js\/jads.js\"><\/script>\r\n<ins id=\"1114301\" data-width=\"160\" data-height=\"600\"><\/ins>\r\n<script type=\"text\/javascript\" data-cfasync=\"false\" async>(adsbyjuicy = window.adsbyjuicy || []).push({'adzone':1114301});<\/script>\r\n<!--JuicyAds END-->\r\n  <\/div>\r\n\r\n<\/div><br \/>\n<br \/> 60 FPS on E-Ink? This Game Boy Emulator Shows It Can Be Done<br \/>\n<br \/>#FPS #EInk #Game #Boy #Emulator #Shows<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wenting Zhang looked at the M5PaperS3 and decided its e-ink screen could do more than&#8230;<\/p>\n","protected":false},"author":1,"featured_media":16036,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[649,3885,13607,13606,232,249],"class_list":["post-16035","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech","tag-boy","tag-eink","tag-emulator","tag-fps","tag-game","tag-shows"],"featured_image_urls":{"full":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy.jpg",960,960,false],"thumbnail":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy-150x150.jpg",150,150,true],"medium":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy-300x300.jpg",300,300,true],"medium_large":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy-768x768.jpg",640,640,true],"large":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy.jpg",640,640,false],"1536x1536":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy.jpg",960,960,false],"2048x2048":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy.jpg",960,960,false],"covernews-slider-full":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy-960x715.jpg",960,715,true],"covernews-slider-center":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy-800x500.jpg",800,500,true],"covernews-featured":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy.jpg",960,960,false],"covernews-medium":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy-540x340.jpg",540,340,true],"covernews-medium-square":["https:\/\/8657085.xyz\/wp-content\/uploads\/2026\/07\/paperboys3-epaper-e-ink-game-boy-400x250.jpg",400,250,true]},"author_info":{"display_name":"admin","author_link":"https:\/\/8657085.xyz\/?author=1"},"category_info":"<a href=\"https:\/\/8657085.xyz\/?cat=8\" rel=\"category\">Tech<\/a>","tag_info":"Tech","comment_count":"0","_links":{"self":[{"href":"https:\/\/8657085.xyz\/index.php?rest_route=\/wp\/v2\/posts\/16035","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/8657085.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/8657085.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/8657085.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/8657085.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=16035"}],"version-history":[{"count":0,"href":"https:\/\/8657085.xyz\/index.php?rest_route=\/wp\/v2\/posts\/16035\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/8657085.xyz\/index.php?rest_route=\/wp\/v2\/media\/16036"}],"wp:attachment":[{"href":"https:\/\/8657085.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16035"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/8657085.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=16035"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/8657085.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=16035"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}