VWF Dialogues Patch v1.01
(c) 2015 RPG Hacker

Screenshot Screenshot Screenshot

Video 1
Video 2


Index

1. Introduction
2. Getting Started
3. Main Functions (Basic)
4. Problem Solving (Advanced)
5. Known Bugs
6. Planned Features
7. Contact
8. History


1. Introduction

Welcome to the VWF Dialogues Patch! Since you got here by yourself you most likely already know what this patch does, but let me give you a general overview anyways.

The aim of this patch is to give a useful alternative to SMW's native text boxes. Unlike Romi's VWF Cutscene Tool (which is great, btw.) this patch is set up for easy event creation, easy customization and compatibility with all kinds of languages. The cost of this is a way harder usage. However, as long as you're somewhat familiar with custom sprites/custom blocks and Asar patches and read this Readme carefully you should be fine.

I've also included a custom block that utilizes this patch. I wanted to include more blocks and also a few custom sprites, but I figured that any custom block or custom sprite from SMW Central which displays a level message is compatible with this if you enable the Message Box Hijack (see section 2). I might add a few customized sprites and blocks in a future version. The one block I included gives a general idea on how to utilize this patch, though. Additionally I've included a few alternative fonts if you don't like the default one. The default font has the most characters, though. If you're using any language that is not English and has some special characters you might have to draw them yourself.

Be aware that this patch does some modifications to the ROM that might seem to be unrelated to the patch itself and aren't mentioned anywhere in this Readme. For example: It automatically expands the SRAM of your ROM to 128 KB since it needs over 32 KB of free RAM during dialogues.

Anyways, let's get started now with the first steps to setting up the patch now.

Return to Index



2. Getting Started

The very first thing you'll have to do is take the files vwfdialogues.asm, vwfmessagepointers.asm, vwfmessages1.asm, vwffont1.bin, vwffont1.asm, vwfpatterns.bin, vwfframes.bin and vwftable.txt and copy them over to your Asar folder. Next you open up "vwfdialogues.asm" in a text editor of your choice.

At the top you'll see the labels !varram, !backupram and !tileram. I suggest you don't touch those at all, especially if you aren't too familiar with ASM. Those addresses are the SRAM locations the patch uses. Of course you can also change them to RAM addresses, but you'll have trouble finding enough free RAM in SMW. It's very unlikely you'll have to change them anyways. I tried to use addresses at the very end of the game's SRAM in an attempt to prevent any possible conflict with another patch.

Scroll further down for a group of labels that define the default settings of your text boxes. "!defbg" is the graphic from the file "vwfpatterns.bin" to use as the default text box background. More details on the format of each bin-file later on. Everything you have to know for now is that this number is in hex and by default you can use any number from $00 to $0D.

Next on the list is "!bgcolor", the default color of the text box background in SNES RGB format. To find out what a color is in SNES RGB format simply open the palette editor in Lunar Magic and move the cursor over whatever color you're looking for. Lunar Magic will display the value of that color in various formats, including the SNES RGB format.

"!defframe" is the group of graphics from the file "vwfframes.bin" to use as the default text box frame. More on this later. By default $00 to $0F are valid.

The label "!framepalette" sets up which palette to use for the frame of the text box. This can not be changed ingame. Since we're using Layer 3 for our dialogues only the first two rows of the palette in Lunar Magic can be used for this. Each Layer 3 palette uses four colors. For example: $00 uses the first four colors, $01 the next four colors etc. Since the first two rows together have 32 colors this means you have the choice between 8 different palettes. In other words: $00 to $07 are valid inputs here. One thing is very important, though: During dialogue processing the colors in that palette get overwritten by new colors, so never use a palette that is used by the level background. I recommend using a palette which is only used by the status bar, since the status bar is invisible during dialogues. You don't have to worry here: My patch restores all 32 original colors of the first two rows of the palette after the dialogue is done, so any palette that is used only for the status bar is save to use here.

Next is the label "!bitmode". With this label you set up the bitmode of the patch. Put in a 0 for 8-Bit-Mode and a 1 for 16-Bit-Mode. In 16-Bit-Mode each letter in your dialogues takes up double the space, but the high byte is always treated as the font to use. In other words: $01FF would be "Font $01, Character $FF". I figured this might be useful for complex languages like Japanese or something. Then again as long as most of the used characters are inside the same font file it is recommended to continue using 8-Bit-Mode. For anyone not using a complex language it is anyways. More details on this will be given whereever 16-Bit-Mode has an effect.

