[Tutorial] A basic guide for Gateshark to NTR translation

Discussion in '3DS - Tutorials' started by imthe666st, May 30, 2016.

?

Did this Guide help you?

  1. Yes, I did a working plugin!

    5 vote(s)
    50.0%
  2. Yes, but I had some questions unanswered

    2 vote(s)
    20.0%
  3. Yes, but I needed help from the comments

    0 vote(s)
    0.0%
  4. No, but I learned something nevertheless.

    3 vote(s)
    30.0%
  5. No.

    0 vote(s)
    0.0%
  1. imthe666st
    OP

    Member imthe666st Felyne Hunter

    Joined:
    Aug 16, 2015
    Messages:
    355
    Location:
    ><HFB>
    Country:
    Germany
    Hello,
    I've been seeing a lot of people attempt their luck at creating NTR Cheatplugins and I see the same naive mistake over and over. Please refer to the following picture:
    Warning: Spoilers inside!
    But, before we begin I think I should explain the gateshark format a bit, since most people don't seem to understand it.

    Warning, this post might get a little bit technical. This tutorial requires to read a lot and utilize C. If you don't know how to code in C, learn it first. I won't answer any basic questions about this programming language. ( Google is always helpful ) Also you should've already taken a look at the demo plugins @cell9 provided to us to understand how these work.

    I'd advise you to declare a uint32 variable called offset for simplification and direct translation. If you want to advance even further you have to think a bit more then just this tutorial :)

    So a gateshark code is made out of multiple smaller codes, which can read, write and compare RAM from the Nintendo 3ds. All Gateshark codes follow this pattern:
    Code:
    ZXXXXXXX YYYYYYYY
    except for the 0xD codes, which are the following:
    Code:
    ZZXXXXXX YYYYYYYY
    Z is the operation that shall be executed. For a full list take a look here
    X is the offset for the RAM.
    Y is the Data used for this code.

    Alright, now how do we translate these codes?

    The most basic Gateshark codes are the 0x0, 0x1, and 0x2 codes, which are used to write RAM.
    The 0x0 Code write a 32 bit Integer value at the address X + Offset,
    Code:
    0XXXXXXX YYYYYYYY--> WRITEU32(XXXXXXX + Offset, YYYYYYYY);
    This means write Integer Y to X + Offset.
    We can represent that in C by:

    The 0x1 Code write a 16 bit Short value at the address X + Offset,
    Code:
    1XXXXXXX 0000YYYY--> WRITEU16(XXXXXXX + Offset, YYYY);
    This means write Short Y to X + Offset.

    The 0x2 Code write a 8 bit Byte value at the address X + Offset,
    Code:
    2XXXXXXX 000000YY --> WRITEU8(XXXXXXX + Offset, YY);
    This means write Byte Y to X + Offset.

    Please note that you should always try to minimize the amount of bytes you want to write, or else there might be some (negative) sideeffects.

    Next are the Gateshark codes to compare RAM. Comparing Integers is from 0x3 to 0x6 and comparing Short are from 0x7 to 0xA. Please refer to the wiki post here for further information about these codes. These are 'if'-statements.

    After that we have another very important gateshark code, the 0xB code. This reads a 32 Bit integer value from the Ram and uses it as the new offset. This is used for Pointers. We can use
    Code:
    Offset = READU32(X+Offset);

    The 0xC code is used for loops. The loop statement is executed Y times and ends with a 0xD1 command which increases the the offset by Y of the 0xD1 command. It's a basic 'For' loop.
    Code:
    C0000000 00000063 <- Start the Loop | Repeat 0x63 times.
    **some other instructions*
    D1000000 00000010 <- End the loop and increase the offset by 0x10 bytes
    
    Most people use the 0xDC code in front of a 0xD1 code to increase the offset ( I'll come back to this one later ), but it isn't necessary, as you can increase it in the 0xD1 block.

    And now to the 0xD codes. There are a lot of these codes. ( 14 to be exact ), but we will only be focusing on the more important codes. The 0xD0, 0xD2, 0xD3, 0xDC and the 0xDD code.
    The D0 code closes the latest conditional statement (0x3 to 0xA codes ), just like we would close our conditional statement in C.
    The D2 code closes all if statements and escapes a 0xC loop.
    D3 is a very commonly used code. Most people use it at the beginning of their gateshark code to declare the offset. However this one if not necessary if the Y block in all 0.
    To increase an offset you use the DC block. It increases the offset by Y.
    And last the DD code. A new code introduced by gateshark. It's used to test for button combinations. Close it with a D0 code. I'd recommend using a menu for plugins though. If you want to use keys anyways - A quick google search will give you your needed information. ( or just look at some other plugins :) )

    And we are done. If you have any questions regarding parsing gateshark to NTR take a look at this small wiki post first. It has a collection of all gateshark codes. Including the not mentioned dxData codes.

    If you want to test a gateshark code if it works, but don't have a gateway card, feel free to use my fork of the NTR debugger which includes a gateshark tab. ( Please note, that not all codes will work. Codes that must be constantly executed like moonjumps, or similar can't be done using this ).

    Credits:
    @cell9 for his awesome work on NTR.
     
  2. Elveman

    Member Elveman A9LH Shitpost Race Smogonite

    Joined:
    Feb 1, 2015
    Messages:
    404
    Location:
    Moscow city
    Country:
    Russia
    That looks amazing (and very understandable)! Thank you!
     
  3. Nyap

    Banned Nyap HTML Noob

    Joined:
    Jan 13, 2016
    Messages:
    973
    Location:
    That Chaos Site
    Country:
    Antarctica
    Idk C, but I know C++
     
  4. imthe666st
    OP

    Member imthe666st Felyne Hunter

    Joined:
    Aug 16, 2015
    Messages:
    355
    Location:
    ><HFB>
    Country:
    Germany
    You can always google if you need a syntax. The point is that you have a basic idea about programming :)
     
    Last edited by imthe666st, May 30, 2016
  5. A H4CK3RS L1F3

    Member A H4CK3RS L1F3 GBAtemp Regular

    Joined:
    Jan 7, 2016
    Messages:
    115
    Country:
    United States
    Great guide! :bow:
     
  6. A H4CK3RS L1F3

    Member A H4CK3RS L1F3 GBAtemp Regular

    Joined:
    Jan 7, 2016
    Messages:
    115
    Country:
    United States
    Bro i got a question. What would the bit byte value be for 0xD3?
     
  7. imthe666st
    OP

    Member imthe666st Felyne Hunter

    Joined:
    Aug 16, 2015
    Messages:
    355
    Location:
    ><HFB>
    Country:
    Germany
    0xD3 sets the offset to the value of the Y-Block. The X-Block is always 0. Just do something like:
    Code:
    uint32 offset = 0xYYYYYYYY;
    
     
  8. jdeath

    Newcomer jdeath Member

    Joined:
    Oct 8, 2015
    Messages:
    27
    Country:
    United States
    Thanks. This was very helpful. By using a ! I could make a few cheats autostart (selecting item disables cheat)
     
  9. A H4CK3RS L1F3

    Member A H4CK3RS L1F3 GBAtemp Regular

    Joined:
    Jan 7, 2016
    Messages:
    115
    Country:
    United States
    O
    Ok thanks i got a code to work!!!
     
  10. quanta

    Newcomer quanta Member

    Joined:
    Jun 3, 2016
    Messages:
    15
    Country:
    United States
    Thanks for this, especially the git. If you know basic programming you can pretty much implement everything. However, can you give a basic rundown on DxData? I saw some codes that I wanted to convert that implemented it but the values made no sense.
     
  11. imthe666st
    OP

    Member imthe666st Felyne Hunter

    Joined:
    Aug 16, 2015
    Messages:
    355
    Location:
    ><HFB>
    Country:
    Germany
    From what I understood DxData is just a separate variable that can be written to any address. I haven't really been able to test these codes yet, since I hadn't found any easy codes using DxData. Therefor I might be wrong with my documentation.

    But let's try to write to an arbitrary inventory where every item is 4 bytes long. the first 2 bytes are the ID, we'll use DxData to write that. and the second 2 bytes are the amount which we will lock to 99 ( 0x0063 )

    So first we will set the offset for the first item, then create a loop with the 0xC command.
    Code:
    D3000000 08123456  <- Replace the Y block with any valid offset
    D5000000 00000000  <- Set the DxData to 0
    C0000000 00000032  <- Create a loop
    D4000000 00000001  <- Add 1 to the DxData (?) Not sure. That's why I'd need to test it more. ( Maybe I could use an old GBA ar to test this )
    D7000000 00000000  <- Write our DxData ( ID ) and increases the offset by 2.
    10000000 00000063  <- Write the amount of 99
    D1000000 00000002  <- End the loop | Increase the offset by2 
    
    So to parse this code just declare a new variable according to the size of our dxData. In our case it would be u16, since we only use a Short. I wouldn't make this variable global, but rather specific to the parsed code.
     
    quanta likes this.
  12. LackieG4002

    Newcomer LackieG4002 Newbie

    Joined:
    Jun 23, 2016
    Messages:
    5
    Location:
    Somewhere in the land of California
    Country:
    United States
    WOW. thanks this was really really helpful :yay: .Though, I do still need help on one thing. The wiki post you linked doesn't show 0xE codes. Could you please show me how one would convert 0xE codes to ntr?
     
  13. imthe666st
    OP

    Member imthe666st Felyne Hunter

    Joined:
    Aug 16, 2015
    Messages:
    355
    Location:
    ><HFB>
    Country:
    Germany
    0xE codes? Never heard about these. Mind posting a code with said code and what the code is supposed to do?
     
  14. LackieG4002

    Newcomer LackieG4002 Newbie

    Joined:
    Jun 23, 2016
    Messages:
    5
    Location:
    Somewhere in the land of California
    Country:
    United States
    I came across a code that i wanted to convert to ntr and it's suppose to stop monster encounters.

    Code:
    D3000000 00000000
    E02CC620 00000028
    E2841F7D E59F001C
    E5900000 E5900000
    E5900004 E3100C02
    03A00000 15940204
    E5840200 E12FFF1E
    002CC648 00308164
    001D077C EB03EFA7
    
    So, I started reading an explanation about 0xE codes but I didn't really get it. Hopefully you'll be able to understand it :D

     
  15. imthe666st
    OP

    Member imthe666st Felyne Hunter

    Joined:
    Aug 16, 2015
    Messages:
    355
    Location:
    ><HFB>
    Country:
    Germany
    I hope I understood that code, but I honestly have no clue how to explain it since I for myself just barely understood this right now.

    Alright, so the first line sets an offset to 0, ( so we can just ignore this line.. )
    Then comes our 0xE code. It uses the offset 0x2CC620 and the next 28 bytes specified in the code ( the next 3 1/2 lines.. [ each block is 4 bytes , and 28 / 4 = 7, so 7 blocks which is 3 1/2 lines] ) So our array of bytes should be E2841F7D E59F001C E5900000 E5900000 E5900004 E3100C02 ( please reverse every block to LE so it works, I'm just a bit lazy right now )
    And this array of bytes is written to the offset 0x2CC620 until 0x2CC648.

    What I don't understand is the then unused block of 4 bytes: 15940204 ( line 6, Block Y ).

    Same with the next 0xE command, there is again a byte unused.
    Sadly I don't own a gateway card. ( my primary reason why I made my debugger btw :P ) So I can't confirm anything. Maybe if you ask somebody with a gateway card he could help you by doing some tests in an unused memory region.
     
  16. LackieG4002

    Newcomer LackieG4002 Newbie

    Joined:
    Jun 23, 2016
    Messages:
    5
    Location:
    Somewhere in the land of California
    Country:
    United States
    Thanks for all the help! I really appreciate it. :bow:
     

Share This Page