News:

11 March 2016 - Forum Rules

Main Menu

Getting Started on a VWF?

Started by justin3009, April 11, 2011, 10:57:08 AM

Previous topic - Next topic

tryphon

For semi-dynamic rendering, would it be possible to store in RAM the last rendered char, and when rendering a new char :

- adding the new pixels to the last rendered char in RAM
- then DMA from RAM to VRAM

It would permit to benefit both of the pre-shifted chars in ROM (you'll need 8 versions of each glyph), and use it for dialogs.

I think I'll take this approach for Genesis games (though I think the 68000 is fast enough to make the logical shifts at runtime), but I don't know if it's doable for SNES. Its processor is know to be slow, but I don't know to which extent...

Nightcrawler

What the article means is rendering all of the menus and items once ahead of time, and storing the results in ROM. Then you simply DMA them like pre-rendered graphics when you need them. That's how you could do a VWF 8x8 menu in 2 frames. The only things that need to be done dynamically are variables such as Gemini mentioned earlier. Even that can be worked around to some degree depending on the specific variables in question.

Dynamic rendering refers to combining the letters and drawing out the tiles in RAM on demand, while static rendering is simply copying the pre-rendered data from straight from ROM to VRAM. Dynamic text rendering vs. static graphics loading.
TransCorp - Over 20 years of community dedication.
Dual Orb 2, Wozz, Emerald Dragon, Tenshi No Uta, Glory of Heracles IV SFC/SNES Translations

justin3009

Quote from: Nightcrawler on January 19, 2014, 06:48:37 PM
What the article means is rendering all of the menus and items once ahead of time, and storing the results in ROM. Then you simply DMA them like pre-rendered graphics when you need them. That's how you could do a VWF 8x8 menu in 2 frames.

That almost sounds like 'faking' a VWF by using the graphics tiles in ROM as different 8x8 blocks.

I didn't think you could store the data straight INTO ROM though and use it from there.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

tryphon

What's really so slow when doing static rendering ?

Nightcrawler

Quote from: justin3009 on January 19, 2014, 07:09:14 PM
That almost sounds like 'faking' a VWF by using the graphics tiles in ROM as different 8x8 blocks.

There's nothing fake about it. A proportional font is a proportional font whether it is pre-rendered and static or dynamically rendered and done in real time. Regardless of what you think about it, that's simply what the article is about. I'm just explaining it to you.

Quote
I didn't think you could store the data straight INTO ROM though and use it from there.

Of course you can. Render all of the menus and grab the resulting tiles. Render ALL of the items in the game and gather those results. Do whatever you need to do to pre-render the text to get the results. Then, assemble a new ROM and store them all in the ROM. That's precisely what static rendering implies for this. It's pre-rendered, it's static. You are no longer dynamically rendering the text. You're not drawing to RAM, you're not drawing to anything but the tilemap, and even that can be statically stored in the ROM too. This the way it is done in 2 frames as demonstrated by the article.
TransCorp - Over 20 years of community dedication.
Dual Orb 2, Wozz, Emerald Dragon, Tenshi No Uta, Glory of Heracles IV SFC/SNES Translations

justin3009

I'm wondering if it's similar or the 'same' thing I had going on Tales of Phantasia to a point?



I had all that pre-rendered then I just plopped it back into ROM.  It's using the empty tiles as a basis for it's text.

Is this basically what it is except it pulls the data from ROM instead when it needs it?  If so, I could easily see this work for item names.

The biggest thing I noticed was that Bahamut Lagoon's item descriptions were lightning fast while Tales of Phantasia's were ridiculously slow.  Were Bahamut Lagoon's descriptions also pre-rendered?  Even if I cut out all the excess on TOP, it's ridiculously slow regardless, which is what caught my eye.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Nightcrawler

Yep, that's pretty much it. Now you're catching on. ;)

I hope I did not confuse you with the wrong idea about the ROM though. While all of this pre-rendered static data is in-fact in the ROM, you still must copy/DMA it all to available VRAM space and map the appropriate tiles to it so it shows up on screen. You can't display anything straight from the ROM. I'm sure you did just that with the example you've pictured though or it wouldn't have worked!