The next and final label is "!hijackbox" and sets up whether you want to hijack SMW's original message boxes or not. Put a 0 here if you don't want to lose the original SMW message boxes. In this case this patch can still be used with custom sprites or custom blocks. Put a 1 here to hijack SMW's message boxes to automatically use this patch. In this case you can never use SMW's original message boxes again, though. Editing the message boxes in the Lunar Magic Overworld Editor also won't have any effect anymore since the messages will use the text from this patch instead. More details on editing the text in the next section. I highly recommend installing this hijack btw., because if you do you can use $7E1426 the same way as in original SMW. In other words: Setting it to $01 will display message 1 from the current level, setting it to $02 will display message 2 from the level and setting it to $03 will display the Yoshi thanks message. Also you can use ANY sprite from the custom sprites section and ANY block from the custom blocks section on SMW Central with a message displaying related function to display the dialogues from this patch instead. This can be really useful, considering I've barely included any custom sprites or blocks.

After you're done with setting up all the labels, save the file and patch it to your ROM with Asar. Make sure only to patch "vwfdialogues.asm" and nothing else. You should get a window that looks somewhat like this:

Screenshot

If that's what you see you've applied the patch successfully. I'll explain all of those lines in detail later on.

Return to Index



3. Main Functions (Basic)

In this section I will explain how to create and display dialogues, how to edit and add new graphics (including fonts) and how to use this patch's features for your own patches.

Graphics, Palettes and Fonts

The first and easiest thing you'll have to learn is how all the different graphic formats this patch uses work. Among them are the following ones:

For all of the graphics you'll need a tile editor that supports 2BPP GB graphics. Theoretically every tile editor will do. If you plan to edit (or create) fonts I really recommend you get YY-CHR v0.99, though. Nope, YY-CHR v0.98 won't do in this case. YY-CHR v0.99 has a very special and useful feature which YY-CHR v0.98 doesn't have and which is needed for editing fonts. I'll use YY-CHR v0.99 for all tile editor references in this Readme.




Background graphics

Let's start with background graphics, the easiest format. Open the file "vwfpatterns.bin" in your tile editor and set it to 2BPP GB. You should get a window similiar to this:

Screenshot

As I said this format is pretty easy. You only have to rules to follow:
1. One 8x8 tile = One BG pattern.
2. Only use the second color of the palette for BG patterns.
That's all there is to it. If you want to add more graphics simply put them into the empty space next to the last graphic. Make sure to expand the bin-file by at least 16 bytes before you do thit, though. You can use Translhextion for this. Otherwise your new graphic won't get saved.


Frame graphics and palettes

Next up are frame graphics. Open up "vwfframes.bin" in your tile editor and set it to 2BPP GB. You should see something like this:

Screenshot

Now frame graphics are a little bit more complicated in that way that each frame set consits of nine 8x8 tiles this time. Here is how they're used:

Screenshot

As you can see tiles 1 to 6 of each set form the actual frame. The tiles may be X and Y flipped to get the according parts of the text box. Tiles 7 and 8 are not used by the actual text box, but rather for the creation of the text box and only if you use the the creation style of Secret of Mana. More on this later. Tile 9 is the blinking cursor that is displayed when the game is waiting for the player to press the A button. It is X and Y flipped, so consider this when you're drawing this. Luckily X- and Y-flipping each is just one click in YY-CHR. Also for frames you can use all colors of the palette. Just like with background graphics you'll have the expand the bin-file before you can add more graphics, this time by at least 144 bytes.

Another thing you have to do for frames is setting up palettes for each frame set. Specifially you have to set up the second, third and fourth color of the frame palette declared in "vvwfdialogues.asm" in section 2 of this Readme. To find the table containing the palettes open up "vwfdialogues.asm", hit CTRL + F and search for "CUSTOMTABLES". You'll get to a section with two different tables of which one table, called "Palettes:", is the table we're looking for. It looks somewhat like this:

dw $0000,$FFFF,$0000
dw $0A56,$04ED,$0044
dw $45ED,$24E6,$0C41
dw $477D,$2E55,$214D
[...]


Each line here sets the palette for 9 tiles in "vwfframes.bin". You should start each line with a "dw", followed by a space and then the values of the three colors in SNES RGB prefixed with a "$" (hex values are always prefixed with a "$", keep that in mind) and seperated by commas. If you forgot about the SNES RGB format look in section 2 again. I explained how to find a SNES RGB value using Lunar Magic there.


Font graphics and width tables

Font graphics are the most complicated of all the graphic formats. First of all open up "vwffont1.bin" in YY-CHR and set it to 2BBP GB. Now you'll notice that the letters are all messed up and it's nearly impossible to edit them that way. Well, this is where YY-CHR v0.99 comes in handy. At the bottom it has a field labeled "Pattern:". Simply select "FC/NES x16" here and the letters will be in the correct format. This is what it looks like:

Screenshot

Each 16x16 tile is one character. Each font can have up to 256 characters. That's four pages in YY-CHR. Just like BG patterns, fonts have their special rules.
1. Only use the third and fourth color of the palette for fonts.
2. Make each letter touch the left border of it's 16x16 tile. This is important for the VWF system.
Everything else here is pretty simple. Just draw the hell out of yourself. I recommend using the third color for the letters and the fourth color for their shading (if using any that is).

