+  RHDN Forum Archive
|-+  Romhacking
| |-+  ROM Hacking Discussion
| | |-+  16x16 2bpp vwf
Pages: [1]
Author Topic: 16x16 2bpp vwf  (Read 2 times)
Gideon Zhi
Guest
« on: January 24, 2007, 01:35:40 am »

Alright, I'm having trouble getting this to work. It's the binary logic that's making my head spin, mostly; the code is generally functional, as it's a mashup of my Rudra no Hihou 1bpp vwf code (which does work.)

Here are some snaps of the tile layout. The first is the font in ROM; the second is the rendered font bitmap in RAM.


The idea behind the code is to load the tile into a scratchpad, rotate it to the right an equivalent number of shifts as the previous character required, then OR it with the font bitmap at $B080. Exceptions for not having to shift at all (a shift value of 0 or $10) have been accounted for and tested; they work fine. I've looked at the VWF examples in the database, but they're constructed differently... I apologize if my code's messy, I don't do VWFs very often.

Code:
$20 - Font address (ROM)
$0B - Bitmap write position (RAM)
FF00-FF7F - 2bpp Scratchpad
$FFE0 - Shift value

VWF:
  LDY #$0000
  SEP #$20

FontScratchpadCopyLoop1:
  LDA [$20],Y
  STA $FF00,Y
  INY
  CPY #$0010
  BNE FontScratchpadCopyLoop1
 
  REP #$20
  LDA $20
  CLC
  ADC #$0100
  STA $20
  SEP #$20
 
  LDY #$0000

FontScratchpadCopyLoop2:
  LDA [$20],Y
  STA $FF40,Y
  INY
  CPY #$0020
  BNE FontScratchpadCopyLoop2

;At this point, I've got my character into the scratchpad....
;Next is the shift loop.
  REP #$20
  LDA $FFE0
  AND #$00FF
  TAY
  SEP #$20
  LDX #$0000

;Y is now number of shifts
;X is offset to shift
;A is 16 bits wide
ShiftLoop0:
  PHY
  SEP #$20
ShiftLoop1:
  CLC
  ROR $FF00,X
  ROR $FF02,X
  ROR $FF04,X
  ROR $FF06,X
  CLC
  ROR $FF01,X
  ROR $FF03,X
  ROR $FF05,X
  ROR $FF07,X
  CLC
  DEY
  BNE ShiftLoop1
  INX
  INX
  INX
  INX
  INX
  INX
  INX
  INX
  PLY
  CPX #$0080
  BNE ShiftLoop0

;Merge scratchpad with buffer
  LDX #$0000
  LDY $0B
  REP #$20

BufferMerge:
  LDA $FF00,X
  ORA $0000,Y
  STA $0000,Y

  LDA $FF40,X
  ORA $0100,Y
  STA $0100,Y

  INX
  INX
  INY
  INY
  CPX #$0040
  BNE BufferMerge
 

The rest of it after this is cleanup and tilemap stuff, which does work. It's the meat that's broken; I get my addresses mixed up and confused :/ Figured I'd post this before going to bed with the hope that someone will come in the night and offer some help, hahah.

Edit: Updated the code with the bottom-half or/copy in the merge loop.
« Last Edit: January 24, 2007, 01:58:45 am by Gideon Zhi »
RedComet
Guest
« Reply #1 on: January 24, 2007, 01:52:55 am »

The only thing that stands out at me is ShiftLoop1. That looks like you're rotating too much data per iteration. Do you have a ram snap shot of the tile in the scratchpad before and after the shifts?
Gideon Zhi
Guest
« Reply #2 on: January 24, 2007, 01:59:23 am »

Before and after:


Bonus: here's what it looks like rendered in RAM by the bad routine.
RedComet
Guest
« Reply #3 on: January 24, 2007, 02:33:50 am »

I'm assuming your buffer is laid out like this in ram ($10 bytes for each 8x8 tile):

TopLeft : TopRight : TempTopLeft : TempTopRight: BottomLeft : BottomRight : TempBottomLeft : TempBottomRight


Code:
;I'm assuming X = 0

  ROR $FF00,X ;TopLeft Row 0
  ROR $FF02,X ;TopLeft Row 1
  ROR $FF04,X ;TopLeft Row 2
  ROR $FF06,X ;TopLeft Row 3

You're could here goes like this:

Shift TopLeft pixel row N
Catch Overflow and place on TopLeft pixel row N+1

When you should be:

Shift TopLeft pixel row N
Catch overflow and place on TopRight pixel row N, which would be $10 bytes away.

Code:
;I'll assume X = 0

  ROR $FF00,X ;TopLeft Row 0
  ROR $FF10,X ;TopRight Row 0

My brain's not up for calculating the position of the next tile, so that $10 bytes (whatever size the 8x8 tile is) may be different. But you're shifting one row of pixels and instead of catching the overflow on the neighboring tile, you're catching it on the row below the row being shifted.

Hope that makes sense.
Nightcrawler
Guest
« Reply #4 on: January 24, 2007, 10:20:54 am »

I'm not sure what you're trying to do with your shift loop, but you're not even using the 'number of shifts value' stored in y...

