derrekr / srb2_3ds

Port of Sonic Roboblast 2 to the Nintendo New3DS
49 stars 6 forks source link

Can't compile the source code #17

Closed wallefan closed 11 months ago

wallefan commented 11 months ago

Apparently the toolchain has evolved a bit since this application was last compiled, and it won't work now.

First the compiler complained about a duplicate definition of the __dmb function in nds_utils.h, since this function has apparently been upstreamed into libctru (in 3ds/synchronization.h). After verifying the two definitions were identical, I commented out the one in this codebase, and the source built, but failed to link -- the linker complained about duplicate definitions (the same symbol from the same .h file appearing in multiple .o's). After telling it that that was okay (by editing the Makefile and adding -z muldefs to LDFLAGS), the application successfully built, and I deployed it to my 3DS. It played the opening cutscene just fine, and made it as far as the title screen, but did not detect any of the savefiles I had created using the binary release of srb2_3ds.3dsx I downloaded from the GitHub page, and crashed when trying to load a level (in demo or in game) because something somewhere called svcBreak().

I'm going through it with a debugger now. Will update with my findings.

wallefan commented 11 months ago

The panic is coming from libctru, specifically here (libctru/source/gpu/gxqueue.c:64):

    if (queue->numEntries == queue->maxEntries)
        svcBreak(USERBREAK_PANIC); // Shouldn't happen.

So the graphics pipeline is becoming overrun. Looks like I've got some diving to do.

derrekr commented 11 months ago

Sorry for my late reply (damn time zones...)! Indeed, the source wasn't updated in a long time and currently doesn't build properly with the latest toolchain version. I have been meaning to update it and make a new release (I have some local changes that I haven't pushed yet), but there are some issues that prevent this.

The builds of srb2_3ds that I released so far actually use a private, modified version of citro3d. This fork includes a feature which allows for a better performance (more FPS). It works with two GPU command buffers instead of one, which allows srb2_3ds to submit GPU commands for the next frame while the GPU is processing the previous command buffer. Unfortunately, this fork is not compatible with the rest of the toolchain anymore. You would have to find and old version of the toolchain to make it work again, but that's not recommended. The proper way to solve this situation would be adding this feature to the latest citro3d. However, the author prefers no further major changes, since the 3DS hombrew graphics stack is quite fragile... (I have talked with him about that ~4 months ago).

The panic/assert you encountered, I've encountered several times before myself, actually. The gxqeue's size is not configurable and citro3d sets it to a constant value during init ( https://github.com/devkitPro/citro3d/blob/master/source/base.c#L91 ). In my private citro3d fork, i've just increased this limit. However, there might be another way to work around that: iirc, it happens because C3D_FrameBufClear is called repeadetly by the renderer ( https://github.com/derrekr/srb2_3ds/blob/master/source/nds/r_nds3d.c#L759 ) when srb2 switches to another level. C3D_FrameBufClear submits a GX command on each invocation, so the queue can fill up quickly and eventually triggers the svcBreak.

...Maybe this explains the current situation a bit. Currently, I can build srb2_3ds locally (with some small changes), but it is lacking the performance the builds with the modified citro3d had. I will ask the citro3d author again for assistance regarding the feature.

wallefan commented 11 months ago

Oh. Well if that's the only problem, just publish your fork of Citro3D on your GitHub and have done with it. If you want someone to help you maintain that fork, I'm between open source projects at the moment and I'll gladly help out.

By the way -- absolutely no worries about the late reply! I've never had a developer respond to a GitHub issue within a week before, let alone 24 hours.

wallefan commented 11 months ago

On a whim, I decided to set a gdb breakpoint at the line you mentioned where the max queue length is hardcoded to 32, and changed it to 128 before continuing the program (since it references that value on the next line when deciding how much memory to allocate, I didn't need to change anything else). It got farther this time -- the top screen showed "Loading... 98%" before hitting a segfault in Z_FreeTags (z_zone.c:411). A cursory glance shows it's trying to free every element of a circular queue that for some reason is not circular.

I am far too tired to debug that at the moment, or to think about how something like that would happen when I compiled it, but not when you did. I'll check what exactly happened and get back to you tomorrow. I would quite like to see/discuss the changes you've made to Citro3D apart from increasing that limit.

wallefan commented 11 months ago

I eventually got tired of setting that breakpoint every time and decided to do it right. While waiting for your reply, I created my own fork of Citro3D that added a second parameter to C3D_Init() for the max queue len, and had the game pass 128. I had intended to do this only to make the game easier to debug, but for whatever reason, that completely solved the issue. The game runs just fine now.

derrekr commented 11 months ago

Oh. Well if that's the only problem, just publish your fork of Citro3D on your GitHub and have done with it.

Yeah, I can do that - keep in mind it won't work with the current libraries. Also, it is extremely messy (both, the changes I made and citro3d itself back then...). I'd rather prefer starting from scratch by forking the current citro3d and see how the feature could be implemented again but a lot cleaner (that's what I'm trying to do atm).

If you want someone to help you maintain that fork, I'm between open source projects at the moment and I'll gladly help out.

Referring to the srb2 fork? Yes, that would be nice!

Not sure if I ever had problems with srb's zone allocator.... maybe it's some thing i fixed locally(?) Do you want me to push my local changes so you can build it with the recent libctru/citro3d?

BTW: Are you on discord? Maybe we can chat there instead of using this github issue... you can msg me ("derrek6").

wallefan commented 11 months ago

BTW: Are you on discord? Maybe we can chat there instead of using this github issue... you can msg me ("derrek6").

Yes I am! My username is wallefan#8167 and I just sent you a friend request.

derrekr commented 11 months ago

msg'd you

derrekr commented 11 months ago

Updated the building instructions in the README.