{"id":50732376,"url":"https://github.com/pepijn-devries/ramiga","last_synced_at":"2026-06-10T10:01:11.846Z","repository":{"id":352824446,"uuid":"1209851010","full_name":"pepijn-devries/ramiga","owner":"pepijn-devries","description":"R package for Emulating the Amiga Using the vAmiga Engine","archived":false,"fork":false,"pushed_at":"2026-05-28T20:31:52.000Z","size":2637,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-28T22:12:03.399Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pepijn-devries.github.io/ramiga/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pepijn-devries.png","metadata":{"files":{"readme":"README.Rmd","changelog":"NEWS.md","contributing":null,"funding":null,"license":"LICENSE.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-13T21:02:12.000Z","updated_at":"2026-05-28T20:21:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pepijn-devries/ramiga","commit_stats":null,"previous_names":["pepijn-devries/ramiga"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pepijn-devries/ramiga","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pepijn-devries%2Framiga","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pepijn-devries%2Framiga/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pepijn-devries%2Framiga/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pepijn-devries%2Framiga/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pepijn-devries","download_url":"https://codeload.github.com/pepijn-devries/ramiga/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pepijn-devries%2Framiga/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34146870,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2026-06-10T10:01:09.831Z","updated_at":"2026-06-10T10:01:11.831Z","avatar_url":"https://github.com/pepijn-devries.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: github_document\n---\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n```\n\n# ramiga \u003ca href=\"https://pepijn-devries.github.io/ramiga/\"\u003e\u003cimg src=\"man/figures/logo.svg\" align=\"right\" height=\"139\" alt=\"ramiga website\" /\u003e\u003c/a\u003e\n\n\u003c!-- badges: start --\u003e\n![Status: Experimental](https://img.shields.io/badge/status-experimental-orange)\n[![R-CMD-check](https://github.com/pepijn-devries/ramiga/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/pepijn-devries/ramiga/actions/workflows/R-CMD-check.yaml)\n\u003c!-- badges: end --\u003e\n\nThe status of this package is currently highly experimental. It provides R\nbindings to the [vAmiga](https://github.com/dirkwhoffmann/vamiga) emulator.\n\nIt will:\n\n  * Provide programmatic access to the emulator\n  * Emulate Amiga's with the original chip set.\n    * So, neither enhanced chip set nor the Advanced Graphics Architecture\n      are supported\n  * Capture output\n  * Provide input (mouse movements, keyboard events, etc.) programmatically\n\nIt will **not**:\n\n  * Provide full interactive visuals and peripherals\n    * There is simply no way to exchange this information between\n      the R environment and the emulator with sufficient speed and efficiency.\n\n## Installation\n\nYou can install the development version of ramiga like so:\n\n```{r github, eval=FALSE}\nremotes::install_github(\"pepijn-devries/ramiga\")\n```\n\nIf available for your OS, you can install from R-Universe:\n\n```{r r-univers, eval=FALSE}\ninstall.packages(\"ramiga\", repos = c('https://pepijn-devries.r-universe.dev', 'https://cloud.r-project.org'))\n```\n\n## Example\n\nIn order to get started, you need to create a new RamigaEmulator object.\nAs the emulator only emulates the Commodore Amiga machine, you\nneed to provide a ROM image. For this you could use official licensed\nKickstart ROM images, or you use an AROS ROM image, which is released\nin the public domain. In the example below we start the machine with\nthe AROS ROM, for which we also need the extension.\n\n```{r initiate}\nlibrary(ramiga)\nemu \u003c- RamigaEmulator$new()\n\nemu$memory$load_rom(\n  \"https://github.com/vAmigaWeb/vAmigaWeb/raw/refs/heads/main/roms/aros-rom-20250219.bin\")\n\nemu$memory$load_rom_extension(\n  \"https://github.com/vAmigaWeb/vAmigaWeb/raw/refs/heads/main/roms/aros-ext-20250219.bin\")\n```\n\nNext we load a disk image, which represents a virtual floppy disk.\nWe use the 'State of the Art' demo by Spaceballs as an ultimate\n90s test case. We insert the virtual disk in the first floppy\ndrive of the emulator, then power on the virtual machine.\n\n```{r insert-disk}\ndisk \u003c- RamigaImage$new(\n  \"https://ftp.amigascne.org/pub/amiga/Groups/S/Spaceballs/Spaceballs-StateOfTheArt.dms\")\n\nemu$floppy_drives[[1]]$insert_disk( disk )\n\nemu$power_on()\n```\n\nThe emulator starts in a paused state, as we don't want to block the\nmain R thread. You actively have to tell the emulator to progress.\nLet's skip 1,269 frames while the machine boots. They are not that\ninteresting.\n\n```{r skip, eval=FALSE}\nemu$fast_forward(1269L)\n```\n\nNow we can progress frame by frame, and capture the video image and\nthe audio output buffer for each frame. In the example below, we\nstore the audio in a `matrix`, and the frames as `\".png\"` files in the\ntemporary directory.\n\n```{r capture-frames, eval=FALSE}\naudio \u003c- matrix(double(), 2, 0)\n\n#drain whatever is in the buffer first:\ndummy \u003c- emu$output$capture_audio_buffer()\n\n## Update frame, refill audio buffer with one frame worth of audio:\nemu$next_frame()\n\n## vector of frame indices:\nidxs \u003c- 1L:1550L\nframe_files \u003c- file.path(tempdir(), sprintf(\"fr%04i.png\", idxs))\nfor (i in idxs) {\n  audio \u003c- cbind(audio, emu$output$capture_audio_buffer())\n  emu$next_frame()\n  emu$output$capture_video_frame( frame_files[[i]] )\n}\n```\n\nNow save the `matrix` as a `\".wav\"` file, such that it can be\nused for rendering a video. We can also use the audio to calculate\nthe emulated time span.\n\n```{r save-audio, eval=FALSE}\n## Save the samples as a \".wav\" such that we can use it for rendering\naudio_file  \u003c- tempfile(fileext = \".wav\")\nsave_wav(audio, audio_file)\n\n## The duration is dictated by the number of samples\n## divided by the sample rate\nsample_rate \u003c- 44100L\nduration    \u003c- ncol(audio)/sample_rate\nframe_rate  \u003c- length(idxs)/duration\n```\n\nIf we have the [av](https://docs.ropensci.org/av/) package installed,\nwe can render the captured frames and audio to a video file.\n\n```{r render-video, eval=FALSE}\nif (requireNamespace(\"av\")) {\n  video_file  \u003c- tempfile(fileext = \".mp4\")\n  \n  ## We use the 'vfilter' argument to correct the aspect ratio\n  ## of the captured video frames.\n  av::av_encode_video(\n    frame_files, video_file, frame_rate,\n    vfilter = \"scale=iw:2*ih:flags=neighbor,setdar=4/3\",\n    audio = audio_file)\n}\n```\n\nWe have now successfully rendered the boot block intro of the demo:\n\n\u003cvideo width=\"100%\" controls\u003e\n  \u003csource src=\"https://github.com/pepijn-devries/ramiga/raw/refs/heads/main/data-raw/state-of-the-art.mp4\" type=\"video/mp4\"\u003e\n  Your browser does not support the video tag.\n\u003c/video\u003e\n\n## Not on CRAN\n\nThis package will not be appearing on CRAN any time soon. If this package\nwere to be submitted to CRAN there are several hurdles to be taken:\n\n  * All code should comply with ISO standards.\n    * With some effort this would be achievable\n  * Package size should not exceed 5 MB, but should at best be below 10 MB\n    * This will be difficult, if we want to keep all features\n  * We should avoid using non-standard compilation flags\n    (like -Wa,-mbig-obj)\n    * This could be fixed by splitting up large objects into multiple\n      smaller ones.\n  * This package relies heavily on C++20 features. C++20 is standardised\n    since R 4.6.0, we need to wait until this becomes old-release.\n    as CRAN expects compatibility with old- and new-release.\n\nI pay as much attention to quality as any of my other R packages, so\nyou should be able to enjoy using this package. But for the reasons stated\nabove, I will not submit to CRAN. You can install it from R-Universe as\nspecified above.\n\n*Why not use libretro?*\nI did explore this avenue. It doesn't need C++20, so in that respect it\nwould be easier to get on CRAN. However, the library is much bulkier than\nvAmiga. It also doesn't have a sleek and easy to implement API like vAmiga.\nSo I'll leave this challenge for someone else to pick up.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpepijn-devries%2Framiga","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpepijn-devries%2Framiga","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpepijn-devries%2Framiga/lists"}