1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
//! Nintendo DS system & game bootstrapping related functions.
use crate::ffi;
/// Probably related to booting the game?
///
/// This function prints the debug message "task proc boot".
///
/// # Safety
/// This function is related to game-boot and will probably modify a lot of global data.
pub unsafe fn task_proc_boot() {
ffi::TaskProcBoot();
}
/// Presumably blocks until the program receives an interrupt.
///
/// This just calls (in Ghidra terminology) coproc_moveto_Wait_for_interrupt(0).
/// See <https://en.wikipedia.org/wiki/ARM_architecture_family#Coprocessors>.
pub fn wait_for_interrupt() {
unsafe {
ffi::WaitForInterrupt();
}
}
/// Sets the Interrupt Master Enable (IME) register to 1, which enables all CPU interrupts
/// (if enabled in the Interrupt Enable (IE) register).
///
/// See <https://problemkaputt.de/gbatek.htm#dsiomaps>.
///
/// Returns the old value in the IME register.
///
/// # Safety
/// The caller needs to make sure the system is in a state where it is safe to enable interrupts.
pub unsafe fn enable_all_interrupts() -> bool {
ffi::EnableAllInterrupts() > 0
}
/// Sets the Interrupt Master Enable (IME) register to 0, which disables all CPU interrupts
/// (even if enabled in the Interrupt Enable (IE) register).
///
/// See <https://problemkaputt.de/gbatek.htm#dsiomaps>.
///
/// Returns the old value in the IME register.
///
/// # Safety
/// The caller needs to make sure the system is in a state where it is safe to disable interrupts.
pub unsafe fn disable_all_interrupts() -> bool {
ffi::DisableAllInterrupts() > 0
}
/// Get the current (system?) time as an IEEE 754 floating-point number.
///
/// Returns the current time (in seconds?).
pub fn get_time() -> f32 {
unsafe { ffi::GetTime() }
}
/// Probably resumes the sound player if paused?
///
/// # Safety
/// This function manipulates low-level global state.
pub unsafe fn sound_resume() -> bool {
ffi::SoundResume() > 0
}
/// Probably aborts the program with some status code? It seems to serve a similar purpose to the
/// exit(3) function.
///
/// This function prints the debug string "card pull out %d" with the status code.
///
/// # Safety
/// This function manipulates low-level global state.
pub unsafe fn card_pull_out_with_status(status: i32) {
ffi::CardPullOutWithStatus(status);
}
/// Sets some global flag that probably triggers system exit?
///
/// This function prints the debug string "card pull out".
///
/// # Safety
/// This function manipulates low-level global state.
pub unsafe fn card_pull_out() {
ffi::CardPullOut();
}
/// Sets some global flag that maybe indicates a save error?
///
/// This function prints the debug string "card backup error".
///
/// # Safety
/// This function manipulates low-level global state.
pub unsafe fn card_backup_error() {
ffi::CardBackupError();
}
/// Maybe halts the process display?
///
/// This function prints the debug string "halt process disp %d" with the status code.
///
/// # Safety
/// This function manipulates low-level global state.
pub unsafe fn halt_process_disp(status_code: i32) {
ffi::HaltProcessDisp(status_code);
}
/// Supposed to return a debug flag. Just returns 0 in the final binary.
pub fn get_debug_flag1(flag_id: u32) -> u32 {
// SAFETY: This is more or less an "atomic" operation.
unsafe { ffi::GetDebugFlag1(flag_id) }
}
/// Supposed to return a debug flag. Just returns 0 in the final binary.
pub fn get_debug_flag2(flag_id: u32) -> u32 {
// SAFETY: This is more or less an "atomic" operation.
unsafe { ffi::GetDebugFlag2(flag_id) }
}
/// Supposed to set a debug flag. No-op in the final binary.
pub fn set_debug_flag1(flag_id: u32, value: u32) {
// SAFETY: This is more or less an "atomic" operation.
unsafe { ffi::SetDebugFlag1(flag_id, value) }
}
/// Supposed to return a debug flag. No-op in the final binary.
pub fn set_debug_flag2(flag_id: u32, value: u32) {
// SAFETY: This is more or less an "atomic" operation.
unsafe { ffi::SetDebugFlag2(flag_id, value) }
}
/// Unpatched this function will always returns true.
///
/// # Background information
/// This function seems to be a debug switch that the developers may have used to disable the
/// random enemy spawn.
/// If it returned false, the call to `[GlobalDungeonData::spawn_monster]` inside
/// `[GlobalDungeonData::try_spawn_monster_and_tick_spawn_counter]` would not be executed.
///
/// [GlobalDungeonData::spawn_monster]: crate::api::dungeon_mode::dungeon_struct::GlobalDungeonData::spawn_monster
/// [GlobalDungeonData::try_spawn_monster_and_tick_spawn_counter]: crate::api::dungeon_mode::dungeon_struct::GlobalDungeonData::try_spawn_monster_and_tick_spawn_counter
pub fn is_debug_flag_monster_spawns_enabled() -> bool {
// SAFETY: This is more or less an "atomic" operation.
unsafe { ffi::MonsterSpawnsEnabled() > 0 }
}