[Tutorial] Switch Homebrew development

Discussion in 'Switch - Tutorials' started by WerWolv, Jun 13, 2018.

  1. WerWolv
    OP

    WerWolv GBAtemp Regular

    Member
    4
    Mar 30, 2018
    Switzerland
    Switch Homebrew development

    I've seen quite a lot questions about how to get into Homebrew development for the switch recently so I decided to share some information I would have found useful when I started.
    This Guide is made on Windows 10. Refer to other resources for the installation process on other operating systems. After the setup is done, pretty much everything will be the same.

    First of all, here's all the topics I'm going to cover in this Guide:
    • What do I need?
    • Setup and Installation
    • Tools
    • Examples and explanation
    • FAQ
    If you find any errors, feel free to report them! So let's get started.




    • First of all you'll need a Nintendo Switch with a way to get into RCM and some way to start up the custom loader (Hekate for example). There are many tutorials out there on how use those.

      Next, you'll need the following tools:
      • devkitPro : Make sure devkitA64 is selected during installation.
      • hb-menu : You need one of the latest commits to properly use nx-link later so you need to compile it from sources for now.
      • Atom : A nice and advanced text editor. You can use any other text editor you want but I recommend this one.
      • Cmder : An advanced console emulator for Windows. You can use the default Windows cmd but I recommend to switch to better one.
      • (Git : Version control tool. I recommend using it to share your progress and to open source your project so the community can benefit from it. It's not necessary though)
      • ASM/C/C++ knowledge : I'll try to explain everything as easy as possible but don't try getting into homebrew without any prior C programming experience.
      • A lot of patience : We don't have GDB yet so your only way to debug right now is via printf.

      Once you're sure you've got everything above you may continue to the next chapter.

    • After you've installed devkitPro, Atom Cmder and hopefully git AND you're running the latest version of the hb-menu we can start with the setup process.
      First of all we need to correct the devkitPro environment variables. By default they get set to the paths used on Linux which won't work on Windows.
      To change them, press Win + Pause/Break and click on Advanced system settings in the window that pops up. Now you press on the Environment Variables... button.
      Now search in the System variables list for DEVKITARM, DEVKITPPC and DEVKITPRO. Change them to your devkitPro path. Now if it's not already there, add a DEVKITA64 variable and set the path to the devkitA64 folder path.
      After you're finished, it should look something like this:

      [​IMG]
      Now find the PATH variable and add the path to the ../devkitPro/tools/bin directory to it.

      After this step you're basically done. You don't need any setup for Atom or Cmder. They just work out of the box.​

    • For compilation and deployment we're going to use two things: make and nxlink. Both get installed by default together with devkitPro.

      If you use the attached template project, all you'll need to do is to type make. This will take care of the whole compilation part. To deploy your compiled project to the Switch now we use nxlink.

      First, enter the hbmenu on your Switch and press the Y Button. This brings you into the nxlink mode. The list of homebrews should disappear now. Now you can run the following command:

      nxlink -s -a 192.168.xxx.xxx out\<homebrew_name>.nro

      This nxlink command some arguments.
      • -s stands for server. It's used for debugging. With this option enabled, printf output can get redirected to our console.
      • -a stands for address. It's the IP address of the Switch. You can look it up either in your router settings or in the Switch settings.
      • out\<homebrew_name>.nro is the path to your homebrew executable. By default it gets built inside the /out folder.


    • First of all, download the attached sample homebrew and load it up in Atom.
      There are a lot of great examples for many different things inside the /devkitPro/examples/switch folder. Read through those first if you want to start developing. You can also look at the source code of EdiZon, Checkpoint, the hbmenu or any other homebrew to find out how they did certain stuff. We're all a community and learn from each others :). For any other questions consult the official documentation of libnx. You may ask here in this thread as well but I can't promise to be able to help everybody.

      So, let's get started with the examples. More examples will come over time.


      • Code:
        #include <switch.h>
        #include <stdio.h>
        
        int main(int argc, char** argv) {
            u32 kdown = 0x00000000;
            u32 kdownOld = 0x00000000;
        
            gfxInitDefault();
            consoleInit(nullptr); //Init the console
        
            while(appletMainLoop()) {
                hidScanInput();    //Scan for input       
                kdown = hidKeysDown(CONTROLLER_P1_AUTO); //Read the currently pressed buttons and store that value into kdown
        
                 //Edge detection. We don't want to print "Hello World" while A is pressed. We only want to print it once and then again on the next press
                if(kdown > kdownOld) {
                    if(kdown & KEY_A)
                        printf("Hello World\n"); //Prints to the console on screen
                }
        
                kdownOld = kdown;
                 
                gfxFlushBuffers();   //Finish this frame
                gfxSwapBuffers();    //Display it on the screen
                gfxWaitForVsync();   //Wait till the last frame finished displaying before updating to avoid flickering
            }
            gfxExit();
            return 0;
        }
        

      • Code:
        #include <switch.h>
        
        int main(int argc, char** argv) {
           u8 *framebuffer;
           u32 framebuffer_width;
           u32 framebuffer_height;
        
           gfxInitDefault();
           framebuffer = gfxGetFramebuffer(&framebuffer_width, &framebuffer_height);  //Gets the address of the framebuffer so we can draw to it
        
           while(appletMainLoop()) {
               //The framebuffer is layed out in RGBA8 format. We're coloring it entirely in Magenta (0xFF00FFFF)
                for(u16 x = 0; x < framebuffer_width; x++) {
                    for(u16 y = 0; y < framebuffer_height; y++) {
                         framebuffer[(x + y * framebuffer_width) * 4 + 0] = 0xFF;   //Red
                         framebuffer[(x + y * framebuffer_width) * 4 + 1] = 0x00;   //Green
                         framebuffer[(x + y * framebuffer_width) * 4 + 2] = 0xFF;   //Blue
                         framebuffer[(x + y * framebuffer_width) * 4 + 3] = 0xFF;   //Alpha
                    }
                }
              
                gfxFlushBuffers();   //Finish this frame
                gfxSwapBuffers();    //Display it on the screen
                gfxWaitForVsync();   //Wait till the last frame finished displaying before updating to avoid flickering
            }
        
            gfxExit();
        
           return 0;
        }
        
     

    Attached Files:

    Last edited by WerWolv, Jun 23, 2018
  2. tomGER

    tomGER GBAtemp Fan

    Member
    6
    Feb 6, 2017
    Germany
    Awesome work, this is definitely a good guide to get someone into it.

    It took my ages of trial and error to get everything set-up so having a guide should hopefully reduce that pain for everyone coming new to the scene!
     
    Nevercholt and WerWolv like this.
  3. Shigure20

    Shigure20 Member

    Newcomer
    2
    Jun 9, 2017
    Switzerland
    Nice work,thx
     
  4. Thetoto

    Thetoto GBAtemp Advanced Fan

    Member
    4
    May 10, 2018
    France
    I can't run nxlink... I just compile hbmenu from source with latest commit, compile the hello world homebrew. It's the correct IP, because FTP works with FTPD.
    upload_2018-6-14_9-21-35.png
     

    Attached Files:

    Last edited by Thetoto, Jun 14, 2018
  5. WerWolv
    OP

    WerWolv GBAtemp Regular

    Member
    4
    Mar 30, 2018
    Switzerland
    Forgot to add that to the guide. Sorry about that. You need to press the Y-Button when you're inside the hbmenu. This will start the nxlink mode
     
  6. Thetoto

    Thetoto GBAtemp Advanced Fan

    Member
    4
    May 10, 2018
    France
    Ok nice, thank you. I'll try later.
     
  7. dovah

    dovah Member

    Newcomer
    2
    Jun 9, 2018
    Italy
    any tips on debugging?

    I use ryujinx and yuzu to test my nro, but i'd like to see the stdout at least
     
  8. WerWolv
    OP

    WerWolv GBAtemp Regular

    Member
    4
    Mar 30, 2018
    Switzerland
    I haven't used any emulators to test my homebrew. AFAIK only Mephisto supports GDB so far. Other than that you have to rely on printf and std::cout on your own Switch like I described in my post
     
  9. dovah

    dovah Member

    Newcomer
    2
    Jun 9, 2018
    Italy
    ok thanks for the tutorial anyway.
    i didn't know about nxlink which i'll surely try later.
     
    WerWolv likes this.
  10. roedesh

    roedesh Member

    Newcomer
    2
    May 25, 2018
    Netherlands
    Nice tutorial and project template!
    One question though, what are those nxfnt files in the data folder? I'm kinda new to this.
     
  11. WerWolv
    OP

    WerWolv GBAtemp Regular

    Member
    4
    Mar 30, 2018
    Switzerland
    Oh. They weren't supposed to there already. The files are built and statically linked into your homebrew. You can put for example images or music in .bin format in there or nxfnts which basically are font files so you can draw text in your program
     
    roedesh likes this.
  12. mariogamer

    mariogamer GBAtemp Maniac

    Member
    5
    Aug 12, 2015
    Canada
    That is good.

    (Especially if you got a *** 32bit PC and you're trying to build a 32bit toolchain on it (and that the build isn't working))
     
  13. 7Akira7

    7Akira7 Newbie

    Newcomer
    1
    Feb 18, 2018
    Germany
    Which language should I learn for this stuff? C, C# or C++?
    I tend to C++ btw :D
     
  14. tomGER

    tomGER GBAtemp Fan

    Member
    6
    Feb 6, 2017
    Germany
    If you tend to learning C++ go for it - Both C and C++ work
     
  15. WerWolv
    OP

    WerWolv GBAtemp Regular

    Member
    4
    Mar 30, 2018
    Switzerland
    Don't look at C and C++ as two different languages. C++ is the same as C but with lots of syntactical sugar and OOP. If you want to develop homebrew, go for C/C++. C# is more for quickly hacking together a GUI. You don't have to be as careful as with C/C++ so it's easier to get started with it.
     
    7Akira7 and tomGER like this.
  16. BurningDesire

    BurningDesire GBAtemp Guru

    Member
    13
    Jan 27, 2015
    United States
    Behind a screen reading news
    How would i go about setting up sdl2?
     
  17. WerWolv
    OP

    WerWolv GBAtemp Regular

    Member
    4
    Mar 30, 2018
    Switzerland
    Check out NX-Shell. Especially the main.c file. Looks like it works basically like on every other platform, just keep in mind that we still don't have a fully working GPU driver so software rendering it is
     
    BurningDesire likes this.
  18. BurningDesire

    BurningDesire GBAtemp Guru

    Member
    13
    Jan 27, 2015
    United States
    Behind a screen reading news
    I mean in terms of installing it. I can find the normal .dll from their website. I am assuming I just set it up like normal?
     
  19. WerWolv
    OP

    WerWolv GBAtemp Regular

    Member
    4
    Mar 30, 2018
    Switzerland
    In your make file, add
    Code:
    -lSDL2_ttf -lSDL2_image -lSDL2_mixer -lSDL2
    to the LIBS varibale. After that just get the sources for SDL2 and compile them with the project. DLLs won't work, since they are for Windows only and we don't have dynamic linking yet. So just link it statically with your project. I have more time next week so I'll probably make a tutorial about that
     
    BurningDesire likes this.
  20. BurningDesire

    BurningDesire GBAtemp Guru

    Member
    13
    Jan 27, 2015
    United States
    Behind a screen reading news
    A tutorial would definitely be greatly appreciated! Especially a noob friendly one :D
     
    WerWolv likes this.
Loading...