-
Notifications
You must be signed in to change notification settings - Fork 3
Creating your own control characters
Note that there can only be up to 128 control characters in total, including gb-vwf's built-in ones. But since there are far fewer than 128 built-in control characters, gb-vwf lets you add your own!
-
Declare the control character in the config file, using the
control_char
macro.Its first argument is the name of the control character's constant/charmap entry; the second argument is the address of the function that evaluates the control character; and any further arguments declare any bytes that the control character may take as arguments.
Those extra arguments follow
.tbl
syntax, and are crucial for the auto-linewrapper to function correctly—the auto-linewrapper uses the number of arguments to this macro to properly process control characters.(If you're not planning to use
.tbl
files, it's okay to put dummy values there, but the arguments have to be present.)Note that if the control character breaks lines, an extra argument should be prepended, consisting of a single
!
character. -
Write the control character's handler!
It is simply a function that gets the input stream pointer in
de
, and is expected to return a pointer to the following character inde
.In essence, the function can simply read a byte from
[de]
and incrementde
whenever it requires an argument.All other registers are fair game to overwrite.
- It follows from the description above that the auto-linewrapper does not support control characters with a variable number of arguments.
- The auto-linewrapper does not call custom control character handlers. (This also simplifies writing a handler, since it's only called in a single way.)
- The auto-linewrapper assumes that no control character prints anything.
(If any of those are a dealbreaker to you, feel free to modify gb-vwf accordingly, and/or to contact me; popular enough characters can end up getting built into gb-vwf itself.)
Let's create a control character that prints a 16-bit number stored in RAM. (This could be useful to print how much money the player has, for example.)
-
Declare the control character in the config file:
control_char PRINT_NUM, PrintNumber, low=%X,high=%X
-
The implementation of the control character itself, placed in any other file:
PrintNumber:: ; Read the pointer to the number. ld a, [de] :: inc de :: ld l, a ld a, [de] :: inc de :: ld h, a ; Read the actual number. ld a, [hli] :: ld b, [hl] :: ld c, a ; Save the pointer to return to to a new stack entry. ld hl, wSourceStack.len ld a, [hl] ; Not decrementing means that we'll point at the entry's second byte. inc [hl] add a, a ; Each entry is 2 bytes. add a, l :: ld l, a :: adc a, h :: sub l :: ld h, a ld a, e :: ld [hld], a :: ld [hl], d ; Write the number in decimal to a buffer. ; (How that's done is not very important). ld de, .charBuf :: call WriteDecimalChars ld a, VWF_END :: ld [de], a ; Continue reading characters from that buffer. ld de, .charBuf ret .charBuf ds 6 ; "65535<END>"
(Note that
PrintNumber
must be exported, here via::
, so that it's visible withinvwf.asm
.)