Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relative Search #45

Open
vector-man opened this issue Jul 14, 2019 · 8 comments
Open

Relative Search #45

vector-man opened this issue Jul 14, 2019 · 8 comments

Comments

@vector-man
Copy link

vector-man commented Jul 14, 2019

Add a relative search feature.

@abbaye
Copy link
Owner

abbaye commented Jul 15, 2019

Soon as possible my friend

@abbaye
Copy link
Owner

abbaye commented Jul 25, 2019

@vector-man can you send me a like to watch a sample of your request. Last time I have worked on relative search is in ~2003. I just need to see again how it work to implement in C# control

@vector-man
Copy link
Author

vector-man commented Jul 26, 2019

Here's an existing tool: https://www.romhacking.net/utilities/513/

It's used to figure out the encoding of text in files (e.g. ROMs)

Here's how the person I requested this for descibed it:

"1- Open game and play until the text you want to figure the encoding for shows up. Say it has the word "World". Make mental note of that.
2- Open relative search tool. I recommend monkeymoore from rhdn. Search for that word "World".
3- It gives a few proposed encodings. Check the one that autocompletes more ingame text you saw in the game, that's the correct one.
4- Save table file. It should have just the A-Z a-z set, I think.
(that applies to Japanese, of course, and characters like space and numerals)
in that case, you're supposed to look up the font graphics and write the set manually, and feed that to monkeymoore's "define character set" option."

So, it's basically a tool to help figure out an encoding by searching with a string of text. I have not personally done this since around 2003 myself, so I'm sorry I can't personally add anything else to that. They wanted it added to your editor.

@abbaye
Copy link
Owner

abbaye commented Jul 26, 2019

Thanks you

@abbaye abbaye pinned this issue Aug 1, 2019
@abbaye
Copy link
Owner

abbaye commented Aug 6, 2019

I think I can use the TBL loaded in editor for make a relative search.

@htdag
Copy link

htdag commented May 4, 2021

Relative Search, string search without knowing the charset in advance.
The Theory of Relative Searching: https://www.romhacking.net/documents/742/

@abbaye
Copy link
Owner

abbaye commented May 4, 2021

Thank you @htdag

@abbaye abbaye unpinned this issue May 31, 2021
@ulissesemuman
Copy link

ulissesemuman commented Apr 26, 2024

I'm creating a visual tool for translating ROMs and I will attach its Hex Editor to my project. I have already implemented Relative Search in my tool. I will soon move my tool to public on GitHub.

Feel free to use or adapt my code for yourself.

    public int RelativeSearch(string textToFind)
    {
        int romLength = binaryFile.Length;
        byte[] binaryFileChunk;
        int textToFindLength = textToFind.Length;
        byte[] binaryText = Encoding.UTF8.GetBytes(textToFind);
        int index = -1;
        int chunkSize = 0x10000;

        binaryText = binaryText.Select(x => (byte)(x - (byte)'a')).ToArray();

        for (int i = 0; i < 255 - (byte)'a'; i++)
        {
            for (int j = headerSize; j < romLength; j += chunkSize - textToFindLength)
            {
                binaryFileChunk = binaryFile.Skip(j).Take(chunkSize).ToArray();

                index = IndexOfArray(binaryFileChunk, binaryText);

                if (index > 0)
                {
                    index += j;
                    break;
                }
            }

            if (index > 0) break;

            binaryText = binaryText.Select(x => (byte)(x + 1)).ToArray();
        }

        return index;
    }

    public static int IndexOfArray<T>(T[] source, T[] search)
    {

        var result = Enumerable.Range(0, source.Length - search.Length)
                               .Select(i => new
                               {
                                   Index = i,
                                   Found = source.Skip(i)
                                      .Take(search.Length)
                                      .SequenceEqual(search)
                               })
                               .FirstOrDefault(e => e.Found);
        return result == null ? -1 : result.Index;
    }

I only use lowercase letters, as the distance between lowercase and uppercase letters in the ROM table may not be the same distance between lowercase and uppercase letters in the ASCII table. I am considering that whoever is translating does not yet have a "relative table". I will implement improvements to allow the use of "relative tables". In my view, a relative table is created through the image of the character sprites.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants