IPS delivery (part 2)

Edit: The version listed in this post is buggy. Please consider using version 0.02 [link] or the current development version [link] instead.

Here it is! The gtk version of the ips patcher I wrote earlier.
It’s based on GTK. And I use Glade to create the interface.

I thought I’d have to implement zillions of callbacks but in the all I had to to is attach the IPS structure to the main window, implement a callback and add a thread.

This was also the occasion to clean up and simplify the IPS code.

You can download it [here].
Feel free to contact me or leave a comment if you have any request or problem.

Here are the mandatory screenshots!

  • Main window :

    IPS patcher main window

  • Error window (it’s a little too big in my opinion 🙂 ) :

    IPS patcher error window

  • Success window :

    IPS patcher success window

IPS delivery

Edit: The version listed in this post is buggy. Please consider using version 0.02 [link] or the current development version [link] instead.

Today I wanted to try the translation of Metal Max Returns. This game looks really cool. As I’m super lazy, I ran the windows version of snes9x through wine. I haven’t tested the 64bit version yet. I realized that there’s no IPS patcher under linux. So once again I had to run a win32 IPS patcher (arkana ips) using wine.

I was wondering where there wasn’t any IPS patcher under linux… Maybe the IPS format is a real mess. In fact it’s the total opposite. It’s really simple.

I coded my own patcher in less than 2 hours (including testing). Here’s the quick non-documented code :

Here’s how you use it :
Usage : ips-patch ipsfile inputrom [outputrom]
ipsfile is the filename of the IPS patch to apply.
inputrom is the filename of the rom to patch.
outputrom is the filename of the patched rom. It’s an optional argument. If you don’t specify it, the input rom will be saved in inputrom.sav and then overwritten.

I’ll try to add some GUI later if I have enough motivation 🙂

Double Bit Dragon

In my quest for demo effects I’m studying zoom. 2 days ago while looking at the code for right shifting signed bytes, I realized that this technique can be used to “double” a byte.

Here’s a little schema showing byte “doubling”:

b0 b1 b2 b3 b4 b5 b6 b7

b0 b0 b1 b1 b2 b2 b3 b3    b4 b4 b5 b5 b6 b6 b7 b7

How can signed byte bit right shifting can help us?
Signed numbers are represented in two’s complement. I won’t explain it here. But when you are shifting a negative value to the right the most significant bit is replaced by 0. However this bit is always 1 for negative values. A way to solve this issue is to use the right bit rotation instruction (ROR) instead of the right bit shift instruction (LSR). ROR shifts the bits on position to the right. The carry flag is shifted to bit 7 and the bit 0 is shifted to the carry flag. We must copy the value of the 7th bit to the carry flag. We’ll use the CMP for this. The carry flag is set if the value in the accumulator is equal or greater to the compared value. So comparing the accumulator to #$80 (128) will do the trick.

We’ll use this technique to “double” the bits. First we shit the source byte to the right. The least significant bit will be in the carry flag. Then we rotate the accumulator to the right. The carry flag is then shifted to the 7th bit of the accumulator. We compare the accumulator to #$08. The carry flag is now equal to the 7th bit of A. Rotate the accumulator to the right one more time. Et voila! 🙂

This macro reads a bit from the source byte and adds it twice to the destination.

doubleBit .macro
    lsr <__src
    ror A
    cmp #$80
    ror A
          .endm

And finally here’s the code to “double” a 8 pixels long line. You’ll have to repeat it for each lines. If you want to double a tile on pc-engine you’ll have to call this of code for each “line” (32 times).

    cla

    doubleBit    ; bit 0
    doubleBit    ; bit 1
    doubleBit    ; bit 2
    doubleBit    ; bit 3
    sta <__dest

    doubleBit    ; bit 4
    doubleBit    ; bit 5
    doubleBit    ; bit 6
    doubleBit    ; bit 7
    sta <__dest+1

We now have the basis to make a complete zoom-in routine! 🙂