Page 3 of 7

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sat Apr 25, 2015 1:10 pm
by tepples
What would the intro look like if dithered to Arne's 4-bit palette throughout? If I can see the result of that, I might be able to suggest strategies to search for a good 2-bit additive blend palette.

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sat Apr 25, 2015 1:13 pm
by Drew Sebastino
tepples wrote:I might be able to suggest strategies to search for a good 2-bit additive blend palette.
I think the 6bpp option seems much more realistic. It could also be a bigger picture at the same framerate than the 8bpp version, which would be the advantage on the SNES side of things.

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sat Apr 25, 2015 3:59 pm
by Sik
tepples wrote:What would the intro look like if dithered to Arne's 4-bit palette throughout? If I can see the result of that, I might be able to suggest strategies to search for a good 2-bit additive blend palette.
Eh, I prefer this one (colors may be tweaked but idea is there) but I imagine it wouldn't work well here:

Image

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sat Apr 25, 2015 4:05 pm
by Drew Sebastino
Where's the skin color though?

(This is a bit random, but I think in Arne's palette, night blue and shade green should be compromised into one dark color, because they are nearly the same. This would leave room for a dark grey, which really appears to be needed.)

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sat Apr 25, 2015 4:16 pm
by Sik
Espozo wrote:Where's the skin color though?
Last one, but yeah it may be a bit too pink (but again, may deserve some tweaking, the idea is what colors should go there). To be fair, the original purpose was to use this palette to dither down true color images in a lazy way anyway.

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sat Apr 25, 2015 4:20 pm
by Drew Sebastino
I just feel that with limited palettes, it's best to go for something a little "muted" so you can kind of use colors around other colors and it will look like there are more colors than there really are. A muted dark green could look like a dark grey next to a grey color, and it could also just look like dark green next to a normal green color. If you've ever seen so Commodore 64 artwork, you'll know what I mean.

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sat Apr 25, 2015 5:52 pm
by tepples
Espozo wrote:Where's the skin color though?
If the brown isn't good enough, such as for northern ethnicities, try dithering pink and orange.
(This is a bit random, but I think in Arne's palette, night blue and shade green should be compromised into one dark color, because they are nearly the same. This would leave room for a dark grey, which really appears to be needed.)
You ended up figuring it out: Arne's palette is designed for dithering. Dark gray is a checkerboard pattern of black and #999 gray, or dark brown and dark blue, or the like.

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sun Apr 26, 2015 12:27 am
by Near
Ramsis wrote:There's a catch though: I don't see how this can be achieved in 8 bpp (Mode 3) as the amount of tile data per frame exceeds 32K (i.e., no "page" switching).
There's a trick to this that I came up with a while ago.

Let's say your image takes up 40KB of VRAM space. So you can't get all 40KB of the next frame in without overwriting some of the current frame, right? But you can write ~16KB of the next frame in there while the screen is going to show the current frame. And then on the next frame, inside Vblank, you send the remaining 24KB of the image, and change the VRAM tiledata address between $0000 and $c000. Your tiledata requests can wrap around back to the beginning of VRAM again, so this works fine in practice.

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sun Apr 26, 2015 3:23 am
by Ramsis
Awesome, thanks for all the valuable feedback, guys! :)
Khaz wrote:Good luck! I don't know if it will be a problem for the Chrono Trigger video, but the last version of my program I posted to Github still fails when you have no 8x8 tiles with a full palette of colours, like a frame that's one solid colour for example. I've fixed that (and it'll run faster in those cases too), and I just posted the new version now...
Thank you!
Khaz wrote:EDIT: Oh yeah. If anyone else is doing video with the Quantomatic and you don't have a way to convert the .inc files into a .msu, I have another quick excel file that does that. I should give my python program the option to export raw binary files as well, to make that easier.
Indeed, the latter would be great. :D
byuu wrote:There's a trick to this that I came up with a while ago.

Let's say your image takes up 40KB of VRAM space. So you can't get all 40KB of the next frame in without overwriting some of the current frame, right? But you can write ~16KB of the next frame in there while the screen is going to show the current frame. And then on the next frame, inside Vblank, you send the remaining 24KB of the image, and change the VRAM tiledata address between $0000 and $c000. Your tiledata requests can wrap around back to the beginning of VRAM again, so this works fine in practice.
Brilliant! :shock: I didn't know it wraps around to $0000 again, so that's good to know. I just converted one frame to 8 bpp SNES graphics, it weighs in at 43.008 bytes.

Okay, let me translate your idea into pseudocode to make sure I understand it correctly. :)

Code: Select all

Vblank #n:
	DMA the first 16K of frame #n+1 to VRAM $6000
	Set VRAM tile data address to $0000

Frame #n:
	Not much to do here, just let it show up ;-)

Vblank #n+1:
	DMA the remaining 26.624 bytes of frame #n+1 to VRAM $0000
	DMA the palette of frame #n+1 to CGRAM
	Set VRAM tile data address to $E000 (due to VRAM word addressing, correct?)

Frame #n+1:
	Not much to do here, just let it show up ;-)
Hmm ... But is one Vblank enough time for a DMA of 26.624 bytes (+512 for the palette)? Apart from that, I'd be really glad if this worked, not only because of the higher number of colors, but also since it'd spare me all that frame processing. :D

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sun Apr 26, 2015 3:48 am
by 93143
Are you using NTSC or PAL? It should barely work on a PAL system if you load tile data into the unused portions of the tilemaps, but it's a no-go on NTSC because you have to preload too much of the new frame alongside the old frame and it blows past 64 kB. With 168 active scanlines, NTSC gives you a little over 15 kB DMA per frame, and PAL gives you a little over 23 kB.