I can't comment on ToP or BL as I haven't played or looked at either in ages. There could be more than one reason why one would be speedier than the other. You'll have to dig deeper and see what's being done if you're interested.
TransCorp - Over 20 years of community dedication.
Dual Orb 2, Wozz, Emerald Dragon, Tenshi No Uta, Glory of Heracles IV SFC/SNES Translations

justin3009

#87
I've been digging through their routines on the item description and I'm just lost on why it's superior in every way.  Chrono Trigger's is the same way actually.  Though, that game just renders it tile by tile on screen, you CAN force it to draw the entire string at once and even then, it's a HELL of a lot faster than Tales of Phantasia's.  I'm really unsure why that's so. 

It seems it must be in the VWF code or something in general with it.  If I remove everything else, it's still laggy.  Cut out the entire way to write the description and you can fly through the items no problem.

----------------------------------------------------

Edit: If I were trace Tales of Phantasia's VWF routine, label as much as I can and post the code, would I be able to get some help on figuring out why it's so slow and ways to improve the code?
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

justin3009

#88
Popping this back up.. again (For like the eighth time) but this time about pre-rendered font!

Is there anyway to have a check to see where data is in VRAM or would it be better to go the route of 'manual' placement?

For example I mean in this image.


Would it be plausible to have it check for a certain 'end' of pixels and then the next item would be written directly next to it? Like, where HP and TP are.  It'd transfer 'HP' over until it hits '00 00 00 00' or something then stop.  After that, it'd hold the position it's at in VRAM, check if there's any slots left in the 8x8 tile, if so, add that to the next storage point.  It'd then store a 'blank' 8x8 tile then the next object you want to transfer would be stored directly AFTER that blank.  Is this a good idea, rather, a POSSIBLE idea?  It'd save a horrific amount of code and data while actually maintaining VRAM nicely.

This would especially help when it came to items, spells, etc..

Edit: The other method I can think of is to have the VRAM location be stagnant and it'd carry that over for each transfer.  Though there'd be a byte to dictate each transfers size that WOULDN'T transfer.  So it'd essentially be consecutive.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

FinS


Are you using a register map. This will all be in it. The register for reading VRAM data is $2139 and to set the address is $2116 and to set the address increment is $2115, but this would not be practical to use because VRAM can only be accessed during blanking. If you absolutely had to get values out of VRAM those are the registers you would use.

It sounds like you are planning a hybrid of static / dynamic rendering. This would probably be best accomplished using WRAM to assemble the tiles which would defeat some of the purpose of pre-rendering.

justin3009

#90
I'm using a mixture of both due to how the game handles it's data.

When I went flat out dynamic, it actually caused a significant amount of lag (Though that was probably my terrible coding).  Most of the data in-game will be static but certain things like PC Names will have to be dynamic due to being able to change them.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

justin3009

...And we're back once more <3 (Anyone else noticed it's like on a yearly basis this pops up and seemingly around similar times?)

So I decided this is PROBABLY the best time to tackle a VWF since it's with a game that has a really, really simple routine to modify.  If anyone's been following my topics, you can probably guess that it's Sailor Moon SuperS - Fuwa Fuwa Panic!

The routine originally stored ALL the tiles it used for the font into VRAM (Which.. was really frikin horrendous for a game like this.  SO, SO MUCH wasted room).  It was a pretty basic routine.  Pick out from VRAM where it loads, update tilemap, blah.

I've altered the routine heavily so 'at this moment' it picks the letter from ROM and sends it into VRAM as it's needed.  I'm holding off with the ROM --> RAM --> VRAM bit until I've got the right idea of what's going on with a VWF, but I'm fairly confident I can get this working.  I took a test whack with the idea I thought was correct (Obviously was wrong), but I see that the only problem I technically had was how it was storing everything as I'm not sure exactly how to space things properly.

So basically, what the heck do I do from here after the ROM --> VRAM is altered to ROM --> RAM --> VRAM?

I think my biggest issue is understanding the whole shifting bit.  I really do not understand that aspect, even re-reading it, it doesn't click with me on how it works.  Do I load the location of the letter from ROM, store it then shift things or.. just what?  I KNOW I can get this now, I just really need help on understanding the main portion of what should be going on.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Gemini