Next thing is the width table. Open "vwffont1.asm". As you can see the width table file and the actual font file share the same file name. This is not required, but recommended. You'll see something like this now:

;Char00to0F:
db $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$06,$06
;Char10to1F:
db $07,$07,$05,$07,$08,$06,$09,$08,$07,$07,$07,$07,$06,$07,$07,$07
;Char20to2F:
db $0B,$07,$07,$07,$07,$07,$06,$07,$07,$06,$07,$07,$03,$06,$07,$03
[...]


This table contains the width of each character in the font file in pixel. This should be quite self explanatory. Just use YY-CHR to count the pixels. This may be pretty annoying, but so far this is the only way to do it.

To create a new font file simply copy "vwffont1.bin" and "vwffont1.asm", rename them accordingly and edit them. Then insert both files into your ROM using xkas and a new free space address at the beginning of a bank. I'll show you an "easy" way for doing this in section 4 of this Readme. Anyways, what you have to do next is opening "vwfdialogues.asm", pressing CTRL + F, jumping to the section "CUSTOMTABLES" and editing the table labeled "Fonttable:" in here. By default there is only one font in here and it looks like this:

Fonttable:
dl Font1,Font1_Width


Each line here is for one font. Start each line with a "dl", followed by a comma, then the address of the font graphics and the address of the width table, seperated by a comma. So let's say we were inserting a new font file and it's width table at $268000. A font file can take up to $4000 bytes in hex, so if we were using a complete font file here and inserting the width table right after it, that would be address $268000+$4000 for our width table. A valid table would look like this:

Fonttable:
dl Font1,Font1_Width
dl $268000,$268000+$4000


This may sound very complicated right now, but eventually you'll get used to it.


Actual Dialogues


Setting Up and Calling Dialogues

So now to actually use my patch and display some text on the screen. Remember this window from applying the patch to your ROM?

Screenshot

This is the first time it actually plays a role. Now if you're not familiar with ASM at all or don't plan on using this patch in your own patches, custom sprites or custom blocks then this won't be very interesting for you. For everyone else here is the general procedure of how to start a dialogue ingame using this patch:

  1. Write the number of the message to display to the Message register. This is a 2-Byte-Address and of course it's in Little Endian. So let's say you'd want to display message $002D. Using the example from the screenshot this would go somewhat like this:

    rep #$20
    lda.w #$002D
    sta.l $727E01
    sep #$20

  2. Write a $01 to the VWF State register. One thing is very important here: Before you do this you'll have to check if a dialogue is already being processed. Why? Well, if you don't this might lead to unexpected results, like Layer 3 glitiching up for example. If the VWF State register equals $00 then no dialogue is being processed. This leads to the following code:

    lda.l $727E00
    bne .SkipDialogue
    lda #$01
    sta.l $727E00
    .SkipDialogue

Whenever a dialogue is currently active, the Status Bar and the level's Layer 3 are hidden. They'll return at the end of the dialogue. I still recommend not using dialogues in Layer 3 levels. Alright. Let's move on. By now you're probably wondering what that number we have written to the Message register corresponds to. Well, open the file "vwfmessagepointers.asm" and find out. You'll see something like this:

dl Message0000,Message0001,Message0002,Message0003,Message0004
dl Message0005,Message0006,Message0007,Message0008,Message0009
dl Message000A,Message000B,Message000C,Message000D,Message000E
dl Message000F,Message0010,Message0011,Message0012,Message0013
[...]


This is the table that points to the text for each dialogue. By now you should know how tables work: A "dl" at the beginning, a space after that and a bunch of labels seperated by commas. In this case the table works like this: If the Message register is $0000, use the first address in this table. If the Message register is $0001, use the second address in this table. Etc.
As you can see I've always used the required value of the Message register as the name of the according label. This is not required, but it's recommended for orientation. Basically you can put any 24-Bit-Address here, even RAM addresses, which can be useful if you're using this in your own patches. Let's have a table with a few valid examples:

dl Message0000,$7F0000,Message0002,Message0003,$05A5D9
dl Message0005,Message0006,Randomname1,Message0008,Message0009
dl Message000A,Randomname2,$268000,Message000D,Message000E
dl Message000F,MessageABCD,Message0011,Message0012,Message0000
[...]


By default there are labels for 256 messages in this table. In theory you can use up to 65536 different messages with this patch, but since SNES ROMs are rather limited in file space it's unlikely you'll ever get to use that many, especially since my patch doesn't compress text in any way. It's not very likely that you'll ever get to have that many messages in your game, anyways. If 256 messages aren't enough for you, simply add more labels at the end of this file. It's as simple as that. By now you might be wondering "OK OK, but where the hell do I put the text now?". Let's head to the next point and clear this question.

Open "vwfmessages1.asm". As you can see labels for each label in the table are already in here. Most of them are ununsed and can be used by yourself. If you chose to replace SMW's original messages by this patch in section 2 then the comments at the end of each label also tell you which original message the according labels are replacing. "Message0009:" replaces SMW's original message 004-2 for example. To edit a dialogue simply put text under the according label. To add new ones simply paste them at the end of the file, but ABOVE "%textend()". This is important to prevent glitches. After we're done with this we can finally get to actually write messages. YAY!

