前言

其实没有什么好讲的,就是随便折腾一下,然后顺手写点东西,鉴于我这个Linux环境下的中文输入法不太正常,我也懒得去修复,所以后面的内容可能会用英文写(暴力放洋屁)。

声明一点,本文并不是正经教程或者什么参考,只是个人折腾过程中记录的一点笔记。使用到的工具链、库之后基本肯定是会更新的,如果有变化,我很可能也不会更新本文内容适应更新。

工具链

基本上来说,照着 https://www.3dbrew.org/wiki/Setting_up_Development_Environment 做就行了。推荐使用Linux或者macOS。我现在用的是Xubuntu,但是ArchLinux大概也会是不错的选择。如果使用Debian,可能会因为软件源太旧而遇到一些问题。

安装完后,建议再运行一下“sudo chown -R YOUR_USER_NAME /opt/devkitpro/“,这样安装第三方库就不需要root权限了。(而且如果需要root权限会导致一些问题,比如说环境变量)

使用Netbeans

维基上已经有了关于NetBeans的说明,我再补充说明下。里面手动配置C/C++的搜索路径是不必要的,Netbeans会自动根据Makefile来确定。这样配置好工程后,所有的项目设定依然是通过Makefile完成的,Netbeans里面对于编译器、链接器的设定是不起效的。所以如果需要修改配置,依然得手动改Makefile。

使用Citra模拟器

如果没有合适的WiFi网络的话,使用3DS真机来调试是一件很痛苦的事情。重启、复制文件、进HBL真是累死人,就算有WiFi传输也会遇到死机等等的问题。所以最好还是用模拟器调试。我选择了Citra-3DS模拟器。因为二进制包和我系统的glibc不兼容,所以就自己编译了。

编译方法: https://github.com/citra-emu/citra/wiki/Building-For-Linux

别忘了用make -jN来加快编译速度(N ∈ Z+):)

使用Citra还是很简单的,在终端里运行citra-qt就能打开Citra的图形界面,然后就不用我多说了吧。

如果要直接从Netbeans运行Citra,打开项目属性,在Make选项卡的Target里面设置目标输出的3dsx文件(这个只是配置IDE,实际上还是由Makefile决定的),然后把Run Command设置为”citra “${OUTPUT_PATH}”“就可以了

使用SDL-1.2

现在没有一个3DS的SDL-1.2移植是可以正常工作的。我现在使用的是nop90的SDL移植,凑合能用,而且原作者还在开发当中。

首先是clone并且编译安装这个库:

git clone https://github.com/nop90/SDL-3DS.git
cd SDL-3DS/SDL-1.2.15
cp Makefile.n3ds Makefile
make
make install

接下来用这个库做一个简单的demo。

首先复制一份样本工程,作为实验程序。新建一个叫做romfs的文件夹(如果不存在的话),在里面放一张尺寸合适的bmp图片(我用了240*240*16bit),重命名为test.bmp。

在Makefile中启用对ROMFS的定义:

ROMFS		:=	romfs 

顺便加上这些CFLAGS:

CFLAGS	+=	$(INCLUDE) -DARM11 -D_3DS -D__3DS__

在库文件夹里面加上portlibs:

LIBDIRS	:= $(CTRULIB) $(PORTLIBS)

最后在链接时链接上SDL:

LIBS	:= -lSDL -lcitro3d -lctru -lm

这样同样也会把portlib的include目录添加到搜索路径中。

测试代码:

#include <3ds.h>
#include <stdio.h>
#include "SDL/SDL.h"

int main(int argc, char **argv)
{
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Surface *screen;
    SDL_Surface *bitmap;
  
    screen = SDL_SetVideoMode(320, 240, 16, SDL_SWSURFACE | SDL_TOPSCR | 
            SDL_CONSOLEBOTTOM);
  
    Result rs = romfsInit();
    if (rs)
        printf("romfsInit: %08lx\n", rs);
    else {
        printf("romfs Initialization succeed.\n");
        bitmap = SDL_LoadBMP("romfs:/test.bmp");
        if (bitmap == NULL)
            printf("Open Bitmap failed!\n");
        else
            SDL_BlitSurface(bitmap, NULL, screen, NULL);
    }
    printf("Should be bilted\n");
    SDL_Flip(screen);
    printf("Should be flipped\n");
    SDL_Delay(2000);
    SDL_Quit();
  
    return 0;
}

然后会发现……特么的不能用!就这么简单一段程序他就不能用( 原因其实是因为这段代码启用了图形加速,以至于对于Flip的要求就比较刁钻(不完全是这样,姑且这么讲吧)。考虑到我本来也是想要移植SDLPAL的,他这个硬件加速一搞顺便就破坏了对8bit色彩的兼容,干脆自己port一发SDL算了(

考虑想说的话很多……我新开一篇博文吧……