Zalo DS Blog

Saturday, July 18, 2015

3DS Homebrew Tips and Tricks (II)

This is the 2nd post on the series 3DS Homebrew Tips and Tricks
3DS Homebrew Tips and Tricks (I)
3DS Homebrew Tips and Tricks (II)
3DS Homebrew Tips and Tricks (III)

3. Application Icon, banner and RSF

If you are going to distribute your creations on cia or 3ds format then you are going to need a banner and an icon. For this I am using bannertool  cerated by Steveice10. You can find a compiled version of it on this thread

- Icons: you create icons using this:

bannertool makesmdh -s $(APP_TITLE) -l $(APP_DESCRIPTION) -p $(APP_AUTHOR) -i icon.png -o icon.smdh

where icon.png should be a 48x48 image. You can define AP_TITLE APP_DESCRIPTION and APP_AUTHOR somewhere else in your makefile, like this

APP_TITLE := "Jumping Jack" 
APP_AUTHOR := "Zalo" 
APP_DESCRIPTION  := "My very first game for the 3DS"

Icons should alse be distributed with your 3dsx file so the homebrew launcher can display information about your homebrew

- Banners: you create banners using this

bannertool  makebanner -i banner.png -a audio.wav -o banner.bin  

where banner.png is a  256x128 image (you can use transparency) and audio.wav I am not sure but I am always using 16 bits, 44100 Hz and stereo for them

- RSF: this files are configurations files for your project. You need a different one depending if you are going to build a cia or a 3ds. There are two good examples on Rinnegatamante's Lua Player Plus for 3DS. Here is the rsf for 3ds with audio support (see point 6) and the rsf for cia files. You only need to edit the BasicInfo and TitleInfo usually. For the TitleInfo you are gonna need a UniqueId. It is recommented to use and ID between 0xF8000 -0xFFFFF or 0xFF000 - 0xFF3FF which is used for Evaulations and Prototypes, ensuring you won't have a collision with a released app. To ensure you don't collide with another homebrew take a look at this post

The banner, the icon and the rsf are required for makerom to create your 3ds using the command

makerom -f cci -o $(PROJECT_NAME).3ds -rsf gw_workaround.rsf -target d -exefslogo -elf $(PROJECT_NAME)_stripped.elf -icon icon.bin -banner banner.bin

or to create your cias using the next one

makerom -f cia -o $(PROJECT_NAME).cia -rsf cia.rsf -target t -exefslogo -elf $(PROJECT_NAME)_stripped.elf -icon icon.bin -banner banner.bin 

[Update: take a look at the 3DSHomebrewTemplate created by Steveice10, those are probably the best makefiles around]

4. Pica Texture Format

Textures are optimized on the 3DS GPU in a special format optimized for cache called Pica Texture Format. This means that in order to use it with the GPU_SetTexture  function, first you need to convert it (either on real time or preprocessing it first)
It took me a while to get the code working for this (as you can see on this thread). But yeah, you just need to copy the code I posted there (actually I forgot to do it and I just did it now)

5. Sideways framebuffer

The framebuffer on the 3ds screens is sideways. Meaning it really goes like this:
In other words, what you really have is an screensize of 240x400, so if you don't do anything special this is what you'll get:
Usually you don't want this (not in the 3DS specially, because if you rotate the console you cannot have the 3D effect working). You need to do three things

- Everywhere in your code where you need the screen size, use 400x240 (which is what we want)

- When you set the viewport size make sure you swap the params. In other words, call

      GPU_SetViewport((u32*)osConvertVirtToPhys((u32)gpuDOut),(u32*)osConvertVirtToPhys((u32)gpuOut), y, x, h * 2, w);

- You need to premultiply your projection matrix by this one

      float mtx_projection_tmp0[16] =
       0.0f, 1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f,
       0.0f, 0.0f, 0.5f, -0.5f,
       0.0f, 0.0f, 0.0f, 1.0f

which basically swaps the x and y axis and also converts z from [-1, 1] to [-1, 0] because those are the viewport coordinates for the 3DS.

Now you can use the typical functions for creating a projection matrix, ortho, oblique... this is important if you are working on a cross platform environment. Creating a particlar case for a specific platform is a bit annoying and will cause you problems


  • "In other words, what you really have is an screensize of 240x400" ... ow, yeah. Of course. That makes it possible to flip between left-eye-viewpoint and right-eye viewpoint on a line-by-line basis, rather than at pixel level!

    By Blogger Sylvain Pypebros, at July 24, 2015 10:03 PM  

  • Yes
    That makes total sense. Thanks for the comment!

    By Blogger Zalo, at July 26, 2015 6:05 PM  

Post a Comment

<< Home