Dialogue Headers

The first thing to do when setting up a dialogue is creating a header for it. This header is mandatory; not having it will cause glitches in the game. It allows you to easily set up position, width, height and other settings of the text box during that one specific dialogue. Let's say we wanted to edit Message0005. The first thing I always do is adding .header- and .body-sublables to each message. Sublables are a special kind of labels in xkas which can be reused inside the same patch, as long as they're not used under the same main label. The main label in this case would be "Message0005:". After adding sublabels we'd have:

Message0005: ; Message 002-2
.header
.body


Now we can put the dialogue header under the ".header"-sublabel and the actual text under the ".body"-sublabel for easier orientation. Let's get to the basic format of headers now.

Message0005: ; Message 002-2
.header
db $aa
db %bbbbbccc,%ccddddee,%eeffffgg,%gghhhhhh,$ii,%jjjj----
dw $kkkk,$llll
db %mnnnop-q
db %rrssttuu,$vv,$ww,$xx,$yy

.body


Simply copy and paste this header for the start. All numbers prefixed with a "%" require binary digits, while numbers prefixed with a "$" require digits in hex. Simply se the Windows calculator in scientific mode for this.

aa
This is the font to use for the dialogue. By default only one font will be inserted in the game and you'll have to put in "00" here. Also here we have the first difference between 8-Bit- and 16-Bit-Mode: In 16-Bit-Mode you MUST skip this line. Otherwise you'll get glitches. Why? Well in 16-Bit-Mode the high byte of each character is used as the font number, so I figured this byte in the header would be redundant. On a second thought I realise that this just causes additional confusion for just one single byte you save per message, but I did it like this anyways, so keep it in mind if you're ever going to use 16-Bit-Mode.

bbbbb
The text box X position. As I mentioned: In binary, since this is prefixed with a "%". The maximum here is 11100, but don't worry if you enter an invalid value here. For certain values in the header - like the text box position and size - I programmed in validation checks to prevent nasty effects. Depending on the text box size the maximum for this value might change. If you were using the full width of the screen for the text box the maximum here would be 00000 for example. Limitations like this apply for a few other settings as well.

ccccc
Same as bbbbb, but for the Y position. Maximum here is 11000.

dddd
The width of the text box. This only counts the inside of the box, not the frame. It also counts 16x16 tiles, not 8x8 tiles. So 0010 would mean "2 16x16 tiles + frame" for example. The maximum input here is 1111.

eeee
Same as dddd, except for the height. The maximum input here is 1101.

ffff
How many pixels of space to leave at the left and right edge of the text box. I usually use 4 pixels (=0100) here.

gggg
The pixel width of a space. I recommend to use at least 8 pixels (=1000) here. The reason for this has to do with the "change palette" command in dialogues. I'll go more into detail there.

hhhhhh
The text speed. This is interpreted as "frames to wait between letters". I usually use 000000 here (for the fastest text speed).

ii
Auto wait options. In other words:"What to do if using a Line Break while at the bottom of the text box".
00: Instantly clear the text box and continue.
01: Wait for the player to press the A button.
02-FF: Wait that many frames.

jjjj
Text box creation options.
0000: Don't use a text box.
0001: Secret of Evermore style. Expand box from top to bottom.
0010: Secret of Mana style. Expand box from the middle.
0011: Mega Man Zero style. Expand box from left to right.
0100: Instantly show complete box.

kkkk
Third color of the palette set up with ppp in SNES RGB. Usually the color of your letters.

llll
Same as kkkk, but for the fourth color. Usually the color of the shading of your letters.

m
Whether to freeze sprites or not.
0: Don't freeze sprites.
1: Freeze sprites.
I recommend 1. 0 can lead to glitches in the current version if - for example - you die while a dialogue is being processed. Also it is pretty slow. If you really want to use it I recommend using Lunar Magic 1.8X or later and using the FastROM patch and addressing. This actually makes the result quite decent.

nnn
The palette to use for the inside of the text box. Read: The text box background and the letters. This has the same restrictions as "!framepalette" from section 2. Never use the same palette for the frame and for the letters. Both palettes will be changed during dialogue processing, so doing that would most likely cause weird color changes.

o
The text layout.
0: Regular layout.
1: Centered layout.

p
Speedup options.
0: Don't allow speedup.
1: Allow speedup.
Speedup only applies if a dialogue uses a text speed which is slower than 000000. In that case, if you put a 1 here, the player can speedup dialogues by holding the A button.

q
Disable all text box sound effects.
0: Don't disable.
1: Disable.
Warning: If you put a 1 here, then it's mandatory to skip the next line (that means everything from rr to yy) completely, otherwise this will cause glitches.

