[utopian-io] ips-util - Python package for manipulating IPS patches
Background
The International Patching System (IPS) patch format is a historically popular distribution format for ROM hacks. It's a very simple format, and a number of tools exist for creating IPS patches from binary data. I wanted to be able to create IPS patches programatically in Python scripts, however, and no existing library provided that support. So I made one.
I got enough testing and polish done on the library that I chose to upload it to PyPI as a formal Python package. As such, a released version can be acquired by any Python user with pip install ips-util.
Links
Usage notes
(Pretty much straight from the README.)
To create a patch, using existing source and target binary files:
> ips_util create "Super Mario World.smc" "Super Mario World [1337357_h4x_3v4r].smc" -o 1337_p47ch.ips
To apply a patch to a binary file:
> ips_util apply 1337_p47ch.ips "Super Mario World.smc" -o w00t.smc
To dump the contents of a patch:
> ips_util trace 1337_p47ch.ips
The package can also be used within Python scripts to build IPS patches manually, as follows:
from ips_util import Patch
def this_is_my_patch():
patch = Patch()
patch.add_record(0x1234, 999.to_bytes(2, byteorder='little')) # Max out some stat
patch.add_rle_record(0x5678, b'\xea', 0x10) # NOP out a bunch of code
with open('gavroche.ips', 'w+b') as f:
f.write(patch.encode())
Testing
The package includes unit tests (contained in the ips_util/tests/test_patch.py script) to verify design requirements and some common edge cases in IPS format:
Manually created patches
- Verify that a basic patch produces the desired result (
test_patch_core) - Verify that a change made past the end of the original data will pad the result data as needed (
test_patch_padding) - Verify that the truncation syntax used by some IPS tools functions as intended (
test_patch_truncation) - Verify that the library generates an error when the starting address of a patch record is exactly 0x454f46 ('EOF') (
test_patch_eof_edge_case)
Patches created from source and target binary data (the Patch.create() API)
- Verify that the patch created from binary data reproduces the desired target data when applied (
test_create_equal_length) - Verify that creating a patch correctly handles padding when the target data is longer than the source data (
test_create_padded_length)- ... even when the padded data contains only zeros. (
test_create_padded_length_all_zero)
- ... even when the padded data contains only zeros. (
- Verify that creating a patch correctly handles truncation when the target data is shorter than the source data (
test_create_truncated_length) - Verify that when a difference occurs at the address 0x454f46, the generated patch shifts that address to avoid the EOF error noted above (
test_create_eof_edge_case) - Verify that an error is generated when the binary data provided is longer than the maximum supported address (
test_create_address_overflow) - Verify that when creating a patch, differences longer than the maximum supported size are handled gracefully (
test_create_size_overflow)- ... even when the record is run-length encoded (
test_create_rle_size_overflow)
- ... even when the record is run-length encoded (
Thank you for your contribution. I am a fan of the vintage game consoles e.g. 8-bit super mario. So does this utility work on 8-bit ROM files?
From the documentation, I can see it is a complete and useful tool and good job for putting it on
pip.testdatadirectories.Path.loadwill probably throw exception?Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]
Thank you for your review, @justyy! Keep up the good work!
Hey, @nleseul!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!
Congratulations @nleseul! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click here to view your Board
If you no longer want to receive notifications, reply to this comment with the word
STOPTo support your work, I also upvoted your post!
Do not miss the last post from @steemitboard:
Hi @nleseul!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server