isle-portable icon indicating copy to clipboard operation
isle-portable copied to clipboard

3DS Port

Open JPeisach opened this issue 5 months ago • 28 comments

Here we are! The port allows for you to play on the touch screen.

Known issues:

  • No gamepad, circle-pad, d-pad, button support yet.
  • Sometimes exiting will cause the console to crash? This should've been mitigated in https://github.com/isledecomp/isle-portable/commit/511acfe82d8c45aba4280b41f205d921e3ea71bc but it's possible I'm missing something. The crash occurs in syncAttributeAddress in libctru.
  • Some frame drop in certain areas, particularly the FMV/video parts, registration book loading
  • No transitions (currently using the "Cut" transition)
  • Some audio/stream glitches can happen

Code changes:

  • Citro3D renderer
  • Sets up 3ds default "config overrides". The main thing currently is the save path, which is broken because it can't work with two forward slashes (it tries to save to sdmc:/3ds/isle//History.gsi which fails)
  • Creates applet hooks, based off of DevilutionX. This makes sure when the game is suspended, that the game pauses.

Packaging:

  • Currently as a 3dsx
  • Small QOL question: Figure out whether the icon should be transparent or total white background to fit better on Homebrew launcher? Should we make new icon?

~~- TODO: CIA. The CIA allows you to install the game to the home menu and launch it from there. What would be nice is a 3D banner of some kind, but I think for now I'll just make it basic just so we have something~~

Will do CIA packaging in another PR

Installation:

  • Once homebrewing your 3DS, copy isle.3dsx to the 3ds folder on the root of your SD card.
  • Place the game files in 3ds/isle/LEGO which should follow the specification in legofiles.cpp
isle
└── LEGO
    ├── data
    │   ├── ACT1INF.DTA
    │   ├── ACT2INF.DTA
    │   ├── ACT3INF.DTA
    │   ├── BLDDINF.DTA
    │   ├── BLDHINF.DTA
    │   ├── BLDJINF.DTA
    │   ├── BLDRINF.DTA
    │   ├── GMAININF.DTA
    │   ├── HOSPINF.DTA
    │   ├── ICUBEINF.DTA
    │   ├── IELEVINF.DTA
    │   ├── IISLEINF.DTA
    │   ├── IMAININF.DTA
    │   ├── IREGINF.DTA
    │   ├── OBSTINF.DTA
    │   ├── PMAININF.DTA
    │   ├── RACCINF.DTA
    │   ├── RACJINF.DTA
    │   ├── testinf.dta
    │   └── WORLD.WDB
    └── Scripts
        ├── Act2
        │   └── ACT2MAIN.SI
        ├── Act3
        │   └── ACT3.SI
        ├── Build
        │   ├── COPTER.SI
        │   ├── DUNECAR.SI
        │   ├── JETSKI.SI
        │   └── RACECAR.SI
        ├── CREDITS.SI
        ├── Garage
        │   └── GARAGE.SI
        ├── Hospital
        │   └── HOSPITAL.SI
        ├── Infocntr
        │   ├── ELEVBOTT.SI
        │   ├── HISTBOOK.SI
        │   ├── INFODOOR.SI
        │   ├── INFOMAIN.SI
        │   ├── INFOSCOR.SI
        │   └── REGBOOK.SI
        ├── INTRO.SI
        ├── Isle
        │   ├── ISLE.SI
        │   ├── JUKEBOX.SI
        │   └── JUKEBOXW.SI
        ├── NOCD.SI
        ├── Police
        │   └── POLICE.SI
        ├── Race
        │   ├── CARRACE.SI
        │   ├── CARRACER.SI
        │   ├── JETRACE.SI
        │   └── JETRACER.SI
        └── SNDANIM.SI

13 directories, 46 files

The isle.ini configuration will be generated with the work done earlier

Testing

  • [X] Old 3DS (@ItzSwirlz , @GabubuAvailable)
  • [X] Old 2DS (@Maxbrick ?, @AllMeatball)
  • [X] New 3DS (@Maxbrick ?, @AllMeatball ?, @hexaheximal)
  • [ ] New 2DS

Credits

@foxtacles for the ini transitions and being supportive of the project in general @AJenbo for Citro3D renderer, he put in so much effort into it. @Maxbrick for teaching me about how 3DS graphics worked, helping me at the start @kynex7510 for C3D help @StevenSYS icon All the testers: @GabubuAvailable , @Maxbrick , @AllMeatball , @hexaheximal

JPeisach avatar Jun 29 '25 15:06 JPeisach

Turns out it was because I didn't dump the DSP firmware, it now works fine on my Old 2DS after dumping it

~~I just compiled a debug build and tested it on my Old 2DS and it freezes (Just the game not the whole OS) when I drag a character on to a place on the map~~