rr
The bank to use for the letter sound effect.
00: $1DF9
01: $1DFA
10: $1DFB (Not recommended to use)
11: $1DFC

ss
Same as rr, but for the "waiting for A button" sound effect.

tt
Same as rr, but for the cursor sound effect.

uu
Same as rr, but for the "pressed A" sound effect.

vv
The actual sound effect to use for letters.

ww
Same as vv, but for the "waiting for A button" sound effect.

xx
Same as vv, but for the cursor sound effect.

yy
Same as vv, but for the "pressed A" sound effect.

WHEW! After being done with the header you'll now finally get to really, really, really write some text for your dialogues.


Dialogue Texts

So if you're using the same labels as I suggested in this Readme then what you're going to edit now is the part under the ".body"-sublabel, which is the actual dialogue.

Regular Text
The first thing you'll obviously want to do is using regular text. Here we have a difference between 8-Bit- and 16-Bit-Mode. In 8-Bit-Mode, regular text goes like this:

db $03,$AF,$34,$CD,$A3,$5B
[...]


So basically you just write the hex value of whatever character from the font file you want to display in a table. In 16-Bit-Mode it works like this:

dw $0003,$00AF,$0034,$01CD,$00A3,$025B
[...]


The main difference here of course is that you need two bytes per character and the high byte is interpreted as the font file to use. So in this case it would be something like this:
Font $00 - Charcter $03
Font $00 - Charcter $AF
Font $00 - Charcter $34
Font $01 - Charcter $CD
[...]
Always putting in everything as hex characters would become really annoying after a while. Therefore there is an easier way of doing it. It goes like this:

db "Hi there! Put some text here!"

So basically you just put the text you want to display in quotations. What xkas does then is looking up the characters in the file "vwftable.txt" and converting them into the according hex numbers when assembling the file. This makes writing texts a lot easier. Be careful, though. It seems like many characters are incompatible with xkas. I've especially noticed this with some special characters, like the German "ü" for example. Sometimes - if you're very unlucky - they mess up the dialogues completely, but usually they just turn out as hex number $00. If that ever happens to you something you can do is this:

db "Text 1 ",$34,"Text 2"

This should be self explanatory. So here are a few valid examples:

db "Hello there!"
db "Pi ",$35," 3.141..." ; The $35 here could be an equal sign or something
db $03,$40,$AF,"More text!"
db $AB,$54,$DF
[...]


Make sure never to forget the commas in your tables and the quotations around text inputs. So that's it for regular text. As much as you can do with regular text, this alone won't be enough to create proper dialogues. You'll need a bunch of special characters to cause certain events during a dialogue. Some of them are mandatory to use in each dialogue, others are optional. To use these special commands simply put their hex codes into the text where they should be activated. In 16-Bit-Mode you need to use $FF as a high byte for each special character (like "$FFFA" for example). Here is a list of each and every special character available.

$FF - End Dialogue
This character ends a dialogue and is mandatory to put at the end of EVERY dialogue. Not using it means the dialogue will continue forever and eventually start to display random text. After the patch reads an $FF the dialogue will end and the text box will vanishing, using the style defined in the dialogue header.

