Working on a 3DS Port

The update loop runs always at 60 “updates per second” (at least it tries). So the 16 you see is the number of frames rendered.
So the graphics will be not perfectly smooth but the game runs at (almost) full speed.

Maybe you find a way to make this faster by using sf2dlib in a different way (or some other lib). By removing the “copy to Screen” call in sf2dlib I got twice the frames last time I tested. So something is wrong with that framebuffer copy.

Fast test on N3DS with 804 MHZ mode, it runs at 51/53 FPS.
Atm i’m working on a little modification to sf2dlib which will increase fps to 23/24 on O3DS (at least for my testings, i just need to patch a bit it).

Nice. Everything above 30 FPS should look smooth. (you probably see the difference between 50 FPS and 16 ;))

Using the modified sf2dlib i mentioned above i got stable 60 FPS on N3DS and 25 fps on O3DS but colors are messed up (probably there still are some problem in the function i’ve modified, i’m going to try to patch it).

Fixxed also the colors!
Here’s the result: … 8402611200

Very nice. Just curious: How many FPS do you get on o3ds when you disable the display copy “UpdateDisplay” completely? Just for figuring out how big the performance bottleneck here is compared to the rest of Player.

When running at 60 FPS you will need the to implement CtrUi::Sleep (Wait for “time” milliseconds). Otherwise the game will run too fast. Probably doesn’t matter here because it runs at ~60 FPS. But just to be save ^^

There still are problems with alpha channel, for example if i go with the player in a forest in the wolrdmap, i get a gray rect instead of the player (like for the fps counter). It’s a pretty strange thing anyway, like if alpha channel is incorrectly processed, what i noticed during the “colors bug” is that fps counter got fixxed, what i used to solve it is a __builtin_bswap32 (which should be a standard C function) on every pixel before tileing the texture used by sf2dlib but that caused the alpha channel comeback. :confused:

As for the stubbed UpdateDisplay, i get 32 FPS on O3DS without UpdateDisplay.

Yeah, sounds like an alpha channel problem. In theory it is enough when the “DynamicFormat” fits the RGBA layout of the screen buffer (When the gpu does not adjust the pixel format).

As for the sounds, what are the files i need to see to?

EDIT: Probably also some generic function on how EasyRPG works for audio and maybe a template for a stubbed “audio-driver” could be good

You must overload “GetAudio” in CtrUi and return an implementation of AudioInterface.

A stubbed driver is “EmptyAudio” in audio.h

Most function of the AudioInterface are nonsense and can be stubbed (no idea why they still exist, we should delete them someday).

See the documentation comments in audio.h

The stuff that must be implemented is BGM_* and SE_. ME_ and BGS_* are unused and can be stubbed (will be deleted someday)
BGM is for back ground music (Music/ folder). You can always only have one background track playing and you can alter the state of the background track, e.g. fade it out or change the volume.
The important ones are BGM_Play, BGM_Fade, BGM_Volume and BGM_Stop. Depends on you if you want to implement all features, at least Play and Stop shoudl work (Fade can just call Stop e.g.). :slight_smile:
BGM_PlayedOnce is for very few games which need this (so you can stub it for now and just return true…). BGM_GetTicks is for counting Midi ticks, even fewer games use this, you can take the bad implementation from SDL_Audio::BGM_GetTicks here.
BGM_Pause and BGM_Resume is only when the game is in the background. Guess the 3DS has better ways to generate silence, so this can be stubbed ;).

SE are sound effects (Sound/ folder). More then one sound effect is possible. They are just fire & forget, so only SE_PLay and SE_Stop exists.

Update() will be called 60 times per second. You can leave it empty if you don’t need it.

Most games use Midi, Wav and MP3. We are currently working on SDL-independend ways to support MIDI and MP3 which will come during the next weeks, so you will probably not need to write this (via mpg123 and fmmidi) because we can contribute the code :). So support for WAV and OGG would be fine by now.

EDIT And you must define the macro SUPPORT_AUDIO

So when you call for example BGM_Play, the file should be converted manually? (I mean there are no pre-builded vorbisfile decoders and similars?)

Correct. Because we just ask SDL to do this for us which doesn’t exist here. We planned to provide these converters by our own someday because SDL has some annoying shortcoming and bugs. But… not yet.

We also have openal_audio which uses libsndfile to do the decoding. But I havn’t compiled libsndfile for you. I can do this if you think it’s useful (for WAV and OGG decoding). Teh relevant func in openal_audio is “setbufferloader”. But I can’t help you here… The AL stuff was written by some japanese guy and the code is… well… “interesting”.
Or google other examples for libsndfile.

Hm, yeah. Or just write your own parser for WAV/OGG. As you wish.

I can try to port my proper decoders used in lpp-3ds but they have a lot of workarounds and temp patches to let it work properly.
(and also they’re based on mfloat-abi=softfp that probably changes the speed of the whole decoder. … aSound.cpp

P.s. in the meantime i tried to create a little stubbed audio-device just to test csnd accessibility in NH 2.X (to see if i have to use dsp or i can use csnd too) and seems the costructor doesn’t output anything (?).
Is something wrong here? (printf just prints on debug console on 3DS like Output does)

Looks fine. You are probably just not initializing it correctly.

In the constructor of CtrUi you must create audio. (see sdl_ui.cpp 174 for this, audio_.reset(new …).
And the GetAudio call must return that instance. Just do it like in sdl_ui. (declare var like in line 158 of sdl_ui.h)
And define SUPPORT_AUDIO as I already said.

If you don’t want to write the Audio decoding at least a skeleton code that sends a buffer of silence to the DSP (or cSnd) would be fine (+ some documentation what to take care of). Because the decoding will be probably the same on all platforms, soon :slight_smile: (few weeks)

I’ve done all the thing you said and seems like the costructor still doesn’t return any output like if it’s not called :confused:

I’ve defined SUPPORT_AUDIO in my makefile and these are the changes i made, maybe i missed something: … 4e5ee5c014

My bad. Look at the bottom of system.h :slight_smile:

BGM files how much big they are? (I mean, probably for sounds i can use a normal playsound but for BGM i suppose is better to do a proper audio streaming to not mess up with out of ram problems)

music Streaming is better. They can be anything from few KB to 10 MB. If you have enough memory you can keep the compressed audio fully in RAM… but uncompressed will not fit.
Sounds should be save to do without streaming.

Looks like csnd is unaccessible at least on Yotube App, that’s pretty bad cause dsp service is a bit more unreliable for audio (for what i’ve tested) so now two are the possible things:

  1. For NH 2.X users i can add svchax execution at startup to gain access to csnd but when such exploit will be patched, (so probably starting from fw 10.8) anyone will not be able to use it properly. [Users on CFW or on NH1.1B are fine]
  2. Use dsp service (which i also had problem with like implementing looping feature in audio streaming for OGG files: … d.cpp#L843

Also dsp service runs (for standard ctrulib) a secondary thread on appcore to manage the whole thing that will probably slowdown main thread. (On my lua interpreter i moved such thread on SYSCORE but streaming thread runs on APPCORE so the slowdown is even here).
Csnd service uses no auxiliary threads so the audio streaming thread can be launched on SYSCORE (resulting in no slowdown for main thread).

So currently it sounds that CSND is more reliable (as long as the exploit is not patched).
Is it a lot of work to change this later when ctrulib improves DSP or are the APIs too different?

Because you are doing the port I think you should stick to the technology that works best for you :slight_smile: