Skip to content

Upgrade troubleshooting

Giovanni Bajo edited this page Jan 24, 2023 · 15 revisions

This guide lists a few common hurdles when upgrading an application to the latest version of libdragon stable (trunk).

Stable vs unstable

This guide refers to the stable version of libdragon (branch trunk). We strive as much as possible (within the limits of a hobby project) not to break backward compatibility. This means that all existing libdragon applications that were developed against libdragon stable should be able to upgrade libdragon version and "just recompile and run".

The unstable version of libdragon (branch opengl) is, as the name implies, unstable. The API is subject to change without notice breaking compatibility. If you develop against the unstable version, you must be aware that an application might be impossible to recompile without changes in a few months or years, and you as the author might not be interested in that application anymore. If possible, develop against the stable branch to leave a stable legacy for future N64 enthusiasts.

Common problems you may encounter after upgrading

Invalid API usage causing assertion screens

In general, we strive to make libdragon stricter and stricter in correct usage of its APIs. One of the many hurdles in N64 development is that it is very easy to misprogram the hardware in a way that does not work, so it is important that libdragon guides you avoiding that. One of the main tool that we use to help programmers is through assertions, that lead to crashes showing an assertion screen (on both the screen, and the debug log).

After upgrading libdragon, it might be that a working application crashes with an assertion screen. This means that the application is actually technically buggy: maybe the bug does not reproduce on emulators, or only reproduce on a few consoles, or might lead to other problems later, but in any case it was deemed to be buggy enough to block it. The assertion screen should point you to the problem and sometimes even suggest the best solution to it.

Deprecation errors during compilations

Sometimes we evolve libdragon APIs and mark older APIs as deprecated through a GCC attribute. We do not remove the old APIs as that would break backward compatibility, and we do not change their behavior: they are expected to still work as before, but we want to advise the developer to upgrade to a newer API whenever possible.

These deprecated APIs are expected to cause deprecation warnings during compilations, without breaking the build. If the application is not using the standard n64.mk and is forcing -Werror, those warnings will instead become errors, blocking the build.

To fix this, you have several alternatives: you can add -Wno-error=deprecated-declarations to the command line, so that the deprecated notices become warnings again; you can take the chance to start using n64.mk, which would have handled this for you; or you can bite the bullet and fix the deprecation warning by changing your code (even though it is not technically required, it might be a good idea anyway).

Compilation error related to rdp_draw_textured_rectangle or MIRROR_ macros

In 2019, a change to rdp.c was merged that added the mirroring functionality to existing APIs, adding one more argument to the several function calls. This broke a lot of existing libdragon applications. It was the fallout of this change that made us appreciate the important of implementing a stable API policy.

Unfortunately, there is no way around this: you need to add MIRROR_DISABLED as last argument to the affected function calls.

Controllers not working

This is often caused by the fact that you are using the controller subsystem (eg: controller_scan(), get_keys_down()) but you forgot to call controller_init(). In older libdragon versions, controller_init() was basically empty, so even if was technically necessary to call it as explained in the documentation, failures to do so would not be apparent. In more recent libdragon versions, you must absolutely call controller_init() fo the controller subsystem to work correctly.

Later libdragon versions will show an assertion screen in this case, but if you are upgrading to some intermediate libdragon version, you might not get it.

Linker errors related to FatFS

At some point, libdragon imported a vendored copy of fatfs for its own SD card support. This broke all applications that already linked against FatFs themselves, causing duplicated symbols.

There is currently no workaround for this. There is a work-in-progress PR to fix this, that contains a tentative patch that might be useful.

Compilation error regarding resolution_t

If you get an error like this:

game.c:254:22: error: incompatible types when initializing type 'int' using type 'resolution_t'
  254 |     int resolution = RESOLUTION_320x240;
      |                      ^~~~~~~~~~~~~~~~~~

the fix is to change the declaration from int to resolution_t.

The problem was born when we added arbitrary resolution support. In that commit, we changed resolution_t from being a enum to a struct. This does not break backward compatibility in general if the user correctly declared resolution_t whenever necessary; if instead the user code relied on the implicit conversion of an enum to int, the code will not compile anymore.

Clone this wiki locally