Programming for Nintendo DS. First steps

    This article discusses the basics of software development for Nintendo DS for Linux. However, all the tools used are cross-platform and there should not be big differences for other OSs.

    First, let's figure out what this game console is all about. Here's what Wikipedia tells us:
    * Processor: ARM946E-S - 67 MHz, ARM7TDMI coprocessor - 33 MHz
    * Memory: 4 MB, 656 KB video memory, 512 KB memory for textures
    * Screen: two separate LCD displays, 77 mm diagonal ( 3 inches), resolution 256x192 pixels, up to 260 thousand colors. The distance between the screens is approximately 21 mm, which is equivalent to 92 “hidden” lines.
    * Video system: Support for 2D and 3D (T&L, texture coordinate conversion, texture mapping, alpha blending, anti-aliasing, whole-shading and Z-buffering), theoretically allows you to draw 120,000 polygons per second (however, it has a limit on rendering 6144 vertices or 2048 triangles in one frame).
    * Sound: Stereo, 16-channel ADPCM / PCM
    * Storage devices: 1 slot for Nintendo DS own cartridges, 2 Nintendo Gameboy Advance cartridge slots
    * Communication: IEEE 802.11 (Wi-Fi), Nintendo proprietary format is used for connection. The radius of the LAN from 10 to 30 meters depending on the conditions.
    * Management: touch screen, built-in microphone for voice recognition, A / B / X / Y buttons, D-Pad, L / R ciphers, Start and Select buttons
    * Operating time: 6-10 hours
    * Weight: 275 grams
    * Dimensions: 148.7 × 84.7 × 28.9 mm

    As we can see, the console has two processors: ARM9 and ARM7. The main thing for us is ARM9, it is on it that our programs will be executed. ARM7 is commonly used to service the touchscreen, keyboard, microphone, and other peripherals. The libNDS library includes a standard program for ARM7 (default.arm7), which fully satisfies the need for communication with standard peripherals. So at the initial stage, we do not have to think about the operation of the second processor.

    Next, configure the environment for cross-compilation.
    We need: a
    set of development tools for ARM - DevkitARM sourceforge.net/projects/devkitpro/files/devkitARM ;
    library that simplifies development for Nintendo DS - libNDS sourceforge.net/projects/devkitpro/files/libnds ;
    as well as an emulator like DeSmuME - desmume.org/download .
    We create the directory / opt / devkitpro, into which we unpack devkitARM and libNDS.
    We set up environment variables: That's just everything and is configured. Now it's time to take a look at the graphics subsystem, and at the same time write a simple little program, something like “Hello World!”. NDS has two graphic cores: main (main) is used by default for the top screen and additional (sub) for the bottom. Each core can work in one of six modes, and the main one has 2 additional modes for displaying large images.
    export DEVKITPRO=/opt/devkitpro
    export DEVKITARM=$DEVKITPRO/devkitARM





    Graphics modes of the video controller:
    Main 2D core
    ModeBG0BG1BG2BG3
    Mode 0Text / 3DTextTextText
    Mode 1Text / 3DTextTextRotation
    Mode 2Text / 3DTextRotationRotation
    Mode 3Text / 3DTextTextExtended
    Mode 4Text / 3DTextRotationExtended
    Mode 5Text / 3DTextExtendedExtended
    Mode 63D-Large bitmap-
    Frame bufferDirect VRAM display as a bitmap
    Additional 2D core
    ModeBG0BG1BG2BG3
    Mode 0TextTextTextText
    Mode 1TextTextTextRotation
    Mode 2TextTextRotationRotation
    Mode 3TextTextTextExtended
    Mode 4TextTextRotationExtended
    Mode 5TextTextExtendedExtended


    To use the kernel, we must first turn it on, set the mode of operation and “map” the memory.
    Our program will require the output of 2D information, so turn on the 2D graphics core for the main screen:
    powerOn(POWER_2D_A);

    Set the video mode for the graphics core:
    videoSetMode(MODE_FB0);
    Framebuffer mode - the direct correspondence of the video memory to the display pixels.

    Next, you need to tell the graphics core which memory area it needs to use, because both graphics cores use shared video memory. We use Bank A as a framebuffer for the top screen:
    vramSetBankA(VRAM_A_LCD);

    This initialization is complete and we can already display information on the screen. For example, fill the screen with randomly colored pixels.
    Here is the full text of the program:
    #include
    int main()
    {
     powerOn(POWER_2D_A); //Включаем основное 2D ядро
     videoSetMode(MODE_FB0);//Включаем режим фреймбуфера
     vramSetBankA(VRAM_A_LCD);//Указываем область памяти
     uint16* buffer;
     while(true){
      buffer = VRAM_A + rand()/(RAND_MAX/SCREEN_WIDTH/SCREEN_HEIGHT); //Случайный адрес в видеопамяти
      *buffer = RGB15(rand()/(RAND_MAX/31),rand()/(RAND_MAX/31),rand()/(RAND_MAX/31)); //Случайный цвет
     }
    }

    * This source code was highlighted with Source Code Highlighter.

    Here is the program with the makefile: narod.ru/disk/23987391000/example1.tar.gz.html

    So, we just created, albeit a primitive, but working properly program for Nintendo DS. In the next article, I plan to consider working with tile graphics, interrupts, a keyboard and a touch screen as an example of a simple game.

    And here is a very good English lesson loop: dev-scene.com/NDS/Tutorials

    Also popular now: