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
//! Lets you interact with the mGBA debug output buffer.
//!
//! This buffer works as a "standard output" sort of interface:
//! * First `use core::fmt::Write;` so that the [`Write`](core::fmt::Write)
//! trait is in scope.
//! * Try to make a logger with `MgbaBufferedLogger::try_new(log_level)`.
//! * Use the `write!` macro to write data into the logger.
//! * The logger will automatically flush itself (using the log level you set)
//! when the buffer is full, on a newline, and when it's dropped.
//!
//! Logging is not always available. Obviously the mGBA output buffer can't be
//! used if the game isn't running within the mGBA emulator.
//! [`MgbaBufferedLogger::try_new`] will fail to make a logger when logging
//! isn't available. You can also call [`mgba_logging_available`] directly to
//! check if mGBA logging is possible.
//!
//! ```no_run
//! # use gba::prelude::*;
//! use core::fmt::Write;
//! let log_level = MgbaMessageLevel::Debug;
//! if let Ok(logger) = MgbaBufferedLogger::try_new(log_level) {
//! writeln!(logger, "hello").ok();
//! }
//! ```
//!
//! ## Fine Details
//! Even when the program is running within mGBA, the [`MGBA_LOG_ENABLE`]
//! address needs to be written with the [`MGBA_LOGGING_ENABLE_REQUEST`] value
//! to allow logging. This is automatically done for you by the assembly
//! runtime. If the `MGBA_LOG_ENABLE` address reads back
//! [`MGBA_LOGGING_ENABLE_RESPONSE`] then mGBA logging is possible. If you're
//! running outside of mGBA then the `MGBA_LOG_ENABLE` address maps to nothing.
//! Writes will do no harm, and reads won't read the correct value.
//!
//! Once you know that logging is possible, write your message to
//! [`MGBA_LOG_BUFFER`]. This works similar to a C-style string: the first 0
//! byte in the buffer will be considered the end of the message.
//!
//! When the message is ready to go out, write a message level to
//! [`MGBA_LOG_SEND`]. This makes the message available within the emulator's
//! logs at that message level and also implicitly zeroes the message buffer so
//! that it's ready for the next message.
use crate;
pub const MGBA_LOGGING_ENABLE_REQUEST: u16 = 0xC0DE;
pub const MGBA_LOGGING_ENABLE_RESPONSE: u16 = 0x1DEA;
/// Returns if mGBA logging is possible.