+  RHDN Forum Archive
|-+  Romhacking
| |-+  General Romhacking
| | |-+  2BPP VWF @#$*!
Pages: [1]
Author Topic: 2BPP VWF @#$*!  (Read 1 times)
RedComet
Guest
« on: November 26, 2007, 08:36:48 pm »

I've spent the last few days working on the VWF for Spider-man: Lethal Foes, right? Well, the font I'm using (Comix Zone) is 2BPP and the letters aren't shadowed in such a way that makes it easy (or practical) to add them to a 1BPP font on the fly. So, I'm left with the task of VWFing a 2BPP. This is a first for me. Ordinarily I do all of the VWF-ing on a 1BPP font and then convert it to XBPP and add shadows (if need be) on the fly.

Before I go any further, here's some data and code:

Code:
1st letter loaded into ram:

00 FF 22 C3 52 8D 30 D7 8C 77 44 33 88 07 00 FF
00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF

2nd letter shifted:

00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 01 FE 00 FF
00 FF 02 C3 50 8D 22 99 8C 0B 40 3F 00 7F 00 FF

How it should be:

00 FF 22 C3 52 8D 30 D7 8C 77 44 33 89 06 00 FF
00 FF 02 C3 50 8D 22 99 8C 0B 40 3F 00 7F 00 FF

The 1st letter is combined with the shifted 2nd letter to create the final product. Now for the code that is responsible for doing this:

Code:
combine_buffers:
ldx #$0000
sep #$20