~~Also when I try to close the Homebrew Launcher after the game freezes, it gets stuck on "Closing software..." and I have to force restart the 2DS using the Rosalina menu~~

~~EDIT: With a release build I can close the Homebrew Launcher fine~~

~~EDIT 2:~~ ~~Here's a screenshot of where it freezes:~~

IsleFreezeO2DS

~~And here's the "SDL_Log.txt" file: SDL_Log.txt~~

~~Also I tried setting the graphics lower but it still freezes~~

StevenSYS avatar Jun 29 '25 16:06 StevenSYS

We need a CI action for this. If we can add it to the continuous release too that would be even better.

foxtacles avatar Jun 29 '25 16:06 foxtacles

Will test on my N3DSXL when I am home.

Aeplet avatar Jun 29 '25 16:06 Aeplet

We need a CI action for this. If we can add it to the continuous release too that would be even better.

Please don't create a new workflow for 3ds, and integrate it along with emscripten and the desktop platforms:

  • Use the docker container provided by devkitpro: https://github.com/libsdl-org/SDL/blob/4217d62fa20195959489afec32ed2d9d8753c96e/.github/workflows/create-test-plan.py#L133 https://github.com/libsdl-org/SDL/blob/4217d62fa20195959489afec32ed2d9d8753c96e/.github/workflows/generic.yml#L16
  • and use this cmake toolchain file (to be added to the test matrix) https://github.com/libsdl-org/SDL/blob/4217d62fa20195959489afec32ed2d9d8753c96e/.github/workflows/create-test-plan.py#L691

madebr avatar Jun 29 '25 16:06 madebr

Please don't create a new workflow for 3ds, and integrate it along with emscripten and the desktop platforms:

Bundling all platforms into a single file makes it hard to maintain, you end up needing to understand several different environments just to adjust one.

Shared workflows are full of platform-specific conditions and cryptic logic like: if: ${{ always() && steps.tests.outcome == 'failure' && (matrix.platform.platform == 'msvc' || matrix.platform.platform == 'msys2') }} That kind of complexity would be unnecessary if platforms were split. It also makes it harder to:

  • Understand how to build a specific target (what could be 50 lines turns into 500+ lines of noise)
  • Avoid conflicts when editing
  • Identify maintainers or cleanly add/remove targets

I get the goal of reuse, but in practice this structure slows things down and increases friction. If de-duplication is the concern, it would be better to factor out common helpers that each workflow can import, rather than entangling everything in one place.

AJenbo avatar Jun 29 '25 16:06 AJenbo

@AJenbo maybe this is a result of the texture fix, I guess it arguably does increase performance since it's only rendering what's close to the player... I don't know if this is a full blocker or part of future rendering improvements you want to make (or whether I should lower my settings on O3DS) Screenshot 2025-06-29 at 1 12 31 PM

JPeisach avatar Jun 29 '25 17:06 JPeisach

I guess it arguably does increase performance since it's only rendering what's close to the player.

Just because you can't see it doesn't mean it didn't render a lot of transparent pixels.

Can you try setting C3D_TexSetFilterMipmap to GPU_NEAREST, and if that doesn't solve it then try removing C3D_TexGenerateMipmap

AJenbo avatar Jun 29 '25 17:06 AJenbo

Please don't create a new workflow for 3ds, and integrate it along with emscripten and the desktop platforms:

Bundling all platforms into a single file makes it hard to maintain, you end up needing to understand several different environments just to adjust one.

I agree and disagree.

There's also overhead in maintaining and keeping multiple workflows in sync. We push hard for all platforms to do as much as possible in cmake so all platforms support the cmake && make && make install workflow. The SDL approach is too complicated for this platform, agreed (the commit message can contain [sdl-ci*] commands that influence ci). But in my limited experience with adding n3ds ci to SDL, n3ds did not require special treatment.

madebr avatar Jun 29 '25 17:06 madebr

I guess it arguably does increase performance since it's only rendering what's close to the player.

Just because you can't see it doesn't mean it didn't render a lot of transparent pixels.

Can you try setting C3D_TexSetFilterMipmap to GPU_NEAREST, and if that doesn't solve it then try removing C3D_TexGenerateMipmap

Didn't work, applying the 2nd made the Brickster transparent 😄

JPeisach avatar Jun 29 '25 18:06 JPeisach

Didn't work, applying the 2nd made the Brickster transparent 😄

Arh you probably have to also set params.maxLevel = 0; when removing C3D_TexGenerateMipmap

On that note i have corrected it for the UI here: https://github.com/ItzSwirlz/isle-portable/pull/13

AJenbo avatar Jun 29 '25 18:06 AJenbo

@ItzSwirlz you can probably use this as a reference, you just have to weave it in to the existing CIs https://github.com/diasurgical/DevilutionX/blob/master/.github/workflows/3ds.yml