NTSC:
VBlank n - load 13984 bytes to VRAM
VBlank n+1 - load 13984 bytes to VRAM (which now contains 43008+(2*1344)+27968 = 73664 bytes; oops)
VBlank n+2 - load 512 bytes to CGRAM and 15040 bytes to VRAM, switch tilemaps
20 fps

PAL:
VBlank n - load 19840 bytes to VRAM
VBlank n+1 - load 512 bytes to CGRAM and 23168 bytes to VRAM, switch tilemaps
25 fps

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sun Apr 26, 2015 5:28 am
by Near
> Okay, let me translate your idea into pseudocode to make sure I understand it correctly.

Hard to be sure with pseudocode, but essentially right, yeah.

Basically, you have frame# 1 in VRAM, and that's ready to draw on the next refresh. So while in Vblank, you write part of frame# 2 to the part of VRAM not used by frame# 1. Frame# 1 is refreshed onto the screen, and now you're in Vblank again. Now you write the remaining portion of frame# 2, and this overwrites part of frame# 1, but it's okay because we are going to finish the transfer. We change the VRAM tiledata address to the start of frame# 2, and the next refresh now draws frame# 2 for us.

As you can imagine, this is a technique that primarily benefits going from 15fps -> 20fps. If you try and push 30fps, then you have to upload frame# 2 and part of frame# 3 once frame# 1 has been drawn on the screen. That's a whole lot of data for one Vblank period.

> Hmm ... But is one Vblank enough time for a DMA of 26.624 bytes (+512 for the palette)?

I don't believe it's possible to draw 256x168(?)@30fps on NTSC, sorry.

I'm sure you know the trick to force-blank the screen during the horizontal blank lines, so you have 262-height lines for transferring tiledata. For each line, you can transfer 165.5 bytes of data to VRAM. So if you have 94 lines, that's a limit of 15,557 bytes. And you really should give yourself a bit more headroom, since you're unlikely to perfectly align your DMA to the start of Vblank and to complete exactly when it finishes (I'd recommend one scanline or so as a buffer.)

Your only options are to:
* reduce color depth, or
* reduce frame rate, or
* reduce resolution (reducing height is much more beneficial; but width still helps), or
* use Picture Always Lousy mode (and only ~1% of PC users will be able to Vsync @ 50hz)

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sun Apr 26, 2015 5:57 am
by Ramsis
Okay, once again ...

The video is 256×168, 15 fps, NTSC. One 8 bpp frame is 43.008 bytes of tile data plus 512 bytes palette data. As NTSC is ~60 Hz, I have 4 Vblanks to transfer that amount of data in, say, chunks of 12K.
byuu wrote:* reduce frame rate
But how does a framerate as low as 15 fps even help with ~43 KB of data having to be transferred and not glitching out by Vblank #n+2 due to data of the last frame getting overwritten? :?:

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sun Apr 26, 2015 8:13 am
by Drew Sebastino
It appears we're ok for this, but has anyone ever considered pushing a little extra tile data using HDMA? You could probably use all 8 HDMA channels.

(Again though, I really think someone should try a transparent 4bpp BG. It would be the exact same amount of memory as a 8bpp BG, but it would have tons and tons more color.)

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sun Apr 26, 2015 8:42 am
by Near
> But how does a framerate as low as 15 fps even help with ~43 KB of data having to be transferred and not glitching out by Vblank #n+2 due to data of the last frame getting overwritten?

If the frame size is too much to complete in the final Vblank before displaying, then it won't help. You will be forced to lower the resolution/refresh/depth.

This technique I'm suggesting won't allow perfect 60fps video at 256x224 :P
But it will increase the maximum resolution you can achieve by a moderate amount.
So if you're trying to push things to the absolute limit, this will be something you'll want to do :D

> It appears we're ok for this, but has anyone ever considered pushing a little extra tile data using HDMA? You could probably use all 8 HDMA channels.

That would only work on ZSNES.

Re: Finally on MSU1: Chrono Trigger with anime intro ;-)

Posted: Sun Apr 26, 2015 8:56 am
by Khaz
Ramsis wrote:
Khaz wrote:EDIT: Oh yeah. If anyone else is doing video with the Quantomatic and you don't have a way to convert the .inc files into a .msu, I have another quick excel file that does that. I should give my python program the option to export raw binary files as well, to make that easier.
Indeed, the latter would be great. :D
Just wrote that in real quick. You can now send it a -b flag to make it output one binary file INSTEAD of the three .inc files, then all you have to do is combine the .bin files into an MSU and you're done. Running a quick test, I'll publish it when it's confirmed working.

Notes: The binary file goes in order of Tile Set, Tile Map, and then Palettes. The tile set and tile map scale in size to the height of the image. The palettes chunk should always contain the target number of palettes and always be the same size, even though there's a slim chance that my program can output less than the target number of palettes if the image is really low on colour. (If you use .inc output, you have to correct for the possibility of not enough palettes when compiling to an MSU...)

EDIT: Test one failed, retrying. I wish Python would actually scan through all the code at the moment you launch it, and not wait until after an hour of processing to tell you "Oh hey you never defined this one variable". (Yes I know variables may or may not be defined depending on conditional branching but clearly it could recognize when a declaration does not exist anywhere)