{"id":17685159,"url":"https://github.com/andwn/xgm-standalone","last_synced_at":"2025-03-30T20:21:35.250Z","repository":{"id":228248518,"uuid":"619572228","full_name":"andwn/xgm-standalone","owner":"andwn","description":null,"archived":false,"fork":false,"pushed_at":"2023-03-27T18:51:24.000Z","size":344,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-05T23:19:37.334Z","etag":null,"topics":["68000","m68k","mega-drive"],"latest_commit_sha":null,"homepage":null,"language":"C","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/andwn.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2023-03-27T12:05:52.000Z","updated_at":"2023-03-27T12:33:49.000Z","dependencies_parsed_at":"2024-03-17T21:21:25.519Z","dependency_job_id":"810f80c6-b914-45be-ad76-9b93ce0e89dc","html_url":"https://github.com/andwn/xgm-standalone","commit_stats":null,"previous_names":["andwn/xgm-standalone"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andwn%2Fxgm-standalone","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andwn%2Fxgm-standalone/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andwn%2Fxgm-standalone/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andwn%2Fxgm-standalone/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andwn","download_url":"https://codeload.github.com/andwn/xgm-standalone/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246374086,"owners_count":20766841,"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":["68000","m68k","mega-drive"],"created_at":"2024-10-24T10:26:44.544Z","updated_at":"2025-03-30T20:21:35.232Z","avatar_url":"https://github.com/andwn.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# XGM Standalone\n\nThe XGM driver (and xgmtool) from SGDK by itself.\n\n\n## Structure\n\n - `z80-xgm` - Contains Z80 source for the sound driver\n - `m68k-xgm` - Contains m68k assembly source and C header to drop into your Mega Drive project\n - `xgmtool` - Source code to xgmtool. Used to convert VGM files to XGM data\n - `wavtoraw` - Tool that can convert sample rate of wav files for sound effects\n - `example` - Example project that demonstrates how to use this thing\n\n\n## Compiling\n\nAssuming you have a C compiler `make` is all you need. This does the following:\n - Build the `xgmtool` and `wavtoraw` utilities.\n - Download and compile `sjasm` (z80 assembler) if you don't have it already.\n - Assemble the Z80 driver to `z80-xgm.bin`.\n\n\n## Installing / Using\n\nOnce you have the `z80-xgm.bin` copy that into your project, along with the\ncontents of the `m68k-src` directory.\n\nGive `m68k-src/xgm.h` and `example/main.c` a read for further instructions.\n\nYou may need to modify these paths in `m68k-src/xgm.s`. \nJust point them to where the files actually are, relative to your project root.\n\n    /* XGM Driver blob */\n    BIN z80_xgm,    \"z80_xgm.bin\"\n    z80_xgm_end:\n    \n    BIN stop_xgm,   \"stop_xgm.bin\"\n\nAs for installing the tools to your system, you could just copy them to\n`/usr/local/bin`, or include compiling them as a step in building your\nown Mega Drive project.\n\n\n## How do I get sound data in my game without Rescomp?\n\nTL;DR - By hand.\n\n\n### For Music:\n\nRescomp just runs xgmtool under the hood.\nYou can script this with Bash, or add a step to your projects Makefile like so:\n\n    # VGM files to convert to XGC. This assumes your VGM files are in res/bgm\n    VGMS  = $(wildcard res/bgm/*.vgm)\n    XGCS  = $(VGMS:.vgm=.xgc)\n    \n    # Make it a dependency somewhere, as long as it builds before the C/ASM code\n    all: $(XGCS) (...other stuff...) mygame.bin\n    \n    # Convert VGM. Replace or define $(XGMTOOL) with the actual path to run xgmtool\n    %.xgc: %.vgm\n        $(XGMTOOL) \"$\u003c\" \"$@\" -s\n    \n    # Clean up after yourself\n    clean:\n        rm -f $(XGCS)\n\nAs for including the output XGC files in the game, put something like this in an asm file:\n\n        .align 2\n        .globl BGM_MySong\n    BGM_MySong:\n        .incbin \"res/bgm/mysong.xgc\"\n\nAnd in a C header:\n\n    extern const uint8_t BGM_MySong[];\n\n\n### For PCM Sound Effects:\n\nXGM samples are signed 8-bit 14000Hz PCM streams with no header.\nYou could convert your samples to this format in Audacity manually,\nor build the wavtoraw tool and convert them like this:\n\n    # WAV files to convert to PCM. This assumes your sound files are in res/sfx\n    WAVS  = $(wildcard res/sfx/*.wav)\n    PCMS  = $(VGMS:.wav=.pcm)\n    \n    # Make it a dependency somewhere, as long as it builds before the C/ASM code\n    all: $(PCMS) (...other stuff...) mygame.bin\n    \n    # Convert WAV\n    %.pcm: %.wav\n        $(WAVTORAW) \"$\u003c\" \"$@\" 14000\n    \n    # Clean up after yourself\n    clean:\n        rm -f $(PCMS)\n\nThen just incbin each of them in an asm file like so:\n\n        .align 256\n        .globl PCM_MySound\n    PCM_MySound:\n        .incbin \"res/sfx/mysound.pcm\"\n    PCM_MySound_end:\n\nAnd in a C header:\n\n    extern const uint8_t PCM_MySound[], PCM_MySound_end[];\n\nWhy is the _end part needed? You have to tell XGM the size of every SFX sample.\nYou can see how this comes together in the example project.\n\n\n## Miscellanea\n\nThe example project can be built with the `-mshort` compiler option.\nHowever, you will need to enable the lines in `xgm.s` with a (-mshort) comment,\nand disable the lines beneath them that they replace, then do the same for\n`dma.s` (dma_queue routine) or freaky things will happen.\nDue to the ABI change with `-mshort` the length of the stack used for those routines\nbecomes smaller and the parameters need to be read from a different offset.\n\nSince xgm.s is the only m68k source file that \"does things\", you could potentially\ninclude this standalone driver in assembly projects without C as well.\nBut since it is written in GNU syntax, you will have to convert it to Asm68k,\nAS, or asmx if you use any of those. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandwn%2Fxgm-standalone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandwn%2Fxgm-standalone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandwn%2Fxgm-standalone/lists"}