Here's an idea. How about you tell us what you INTENDED for the shift loop to do. Because I doubt it's doing it. I don't know how you could have possibly tested shift value cases like you said. Unless I have a case of the Mondays on Wednesday, you're not using the shift value in Y at all.
Gideon Zhi
Guest
« Reply #5 on: January 24, 2007, 11:26:03 am »

It's definitely using the value in Y:

  DEY
  BNE ShiftLoop1

I push the value in Y, run through the shift loop a number of times equivalent to the value in Y for a single line, then increase X and move on to the next line. In 1BPP at least, it looks like this:

Code:
ShiftLoop0:
PHY
SEP #$20
ShiftLoop1:
CLC
ROR $FF80,X
ROR $FF81,X
ROR $FF82,X
ROR $FF83,X
DEY
BNE ShiftLoop1
INX
INX
INX
INX
PLY
CPX #$0040
BNE ShiftLoop0

Basically what the shift loop's supposed to be doing is going through the tile in the scratchpad line by line, rotating the character over to the right an appropriate number of times (i.e. if the previous character ended on a 16x16 pixel position 6, the rotate loop rotates the new character over 6 + a pixel of padding, all stored in Y before the shift loop calls.) Then it's supposed to be merging it with the main buffer, line by line.
Gideon Zhi
Guest
« Reply #6 on: January 24, 2007, 01:47:36 pm »

Edit: Got it even cleaner!

Alright, I took KingMike's suggestion. Here's the new routine, and the new output. It almost works....


(original, for easy reference)


Code:
VWF:
  LDY #$0000
  SEP #$20

FontScratchpadCopyLoop1:
  LDA [$20],Y
  STA $FF00,Y
  INY
  CPY #$0020
  BNE FontScratchpadCopyLoop1
 
  REP #$20
  LDA $20
  CLC
  ADC #$0100
  STA $20
  SEP #$20
 
  LDY #$0000

FontScratchpadCopyLoop2:
  LDA [$20],Y
  STA $FF40,Y
  INY
  CPY #$0020
  BNE FontScratchpadCopyLoop2

;At this point, I've got my character into the scratchpad....
;Next is the shift loop.
  REP #$20
  LDA $FFE0
  AND #$00FF
  TAY
  SEP #$20
  LDX #$0000

;Y is now number of shifts
;X is offset to shift
;A is 16 bits wide
ShiftLoop0:
  PHY
  SEP #$20
ShiftLoop1:
  CLC
  ROR $FF00,X
  ROR $FF10,X
  ROR $FF20,X
  ROR $FF30,X
  ROR $FF40,X
  ROR $FF50,X
  ROR $FF60,X
  ROR $FF70,X
  CLC
  ROR $FF01,X
  ROR $FF11,X
  ROR $FF21,X
  ROR $FF31,X
  ROR $FF41,X
  ROR $FF51,X
  ROR $FF61,X
  ROR $FF71,X
  CLC
  DEY
  BNE ShiftLoop1
  INX
  INX
  PLY
  CPX #$0010
  BNE ShiftLoop0

;Merge scratchpad with buffer
  LDX #$0000
  LDY $0B
  REP #$20

BufferMerge:
  LDA $FF00,X
  ORA $0000,Y
  STA $0000,Y

  LDA $FF40,X
  ORA $0100,Y
  STA $0100,Y
  INX
  INX
  INY
  INY
  CPX #$0040
  BNE BufferMerge
 
« Last Edit: January 24, 2007, 01:55:43 pm by Gideon Zhi »
Gideon Zhi
Guest
« Reply #7 on: January 24, 2007, 02:18:32 pm »

Alright, fixed it. Had to trap for the drop-down at the end of the top row. All that's left is to fix some tilemapping issues Cheesy
Cyberman
Guest
« Reply #8 on: January 24, 2007, 02:25:08 pm »

Ack... well I was going to say the problem was your 'symbol wrap' algorythm. LOL.
Oh well glad it works for your sanitys sake.

Cyb
RedComet
Guest
« Reply #9 on: January 24, 2007, 05:31:42 pm »

Good job, Gid. Smiley
Nightcrawler
Guest
« Reply #10 on: January 24, 2007, 05:45:15 pm »

Oops Sorry Gid.  Embarrassed I indeed did have case of the Mondays on Wednesday. Higher level intelligence was not functioning today. Wink I don't know how I missed that. Maybe it was the eight INX statements.
KingMike
Guest
« Reply #11 on: January 24, 2007, 08:24:35 pm »

Quote from: Gideon Zhi on January 24, 2007, 01:47:36 pm
Alright, I took KingMike's suggestion. Here's the new routine, and the new output. It almost works....

I can't remember what my suggestion was, but it looks good just the same.
Gideon Zhi
Guest
« Reply #12 on: January 24, 2007, 08:32:56 pm »

It was redcomet's suggestion Sad My brain wasn't working at the time, I swear!
...seems like this is pretty common around here today, hah.
Neil
Guest
« Reply #13 on: January 01, 2009, 09:08:43 pm »

-necrobump to save a thread from the great board prune of 2009-
some arguably useful teaching type stuff in here.
Pages: [1]  


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