combine_loop:
;if(!vwf_buffer,x or !draw_buffer,x == #$ff)
;take the value of whichever != #$ff and
;store that in the draw_buffer

lda !vwf_buffer,x ;if(!vwf_buffer,x == #$ff)
cmp #$ff ;keep what's already in the draw_buffer
beq inc_and_loop ;i.e. do nothing

lda !draw_buffer,x ;if(!vwf_buffer,x && !draw_buffer,x != #$ff)
cmp #$ff ;combine the two to get the correct value
bne combine_pixels

lda !vwf_buffer,x ;if(!vwf_buffer,x != #$ff && !draw_buffer,x == #$ff)
bra store_pixels ;store value of !vwf_buffer

combine_pixels:
ora !vwf_buffer,x

store_pixels:
sta !draw_buffer,x

inc_and_loop:
inx                                               
cpx #$0020
bne combine_loop

rts

That works perfectly except for one little bitty problem. Here's the output of this routine using the 1st and 2nd letters (which I'll reprint, along with what it's supposed to be, for convenience) mentioned above:

Code:
1st letter loaded into ram:

00 FF 22 C3 52 8D 30 D7 8C 77 44 33 88 07 00 FF
00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF

2nd letter shifted:

00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 01 FE 00 FF
00 FF 02 C3 50 8D 22 99 8C 0B 40 3F 00 7F 00 FF

How it should be:

00 FF 22 C3 52 8D 30 D7 8C 77 44 33 89 [b]06[/b] 00 FF
00 FF 02 C3 50 8D 22 99 8C 0B 40 3F 00 7F 00 FF

How it currently is (ORing):
00 FF 22 C3 52 8D 30 D7 8C 77 44 33 89 [b]FF[/b] 00 FF
00 FF 02 C3 50 8D 22 99 8C 0B 40 3F 00 7F 00 FF

I've made the problem byte bold. As you can see, it should be $06, but as we all know $07 OR $FE equals $FF. If I change the ora under combine_pixels to an and, that byte is fixed, but everything else is messed up. At the moment, I'm fresh out of things to try. So, anybody got any ideas?

EDIT:
After the first character is loaded into ram (top two tiles are !vwf_buffer, bottom two are !draw_buffer):


After the second character is loaded into ram:
« Last Edit: November 27, 2007, 12:28:17 pm by RedComet »
tomaitheous
Guest
« Reply #1 on: November 26, 2007, 10:36:30 pm »

Hey Red,


 You're working 4bit packed pixel mode. Shifting aside, you need to test the pixel (nibble) to see if you should OR it or not.

  source ($07): 0  7 <- two pixels, if neither nibble is 0, then no OR - else OR nibble that is  0
  operand ($FF) : F  F <- two pixels

 07 ;source
 FF ;operand
----
 F7 ;destination


 Atleast... that looks correct.
 
byuu
Guest
« Reply #2 on: November 27, 2007, 03:11:20 am »

I always use 2bpp fonts for my VWFs for one reason ... you can store the shadow data directly in the font itself, rather than adding it dynamically. It saves a lot of hassle, especially when you run into shadows falling off onto the next tile, or a down-right shadow falling down and right one full tile each. Very messy.
Nightcrawler
Guest
« Reply #3 on: November 27, 2007, 10:17:48 am »

Quote from: byuu on November 27, 2007, 03:11:20 am
I always use 2bpp fonts for my VWFs for one reason ... you can store the shadow data directly in the font itself, rather than adding it dynamically. It saves a lot of hassle, especially when you run into shadows falling off onto the next tile, or a down-right shadow falling down and right one full tile each. Very messy.

This was trivial back in Dual Orb 2 with on the fly VWF shadowing there. If memory serves me correctly, I probably just had the width of each letter one pixel longer to account for the shadow(my shadow was one pixel wide on that font). It didn't matter then if it crossed tile boundaries. I added shadow with probably 4 or 5 lines of extra code. It's treated the same as if it were stored in the ROM that way. I have no special preference for doing it either way. I usually pick based on how the original font is stored. If it's 1bpp, I'll do dynamic, if it's already 2, just add shadow to the font in the ROM.


Red:

How is your font stored? I'm assuming:

Byte 1 = first row first bitplane
Byte 2 = first row second bitplane
Byte 3 = second row first bitplane
Byte 4 = second row second bitplane
... Repeat for entire 8x16 character

I want to make sure I have it straight. A 'blank' row would be $00FF' 0 for first bitplane, ff for second bitplane?
RedComet
Guest
« Reply #4 on: November 27, 2007, 12:18:20 pm »

Quote from: Nightcrawler on November 27, 2007, 10:17:48 am
Red:

How is your font stored? I'm assuming:

Byte 1 = first row first bitplane
Byte 2 = first row second bitplane
Byte 3 = second row first bitplane
Byte 4 = second row second bitplane
... Repeat for entire 8x16 character

I want to make sure I have it straight. A 'blank' row would be $00FF' 0 for first bitplane, ff for second bitplane?

You got it.

EDIT: I updated my first post with a couple snapshots of ram.
« Last Edit: November 27, 2007, 12:29:13 pm by RedComet »
Nightcrawler
Guest
« Reply #5 on: November 27, 2007, 01:30:41 pm »

Potential easy solution here...

OR on bitplane 1 bytes. AND on bitplane 2 bytes because 'blank' is actually 1 on this bitplane, so we want the AND operation to give us 'blank' pixels only when BOTH data bits are blank, otherwise mark it.

That should work. STOP comparing for 0xFF. You don't care what the data is. For each row, you do OR for the first byte, AND for the second byte.

Example loop:

Code:
loop_core:
   lda !draw_buffer,x   ;load the first bitplane byte
   
combine_pixels:
   ora !vwf_buffer,x      ;OR the bitplane one data

store_pixels:
   sta !draw_buffer,x   ;store the first byte

    inx                           ;increment x for next byte
    lda !draw_buffer,x   ;load the second bitplane byte

combine_pixels2:
   and !vwf_buffer,x      ;AND the bitplane TWO data

store_pixels2:
   sta !draw_buffer,x   ;store the second byte

inc_and_loop:
   inx                                               
   cpx #$0020
   bne loop_core          ;do this for all 32 bytes(16 total rows)!



That should be all there is to it unless my brain has failed today which it often does with lack of sleep on work days. Wink
« Last Edit: November 28, 2007, 08:37:40 am by Nightcrawler »
RedComet
Guest
« Reply #6 on: November 27, 2007, 02:10:39 pm »

Thanks, NC. That worked except for one thing, you forgot to load the second plane before ANDing:

Code:
combine_buffers:
ldx #$0000
sep #$20

combine_plane_1:
lda !draw_buffer,x
ora !vwf_buffer,x
sta !draw_buffer,x

inx

combine_plane_2:
lda !draw_buffer,x
and !vwf_buffer,x
sta !draw_buffer,x

inc_and_loop:
inx                                               
cpx #$0020
bne combine_plane_1

rts

It works perfectly though. Thanks again, man! Cheesy
Nightcrawler
Guest
« Reply #7 on: November 27, 2007, 05:22:05 pm »

Thanks. Glad I could help! Sorry about the missing instruction. I know it gets a little loopy the more you think about it with so many bits and bytes and what's going on with what. I had to write a few things on paper before I came to the simple answer I gave you.

You had a slightly trickier 2bpp one than I normally see. In many cases 2bpp fonts I've seen don't even use all 4 colors like yours does. And yours just happened to use that nice combo of 00 on bit plane 1 and FF on bit plane 2  to make a 'blank' tile for added mental complications.

Hope this is some good information for some other people who may not be 100% clear on these things.

We're ready for 4bpp 16 color VWF now! I suppose you'd need a rainbow colored font or something for that!  :crazy:
tomaitheous
Guest
« Reply #8 on: November 27, 2007, 06:11:28 pm »

Hah! I thought that was a Genesis game you were working on...  Embarrassed ( Guess LDA should have been a dead give away)
Neil
Guest
« Reply #9 on: January 02, 2009, 08:29:11 am »

-necrobump to save a thread from the great board prune of 2009-
Pages: [1]  


Powered by SMF 1.1.4 | SMF © 2006-2007, Simple Machines LLC