{"id":19191248,"url":"https://github.com/invisibleup/sonicr-jsonmenu","last_synced_at":"2025-07-23T14:08:02.822Z","repository":{"id":84256617,"uuid":"126738051","full_name":"InvisibleUp/sonicr-JSONMenu","owner":"InvisibleUp","description":"Completely rewritten menu system for Sonic R","archived":false,"fork":false,"pushed_at":"2018-03-26T05:33:53.000Z","size":7045,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-07T06:39:57.007Z","etag":null,"topics":["mod","sonic","sonicr"],"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/InvisibleUp.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,"publiccode":null,"codemeta":null}},"created_at":"2018-03-25T20:38:04.000Z","updated_at":"2018-12-07T03:34:46.000Z","dependencies_parsed_at":"2023-05-24T03:45:15.356Z","dependency_job_id":null,"html_url":"https://github.com/InvisibleUp/sonicr-JSONMenu","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/InvisibleUp/sonicr-JSONMenu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InvisibleUp%2Fsonicr-JSONMenu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InvisibleUp%2Fsonicr-JSONMenu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InvisibleUp%2Fsonicr-JSONMenu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InvisibleUp%2Fsonicr-JSONMenu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/InvisibleUp","download_url":"https://codeload.github.com/InvisibleUp/sonicr-JSONMenu/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InvisibleUp%2Fsonicr-JSONMenu/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266691580,"owners_count":23969182,"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","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"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":["mod","sonic","sonicr"],"created_at":"2024-11-09T11:39:50.464Z","updated_at":"2025-07-23T14:08:02.781Z","avatar_url":"https://github.com/InvisibleUp.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"JSONMenu\n========\n\nJSONMenu is a rewrite of Sonic R's menu system meant to make customization, expandability and testing much, much easier than the vanilla menu.\n\nFeatures\n--------\n\n- Launch Sonic R into a race from the command line\n- Define your own styles with your own custom mod (See the SonicRushMenu project for an example)\n- Easily add options from your mod to an existing menu\n- Faster and quieter\n\nTodo\n----\n\n- Move graphics, font, and music routines into a seperate \"libcore\" sort of library\n- Finish Sonic Rush example menu (only title screen is implemented right now)\n- Add support for mod-defined racers and tracks (likely will be rolled into that \"libcore\" thing)\n- Add multiplayer support\n- Port Options menu\n- Add ability to specify screen alignment of a Menu2DElement\n\nCommand Line Quick Reference\n----------------------------\n(Assuming no other theming mods are installed) Call SonicR.exe with the following arguments:\n\n- `qstart=gp` : Start race as Sonic (character 0) in Resort Island in Grand Prix mode\n- `qstart=tt` : Start race as Sonic (character 0) in Resort Island in Normal Time Attack mode\n- `gp [racer id] [track id]` : Start race as given racer in given track in Grand Prix mode\n- `tt [tt mode] [racer id] [track id]` : Start race as given racer in given track in given Time Attack mode\n\n- `[racer id]`: One of\n\t- sonic\n\t- tails\n\t- knux\n\t- amy\n\t- robotnik\n\t- msonic\n\t- dtails\n\t- mknux\n\t- eggrobo\n\t- ssonic\n- `[track id]`: One of\n\t- island\n\t- city\n\t- ruin\n\t- factory\n\t- emerald\n- `[tt mode]`: One of\n\t- normal\n\t- reverse\n\t- balloon\n\t- tag4\n\nAPI Quick Reference\n-------------------\nInclude the `export` directory in a new DLL project. To define a new style, do the following:\n\n1. Define SonicRModInfo and Init to make the mod loader happy\n2. Create a new class that extends MenuSelector and defines\n\t- Constructor: Reads the JSON for that style and populates the menu\n\t- loadTextures: Loads whatever textures are needed, not including any textures required by option icons.\n\t- draw: Updates and draws the menu elements\n\t- hscroll: Horizontal scroll action. Typically just moves the current selection or sub-selection.\n\t- vscroll: Vertical scroll action. Typically just moves the current selection or sub-selection.\n\t- querySelection: Gets the currently selected option\n\t- querySubSelection: For options with sub-options, gets the current suboption. Otherwise returns -1.\n\t- doAction: If your theme supports custom actions (eg: changing the background, transitions, etc.) put them here\n3. Define a constructor function that returns a new instance of your style class as a `void *`\n4. In `DllMain` \u003e `DLL_PROCESS_ATTACH`,\n\t1. Load JSONMenu.dll using LoadLibrary, and relevant functions using GetProcAddress\n\t2. Check that the result of `MajorVersion` == 1. Alert user and return false otherwise.\n\t3. To register your style, call `AddMenuClass` with a `std::pair` containing your class name and the constructor function you created earlier.\n\t4. To add or replace an existing menu, call `AddMenu(dump_json(filepath).GetObject());` where filepath is a JSON file containing a single menu.\n\t5. To add or replace an existing menu option, call `AddMenuOption(dump_json(filepath).GetObject());` where filepath is a JSON file containing a single option.\n\t6. Free the JSONMenu.dll library!\n\nIf you're stuck, refer to the example project in the SonicRushMenu folder, which defines a custom title screen mimicking the Sonic Rush title screen.\n\nJSON Quick Reference\n--------------------\n### Important notes\n- The screen is 640x480. For widescreen displays, negative values will still be shown.\n- Colors are stored in the format \"0xAaRrGgBb\". Sonic R uses \"0xFFE0E0E0\" for most graphics for some reason.\n- Menus run at 60FPS, or probably whatever your monitor's refresh rate is\n\n### Annotated example\n```javascript\n{\n\t\"id\": \"test\", // ID that will be used for goto commands and the command line interface\n        \"layout\": { // See below\n            \"class\": \"simple_vertical\", // One of the defined style classes\n            \"properties\": { // Style-specific properties. See below\n                \"xoff\": 200,\n                \"yoff\": 400,\n                \"selcolor\": \"0xFFFFFFFF\"\n            }\n        },\n        \"timeout\": {\n\t\t\"time\": 600, // Frames to show menu for\n\t\t\"actions\": [...] // Actions to be performed when time runs out. After all actions, returns to previous menu\n\t},\n        \"music\": \"mods/MyCoolStyle/music/menu.adx\", // Music to play in ADS, OGG, BRTSM, etc.\n        \"background\": {\n            \"src\": \"mods/MyCoolStyle/art/bg.raw\" // Optional background to display. Can be in PNG or RAW. Must be 640x480.\n        },\n        \"options\": [\n            {\n                \"id\": \"start\", // ID used for command line interface\n                \"text\": \"Press Start Button\", // Text to display on menu\n\t\t\"icon\": { // Icon to display on menu\n                    \"filepath\": \"bin/option/smode00.raw\", // Path to 256x256 PNG or RAW texture to use\n                    \"x\": 0, // X position of icon in texture\n\t\t    \"y\": 160, // Y position of icon in texture\n\t\t    \"w\": 56, // Width of icon in texture\n\t\t    \"h\": 48, // Height of icon in texture\n\t\t    \"scale\": 2 // Integer scaling factor\n                },\n\t\t\"condition\": {\n\t\t    \"getInt\": [address] // Address of Int32 to test against\n\t\t    \"value\": [integer] // Disabled option unless [address] == value\n\t\t}\n                \"actions\": [ // List of actions to perform. See below.\n                    {\"goto\": \"root\"}\n                ]\n            }\n        ]\n}\n```\n\n### Style Classes\n- `simple_vertical`: Just a simple vertical menu with no scrolling\n\t- `xoff`: Position menu starts from the left side of the screen\n\t- `yoff`: Position menu starts from the top side of the screen\n\t- `xspacing`: Spacing between icon and text\n\t- `yspacing`: Spacing between menu options\n\t- `basecolor`: Color of unselected text\n\t- `selcolor`: Color of selected text\n\t- `disabledcolor`: Color of disabled text\n\t- `brightcolor`: Color used for icons \u0026 graphics. (white)\n- `scroll_vertical`: Like simple_vertical except it scrolls up and down to accommodate many options\n\t- `xoff`: Position menu starts from the left side of the screen\n\t- `yoff`: Position menu starts from the top side of the screen\n\t- `xspacing`: Spacing between icon and text\n\t- `yspacing`: Spacing between menu options\n\t- `basecolor`: Color of unselected text\n\t- `selcolor`: Color of selected text\n\t- `disabledcolor`: Color of disabled text\n\t- `brightcolor`: Color used for icons \u0026 graphics. (white)\n\t- `scrollspeed`: Speed to scroll at, in pixels/frame\n- `scroll_horizontal`: Horizontal layout that scrolls\n\t- `xoff`: Position menu starts from the left side of the screen\n\t- `yoff`: Position menu starts from the top side of the screen\n\t- `xspacing`: Spacing between menu options\n\t- `yspacing`: Spacing between icon and text\n\t- `basecolor`: Color of unselected text\n\t- `selcolor`: Color of selected text\n\t- `disabledcolor`: Color of disabled text\n\t- `brightcolor`: Color used for icons \u0026 graphics. (white)\n\t- `scrollspeed`: Speed to scroll at, in pixels/frame\n\n### Actions\n- `{functcall: [address]}`: Calls the given address, which is assumed to be a function that takes no arguments and returns no arguments.\n- `{setInt: [address], value: [integer]}`: Sets the Int32 at `[address]` to `[integer]`.\n- `{goto: [menuID]}`: Suspends the current menu as-is and starts execution of the menu given by `[menuID]`.\n- `{stopmusic: true}`: Stops any currently playing music.\n- `{startgame: true}`: Starts the game with the current settings. Be careful; without proper setup this WILL crash the game!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finvisibleup%2Fsonicr-jsonmenu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finvisibleup%2Fsonicr-jsonmenu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finvisibleup%2Fsonicr-jsonmenu/lists"}