Open Luciogi opened 1 month ago
I've disabled prompting for puzzle solutions in https://github.com/Bithack/principia/commit/1c506dded7ca56dd694365494633d4e671cc44ed on Android which fixes the crash but doesn't solve the underlying issue that some sort of mangling that happens when data is passed from the dialog prompt between C++ and Java. (This issue is exclusive to the Android version and doesn't occur with the GTK3 dialogs on desktop)
Some technical details:
When the dialog opens (src/src/menu_pkg.cc:483) it sends a pointer to some data (open_play_data) within a principia_action to accompany the button label.
open_play_data *opd = new open_play_data(LEVEL_LOCAL, level_id, &pkg, false, 1);
ui::confirm("Do you want to load your last saved solution?",
"Yes", principia_action(ACTION_OPEN_MAIN_PUZZLE_SOLUTION, opd),
"No", principia_action(ACTION_CREATE_MAIN_PUZZLE_SOLUTION, opd),
"Cancel", principia_action(ACTION_IGNORE, 0));
For Android ui::confirm is implemented in src/src/ui_android.hh at ~line 81 which passes a reference to the action data over the JNI from C++ to Java:
env->CallStaticVoidMethod(cls, mid,
_text,
_button1, (jint)action1.action_id, (jlong)action1.action_data,
_button2, (jint)action2.action_id, (jlong)action2.action_data,
_button3, (jint)action3.action_id, (jlong)action3.action_data,
(jboolean)_confirm_data.confirm_type == CONFIRM_TYPE_BACK_SANDBOX);
This in turn calls org.libsdl.app.SDLActivity.confirm
, which is a custom method added in there by Principia (gross, I know). What it effectively does is send the action of the pressed button back to C++-land which is either ACTION_OPEN_MAIN_PUZZLE_SOLUTION
or ACTION_CREATE_MAIN_PUZZLE_SOLUTION
. It should keep the same pointer to the action data which it casts to open_play_data and then retrieves fields from:
open_play_data *opd = static_cast<open_play_data*>(data);
uint8_t pkg_type = opd->id_type;
Then, segfault. The pointer is garbage and it fails when trying to get the package type.
Clue: The crash only occurs on 64-bit. I can reproduce the issue on my 64-bit ARM phone or on an x86_64 emulator. I cannot reproduce the issue on 32-bit ARM (namely my Nexus 7 tablet), which would make me believe it has something about pointer sizes differing that causes issues when sending it over the JNI in ui::confirm. This would also explain why it never caused issues in 2014 since the game did not have a 64-bit build back then. But I really do not know where the issue exactly lies. Maybe someone smarter than me could point to how to actually fix it.
Principia version
24.02.29
OS / Hardware
Summary
When I load any previous level, game crashes
Steps to reproduce
https://github.com/Bithack/principia/assets/84625092/4915f6da-073a-4f02-a373-098d5c3ea31d