{ "info": { "author": "Tom Sherman", "author_email": "tomsherman159@gmail.com", "bugtrack_url": null, "classifiers": [], "description": "WiiMake 2.0.0\n======================\n\nIntroduction\n------------\n\nWiiMake is a cross-platform command line tool for building Gamecube/Wii mods written in C. It manages the entire build process, from compiling the C files and arranging the code in the available memory regions of the game, to injecting the final code into the **.iso** file. It also comes with a utility for interacting directly with **.iso** files, to provide an easier workflow when developing mods.\n\nFor an example of this tool being used to build a real project, see the `MeleeModdingLibrary Tutorials`_ which show how to create a simple AI for Super Smash Bros Melee.\n\n.. _MeleeModdingLibrary Tutorials: https://github.com/sherman5/MeleeModdingLibrary/wiki/Tutorial\n\nInstallation \n------------\n\nIf you have any trouble with the installation steps, feel free to ask a question in the `MeleeModdingLibrary Discord`_ on the **#wiimake** channel.\n\n.. _MeleeModdingLibrary Discord: https://discord.gg/gJXR77v\n\nInstalling devkitPPC\n********************\n\nWiiMake relies on the `devkitPPC toolchain`_. Follow the installation instructions `here`__. Make sure to add the toolchain to your PATH. You can try running :code:`powerpc-eabi-gcc` to see if everything was installed correctly. You should see\n\n__ https://devkitpro.org/wiki/Getting_Started\n.. _devkitppc toolchain: https://wiibrew.org/wiki/DevkitPPC\n\n::\n\n $ powerpc-eabi-gcc\n \n powerpc-eabi-gcc: fatal error: no input files\n\nInstalling Python\n*****************\n\nBefore installing WiiMake, you must have a supported version of Python_ installed. You can see which version you currently have by running\n\n.. _Python: https://www.python.org/downloads/\n\n::\n\n $ python --version\n\nWiiMake works with Python versions **2.7, 3.4, 3.5, 3.6, 3.7**.\n\nInstalling WiiMake\n******************\n\nThe easiest way to install WiiMake is to use the package management tool pip_.\n\n.. _pip: http://www.pip-installer.org/en/latest/\n\n::\n\n $ pip install wiimake\n\n\nIf the installation worked correctly, you should be able to run :code:`wiimake` in your terminal and see\n\n::\n\n $ wiimake\n \n usage: wiimake [-h] [--version] [--save-temps] [--verbose]\n iso_file config_file\n wiimake: error: the following arguments are required: iso_file, config_file\n\nUsing WiiMake\n-------------\n\nWiiMake has two required arguments, **iso_file** which is the path to the **.iso** file you want to modify and **config_file** which is the path to your WiiMake configuration **.ini** file. This configuration file contains all the neccesary information to build and inject your mod. See the `WiiMake Configuration File`_ section for more information. To build a mod, simply run\n\n::\n\n $ wiimake game.iso config.ini\n\nThis command will build and inject a mod into the :code:`game.iso` file based on the settings in the :code:`config.ini` file. Since this command overwrites the :code:`game.iso` file, it's usually a good idea to create a backup. WiiMake also comes with a tool for manipulating an **.iso** file directly, :code:`wiimake-isotool`. This lets you save the original state of the **.iso** file before overwriting it with your mod. If the configuration file changes significantly, it is usually a good idea to restore the **.iso** file to it's original state before building the mod again. A sample workflow might look like this:\n\n::\n\n $ wiimake-isotool game.iso --save original.out\n saving file state...\n done!\n \n $ wiimake game.iso config.ini\n WiiMake version: 1.99.17\n devkitPPC version: (devkitPPC release 35) 8.3.0\n ...\n \n ... make some changes to the memory layout in the configuration file ...\n \n $ wiimake-isotool game.iso --load original.out\n loading file state...\n done!\n \n $ wiimake game.iso config.ini\n WiiMake version: 1.99.17\n devkitPPC version: (devkitPPC release 35) 8.3.0\n ...\n\nThere is also an option for calculating an MD5 checksum on the **.iso** file, which allows you to verify the state of your **.iso**.\n\n::\n\n $ wiimake-isotool game.iso --checksum\n 1dad5e2edeb630d7a3bc7b77902e5834 game.iso\n \n $ wiimake-isotool game.iso --save original.out\n saving file state...\n done! \n \n ... make changes to the iso file ...\n \n $ wiimake-isotool game.iso --load original.out\n loading file state...\n done!\n \n $ wiimake-isotool game.iso --checksum\n 1dad5e2edeb630d7a3bc7b77902e5834 game.iso\n\nIn this example both checksums will be the same since we loaded the saved state of the original **.iso** file.\n\nAdditional Options\n******************\n\nThere are two additional options you can enable when running :code:`wiimake`,\n\n::\n\n wiimake game.iso config.ini --verbose\n\nwill print more information about what's happening during the build process.\n\n::\n\n wiimake game.iso config.ini --save-temps\n\nwill save all the temporary files that are created during the build process. This can sometimes be useful when debugging an issue with the mod. Note that **injected_code.txt**, which contains a full dump of all the injected code, is always saved and is the most useful reference for debugging.\n\nWiiMake Configuration File\n--------------------------\n\nThe configuration file contains all information needed to create a mod. The format for this file is the standard **.ini** format where the ';' character starts a comment and the '=' denotes a variable. Lines wrapped in '[]' are section headers and are treated the same way as comments. There are several variables that WiiMake looks for in the configuration file. Each of them is described here and at the end of this section you can find some example configuration files.\n\n**SOURCES**\n\n::\n\n SOURCES = file1.c file2.c file3.c subfolder/file1.c\n\nThis variable tells WiiMake which C files are part of this mod. WiiMake will compile these files and inject the resuling code into the game **.iso** file.\n\n**REGIONS**\n\n::\n\n REGIONS =\n 80393a5c-80393c0c\n 803fa3e8-803fc2e8\n\nThis variable specifies the regions in the game memory that are available to be overwritten. After all the code has been compiled, WiiMake will find an arrangement of the code so that it fits in these regions. All addresses in these regions must be able to be overwritten without affecting the game. To test if a region if viable, you can use\n\n::\n\n $ wiimake-isotool game.iso --zero-out 0x80393a5c 0x80393c0c\n\nwhich will write zeros to every address in the given range. If the game is still playable like this, then it is likely that this region is safe to overwrite.\n\nNote: the regions must have the format of **start_address-end_address** with no spaces.\n\n**ENTRY_POINTS**\n\n::\n\n ENTRY_POINTS = \n _main 80377998 7ee3bb78\n foo 801a633c 60000000\n bar 801b15cc 38800000\n\nWhen your code is injected into the available memory regions, it is completely separated from the running game code. There needs to be a point where the game code branches into your code in order for your mod to do anything. This variable specifies the functions in your C files which will serve as entry points to your code. The first value is the name of the function you want as an entry point. The second value is the address where a branch to this function will be inserted. This address depends on what the purpose of your function is. If it is a function that should be called every frame, then you need to find an address in the main game loop. If it is a function that should be called whenever a certain event happens, then you need to find an address in the code that handles that event. The third value is the instruction that is originally at that address in memory. Since this code is part of the actively running game, it can't be overwritten without any consideration for what the original instruction was doing. To see the value of an instruction at any memory address, use\n\n::\n\n $ wiimake-isotool game.iso --read 0x801a633c\n interpreting 0x801a633c as a memory address\n 0x7c7f1b78\n\nIf you want the game to run as normal you should provide the same value read from the original disc. However, you can also choose to ignore the original instruction by replacing it with a :code:`nop` (60000000). This will effectively make your function overwrite whatever instruction was originally at that address.\n\nBefore the code branches to an entry point, all the registers are preserved on the stack. Thus, these functions can take input from the game registers, but any return values will be discarded when the registers are restored. If you are unfamiliar with registers and how they are used to pass values to a function, it is always safe to have all entry points have a signature like :code:`void foo()`.\n\n**INCLUDE_PATHS** and **LIBRARIES**\n\n::\n\n LIBRARIES = lib1.a lib2.a\n INCLUDE_PATHS = path/to/dir1 path/to/dir2\n\nOften, you will want to include external libraries in your C code. You can use these variables to specify the include paths you want to be able to use, as well as the path to any static libraries (**.a** files) you want to link with your code.\n\n**COMPILER_FLAGS** and **LINKER_FLAGS**\n\n::\n\n COMPILER_FLAGS = -flag1 -flag2\n LINKER_FLAGS = -flag1 -flag2\n\nWiiMake also allows you to pass flags to the underlying calls to :code:`powerpc-eabi-gcc` and :code:`powerpc-eabi-ld` during the compiling and linking stages, respectively. This can be especially useful if your code is too large to fit in the available memory regions. Using the :code:`-O` optimization flags allow for a significant reduction in size for your compiled code, but sometimes can introduce bugs that are difficult to fix.\n\nStatic Overwrites\n*****************\n\nIn addition to named variables, WiiMake also looks for lines of the form\n\n::\n\n 801648c8 = 38a007ff\n\nThese lines are interpreted as a static overwrite, where the value on the right hand side of the \"=\" will be written to the specified address on the left hand side. This happens directly in the **.iso** file, so if this address is updated at runtime, your overwrite will be lost.\n\nExamples\n********\n\nHere are a few examples of configuration files being used for modding Super Smash Bros Melee in the MeleeModdingLibrary_ tutorials. `Example 1`__, `Example 2`__, `Example 3`__.\n\n__ https://github.com/sherman5/MeleeModdingLibrary/blob/master/tutorials/SimpleProgram/SimpleProgram.ini\n__ https://github.com/sherman5/MeleeModdingLibrary/blob/master/tutorials/DashDancing/DashDancing.ini\n__ https://github.com/sherman5/MeleeModdingLibrary/blob/master/tutorials/DefensiveAI/DefensiveAI.ini\n.. _MeleeModdingLibrary: https://github.com/sherman5/MeleeModdingLibrary/", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/sherman5/wiimake", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "wiimake", "package_url": "https://pypi.org/project/wiimake/", "platform": "", "project_url": "https://pypi.org/project/wiimake/", "project_urls": { "Homepage": "https://github.com/sherman5/wiimake" }, "release_url": "https://pypi.org/project/wiimake/2.0.0/", "requires_dist": null, "requires_python": "", "summary": "Command line tool for building Gamecube/Wii mods", "version": "2.0.0" }, "last_serial": 5241084, "releases": { "1.99.0": [ { "comment_text": "", "digests": { "md5": "4badd95340d5c1699ec6c2edc7da3e9a", "sha256": "eb5cbadd62cec6b301329894c4819c154f42ca988a6ad4a40743a94bdf2450da" }, "downloads": -1, "filename": "wiimake-1.99.0-py3-none-any.whl", "has_sig": false, "md5_digest": "4badd95340d5c1699ec6c2edc7da3e9a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 18803, "upload_time": "2019-05-04T17:55:01", "url": "https://files.pythonhosted.org/packages/4e/a3/10cda045d69bb6d6c78a3944e93919509fe8ee14103acb87a2fd4b7705a4/wiimake-1.99.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b738ad1a54ca2d8bec127115f49fe343", "sha256": "8f26ad7e4b6ca36d55429aa03e9eececb564d57df0bcd1cee618cc66de209642" }, "downloads": -1, "filename": "wiimake-1.99.0.tar.gz", "has_sig": false, "md5_digest": "b738ad1a54ca2d8bec127115f49fe343", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22258, "upload_time": "2019-05-04T17:55:03", "url": "https://files.pythonhosted.org/packages/e3/5b/2c7b1cfff90fc37597cd10168640905884a64c1e044842db637443068801/wiimake-1.99.0.tar.gz" } ], "1.99.1": [ { "comment_text": "", "digests": { "md5": "00bbabc176fd39489e54d7623d32aa16", "sha256": "f93516b39af41ad01aeff1f1d35c64185540a9a492d9a50c32cefc11ae3a8b52" }, "downloads": -1, "filename": "wiimake-1.99.1.tar.gz", "has_sig": false, "md5_digest": "00bbabc176fd39489e54d7623d32aa16", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21371, "upload_time": "2019-05-04T19:46:22", "url": "https://files.pythonhosted.org/packages/c1/eb/72650bad2d8baf3fe2b841947dd604d3b6f8b78aee5a1d79e44c2f585695/wiimake-1.99.1.tar.gz" } ], "1.99.12": [ { "comment_text": "", "digests": { "md5": "1a0856e25e794ae5fba310fd9c6430d2", "sha256": "b1300eab32e9ab2b3b769089b49e9b603ad99937a134c150b2935635c0a26406" }, "downloads": -1, "filename": "wiimake-1.99.12.tar.gz", "has_sig": false, "md5_digest": "1a0856e25e794ae5fba310fd9c6430d2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21387, "upload_time": "2019-05-04T21:07:17", "url": "https://files.pythonhosted.org/packages/7d/19/52a0a6a83d5d3649c94ad0d43c523d92822485f69f35ad42b7944826331b/wiimake-1.99.12.tar.gz" } ], "1.99.16": [ { "comment_text": "", "digests": { "md5": "c04388b8ce1512980fbbefd9fa75b743", "sha256": "2003d003875b93d962ff7f2bdd41fb7e099efc0c445c704a2b3272b39e589f23" }, "downloads": -1, "filename": "wiimake-1.99.16.tar.gz", "has_sig": false, "md5_digest": "c04388b8ce1512980fbbefd9fa75b743", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21384, "upload_time": "2019-05-05T16:33:27", "url": "https://files.pythonhosted.org/packages/a2/36/812641c73eb21537cc4067e9878ebbb9eeb32391c2278e59b5e920f1faa6/wiimake-1.99.16.tar.gz" } ], "1.99.17": [ { "comment_text": "", "digests": { "md5": "dd48556080d9d8dec76de22ad66f25ad", "sha256": "4c8c4fdab8938ec7bc87e1618e5a7f0a7291b9822a20b7ca025e6f7f863bbf56" }, "downloads": -1, "filename": "wiimake-1.99.17.tar.gz", "has_sig": false, "md5_digest": "dd48556080d9d8dec76de22ad66f25ad", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21380, "upload_time": "2019-05-05T17:02:17", "url": "https://files.pythonhosted.org/packages/ff/8d/deb97c5256295b5cf86d9644a48f19a755fd3456b1011570c03bfb38fa2c/wiimake-1.99.17.tar.gz" } ], "1.99.18": [ { "comment_text": "", "digests": { "md5": "077c118bf92f8cb4e90406428942bdf1", "sha256": "4bd90a5570d040ad6131082b47e43891b6e43af908b11effeb28af585c15b959" }, "downloads": -1, "filename": "wiimake-1.99.18.tar.gz", "has_sig": false, "md5_digest": "077c118bf92f8cb4e90406428942bdf1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23677, "upload_time": "2019-05-08T02:07:08", "url": "https://files.pythonhosted.org/packages/67/73/7997fd9fbed407dfdade0925a152219a820e6dc056b8edfdea95ec893bf0/wiimake-1.99.18.tar.gz" } ], "1.99.19": [ { "comment_text": "", "digests": { "md5": "e63b1bf676cd8c24e81374e54d70ca8c", "sha256": "e8fac358560f5982cf0b5cd9165f958234cf231eb67b10fa8b5336ac275de933" }, "downloads": -1, "filename": "wiimake-1.99.19.tar.gz", "has_sig": false, "md5_digest": "e63b1bf676cd8c24e81374e54d70ca8c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23679, "upload_time": "2019-05-08T02:29:48", "url": "https://files.pythonhosted.org/packages/3a/d6/90ef80aee0004eaac1fe8ca1e3bb4b003ccfc524fc3f6d9d593c567cb955/wiimake-1.99.19.tar.gz" } ], "1.99.20": [ { "comment_text": "", "digests": { "md5": "1e745aae7bfe57b1940f5f6c283fe8fd", "sha256": "774c6bc4aeb339d8a6c3a25f1cc1b724469769224ca9575b646a8628986b626c" }, "downloads": -1, "filename": "wiimake-1.99.20.tar.gz", "has_sig": false, "md5_digest": "1e745aae7bfe57b1940f5f6c283fe8fd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23677, "upload_time": "2019-05-08T02:38:06", "url": "https://files.pythonhosted.org/packages/f9/ab/72bd4c9692056cd9001cf474c9fdbc0b938c7cdc34835dfb646ece8ee77b/wiimake-1.99.20.tar.gz" } ], "1.99.5": [ { "comment_text": "", "digests": { "md5": "ca49e3fd752201460a19bc91dcc1ff68", "sha256": "25b3bac3abfddc7e9ed0ce4ab7e7b3b50a15d1d83ee2d4b6ce38adc0e6a8d0f3" }, "downloads": -1, "filename": "wiimake-1.99.5.tar.gz", "has_sig": false, "md5_digest": "ca49e3fd752201460a19bc91dcc1ff68", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21375, "upload_time": "2019-05-04T20:10:07", "url": "https://files.pythonhosted.org/packages/1b/3b/361f205db6cf9fdc7c96c099bfc116d5931cdfd268d298b50a1103b81d40/wiimake-1.99.5.tar.gz" } ], "2.0.0": [ { "comment_text": "", "digests": { "md5": "bb19a503b7ca575397bbfac2492fd08a", "sha256": "94e7f53475d365bb2c3028fba7b2ddacabfa0cfda29b6e8634681f8c30b25686" }, "downloads": -1, "filename": "wiimake-2.0.0.tar.gz", "has_sig": false, "md5_digest": "bb19a503b7ca575397bbfac2492fd08a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23676, "upload_time": "2019-05-08T02:44:09", "url": "https://files.pythonhosted.org/packages/b6/9d/a6bcbc19e961c3cd6b64bc9a4373a9755c17f06a1bd4abd7f43b726287ee/wiimake-2.0.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "bb19a503b7ca575397bbfac2492fd08a", "sha256": "94e7f53475d365bb2c3028fba7b2ddacabfa0cfda29b6e8634681f8c30b25686" }, "downloads": -1, "filename": "wiimake-2.0.0.tar.gz", "has_sig": false, "md5_digest": "bb19a503b7ca575397bbfac2492fd08a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23676, "upload_time": "2019-05-08T02:44:09", "url": "https://files.pythonhosted.org/packages/b6/9d/a6bcbc19e961c3cd6b64bc9a4373a9755c17f06a1bd4abd7f43b726287ee/wiimake-2.0.0.tar.gz" } ] }