Going Hi-Res Often using 320*240 or thereabouts, gives a horribly low definition to the picture. Such that, it hinders the visual element of the game. We all like nice graphics and that, so to achieve smoother visuals high resolution is a must. In this document, I will give describe how to get into hi resolution. Any suggestions or criticisms on this document welcome. James Chow aka jc 22 June 1998 james@chowfam.demon.co.uk --------------------------------------------------------------- The Display ----------- In normal resolution the beam traces every line from top to bottom. However, due to the way a television works it is not possible to go in a higher resolution than the number of lines it can scan. In NTSC this is 262 and in PAL this is 312. Due to smart trickery, we can actually go higher than this. In interlaced mode, we display all the even scan lines in one frame, and in the subsequent frame all the odd scan lines. By rapidly changing between the two frames, we can effectively double the vertical resolution of the display. To work in interlaced we must initialise the graphics system by, GsInitGraph(SCNW,SCNH,GsOFSGPU|GsINTER,0,0); where SCNH is 480 or 512 appropriately. Since in interlaced mode, either even lines or odd lines are used, the frame buffer is optimised so that the display buffer and the off-screen buffer can overlap. We therefore set the two display buffers to overlap in the frame buffer, GsDefDispBuff(0,0,0,0); And that's it! Really? Not quite, read on. Hi-Res Restrictions ------------------- One of the problems in working in high resolution is that all calculations and drawing must be completed in time for the vertical retrace. There are no if's and but's here, it MUST be done otherwise the off screen buffer is displayed incomplete. To ensure that drawing is complete, we can either code it so that it will finish in time. If we don't know if this can be achieved, we must abort all the drawing commands at the time of the vertical retrace. We do this by VSync(0); ResetGraph(1); //erase drawing commands GsSwapDispBuff(); Another thing, I find when working in hi-res is the distinct lack of video memory. Say working in 640*512 PAL, leaves only 384*512 free for placing sprites. This is usually a very tight fit, which may result in having to scale down the original sprites. By scaling down the sprites, and then having to scale them back up again to the intended size for display loses the smoothness strived for in converting to hi-res. Augh!! Depending on the type of game being written, it may be better to use slight variations to the resolution. Using the concept of a scroller shoot-em-up, we can differentiate between the two. For a vertical scroller, the height definition is more important than the width and so working in hi-res vertically is more desirable. Say, 320*480.But this means having to keep to the vertical retrace conditions. On the other hand, for a horizontal scroller the horizontal definition is more important. So using, say 512*240 may be better. PAL Problems ------------ Unfortunately, there is an error in the libraries, such that it makes it impossible to display the maximum 512 lines. Basically the clipping range lies at 511, so the last line is not updated correctly. This gives rise to a whole host of problems. Obviously, the bottom line is not cleared during each frame. This means, when a sprite runs over the bottom line, a trace is left behind. Also, primitives exceeding vertical height of 512 are ignored, and this includes the very useful, GsSortClear(). One possible workaround to this problem is to work to 512 lines. And hide the bottom 2 lines, (we cannot hide one, since we are in interlaced mode). Also, manually clearing the background, either by drawing a suitably sized filled box, or by altering GsDRAWENV. Some Code --------- #define PALVER //comment this out for NTSC #ifdef PALVER #define SCRN_HEIGHT 512 #else #define SCRN_HEIGHT 480 #endif #define SCRN_WIDTH 640 void main(void) { #ifdef PALVER SetVideoMode(MODE_PAL); #else SetVideoMode(MODE_NTSC); #endif GsInitGraph(SCRN_WIDTH,SCRN_HEIGHT,GsOFSGPU|GsINTER,0,0); #ifdef PALVER GsDISPENV.screen.y = 20; GsDISPENF.screen.h = 255; //not 256! bug: can't use bottom line! GsDRAWENV.isbg = 1; GsDRAWENV.r0 = 0; //clear the background by GsDRAWENV GsDRAWENV.g0 = 0; GsDRAWENV.b0 = 0; #endif GsDefDispBuff(0,0,0,0); while(1) { //some game update code VSync(0); ResetGraph(1); //remove if can finish drawing in time GsSwapDispBuff(); //GsDrawOt(); } }