Introduction Hi, this is a very early version of my sprite tutorial (it's not even finished yet), the aim behind this tutorial is to show people a step by step guide to displaying 2d graphics (eventually) Updates : None so far, just this first release 18/08/98 I will update this tutorial in a couple of days, hopefully Acknowledgments : Er, well most of the info in this is from the Sony User Guide, and the Sony Library Reference Manual, so thanks to Sony. Thanks to Peter Passmore and Robert Swan for running the net yaroze short course that I went to, which refined how I went about doing things. I can't think of anyone else, so I will just leave it at this. Notice : This is by no means the perfect way to code, I don't know if the method I use is efficient or not, all this is meant to do is show how to get something up and running. Ordering Tables Ordering Tables (OTs), are something you really need to understand and are a crucial part to using the net yaroze. The Sony User Guide only explains the OTs use with 3D objects but the same thing applies for using 2D graphics. The OT is basically a register, and using a GsSort...() function puts a drawing command into the register (the OT) with a priority, this can then be used by the graphics system to figure out what objects should be drawn in the background and what should be drawn in the foreground. A simpler way to understand it is with an example; say you are doing a 2D beat-em-up you will have your background, and your fighters. Using the GsSort...() function you put your background and fighters into the OT, know you want your fighters to be in front of the background so you would set the priority of your fighters to say 0, and the priority of your background to 2. When the objects are drawn the graphics system will use the commands in the OT to know that the background must be drawn behind the fighters and the fighters must be drawn in front of the background. PACKETS A packet is the smallest drawing command that can be executed by the GPU, all that you need to know about packets is that they are used to define a temporary drawing area that will be used to draw to the frame buffer. The problem is that this area has to be defined by you in your program, and this area has to be large enough for what you will be drawing or your program will lock up. The following is a good way of calculating the packet size your program will need, I can't remember where I saw this but it works. You first create a couple of Global definitions, such as #define NUM_OF_SPRITES (?) #define MAX_NUM_SPRITES (NUM_OF_SPRITES + 1) The ? should be replaced by the number of sprites that you will be drawing, for example if you have 8 sprites it would be 8, the second definition just adds one to the number, just to create an area that will be large enough, you then create the packet area by doing this, PACKET GpuPacketArea[2][MAX_NUM_SPRITES*24]; You need to create two packet areas (one for each buffer), MAX_NUM_SPRITES*24 is done to create the size of the packet area, the number 24 is the average size of a GsSPRITE. FRAME BUFFER The frame buffer is 1MB of VRAM (Video RAM) that is used by the GPU. The best way to describe the frame buffer is that it is actually a 1024*512 two-dimensional address space composed of 16-bit pixels. The top-left position is (0,0) and the bottom-right position is (1023,511). The frame buffer contains your display area and drawing area, the display area is the same size as the screen resolution that you use, the drawing area may be any size that can be accommodated in the frame buffer. Structures Used For 2D Graphics The following is a description of some of the structures that will be used in the program GsSPRITE : The GsSPRITE structure is a sprite handler, the members of the GsSPRITE structure are mostly don't require explanation, but I will explain them in the program listing. GsIMAGE : The GsIMAGE structure is used to hold information about a tim file. RECT : The RECT structure is a very useful structure, but in this case it will only be used to specify an area of the frame buffer to be accessed. Displaying A Sprite This uses example 1, the program is included with this document. The listing is commented and explains most of the things it does. Below is the basic algorithm it follows (roughly) // Example 1 #include // Contains all net yaroze functions #include "pad.h" // Contains pad definitions, for use with reading pads #define Screen_Width (320) // Screen resolution definitions #define Screen_Height (240) #define Sprite_Mem_Addr (0x80090000) // memory address of sprite #define OT_LENGTH (2) //Ordering Table length #define NUM_OF_SPRITES (1) // Used to calculate packet size #define MAX_NUM_SPRITES (NUM_OF_SPRITES + 1) // Used to calculate packet size GsOT WorldOT[2]; // OT headers GsOT_TAG OTTags[2][1<cx = timdata.cx; sprite->cy = timdata.cy; // Set Sprite attribute to specify colour depth sprite->attribute = (1<<24); // Set Screen position of sprite sprite->x = tx; sprite->y = ty; // Set width and height of sprite sprite->w = (timdata.pw*tmp2); sprite->h = (timdata.ph); // Get texture page sprite is on sprite->tpage = GetTPage(tmp1,0,timdata.px,timdata.py); // Set texture page offset from top-left of page sprite->u = timdata.px%64; sprite->v = timdata.py%256; // Set sprite brightness to normal sprite->r = sprite->g = sprite->b = 128; // Set sprite rotation point to center sprite->mx = (sprite->w/2); sprite->my = (sprite->h/2); // Set sprite size and orientation to normal sprite->scalex = ONE; sprite->scaley = ONE; sprite->rotate = 0; void RenderPrepare() // Stores what buffer is in use, in activeBuff activeBuff = GsGetActiveBuff(); // Initialises the OT GsClearOt(0,0,&WorldOT[activeBuff]); // Sets drawing command storage address GsSetWorkBase((PACKET *)GpuPacketArea[activeBuff]); void RenderFinish() // Waits for drawing to be completed DrawSync(0); // Waits for vertical synchronisation before moving on VSync(0); // Swaps display buffers GsSwapDispBuff(); // Registers a drawing clear command in the OT GsSortClear(0,0,0,&WorldOT[activeBuff]); // Executes the drawing commands in the OT GsDrawOt(&WorldOT[activeBuff]);