GBATemp ROM hacking documentation project (new 2016 edition out)

Discussion in 'NDS - ROM Hacking and Translations' started by FAST6191, Jan 28, 2008.

  1. Noitora

    Noitora ::

    Member
    3,765
    0
    Aug 9, 2007
    Greece
    Athens
    Crystaltile 2
     


  2. psycoblaster

    psycoblaster Divine

    Member
    2,132
    2
    Jan 26, 2008
    Seoul.. (in Korea)
    it's probably because of the encoding of the table file
    open it up with something like notepad or emeditor in the correct encoding, and "save as" it with a unicode encoding (UTF-16LE)
     
  3. Sp33der

    Sp33der GBAtemp Fan

    Member
    435
    1
    May 31, 2008
    Netherlands
    How do you dump text with Crystaltile2? I head it had CrystalScript built in or something like that but still can't find anything. [​IMG]
     
  4. psycoblaster

    psycoblaster Divine

    Member
    2,132
    2
    Jan 26, 2008
    Seoul.. (in Korea)
    http://bg.tgb.net.cn/CrystalScript.zip
    However, I recommend learning the basics of programming and using a custom tool to dump text, as general text dumpers aren't always accurate.
     
  5. Sp33der

    Sp33der GBAtemp Fan

    Member
    435
    1
    May 31, 2008
    Netherlands
    Don't worry about programming languages lol, i already know Python(most used), C++ and Java. The thing is i never used those for romhacking so now looking for a small little guide
     
  6. FAST6191
    OP

    FAST6191 Techromancer

    pip Reporter
    23,341
    9,117
    Nov 21, 2005
    @Sp33der what psycoblaster was getting at is that roms can use all manner of methods to store text. I am assuming you have a grasp of the principles behind text encoding (table making) and pointers.

    In general assuming the text is not in the binary then it comes as files in the file system, usually as distinct files but occasionally as part of a monster file (see theli's recent work on Culdcept DS http://gbatemp.net/index.php?showtopic=109841 or have a go with the first tony hawks game or the earlier phoenix wright games).

    Still the general arrangement is pointers (which are usually in the same file but not always) followed by text and this is where it gets complex as you then have formatting and wildcards to deal with.
    Pointers can be used to end sections and lines or the line ending characters can be in the text itself and to make matters more confusing this can often be a single byte in among a 16 bit character set which can mess up basic viewers (it is prominent in shiftJIS based games). A note on formatting though, games can sometimes wrap lines and other times you need to do it by hand.
    Pointers need not be end to end either, many times other useful and not so useful pieces of data find their way into the pointer section (many games use 4byte or more entries when one byte will do), I discuss the basic pointer techniques elsewhere so I will leave that for now.

    Wildcards (think "please pay [amount] for a room for the night" or "you have [money value] dollars") can be anything from square bracketed human readable terms (final fantasy 3 has a nice example if I recall correctly) to single bytes and can even be determined by things in the pointer sections. New Super Mario Brothers has some good examples.

    General formatting, compared to earlier consoles the DS is quite powerful and so many games can have things that makes text flash, appear in a different colour, wobble on the screen..... Some games have it in the binary while others have it in the game much like wildcards.

    All this is why we suggest manual dumping or a custom text dumper as the dumpers are either too low end (some of the first ones are little more than glorified file trimmers), too specific (several text dumpers are game specific later modded into a more general form) or as complex as programming a new one (none of these exist in any real form as far as I am aware).
    You also have the option of serving up your text dump to the translator in a complex form (leaving the formatting as in the game for example). Text usually compresses fairly well too so be forewarned that you will be dealing with that too.
     
  7. psycoblaster

    psycoblaster Divine

    Member
    2,132
    2
    Jan 26, 2008
    Seoul.. (in Korea)
    It's not that hard.
    How I do it is by creating a byte array with the file that I open.

    FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read);
    byte[] data = new byte[file.Length];
    ReadStream(file, data);

    Then, if the game uses an encoding like SJIS or UNICODE, you can do this:

    List textDump = new List();
    Encoding e = Encoding.GetEncoding(codepage);

    and for each pointer,

    textDump.Add()e.GetString(fileData, i, textLength));

    i is the current counter, (my loop reads 1 byte at a time)
    and the textLength is part of the file (requires a little bit of reverse engineering)



    I create Hashtables for table files.
    (Character map as the key and character as the value; other way around for converting text back into binary)
    You always need to be aware that the text can be both double and single byte, so I read one byte at a time.
    Convert the value to a hex string, and then look for a match in the Hashtable.
    If there is a match, then I deal it as a single byte character.
    If there isn't, then I also read the next byte, and put the 2 hex strings together, and get the double byte character.

    It is really easy once you understand the basics of text files.

    Usually, in the most common formats of text files, there are only few values when reverse engineered -
    Count (number of lines)

    For each line,
    Pointer (Where the text is located in the file)
    Text length (The length of the text)
    Line (The actual string)

    There can also be control codes for color, font, location, speaker, top/bottom screen, etc, which might need extra testing to figure out.
     
  8. DarthNemesis

    DarthNemesis GBAtemp Maniac

    Member
    1,211
    41
    Feb 19, 2008
    United States
    Util isn't a standard class, it's part of the source I gave you XD

    Actually if you're looking to write a custom inserter, looking at the source to an existing one would probably be the fastest way to get started.
     
  9. Sp33der

    Sp33der GBAtemp Fan

    Member
    435
    1
    May 31, 2008
    Netherlands

    Ahhhhhhhhhhhhhhhhh, thanks alot man, i understand most of it, but i know shit of C#(it is C# right?) so i don't understand some lines [​IMG], thanks again anyways [​IMG]
     
  10. psycoblaster

    psycoblaster Divine

    Member
    2,132
    2
    Jan 26, 2008
    Seoul.. (in Korea)
    Oops I just copied and pasted my code, so I didn't catch that [​IMG]
    Actually, I kept your Util class and added my own stuff for dealing with files, such as my custom table code, text file -> string array, etc, because I thought it was worth keeping what was there [​IMG]

    Back onto topic, Util.ReadStream(stream) is basically
    byte[] File = new File[stream.Length];
    ReadStream(stream, File);
     
  11. psycoblaster

    psycoblaster Divine

    Member
    2,132
    2
    Jan 26, 2008
    Seoul.. (in Korea)
    Oops I just copied and pasted my code, so I didn't catch that [​IMG]
    Actually, I kept your Util class and added my own stuff for dealing with files, such as my custom table code, text file -> string array, etc, because I thought it was worth keeping what was there [​IMG]

    Back onto topic, Util.ReadStream(stream) is basically
    byte[] File = new byte[stream.Length];
    ReadStream(stream, File);
     
  12. Sp33der

    Sp33der GBAtemp Fan

    Member
    435
    1
    May 31, 2008
    Netherlands
    What's this thing in C#?
     
  13. DarthNemesis

    DarthNemesis GBAtemp Maniac

    Member
    1,211
    41
    Feb 19, 2008
    United States
  14. psycoblaster

    psycoblaster Divine

    Member
    2,132
    2
    Jan 26, 2008
    Seoul.. (in Korea)
    List is a generic list class C#.
    Similar to how you can set the types of the contents in an ArrayList in the latest version of JAVA, I set the content type of the List class as String.
    so List textDump is similar to String[] textDump
    However, a List, similar to an ArrayList, expands and contracts its size, rather than having a fixed size such as an ordinary array.
     
  15. Lockon Stratos

    Lockon Stratos GBAtemp Regular

    Member
    262
    0
    Apr 1, 2008
    Sylvarant - Tales of Symphonia
    umm so which ones better/ easier to use C++ or C#? Because I don't want to go and learn the harder version when they're both the same. [​IMG]
     
  16. psycoblaster

    psycoblaster Divine

    Member
    2,132
    2
    Jan 26, 2008
    Seoul.. (in Korea)
    That depends on what you are going to do.
    There is NO harder version. It just depends on what you want to do and how you want to do it.
    Just for ROMhacking purposes, both can be used, as they are both similar is style.
    Because C++ was here for a longer time, C++ should have a larger library compared to C#, but for everything basic, C# is good enough.
    So it just depends on what you want to do. If you learn one, then it isn't hard to learn the other, as they are both very similar.
     
  17. Lockon Stratos

    Lockon Stratos GBAtemp Regular

    Member
    262
    0
    Apr 1, 2008
    Sylvarant - Tales of Symphonia
    I'm going to try learning C# then but is there any detailed tutorials because I can only find a few. [​IMG]
     
  18. gosp

    gosp GBAtemp Regular

    Member
    216
    0
    Jun 29, 2008
    Italy
    AHhh! It's gone! Should we panic? Where can I learn now?
     
  19. FAST6191
    OP

    FAST6191 Techromancer

    pip Reporter
    23,341
    9,117
    Nov 21, 2005
  20. Sp33der

    Sp33der GBAtemp Fan

    Member
    435
    1
    May 31, 2008
    Netherlands