$FE - Space
This puts a space into your text (using as many pixels as defined in the dialogue header. It does something else, to. It activates the Word Wrap function. At first it calculates the length of the next word, then, if that word doesn't fit into the current line anymore, it automatically causes a Line Break. Also, if you look at the bottom of "vwftable.txt", you can see that a space inside quotations is automatically converted to an $FE. I recommend not to change this.

$FD - Force Line Break
This - as the name suggests - forces a Line Break. Don't forget: If using a Line Break while already at the bottom line of the text box, the patch will do whatever you've defined in the Auto wait options in the dialogue header.

$FC - Set Message Number
This clears the text box, loads message $XXXX, loads the header from the new message and then displays the new message. Usage:

db $FC
dw $XXXX


This is the command you have to use if you want to change the position and size of the text box during a dialogue (as seen in the beginning of Video 2).

$FB - Modify Text Pointer
This makes the patch read text from another address. Usage is like this:

db $FB
dl Address


Here is an example:

db "Hey you!",$FD,$FB
dl .part2

db "Bla bla bla..."

.part2
db "What are you doing there?"


This will display the text "Hey you!", then cause a Line Break ($FD) and then display the text "What are you doing there?". As you can see, the part in the middle is skipped completely. You could also use this to create infinite loops:

db "Bla "

.loop
db "bla ",$FB
dl .loop


This will display infinite "bla"s.

$FA - Wait for A Button
This is a command which you'll use a lot in your messages. It makes the game wait for the player to press the A button. Usually you'll at least put it in front of the $FF at the end of each dialogue, otherwise the text box would just be closed and the player wouldn't even get to read everything in time. Of course, if you need to, you can also put it inbetween text. Here is an example:

db "I like you a lot... ",$FA
db "NOOOT!",$FA,$FF


Also, whenver the game reads this character, it starts displaying that blinking cursor at the bottom of the text box until the player presses the A button.

$F9 - Wait for $XX frames
This makes the patch wait for $XX frames. Usage is like this:

db $F9,$XX

$F8 - Change Text Speed
This changes the text speed to $XX. Usage is like this:

db $F8,$XX

I went more into detail on this in the explanation of dialogue headers.

$F7 - Display Decimal Number
The first somewhat complex function. It takes the content of a RAM address, converts it to a decimal number and then displays it. Usage is like this:

db $F7
dl Address
db $BZ


"Address" of course means the RAM address. Refer to the SMW Central RAM Map for this. B is how many Bits the number has (0 means 8-Bit and 1 means 16-Bit) and Z defines whether to display prefixed zeros or not (0 for yes, 1 for no; yeah, I switched the order here :P ). Here is an example:

db $F7
dl $7E0DBF
db $01


$7E0DBF contains the current player's coins. Since this is an 8-Bit-value, B = 0. We want to wipe any prefixed zeros, so Z = 1. Also, in order for this function to work, the digits 0 to 9 have to be the first characters in your font file and in the correct order. Look into "vwffont1.bin" to see what I mean.

$F6 - Display Hexadecimal Number
Takes the content of a RAM address and displays it as a hex number. Usage is like this:

db $F6
dl Address


This one is a lot simpler then the decimal one, which is mainly for the reason that the SNES uses hex addressing and values natively. In order for this function to work, the digits 0 to F have to be the first characters in your font file and in the correct order. Look into "vwffont1.bin" to see what I mean.

$F5 - Display RAM Character
Takes the content of a RAM address as the next character to display. Usage is like this:

db $F5
dl Address


The difference to $F6 is that $F6 displays the actual hex value, while $F5 displays the character of the value. So if we were using $7E0DBF once again and the player had $19 coins, $F6 would display "19", while $F5 would display character $19 from the font file in use. In "vwffont1.bin" this would be a "P". Here are screenshots of $F5, $F6 and $F7 all being used in the same text box.

Screenshot Screenshot

The timer uses $F5, the hexadecimal numbers use $F6 and the decimal numbers use $F7.

$F4 - Display Character
This displays character $XX. Usage is like this:

; 8-Bit-Mode
db $F4,$XX

; 16-Bit-Mode
dw $FFF4,$XXXX


You may wonder what the point of this function is. Well, let's say you had a font file with 256 characters and you wanted to display character $FF. How would you do that? If you used "db $FF", the game would treat this as special character $FF and end the dialogue. Using "db $F4,$FF", however, it would display character $FF instead. So basically this function is for displaying characters that would otherwise be treated as special characters.
$F3 - Change Text Palette
This changes the palette currently in use for text to XXX (Maximum: 111 = 7). Usage is like this:

db $F3,%-----XXX

What is this useful for? It allows you to use multiple colors for your text inside the same text box. Be careful as this overwrites the second color of whatever palette you're going to use with the background color of the text box. Therefore, this has the same restrictions as the letter palette from the dialogue header. This function is also the reason why you should always use at least $08 pixel for spaces. How so? Well, natively Layer 3 on the SNES only supports 8x8 tiles. To have VWF text new graphics are created in RAM that have multiple letters on one 8x8 tile. Palettes, however, are connected with 8x8 tiles, not with letters. Therefore, if two or more letters end up on one tile and you're using this command, all these letters will change their color, even if you only planned to change the color of one of them. If there are at least $08 pixels of space between letters they will never end up on the same tile, though. This also means that you ALWAYS have to use a space before using this command. NEVER change the text palette in the middle of a word.

$F2 - Change Font
Changes the number of the Font in use to $XX. In short, the same stuff as the first option in the header. Also in 16-Bit-Mode this command is redundant as it does nothing. Usage:

db $F2,$XX

$F1 - Execute Code
Executes ASM code at whatever address you use. It does that by JSLing to it, so the code should end on an RTL. This is one of the most useful commands in the patch, but only for people experienced with ASM. Usage is like this:

db $F1
dl Address


So what makes this function so special? Well aside from the fact that (with some ASM knowledge) you can basically do everything during dialogues this - just like character $FB - also lets you modify the text pointer. In combination with the ASM code this makes conditional text jumps possible. In other words: It allows you to display different text if certain conditions are met. This is demonstrated in video 2 by the Toad who sells star power. If you answer his question with "Yes", he only sells the star power to you if you have enough coins. Some code that does just that can be seen here:

.body
db "Here you go!",$F1
dl .checkcoins

db " Thank you very much!",$FA,$FF

.notenough
db " Wait, you don't even have enough coins!",$FA,$FF

.checkcoins
!number = #$28
!address = $0DBF
!destination = .notenough

lda !address
cmp !number
bcc .changepointer
sec
sbc !number
sta !address
rtl

.changepointer
lda.b #!destination ; Destination address low byte
sta !vwftextsource ; Text pointer low byte
lda.b #!destination>>8 ; Destination address middle byte
sta !vwftextsource+1 ; Text pointer middle byte
lda.b #!destination>>16 ; Destination address high byte
sta !vwftextsource+2 ; Text pointer high byte
rtl


What this will do is first display the text "Here you go!". Then it will execute the code at ".checkcoins". Here it will compare the address $0DBF (the current player's coins) with $28 (=40). If it is bigger or equal, it will simply return without changing the text pointer and display " Thank you very much!". Otherwise it will change the text pointer to ".notenough" and display " Wait, you don't even have enough coins!". Also as you can see here you modify the text pointer by writing to "!vwftextsource", with "!vwftextsource" being the low byte and "!vwftextsource+2" being the high byte. You can also see that I simply put the code under the text. This is OK and recommended as long as the code is in a place where it can not be reached by the VWF system. In other words: Under an $FF should be fine, in the middle of a message should be avoided. Another thing I recommend is always putting a space or line break after this command (in this case it's the space in front of "Thank you". The reason for this is that this command is ignored by the word wrap function. This function gets the correct width by counting the width of all characters between a space and some other special character (like a Line Break or another space). So in this case: If you don't put a space (or whatever other character is suitable) after this command, the word wrap function will count the "Thank" as part of the same word, even if eventually that word won't even be written at all. This might lead to automatic line breaks at the wrong places. In short: Always put a space after this command.

$F0 - Display Options
This is - without any doubt - the most complex of all special commands. This function gives the player various options in the text box, which he can then select with a cursor. After that the text pointer is changed to another address depending on the option the player selected. Usage is like this:

db $F0,$ns
db $cc ; If in 8-Bit-Mode
dw $cccc ; If in 16-Bit-Mode
dl .option_1
[...]
[dl .option_n]

db "Option 1 Text",$FD

[...]

[db "Option n Text",$FD]

.option_1
db "You selected option 1!",$FA,$FF

[...]

[.option_n]
[db "You selected option n!",$FA,FF]


Yup, I told you this function was complex. So let's go through everything step by step. n is the number of options to give the player. 1 is the minimum and the text box height the maximum number of options you can have. If you put more options here than fit into a complete text box of the current height the game will simply ignore them. If there is some text in the text box already and because of that not all options would fit into it at the same time, the text box will be cleared. Oh, did I already mention that this command automatically causes a Line Break if not already at the beginning of a line? Anyways, next is s, which is the space to leave between cursor and the following letter. I usually put a 4 here. The next thing, cc (or cccc in 16-Bit-Mode) is the character from the font to use as the cursor. The default font has a very decent cursor as character $A8, so I recommend using this. Next are dl tables according to the value you used for n. To give a few examples: If n = 3, put 3 dl tables here. If n = 5, put 5 dl tables here. Don't mess this up; doing so here can easily cause glitches. These dl tables contain the addresses to set the text pointer to for each of the options. So if the player selects the first option, the first dl table will be used. If the player selects the third option, the third dl table will be used. Because of this the number of dl tables always has to match n. Next up are the lines for the actual text of each option. What is important here is that whenever a Line Break occures - whether it's a forced or an automatic Line Break - the next new line will automatically be treated as the next option. This will continue until until as many Line Breaks as there are options have occured. After that the player will be able to move the cursor. This also means: Always make sure that all the text for one option fits in one line and always have as many Line Breaks as you have options. So if your n is 2, have 2 Line Breaks. If your n is 5, have 5 Line Breaks. It's very important to follow this rule. And don't - by all means - put any obscure character in the middle of option text. $FF, for example, counts as an obscure character here. As using this character inside option text would most likely cause unexpected effects I've made it so that $FF is treated as $FD during option processing. Still it's not recommended to use it. The best thing is to simply stick to $FD here and not use any other special character. So yeah, that's basically it. All you have to do now is set up some text for each address in the dl tables and you're done. After the player has selected an option, the text box will automatically be cleared. I know this is very, very complicated but I didn't see any other way to implement this feature and if you just play around with it a bit you'll get used to it faster than you think. Anyways, here is an example of some valid code:

db "Do you want to buy a 1-UP?"
db $F0,$24,$A8
dl .yes
dl .no
db "Yes",$FD
db "No",$FD

.yes
db "Thank you very much!",$FA,$FF

.no
db "Too bad. Come again later!",$FA,$FF


See? It only LOOKS complicated, but it's actually rather simple.

$EF - Setup Teleport
This sets up a teleport which will occure as soon as dialogue processing is over. Usage is like this:

db $EF
dw $-lll
db %----w-s-


lll is the level to teleport to or the secondary exit number to use. This can be anything from 000 to 1FF. Set w to 1 if the destination level is a water level, otherwise set it to 0. Set s to 1 if lll should be used as a secondary exit number, otherwise set it t0 0 to use lll as the destination level number. An example:

db $EF
dw $010D
db %00000000

$EE - Edit Color
This command sets color $XX to SNES RGB $YYYY and is to be used together with $F3. Usage is like this:

db $XX
dw $YYYY


I recommend only to use $00 to $1F for $XX, as these are the only colors that are restored at the end of the dialogue. Also once again avoid using colors that are used by the background or anything else that is visible during dialogue processing. Here is an example of it being used:

db $EE,$1A ; Palette $06, Third Color
dw $031F ; Dark Yellow
db $EE,$1B ; Palette $06, Fourth Color
dw $0000 ; Black
db $F3,%00000110
db "Mario:",$FD
db $F3,%00000111
db "Hi there!",$FA,$FF

$ED - Clear Text Box
Well what is there to say about this one? It's pretty obvious. This command clears the text box. Not more, not less. Well that's not true, it obviously also resets the text position to the top of the text box. That's all it does now, really.

$EC - Play BGM
This changes the background music to $XX. Usage is like this:

db $EC,$XX

Of course it has the usual music restrictions, like "only using custom music from the same bank" if using carol's or Romi's Addmusic and stuff like that. That's all there is to say about this command.

And with that another section of this ridiculously long Readme is done and you're finally able to write your own dialogues. WOO HOO!


Custom Patches

Everything left now is to explain how to use the functions of this patch in your own patches. For this we need the screenshot from xkas once again.

Screenshot

VWF Creation Routine
This routine creates VWF text graphics in RAM when JSLed to. You use SMW's Scratch RAM to set it up.
$00-$02: Text source address.
$03-$05: Font graphics address (2BPP GB format).
$06-$08: Font width table address.
$09-$0B: Destination address.
$0C-$0D: Number of characters.
$0E: Pixel to start on.
$0F: Set to $01 if the destination address doesn't contain VWF text graphics yet.
Note that the special characters explained before are not actually used by this routine.

Pattern Addition Routine
This routine adds a background pattern to VWF text previously created in RAM when JSLed to. This assumes that the text only uses the third and fourth colors of the palette and that the background pattern graphic only uses the second color. Otherwise the result may not turn out as expected. You use SMW's Scratch RAM to set it up.
$00-$02: Pattern graphic source address (2BPP GB format)
$03-$05: VWF text graphics address = destination address (2BPP GB format).
$06: Number of tiles

BG GFX register
Which graphic to use for the background pattern of the text box.

BG Color register
Which color to use for the background of the text box in SNES RGB. This is a 2-Byte-Address.

Frame GFX register
Which set of graphics to use for the text box frame.

Return to Index



4. Problem Solving (Advanced)

In this section I'll go over a few problems that may or may not be more complicated than most of the other stuff here so far.


Dialogues Without Freezing Sprites

So you're planning to use a dialogue in your game without freezing sprites? Dialogues like that can be found in various RPGs as system messages. First of all there are certain things you have to note when using this option:

Well, if you plan to use this feature anyways you may notice that it can be pretty slow in certain situations, so here are a few tips to help you speed it up:


Bank Limits

If you make your message list long enough (around 200 messages), it is possible that you'll get an error like this:

Screenshot

As Asar says, this is caused by crossing a bank border. What a bank is is out of scope for this document, but the solution is easy: Just add %nextbank() before the last message in the file, and the errors should go away (until you add two hundred more messages). If they don't, move the %nextbank()s around until the problems disappear.

Also one important thing to add: There is no way to split the pointer table to multiple banks. file "vwfmessagepointers.asm" into multiple files. At first I wanted to add bank border checking for this one file only, but then I figured that even without bank border checking you can still get up to $2AAA (that's 10922) pointers in a single bank. And let's be serious: Who is EVER going to put that many messages in a single SNES game? Noone. Therefore this one limitation should be a limitation you can bear.


Conflicts With HDMA Effects

This patch makes use of DMA transfers. DMA transfers share their channels with HDMA. This means they will influence any HDMA effects that use the same channels. The DMA transfers in this patch all use channel 4 (%00010000). If you experience problems with an HDMA effect while displaying a dialogue box, just make sure not to use channel 4 for that effect. Read an HDMA tutorial for further information on this subject.


Duplicate Cursors

Using the option function and getting duplicate cursors? This can happen when VBlank time is exceeded. Usually this is caused by many patches hijacking VBLank routines for loading up graphics or something similiar. This can easily be fixed by applying Lunar Magic's FastROM patch and FastROM addressing.

Return to Index



5. Known Bugs

Return to Index



6. Planned Features

Return to Index



7. Contact

Bugs or suggestions? Contact me!

E-Mail: markus_wall@web.de
MSN: rpg_hacker@hotmail.de
ICQ: 354382300
Yahoo: rpghacker
AOL: RPGHacker91
Skype: rpghacker
YouTube: RPGHacker86

Return to Index



8. History

Version 1.0 - 11/13/2010

Version 1.0B - 01/16/2012 by Alcaro

Version 1.01 - 07/06/2014 by Vitor Vilela

Return to Index