{"id":23004370,"url":"https://github.com/amjad50/plastic","last_synced_at":"2025-05-14T21:08:11.483Z","repository":{"id":37178033,"uuid":"272356819","full_name":"Amjad50/plastic","owner":"Amjad50","description":"NES emulator in rust with egui and TUI","archived":false,"fork":false,"pushed_at":"2024-12-28T04:50:15.000Z","size":4885,"stargazers_count":498,"open_issues_count":8,"forks_count":18,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-14T02:58:20.928Z","etag":null,"topics":["emulator","hacktoberfest","nes","nes-emulator","ratatui","rust","terminal","tui"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Amjad50.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-15T06:13:17.000Z","updated_at":"2025-04-13T10:15:33.000Z","dependencies_parsed_at":"2024-10-25T12:49:39.387Z","dependency_job_id":"f6dbd69f-6c2f-48de-ac45-95c6d1164953","html_url":"https://github.com/Amjad50/plastic","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amjad50%2Fplastic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amjad50%2Fplastic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amjad50%2Fplastic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amjad50%2Fplastic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Amjad50","download_url":"https://codeload.github.com/Amjad50/plastic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248813789,"owners_count":21165633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["emulator","hacktoberfest","nes","nes-emulator","ratatui","rust","terminal","tui"],"created_at":"2024-12-15T07:18:15.784Z","updated_at":"2025-04-14T02:58:27.768Z","avatar_url":"https://github.com/Amjad50.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003c!-- Really ugly workaround, but the image isn't working in crates.io without this --\u003e\n  \u003ca href=\"https://github.com/Amjad50/plastic\"\u003e\u003cimg alt=\"plastic\" src=\"https://raw.githubusercontent.com/Amjad50/plastic/refs/heads/master/images/logo.svg\" width=\"60%\"\u003e\u003c/a\u003e\n  \u003cp align=\"center\"\u003eNES emulator in \u003cem\u003eRust\u003c/em\u003e\u003c/p\u003e\n\u003c/p\u003e\n\n\n[![Build status](https://github.com/Amjad50/plastic/workflows/Rust/badge.svg)](https://actions-badge.atrox.dev/Amjad50/plastic/goto)\n[![codecov](https://codecov.io/gh/Amjad50/plastic/branch/master/graph/badge.svg)](https://codecov.io/gh/Amjad50/plastic)\n[![dependency status](https://deps.rs/repo/github/Amjad50/plastic/status.svg)](https://deps.rs/repo/github/Amjad50/plastic)\n[![license](https://img.shields.io/github/license/Amjad50/plastic)](./LICENSE)\n\u003cbr\u003e\n[![Crates.io Version](https://img.shields.io/crates/v/plastic_core?label=plastic_core)](https://crates.io/crates/plastic_core)\n[![docs.rs](https://img.shields.io/docsrs/plastic_core)](https://docs.rs/plastic_core/latest/plastic_core/)\n\u003cbr\u003e\n[![Crates.io Version](https://img.shields.io/crates/v/plastic?label=plastic)](https://crates.io/crates/plastic)\n[![Crates.io Version](https://img.shields.io/crates/v/plastic_tui?label=plastic_tui)](https://crates.io/crates/plastic_tui)\n\n\n**plastic** is a [NES][NES-wiki] emulator built from scratch using [Rust][Rust].\n\nThis is a personal project for fun and to experience emulating hardware and connecting them together.\n\n- [Building and installation](#building-and-installation)\n  - [Dependencies](#dependencies)\n  - [Installing](#installing)\n  - [Building](#building)\n- [Components](#components)\n- [Interfaces](#interfaces)\n  - [EGui UI](#ui)\n  - [TUI](#tui)\n- [Controls](#controls)\n  - [Keyboard](#keyboard)\n  - [Gamepad](#gamepad)\n- [License](#license)\n- [References](#references)\n\n### Building and installation\n\n#### Dependencies\n\nFor linux, this project depends on `alsa` and `libudev`, you can install them using:\n```sh\n# Debian/Ubuntu\nsudo apt install libasound2-dev libudev-dev\n# Arch\nsudo pacman -S alsa-lib systemd-libs\n```\n\n#### Installing\nYou can install the latest version of [plastic](https://crates.io/crates/plastic) or [plastic_tui](https://crates.io/crates/plastic_tui) using cargo:\n```sh\ncargo install plastic\ncargo install plastic_tui\n```\n\nIf you are using Debian/Ubuntu, you can directly install the `.deb` package from [here](https://nightly.link/Amjad50/plastic/workflows/rust/master/plastic.deb.zip)\n```sh\nunzip plastic.deb.zip\nsudo dpkg -i plastic_*.deb # will have the version in the name\n```\n\nIf you are using Arch Linux, `plastic` is available in the [official repositories](https://archlinux.org/packages/extra/x86_64/plastic/):\n\n```sh\npacman -S plastic\npacman -S plastic_tui\n```\n\n#### Building\nIf you want to experience the latest development version, you can build `Plastic` yourself.\nFor example:\n```\ncargo run --release\n```\n\n### Components\n- [x] 6502 CPU, all official and unofficial instructions with accurate timing (without BCD mode).\n- [x] Picture Processing Unit, almost accurate with some small timing issues that would not effect most games.\n- [x] Cartridge and INES file handling (still missing INES2.0)\n- [x] Mappers:\n  - [x] Mapper 0\n  - [x] Mapper 1\n  - [x] Mapper 2\n  - [x] Mapper 3\n  - [x] Mapper 4\n  - [ ] Mapper 5 (Milestone)\n  - [ ] Mapper 6\n  - [x] Mapper 7\n  - [ ] Mapper 8\n  - [x] Mapper 9\n  - [x] Mapper 10\n  - [x] Mapper 11\n  - [x] Mapper 66 \n- [x] Audio Processing Unit:\n  - [x] 2 Pulse wave(square)\n  - [x] Triangle\n  - [x] Noise\n  - [x] DMC\n  - [x] IRQ support\n- [x] Controller:\n  controllable using the keyboard and controller (tested with PS4 controller)\n\n### Interfaces\n\nThe main emulator is at [`plastic_core`](./plastic_core/)\nAnd its a struct `NES`, where the UI would clock it, and then\ntake the resulting audio and pixel buffers to handle them.\n\nWe have 2 UIs, one main and the other just for fun.\n\n#### EGui UI\nSimple ui built with [egui]\n\n\u003c!-- omit in toc --\u003e\n##### Advantages\n1. Very simple and easy to use immediate mode UI.\n\n#### TUI\n[![TUI demo](images/tui_demo.gif)](https://www.youtube.com/watch?v=3wKILnY0AHU)\n\nThis is just for fun, but it is actually working way better than\nI expected. Check the [full demo](https://www.youtube.com/watch?v=3wKILnY0AHU).\n\nIf you have one of these terminals mentioned [in this docs](https://docs.rs/crossterm/0.28.1/crossterm/event/struct.PushKeyboardEnhancementFlags.html)\nThen you will have a much better experience, since these terminals support detecting button `Release`, normally other terminals don't have this feature, so\nthe input for this UI can be a bit wonky.\n\nI used [gilrs][gilrs] for gamepad support and its working very\nnicely, keyboard on the other hand is not very responsive, so it\nis advised to use gamepad. Also since this uses one character for\neach pixel, it is advised to use the smallest font size your\nterminal emulator supports. Have fun.\n\nThe gamepad support is for both UIs.\n\n### Controls\nIn all the UI providers I followed the same controlling scheme,\nas well as the ability to reset through `\u003cCTRL-R\u003e`:\n\n#### Keyboard\n| keyboard | nes controller |\n| -------- | -------------- |\n| J | B |\n| K | A |\n| U | Select |\n| I | Start |\n| W | Up |\n| S | Down |\n| A | Left |\n| D | Right |\n\n#### Gamepad\n| gamepad (PS4) | nes controller |\n| -------- | -------------- |\n| X | B |\n| O | A |\n| Select | Select |\n| Start | Start |\n| Button Up | Up |\n| Button Down | Down |\n| Button Left | Left |\n| Button Right | Right |\n\nFor now its static, and there is no way to change it except for\ndoing it in the code, TODO later.\n\n### License\nThis project is under [MIT](./LICENSE) license.\n\nNES is a product and/or trademark of Nintendo Co., Ltd. Nintendo Co., Ltd. and is not affiliated in any way with Plastic or its author\n\n### References\nMost of the documentation for NES components can be found in the [NES dev wiki](http://wiki.nesdev.com/w/index.php/Nesdev_Wiki)\n\nFor the CPU(6502), [this](https://www.masswerk.at/6502/6502_instruction_set.html) has the instruction set, and I used\n[Klaus2m5's tests](https://github.com/Klaus2m5/6502_65C02_functional_tests) for testing the CPU alone without the other NES components.\n\n\n\n[NES-wiki]: https://en.wikipedia.org/wiki/Nintendo_Entertainment_System\n[Rust]: https://www.rust-lang.org/\n[gilrs]: https://gitlab.com/gilrs-project/gilrs\n[egui]: https://github.com/emilk/egui\n[ratatui]: https://github.com/ratatui/ratatui\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famjad50%2Fplastic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famjad50%2Fplastic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famjad50%2Fplastic/lists"}