Page 1 of 2
Help wanted with 8×8 VWF algorithm
Posted: Sun Jun 28, 2015 11:13 am
by Ramsis
So I've been trying and trying to implement a VWF for the dialogue in Furry RPG, but without success so far.
Note that I spent the last two weeks studying
VWF source examples on RHDN (including
this one) -- most of which are a pain to even read, or simply incomplete. Also, I stumbled across
Stealth Translation's doc, and couldn't help but notice that it too is
more than incomplete. Also, I looked at both tepples' Action menu and bisqwit's Chronotools 8×8 VWF engine, both of which only managed to confuse me even more.
Please note that the bit-shifting apparently works correctly -- the left half of the "2" appears shifted to the right just fine (albeit on the wrong tile), whereas the right half appears unnecessarily shifted, and shows up as garbage in an unwanted place.
Here's the code I came up with after studying all those other documents. Code executes during Vblank, variables starting with DP_ are direct page, vars starting with ARRAY_ are in the range of $0200-$1FFF (minus stack pointer) in WRAM:
Code: Select all
ProcessVWFTiles:
A16
lda DP_TextASCIIChar ; ASCII char no. --> font tile no.
asl a ; value * 16 as 1 font tile = 16 bytes
asl a
asl a
asl a
tax
A8
lda DP_VWFBitsRemaining
and #$07
sta DP_VWFBitsRemaining
bne __UseOldVWFTile
A16
lda DP_VWFTileNew ; new tile no. --> VWF buffer index
bra +
__UseOldVWFTile:
A16
lda DP_VWFTileOld ; old tile no. --> VWF buffer index
+ asl a
asl a
asl a
asl a
tay
A8
lda #16 ; loop through 16 bytes per tile
sta DP_VWFLoop
- lda.l GFX_FontMode5, x
xba ; move to high byte
lda #$00
jsr __VWFShiftBits ; shift tile data if necessary
ora ARRAY_VWFTileBuffer1+1, y
sta ARRAY_VWFTileBuffer1+1, y
xba
ora ARRAY_VWFTileBuffer1, y
sta ARRAY_VWFTileBuffer1, y
iny
inx
dec DP_VWFLoop
bne -
ldx DP_TextASCIIChar ; ASCII char no. --> font width table index
lda DP_VWFBitsRemaining ; adjust pixels remaining for shifting
bne +
inc DP_VWFTileOld
inc DP_VWFTileNew
inc DP_VWFTileNew
lda #8 ; 8 = max. no. of bits
+ sec
sbc.l SRC_FWTDialogue, x
bpl +
eor #$FF ; handle overflow
inc a
sta DP_VWFBitsRemaining
inc DP_VWFTileOld
inc DP_VWFTileNew
inc DP_VWFTileNew
lda #8
sec
sbc DP_VWFBitsRemaining
+ sta DP_VWFBitsRemaining
rts
__VWFShiftBits:
phx
A16
pha
lda DP_VWFBitsRemaining
bne +
pla
bra __VWFShiftBitsDone
+ dec a
asl a
tax
pla
jmp (__VWFShiftAmount, x)
__VWFShiftAmount:
.DW _R1, _R2, _R3, _R4, _R5, _R6, _R7
_R1:
lsr a
_R2:
lsr a
_R3:
lsr a
_R4:
lsr a
_R5:
lsr a
_R6:
lsr a
_R7:
lsr a
__VWFShiftBitsDone:
A8
plx
rts
Download:
http://manuloewe.de/snestuff/projects/f ... d_00224.7z
Any substantial help is very much appreciated. Thanks!
Ramsis
Re: Help wanted with 8×8 VWF algorithm
Posted: Sun Jun 28, 2015 11:46 am
by Sik
I'm getting the impression the problem is calculating which byte to write into (note how the right half of the digits is shifted down by 1 pixel as well).
Also consider testing with letters, numbers are probably the one thing you want to keep fixed width (yes, this means extra spacing around the 1).
Re: Help wanted with 8×8 VWF algorithm
Posted: Sun Jun 28, 2015 11:57 am
by lidnariq
<tangent> Bring back text figures! (It turns out that monospaced numerals are a modern invention, to accommodate computers not needing to know the difference between tabular data and mid-text data)
Re: Help wanted with 8×8 VWF algorithm
Posted: Sun Jun 28, 2015 12:27 pm
by Sik
It's more to do with the fact that if you have variable-width digits then use that font in a counter, the width of the number will go all over the place as the number changes - especially annoying when the value is changing constantly like with timers and such.
Re: Help wanted with 8×8 VWF algorithm
Posted: Sun Jun 28, 2015 12:59 pm
by tepples
What's the
first thing that confuses you about the VWF engine in the Action 53 menu? I'm willing to document everything more thoroughly.
Agreed about digit width, which is why the font shipped with my own VWF engine leaves an extra pixel of space on the sides of the glyph for '1'.