AJenbo avatar Jun 29 '25 19:06 AJenbo

Not now but later I'll tackle the CI.

I'm also probably going to make it so old 3ds models use low island quality, and new models use high island quality.

JPeisach avatar Jun 29 '25 20:06 JPeisach

Not now but later I'll tackle the CI.

I'm also probably going to make it so old 3ds models use low island quality, and new models use high island quality.

I can be your new 3DS tester in a few days for sure.

Aeplet avatar Jun 29 '25 20:06 Aeplet

Does the 3D effect work?

On Sun, Jun 29, 2025, 4:34 PM Aep @.***> wrote:

Aeplet left a comment (isledecomp/isle-portable#450) https://github.com/isledecomp/isle-portable/pull/450#issuecomment-3017080491

Not now but later I'll tackle the CI.

I'm also probably going to make it so old 3ds models use low island quality, and new models use high island quality.

I can be your new 3DS tester in a few days for sure.

— Reply to this email directly, view it on GitHub https://github.com/isledecomp/isle-portable/pull/450#issuecomment-3017080491, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFOLQTY4S2L3AKMLIVGOKZD3GBEUTAVCNFSM6AAAAACAMK43DKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTAMJXGA4DANBZGE . You are receiving this because you are subscribed to this thread.Message ID: @.***>

27hectormanuel avatar Jun 29 '25 20:06 27hectormanuel

Does the 3D effect work?

No, FPS isn't 40+ so I don't think it's viable to do so.

AJenbo avatar Jun 29 '25 20:06 AJenbo

One second, I think I can use the DKP wrapper; thats why emscripten broke

JPeisach avatar Jun 30 '25 14:06 JPeisach

Okay, so here's the thing: as far as I can tell, devkitpro does not really have a "wrapper" like emscripten does. It requires that the toolchain gets passed in, and this also helps it locate the compiler files.

I don't know if Emscripten has this, but I know other device toolchains have CMake files ready to use. Perhaps I'm missing something?

JPeisach avatar Jun 30 '25 14:06 JPeisach

right now it's packing up everything in the build folder, it should be just the .3dsx file

AJenbo avatar Jun 30 '25 15:06 AJenbo

right now it's packing up everything in the build folder, it should be just the .3dsx file

The .elf file is actually helpful for debugging - when Luma3DS crashes, it shows a PC address which can be used with addr2line to find the crash.

Also: Eventually, it will include the .cia

JPeisach avatar Jun 30 '25 15:06 JPeisach

But them when you need them, it's not something that should be shipped to everyone that wants to play the game.

AJenbo avatar Jun 30 '25 15:06 AJenbo

Makes sense. I'm just trying to think of the best way to go about the exclusion of these files: a regex? a list? Won't there be some platforms that actually will want a .elf?

JPeisach avatar Jun 30 '25 16:06 JPeisach

Makes sense. I'm just trying to think of the best way to go about the exclusion of these files: a regex? a list? Won't there be some platforms that actually will want a .elf?

Each target should specify what needs to be installed, you probably want to do something like this to leave out the intermediate files for 3DS:

if(NOT NINTENDO_3DS)
  install(TARGETS isle ${install_extra_targets}
    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  )
endif()

@madebr how can we avoid the .tar.gz wrapper? If we have a direct link to the binary 3DS users can install it directly using a QR code.

AJenbo avatar Jun 30 '25 18:06 AJenbo

@madebr how can we avoid the .tar.gz wrapper? If we have a direct link to the binary 3DS users can install it directly using a QR code.

I think instead of running cpack, copying the .3dsx to the dist folder.

madebr avatar Jun 30 '25 19:06 madebr

@madebr how can we avoid the .tar.gz wrapper? If we have a direct link to the binary 3DS users can install it directly using a QR code.

I think instead of running cpack, copying the .3dsx to the dist folder.

Would you like me to disable cpack and manually copy the file?

JPeisach avatar Jun 30 '25 21:06 JPeisach

Close, it's still in a zip file, but that's apparently also the the case for AppImage, but not flatpak so maybe that's a better reference for that.

AJenbo avatar Jun 30 '25 22:06 AJenbo

Close, it's still in a zip file, but that's apparently also the the case for AppImage, but not flatpak so maybe that's a better reference for that.

Zipped archives is the default (only?) behavior of actions/artifact The continuous release should have an unzipped 3dsx.

madebr avatar Jun 30 '25 23:06 madebr

Zipped archives is the default (only?) behavior of actions/artifact The continuous release should have an unzipped 3dsx.

Arh sounds good then.

AJenbo avatar Jul 01 '25 01:07 AJenbo

How the heck do the AppImage's in the tagged CI get uploaded by itself but not the 3dsx?

JPeisach avatar Jul 01 '25 01:07 JPeisach