Freeze the screen while updating the VRAM
Moderators: BigEvilCorporation, Mask of Destiny
Freeze the screen while updating the VRAM
Hello guys.
I'm trying to play an animation in the whole screen, by updating its 8x8 tiles and the palette.
The problem is, is possible to see how the palette and the tiles updates in the screen. I tried to get rid of this problem by freezing the screen, by disabling the display and interrupts meanwhile I update the info in VRAM. But this only seems to shut down the screen (everything goes to black) during this process.
What I can do to get rid of this?
I'm trying to play an animation in the whole screen, by updating its 8x8 tiles and the palette.
The problem is, is possible to see how the palette and the tiles updates in the screen. I tried to get rid of this problem by freezing the screen, by disabling the display and interrupts meanwhile I update the info in VRAM. But this only seems to shut down the screen (everything goes to black) during this process.
What I can do to get rid of this?
-
- Very interested
- Posts: 615
- Joined: Thu Nov 30, 2006 6:30 am
So you can't "freeze" the screen the way you describe. There is no framebuffer on the Genesis so the entire screen is rendered a line at a time every frame. That said, your goal is generally quite achieable.
Generally speaking, you want to do all your updates during VBLANK during which no rendering occurs. If you're using DMA, you can transfer a bit over 7KB per frame during this period. This is enough to transfer a couple hundred tiles which is one way to do animation, but a lot of animation on the Genesis doesn't involve transferring tiles at all, but just updating maps and sprite attributes to point at different tiles that were loaded into VRAM ahead of time.
If you're doing something that can't fit into a single frame transfer budget, then you'll need to do some sort of double buffering where you update tiles or maps in some part of VRAM that's not being used for the current frame of the animation.
Generally speaking, you want to do all your updates during VBLANK during which no rendering occurs. If you're using DMA, you can transfer a bit over 7KB per frame during this period. This is enough to transfer a couple hundred tiles which is one way to do animation, but a lot of animation on the Genesis doesn't involve transferring tiles at all, but just updating maps and sprite attributes to point at different tiles that were loaded into VRAM ahead of time.
If you're doing something that can't fit into a single frame transfer budget, then you'll need to do some sort of double buffering where you update tiles or maps in some part of VRAM that's not being used for the current frame of the animation.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
You need to leave the pattern name table and the patterns used alone while loading new patterns elsewhere in the vram, and new pattern names.
If you make the layer 128x32, you keep the pattern names for the first screen in the first 40 columns, and load the next screen pattern names in the next 40 columns. Then at the vertical blank, scroll the scroll over 40 columns and it will show the next screen all at once. If you use different colors for each frame, you need to load the next colors into a different palette than the current color, and set the palette for those colors in the pattern names. So the current frame may use palettes 0 and 1 (for 32 colors0) while the next frame uses palettes 2 and 3.
All this double-buffering takes space, so you probably won't be able to do full screen frames unless you find a way to cut the number of patterns used by each frame.
If you make the layer 128x32, you keep the pattern names for the first screen in the first 40 columns, and load the next screen pattern names in the next 40 columns. Then at the vertical blank, scroll the scroll over 40 columns and it will show the next screen all at once. If you use different colors for each frame, you need to load the next colors into a different palette than the current color, and set the palette for those colors in the pattern names. So the current frame may use palettes 0 and 1 (for 32 colors0) while the next frame uses palettes 2 and 3.
All this double-buffering takes space, so you probably won't be able to do full screen frames unless you find a way to cut the number of patterns used by each frame.
Hello,
This is something I'm curious about, I'm just starting genesis coding, and didn't tried DMA yet, but I always read on tech docs and forum that DMA can only transfer 7kb of datas during vblank.
What's happening if we transfer data during screen rendering ?
Does this make glitch appearing on screen ? or can we do it, as long as the data transfered are not yet used on the currently rendered screen ?
This is something I'm curious about, I'm just starting genesis coding, and didn't tried DMA yet, but I always read on tech docs and forum that DMA can only transfer 7kb of datas during vblank.
What's happening if we transfer data during screen rendering ?
Does this make glitch appearing on screen ? or can we do it, as long as the data transfered are not yet used on the currently rendered screen ?
Retro game programming !
-
- Very interested
- Posts: 615
- Joined: Thu Nov 30, 2006 6:30 am
That's roughly correct. 7KB actually goes a fairly long way with the Genesis video hardware though. The sprite attribute table is only 640 bytes. The name tables for the BG planes are only 2-bytes per tile. So you can upload a new sprite list, do some name table updates and still have some bandwidth to spare for uploading some new tiles.Orion_ wrote:This is something I'm curious about, I'm just starting genesis coding, and didn't tried DMA yet, but I always read on tech docs and forum that DMA can only transfer 7kb of datas during vblank.
Depends on the DMA destination. DMA to VRAM is safe (as long as the part of VRAM you're DMA-ing too is not being used). DMA to CRAM will generally result in some garbage pixels onscreen. Unlike VRAM, the VDP is constantly reading from CRAM during the entire visible portion of the display and it's not dual-ported so writes cause whatever color you're writing to be displayed rather than the color the VDP was trying to read. I'm not sure about VSRAM.Orion_ wrote:What's happening if we transfer data during screen rendering ?
Does this make glitch appearing on screen ? or can we do it, as long as the data transfered are not yet used on the currently rendered screen ?
Also keep in mind, that there's not a lot of available DMA bandwidth during the active display, only 18 bytes per line. You're better off doing all your DMA during VBLANK and saving the active display period for your game logic.
Thanks for the details, so, I understand now, if it can only transfer 18 bytes per line during active display, while holding the 68k, it's not really useful.
I thought you could transfer at fullspeed during active display, so transferring a complete screen for example..
but It's just logical, the vram need to have alsmost full access for the active display.
I thought you could transfer at fullspeed during active display, so transferring a complete screen for example..
but It's just logical, the vram need to have alsmost full access for the active display.
Retro game programming !
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
Don't know if you're using SGDK or not but if you are, you may try to use the bitmap mode. It may help you in doing animation, you just need to fill the frame buffer and the API automatically convert and send it to the VRAM.
You may look in the header file to learn a bit mode about the bitmap engine in SGDK :
http://code.google.com/p/sgdk/source/br ... lude/bmp.h
Due to hardware limitation (ram / bandwidth), the bitmap mode is limited to 256x160 resolution at update rate of 20 FPS in NTSC and 25 FPS in PAL.
There is double buffering support so you can prepare your next frame while the current frame is being transfered.
You may look in the header file to learn a bit mode about the bitmap engine in SGDK :
http://code.google.com/p/sgdk/source/br ... lude/bmp.h
Due to hardware limitation (ram / bandwidth), the bitmap mode is limited to 256x160 resolution at update rate of 20 FPS in NTSC and 25 FPS in PAL.
There is double buffering support so you can prepare your next frame while the current frame is being transfered.
For my first test I used the everdrive sdk which seems based on sgdk, but I have the sgdk too
I think I got it
NTSC 262 lines total
PAL 312 lines total
224 lines of active display
dma speed during vblank 205 bytes per line
NTSC vblank total (262-224)*205=7790
PAL vblank total (312-224)*205=18040
Res (256*160)/2=20480
NTSC 20480/7790 ~= 3 -> 60/3 = 20fps
PAL 20480/18040 ~= 2 -> 50/2 = 25fps
Well 256*160 is not very 4/3 friendly, but I think I will try it. I have a little intro video for my game and wanted to try something like cd streaming, but I think it will not be easy to do.
I will definitely look at the sgdk sources to understand who everything works
Stef > D'ailleurs j'ai posté ici sur ton topic a propos d'info sur le son http://www.yaronet.com/posts.php?sl=0&s ... =2&h=51#51
I think I got it
NTSC 262 lines total
PAL 312 lines total
224 lines of active display
dma speed during vblank 205 bytes per line
NTSC vblank total (262-224)*205=7790
PAL vblank total (312-224)*205=18040
Res (256*160)/2=20480
NTSC 20480/7790 ~= 3 -> 60/3 = 20fps
PAL 20480/18040 ~= 2 -> 50/2 = 25fps
Well 256*160 is not very 4/3 friendly, but I think I will try it. I have a little intro video for my game and wanted to try something like cd streaming, but I think it will not be easy to do.
I will definitely look at the sgdk sources to understand who everything works
Stef > D'ailleurs j'ai posté ici sur ton topic a propos d'info sur le son http://www.yaronet.com/posts.php?sl=0&s ... =2&h=51#51
Retro game programming !