Because the message content are terminated.
[s[n]]printf
There are a few major differences to note between the standard printf
functions and EZTR's implementations:
\xBF
TerminationMessage strings do not use the \0
null character to terminate, as is done in standard ASCII. Instead, strings are terminated with \xBF
, and \0
is used as the control code to set the text color back to normal. As a result of this, EZTR cannot assume your string arguments will be \0
terminated either. It is expected that any message data argument of a EZTR_MsgSContent_*
function will manually terminated with \xBF
by the programmer.
See The Message Buffer for more information on message control codes and massage termination.
Because of the non-standard encoding that Majora's Mask uses for control characters, EZTR offers an optional special syntax for handling these in the form of "Pipe-escaped bytes". When used, single bytes can be written in your string using the syntax |XX
, where each X
is a hexidecimal character. Note that this only does a single byte at a time, so the correct way to write 2 bytes would be |XX|XX
and not |XXXX
(unlike the \x
escape sequence used by C, where \xXXXX
would be a valid expression of two bytes). This is a useful feature if you need to load message data from an external, ASCII or Unicode-based source.
Pipe-escaped bytes are used in 3 places:
format
argument of any of the normal EZTR_MsgSContent_*Printf
functions (the ones with NoPipe
in the name are alternate versions without this behavior).EZTR_MsgSContent_*Printf
(including the NoPipe
versions) using the m
or q
type specifiers.content
argument of EZTR_Basic_ReplaceText
, EZTR_Basic_AddCustomText
, and EZTR_Basic_ReplaceCustomText
, provided the pipe_escaped_bytes
argument is set to true.Note that this feature is entirely optional. EZTR is fully capable of processing control code bytes directly (such as using C escape sequences in string literals).
%m
and %M
Type SpecifiersBecause the s
string specifier in C expects the argument to be \0
terminated, the specifier cannot be easily used to pass in control codes and formatting data. To solve this, EZTR_MsgSContent_*Printf
have two unique specifiers: %m
and %M
. These specifiers function identically to s
except they assume that the corresponding argument is Majora's Mask message data and thus \xBF
terminated.
That is to say, when using %m
and %M
to pass in message data, terminate your argument with \xBF
. This argument termination will not be copied into the output string (much like how *printf
doesn't copy in the \0
null terminator from s
arguments).
The only difference between %m
and %M
is that %m
processes pipe-escaped bytes, whereas %M
does not.
%q
Type Specifiers%q
is a \0
null terminated string, like %s
, except that it also processes pipe-escaped bytes. This allows you to pass in message content strings using the pipe-escaped byte syntax, but without needing to manually add \xBF
or |BF
at the end of the argument, making this type specifier useful for copying message data from external applications or sources. Note that this specifier stops writing to the buffer ONLY when the \0
byte is encountered, and not as a pipe-escaped byte. Therefore, if |BF
or |00
is encountered, it will be converted into corresponding byte, but writing will continue anyway.
%w
Type Specifiers%w
is a two-byte version of the %c
flag. Although Majora's Mask doesn't make use of wide characters in displaying text, several control codes will use the following two bytes as an argument that affects their behavior. The %w
specifier makes it easy to set the argument value via a printf argument.
The control codes that use this behavior are:
EZTR_CC_BOX_BREAK_DELAYED
(hex value 0x1B
)EZTR_CC_FADE
(hex value 0x1C
)EZTR_CC_FADE_SKIPPABLE
(hex value 0x1D
)EZTR_CC_SFX
(hex value 0x1E
)EZTR_CC_DELAY
(hex value 0x1F
)Control code EZTR_CC_SHIFT
(hex value 0x14
) uses a single following byte as its argument, and thus the value for that can be specified with %c
.
When printing to the console using EZTR_MsgSContent_Printf
, EZTR_MsgSContent_PrintfLine
, or the NoPipe
variants thereof, all control codes are displayed according to EZTR's text_dumping_byte_format
and text_dumping_cc_macros
options. This does not apply to any other printf functions, which preserves the control bytes.
A format specifier follows this prototype: %[flags][width][.precision][length]type
The following format specifiers are supported:
Type | Output |
---|---|
d or i | Signed decimal integer |
u | Unsigned decimal integer |
b | Unsigned binary |
o | Unsigned octal |
x | Unsigned hexadecimal integer (lowercase) |
X | Unsigned hexadecimal integer (uppercase) |
f or F | Decimal floating point |
e or E | Scientific-notation (exponential) floating point |
g or G | Scientific or decimal floating point |
c | Single character |
s | ASCII string of characters. To offer parity with standard C, it is assumed that this string is null-terminated. |
q | ASCII string of characters. Like s , it is assumed that this string is null-terminated, but pipe-escaped bytes will still be evaluated. |
m | Message content string using pipe-escaped bytes. |
M | Message content string NOT using pipe-escaped bytes. |
w | Unsigned 16-bit value to be inserted into the byte string raw. Useful for pass argument bytes following EZTR_CC_SFX , EZTR_CC_DELAY , etc. |
p | Pointer address |
% | A % followed by another % character will write a single % |
Specifiers %m
, %M
, %q
, and %w
are unique to EZTR.
Flags | Description |
---|---|
- | Left-justify within the given field width; Right justification is the default. |
+ | Forces to precede the result with a plus or minus sign (+ or -) even for positive numbers. By default, only negative numbers are preceded with a - sign. |
(space) | If no sign is going to be written, a blank space is inserted before the value. |
# | Used with o, b, x or X specifiers the value is preceded with 0, 0b, 0x or 0X respectively for values different than zero.Used with f, F it forces the written output to contain a decimal point even if no more digits follow. By default, if no digits follow, no decimal point is written. |
0 | Left-pads the number with zeros (0) instead of spaces when padding is specified (see width sub-specifier). |
Width | Description |
---|---|
(number) | Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger. |
* | The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted. |
Precision | Description |
---|---|
.number | For integer specifiers (d, i, o, u, x, X): precision specifies the minimum number of digits to be written. If the value to be written is shorter than this number, the result is padded with leading zeros. The value is not truncated even if the result is longer. A precision of 0 means that no character is written for the value 0.For f and F specifiers: this is the number of digits to be printed after the decimal point. By default, this is 6, maximum is 9.For s: this is the maximum number of characters to be printed. By default all characters are printed until the ending null character is encountered.If the period is specified without an explicit value for precision, 0 is assumed. |
.* | The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted. |
The length sub-specifier modifies the length of the data type.
Length | d i | u o x X |
---|---|---|
(none) | int | unsigned int |
hh | char | unsigned char |
h | short int | unsigned short int |
l | long int | unsigned long int |
ll | long long int | unsigned long long int (if PRINTF_SUPPORT_LONG_LONG is defined) |
j | intmax_t | uintmax_t |
z | size_t | size_t |
t | ptrdiff_t | ptrdiff_t (if PRINTF_SUPPORT_PTRDIFF_T is defined) |
Upon successful return, all functions return the number of characters written, excluding the terminating null character used to end the string. Functions snprintf()
and vsnprintf()
don't write more than count
bytes, including the terminating null byte ('\xBF'). Anyway, if the output was truncated due to this limit, the return value is the number of characters that could have been written. Notice that a value equal or larger than count
indicates a truncation. Only when the returned value is non-negative and less than count
, the string has been completely written. If any error is encountered, -1
is returned.
If buffer
is set to NULL
(nullptr
) nothing is written and just the formatted length is returned.
Special thanks to mpaland on GitHub for creating this embedded printf library, as EZTR's printf logic is a modified version of this project. The documentation on this page is partially copied from there as well.