Porting an emulator to Nintendo Swith (Tutorial/Walkthrough and Discussion)

Discussion in 'Switch - Tutorials' started by salami68, Jun 1, 2018.

  1. salami68
    OP

    salami68 Member

    Newcomer
    2
    Jun 1, 2018
    United States
    Hey guys, A few weeks ago I ported a CHIP 8 emulator to the Nintendo switch and I was pretty surprised with how easy it turned out to be. I wanted to do a quick write up/guide so other people can hopefully get involved. I am hoping to find some people interested in porting other things to help me with future projects.
    It would be great to get a few people going to work together on stuff and bounce ideas off of each other. Without further introduction, here begins my guide:

    Step 1: Finding a suitable candidate for porting
    The first thing we need to do is find something to port, right now the tools we have in libnx are somewhat limited, but we do have SDL2! I wanted to start off simple, so I decided to port a CHIP 8 emulator, possibly the easiest system to emulate. Because I knew I had access to SDL2, I googled "SDL2 chip 8 emulator".
    I was able to find this project on github (scanlong/c8-master) which is licensed under the WTHPL license, which means "do whatever the hell you want". This is a perfect candidate for our purposes because it's only dependency is SDL2 and is written in standard c.

    Step 2: Successful compilation
    Now we have a source that we are ready to start working on. However, it will not compile under libnx currently, as it was written for pc. We need to completely rewrite the makefile.
    A good starting point is a makefile from one of the switchbrew examples on github. However we will need to make some changes to get it to compile.

    To link SDL2 to the source, we need to add lLSDL2 to the libs line in the makefile.

    From:
    LIBS := -lnx
    To:
    LIBS := -lSDL2 -lm -lnx



    Notice we also added -lm library, which is for mathematical functions, which we also need.

    Now we need to change some of the include statements in the header files to find SDL2 in the correct place.

    From:
    #include "SDL.h"
    To:
    #include <SDL2/SDL.h>
    #include <SDL2/SDL_events.h>


    We now have a compilable project! However it still does not work.

    Step 3: Getting it to run
    If we try to run our current build, we will notice that it exits immediately.
    If we look at the entrypoint to the emulator, we will notice a few things:



    int main(int argc, char* args[]) {
    if (argc != 2) {
    printf("usage: c8 game\n");
    printf(" game: Chip8 bianry file to play\n");
    return -1;
    }
    char* filename = args[1];

    struct cpu cpu;
    if (cpu_init(&cpu, filename)) {
    fprintf(stderr, "Unable to initialize the emulator!\n");
    return -1;
    };

    struct display display;
    if (display_init(&display)) {
    fprintf(stderr, "Unable to initialize the display!\n");
    return -1;
    }


    The first thing we see is that the emu is looking for command line arguments, there's no way were passing any command line args on the switch, so we have to remove those checks. The arguments are for a path to a rom, and to make this quick and not jump into switch FS stuff, we will use a hardcoded rom for this proof of concept.

    We can remove this entire section of code.



    if (argc != 2) {
    printf("usage: c8 game\n");
    printf(" game: Chip8 bianry file to play\n");
    return -1;
    }
    char* filename = args[1];





    We wont use filename, but it is an argument for the creation of the cpu, so when we call the cpu create method, we can put whatever in there:


    cpu_init(&cpu, "_");


    Now, in the cpu.c file, we see this section of code related to pulling a rom from the filesystem:


    FILE* game = fopen(filename, "rb");
    if (!game) {
    fprintf(stderr, "Unable to open file '%s'!\n", filename);
    return -1;
    }
    fread(&cpu->memory[PC_START], 1, MEMORY_SIZE - PC_START, game);
    fclose(game);



    You can comment this all out or delete it, we will use a hardcoded rom for now, just to get something running.

    To get the data from a chip8 rom, you can run xxd -i on it, which will output a C array with the relevent binary data.


    unsigned char rom_bin[] = {
    0x12, 0x25, 0x53, 0x50, 0x41, 0x43, 0x45...


    We will store this on the heap, and then copy it into the cpu struct for the emulator.

    memcpy(&cpu->memory[PC_START], &rom_bin, MEMORY_SIZE-PC_START);


    We are getting close, but the program still immediately crashes.

    After some debugging, we find the culprit in the display.c file:

    display->renderer =
    SDL_CreateRenderer(display->window, -1, SDL_RENDERER_ACCELERATED);
    if (display_check_error("renderer", display->renderer)) return -1;


    We have no accelerated rendering in libnx yet, so we must use software rendering.

    display->renderer =
    SDL_CreateRenderer(display->window, -1, SDL_RENDERER_SOFTWARE);
    if (display_check_error("renderer", display->renderer)) return -1;


    Now make again, and test. We now have a working emulator!

    Step 4: Next steps
    This is far from finished, and uses some bad coding practices to get things going, but I think its a great beginners proof of concept.
    You can use what you've learned and more research to add controller support, loading roms from filesystem, and any other features!

    Thanks for reading guys, this is my first tutorial so please let me know if I could have done anything better, or anything needs clarification. I would post some pictures, links, and files, but I don't think I have enough posts yet to do that.
     
  2. epickid37

    epickid37 ( ͡° ͜ʖ ͡°)

    Member
    8
    Jan 4, 2017
    United States
    mushroom kingdom
    Thanks for this! this is insanely cool!
     
  3. Nudu

    Nudu Advanced Member

    Newcomer
    1
    Feb 18, 2018
    Germany
    Final Destination
    Wow you just joined 2day..
    .
     
    Slackot and cagycee like this.
  4. hamrawk

    hamrawk Content Creator

    Member
    4
    Oct 18, 2014
    United States
    Your signature makes this comment so much better...
     
    Wolfy, Sonicbrawler, cagycee and 4 others like this.
  5. Deathscreton

    Deathscreton GBAtemp Advanced Fan

    Member
    6
    Oct 1, 2009
    United States
    This is the kinda baller content I'm talking about. Fuck yeah, good job m8. Take my like and eat it too.
     
  6. Drud1995

    Drud1995 GBAtemp Regular

    Member
    3
    Apr 18, 2012
    United States
    Magicant
    Perhaps it's time to put my programming skills to good use. I'll check into porting something over! =)
     
  7. salami68
    OP

    salami68 Member

    Newcomer
    2
    Jun 1, 2018
    United States
    Thanks for the positive feedback guys, I realized I completely skipped instructions on how to set up the dev environment, but they are available if you search the switchbrew wiki.
     
  8. thekarter104

    thekarter104 GBAtemp Advanced Maniac

    Member
    7
    Mar 28, 2013
    United States
    Awesome!

    This means an easier way of us getting an N64 emulator for Switch :D
     
  9. salami68
    OP

    salami68 Member

    Newcomer
    2
    Jun 1, 2018
    United States
    An n64 emulator is a whoooole different ball game. We don't even have hardware acceleration or a library like openGL yet. I'm sure it will come in time though.
     
  10. Nudu

    Nudu Advanced Member

    Newcomer
    1
    Feb 18, 2018
    Germany
    Final Destination
    xD
     
  11. Red1Reaper

    Red1Reaper Asperger Dude

    Member
    5
    GBAtemp Patron
    Red1Reaper is a Patron of GBAtemp and is helping us stay independent!

    Our Patreon
    Feb 5, 2017
    Spain
    Valencia, Rafelbuñol
    And this is what i call a great way to enter in a forum, whit actual content. so clasy, thanks.
     
    Wolfy likes this.
  12. huma_dawii

    huma_dawii GBAtemp Addict

    Member
    9
    Apr 3, 2014
    United States
    Planet Earth
    <3 Welcome :)
     
  13. ShadowOne333

    ShadowOne333 GBAtemp Guru

    Member
    18
    Jan 17, 2013
    Mexico
    Hopefully this helps to port Wolf4SDL as well :P
     
  14. jimmyj

    jimmyj Official founder of altariaism. Copyright jimmyj

    Member
    7
    May 26, 2017
    Italy
    Hyrule
    how about controller commands?
     
  15. jimmyj

    jimmyj Official founder of altariaism. Copyright jimmyj

    Member
    7
    May 26, 2017
    Italy
    Hyrule
    which makefile should I be using?

    — Posts automatically merged - Please don't double post! —

    so just to be sure,I just need devkitpro?
     
  16. Type_O_Dev

    Type_O_Dev GBAtemp Advanced Fan

    Member
    7
    Dec 12, 2017
    United States
    Great write up
     
  17. salami68
    OP

    salami68 Member

    Newcomer
    2
    Jun 1, 2018
    United States
    Download one of the sample makfiles from the switchbrew examples repo, then make the changes that i mentioned.

    Yes you need devkitpro and make sure to also install the SDL2 packages with pacman or msys on windows
     
    jimmyj likes this.
  18. jimmyj

    jimmyj Official founder of altariaism. Copyright jimmyj

    Member
    7
    May 26, 2017
    Italy
    Hyrule
    this is really cool,I just got space invaders running, now I just need controls. :mthr:
     
  19. MrWhosHacking

    MrWhosHacking GBAtemp Regular

    Member
    2
    May 3, 2018
    United States
    Is there a video how to
     
  20. DarkOrb

    DarkOrb GBAtemp Regular

    Member
    5
    Oct 11, 2013
    Germany
    I follow this tutorial for porting games/emulators to Nintendo Switch:



    But I have problems modifying an existing makefile (I'm using the makefile from the "CannonBall Engine") so it's working with my project. Somebody has any idea how to modify a makefile so it's refering to the source files of another project? "MVG" said that it took him 45 minutes to port chocolate doom, but it took me 6+ hours to modify the existing CannonBall makefile alone so it's refering to the source files (and headers) of the project I want to port (but it still doesn't work, I don't know what's wrong). That can't be right!? Somebody have any clue?
     
    Last edited by DarkOrb, Jun 12, 2018
    MrWhosHacking likes this.
Loading...