It depends entirely on what you need it for. Example: you need a dialog box with proportional rendering. You have a number of options, if your game prints characters in sequences, rather than a single pass. In this case, the simplest solution used by some games is to have a line of dialog stored in a region of RAM used like a canvas, and you DMA transfer every character update. Seek to next line? Clear the buffer and start over again, until you hit the end.

As for the actual execution of canvas code, it's nothing more than bit logic. You shift a lot and OR the result to your tile canvas. This is some old C code I had for a DS project, which works with canvas logic: http://pastebin.com/GFKQ1cZV
Check RenderCanvasChar from line 219, that's where the VWF magic happens. It should help you understanding a bit better the logic, although SNES graphics work a little differently.

justin3009

In this game's case, the RAM canvas would be completely blank and be written to as the dialogue is going.  After each letter, it'd send the whole section into VRAM and the tilemap would be updated accordingly (Which works fine with no noticeable lag)

But what exactly do I shift?  The C code looks like it just grabs the bits of the letter, shifts it right however then adds it back to the buffer.  (Would the buffer in this case be the RAM canvas or would it be essentially how many bytes are available to write to or..?).

If that's the case, would I just load the first couple bytes (maybe the first byte?) of the letter it calls from ROM, ROR it, send to RAM, load the next bit, ROR it then OR it with the last value there or.  I'm just lost on that aspect really.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Gemini

The code shifts to the left and ORs when it needs a pixel merge, otherwise it shifts to the right when it needs to fill a new tile. In other words, left shift pushes the tile to right in terms of graphics, while right shift does the exact opposite. On SNES it's the opposite iirc and you also need to account for how planar works in representing scanlines.

Another solution to VWF with no shifting is represented by having multiple copies of the font with tiles already shifted, which drastically reduces overheat due to looping a lot per tile. In that case you'd only have to OR for a merge and assign for pushing a new tile.

justin3009

I'd prefer to go the straight up route of having it pull the letters from one font set instead of multiples.

So then if I understand any of this correctly: It grabs the font graphics, shifts it to the left and repeats the process until it hits the end of the 'width'.  Once it does, if there's another letter or anything after, it ORs it so it can merge the two bits together after that space?
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Gemini

Quote from: justin3009 on July 08, 2015, 11:19:26 AMI'd prefer to go the straight up route of having it pull the letters from one font set instead of multiples.
That would be only useful for screens with intensive lag due to shifting. Otherwise you probably don't need it.

QuoteSo then if I understand any of this correctly: It grabs the font graphics, shifts it to the left and repeats the process until it hits the end of the 'width'.  Once it does, if there's another letter or anything after, it ORs it so it can merge the two bits together after that space?
It reads, left shifts, ORs and writes when you push a tile to merge, then it simply reads, right shifts and writes if you have graphics left from a previous tile. In other words: x%8 != 0 -> read+left shift+or+write, otherwise read and write; data left from tile? Read+right shift+write.

justin3009

#97
Hm.. maybe I'm going about this the wrong way.  The original idea I had was to just have it sequentially keep writing to RAM and send the whole chunk into VRAM at once.

Would it be easier if I had just a very small section of RAM, maybe enough room for a one line sentence in itself (Relatively small chunk overall), and have that be like a scratchpad?  It'd write the letter first, if any space left, merge with the next letter via ROR/ORA otherwise just take that letter and send to VRAM?

Or would I need to have two sections essentially.  One for a scratchpad for the letter and another for the 'actual' area to be transferred into VRAM?
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

tryphon

Quote from: Gemini on July 08, 2015, 11:53:13 AMdata left from tile? Read+right shift+write.

It's slighter easier if you use 16 bits words. But maybe SNES has not 16 bits data registers ?

mziab

Quote from: tryphon on July 08, 2015, 02:15:48 PM
It's slighter easier if you use 16 bits words. But maybe SNES has not 16 bits data registers ?

The SNES does have 16-bit registers. Otherwise it would be a pretty poor 16-bit console :) And in fact that's a good trick I like to use to avoid left-shifts altogether.