- See the extra pixel of space on left and right sides of '1' glyph
- vwf7_digits.png (462 Bytes) Viewed 5843 times
In any case, text figures (digit glyphs with descenders) and a narrow advance width for '1' are orthogonal, meaning each can be used without the other. Here are some fixed-width text figures that I designed for another project.

- See descenders on '3', '4', '5', '7', and '9' and ascenders only on '6' and '8'
- text_figures.png (636 Bytes) Viewed 5845 times
Re: Help wanted with 8×8 VWF algorithm
Posted: Sun Jun 28, 2015 3:36 pm
by Myask
That ascent/descent is very subtle, tepples.
Sik wrote:It's more to do with the fact that if you have variable-width digits then use that font in a counter, the width of the number will go all over the place as the number changes - especially annoying when the value is changing constantly like with timers and such.
This is alleviated somewhat when the number is justified to the most-significant digit rather than the least...but still a problem. (And if you do that, then you get a confusing change when a digit is added, if you weren't using leading zeros.)
Re: Help wanted with 8×8 VWF algorithm
Posted: Mon Jun 29, 2015 5:30 am
by Ramsis
Sik wrote:I'm getting the impression the problem is calculating which byte to write into (note how the right half of the digits is shifted down by 1 pixel as well).
Thanks. Indeed, I'm not quite sure if I'm getting the correct Y index value at all. And since I don't really know what to take into account for that, I can only hope someone will point me in the right direction.
Sik wrote:Also consider testing with letters, numbers are probably the one thing you want to keep fixed width (yes, this means extra spacing around the 1).
The dialogue, where numbers barely ever appear anyway, will be an all-VWF. The menu, on the other hand, will employ fixed-width fonts for numbers etc., and possibly a VWF for descriptions and such.
tepples wrote:What's the first thing that confuses you about the VWF engine in the Action 53 menu?
Nothing in particular, really. I've just been a bit frustrated about all that time spent on staring at other peoples' code examples without ever fully grasping the essence of how and why those work.

Re: Help wanted with 8×8 VWF algorithm
Posted: Mon Jun 29, 2015 5:57 am
by tepples
Ramsis wrote:tepples wrote:What's the first thing that confuses you about the VWF engine in the Action 53 menu?
Nothing in particular, really. I've just been a bit frustrated about all that time spent on staring at other peoples' code examples without ever fully grasping the essence of how and why those work.

Do you use IRC or AIM or Skype or Hangouts? I'm willing to explain how it works in real time text chat.
Re: Help wanted with 8×8 VWF algorithm
Posted: Mon Jun 29, 2015 11:16 am
by Ramsis
Today's progress:
I rewrote/simplified the routine quite significantly, which now looks like this:
Code: Select all
ProcessVWFTiles:
A16
lda DP_TextASCIIChar ; ASCII char no. --> font tile no.
asl a ; value * 16 as 1 font tile = 16 bytes
asl a
asl a
asl a
tax
A8
ldy DP_VWFBufferIndex
lda #16 ; loop through 16 bytes per tile
sta DP_VWFLoop
- lda.l GFX_FontMode5, x
xba ; move to high byte
lda #$00
jsr __VWFShiftBits ; shift tile data if necessary
A16
xba
ora ARRAY_VWFTileBuffer1, y
sta ARRAY_VWFTileBuffer1, y
A8
iny
inx
dec DP_VWFLoop
bne -
ldx DP_TextASCIIChar ; ASCII char no. --> font width table index
lda.l SRC_FWTDialogue, x
clc
adc DP_VWFBitsUsed
cmp #8
bcs +
sta DP_VWFBitsUsed
A16
tya
sec
sbc #16
sta DP_VWFBufferIndex
A8
bra ++
+ sec
sbc #8
sta DP_VWFBitsUsed
sty DP_VWFBufferIndex
++
rts
__VWFShiftBits:
phx
phy
A16
pha
lda DP_VWFBitsUsed
bne +
pla
bra __VWFShiftBitsDone
+ tay
pla
- lsr a
dey
bne -
__VWFShiftBitsDone:
A8
ply
plx
rts
Still, when characters have a width of other than 8 or 4 pixels, it freaks out (this should read "bc", both of which are 7-pixel-wide characters):
Anyone spot the error in my code? Please?
tepples wrote:Do you use IRC or AIM or Skype or Hangouts? I'm willing to explain how it works in real time text chat.
Thanks, I might actually come back to you some time.

Re: Help wanted with 8×8 VWF algorithm
Posted: Mon Jun 29, 2015 4:20 pm
by Near
When you are building your proportional text string in RAM, you need to store the other half of the tiledata that shifts off of your original tile.
Let's say you are drawing 'bc', and each is six pixels long.
The first one is easy, it fits cleanly onto one tile. But the second one splits two pixels of 'c' onto the first tile, and four onto the next tile.
The way to do this is to use a 16-bit accumulator and xba.
Keep a bit-position for where you are at on the screen. This value lsr #3 (divided by 8) is the tile# you are on, and this value and #7 (low three bits) is the bit position on said tile.
In our case with 'bc', you've drawn 'b', so now you're on tile# 0, bit position #6.
Load up a horizontal line of 'c', and #$ff, and now use xba on it.
Thus we go from:
jjjjjjjj cccccc00 (j = junk, c = c, 0 = padding)
and #$ff
00000000 cccccc00
xba
cccccc00 00000000
Now remember our tile/bit position and #7 is 6. So we right shift A six times (lsr #6)
lsr #6
000000cc cccc0000
Or the way I like to do it:
pha; lda bitpos; and #7; tax; pla ;get the bitpos into X
-; beq +; lsr; dex; bra -; + ;shift right and decrement X until zero
(you can get this faster with a jmp (table,x) into a block of lsr's, but this is for demonstration.)
We first need to OR the upper 8-bits with the existing tile# 0 in RAM, and then store the remaining four bits of 'c' into the next tile. This usually goes something like this:
xba
sep #$20
ora tiledata,x
sta tiledata,x
xba
sta tiledata+16,x ;16 for 2bpp tiles
inx #2 ;one horizontal line
<repeat for all lines>
(the above can be optimized by doing it in the reverse order, this is for demonstration though.)
Now when you're done, add the length of 'c' (6) to your tile/bit-pos. It was 6 from 'b', now we add 6 from 'c' and it's 12. Or tile#1, bit-position #4. And repeat for the rest of the string.
When you're done building your string, the total # of tiles you need has to be incremented by one if bitpos&7 != 0. Say you only drew 'bc', since we're at 12, we have -two- tiles we need to transfer data for, and two tilemap entries need to be valid for that.
Simple method:
lda bitpos
clc; adc #7
lsr #3
Have fun ;)
Re: Help wanted with 8×8 VWF algorithm
Posted: Tue Jun 30, 2015 10:06 am
by Ramsis
1000 kudos to you, byuu. ^^ That
16 for 2bpp tiles clue of yours helped me make my algorithm work almost instantly.
Of course, it still took a lot more changes to my text engine, as well as an all-new buffer management/VRAM transfer routine, in order to get the desired result.
Which currently looks like this:
To do:
- move the buffer-building routine to the active display period (this should avoid gfx glitches)
- rework carriage returns / maybe even implement automatic line-wrapping?!
- track down and fix all buffer-related bugs (of which there are many
)
Download:
http://manuloewe.de/snestuff/projects/f ... d_00226.7z
(Please be warned -- this build is buggy!)
Re: Help wanted with 8×8 VWF algorithm
Posted: Tue Jun 30, 2015 10:57 am
by Sik
Now nitpicking on the font: how does it look on TV? (or at least with a NTSC filter) Because I have the feeling that font must be awful to read since it's so thin.
Re: Help wanted with 8×8 VWF algorithm
Posted: Tue Jun 30, 2015 12:16 pm
by Ramsis
Sik wrote:Now nitpicking on the font: how does it look on TV? (or at least with a NTSC filter) Because I have the feeling that font must be awful to read since it's so thin.
Rest assured that FURRY RPG will be designed with modern 40"+ TV sets in mind -- though not with all-anamorph tiles for 16:9, despite this actually being a short-listed (i.e., early on discarded) design question.

Re: Help wanted with 8×8 VWF algorithm
Posted: Tue Jun 30, 2015 1:13 pm
by Sik
I was talking about the SDTV ones =S (i.e. the ones the SNES was originally intended for... maybe over composite instead of RF though)
Re: Help wanted with 8×8 VWF algorithm
Posted: Tue Jun 30, 2015 2:34 pm
by tepples
Plenty of SDTVs take an S-Video signal. I may take a photo of S-Video displayed on an SDTV tonight.